ae_page_objects 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ae_page_objects/core/application_router.rb +27 -8
- data/lib/ae_page_objects/core/dsl.rb +4 -4
- data/lib/ae_page_objects/element_proxy.rb +55 -11
- data/lib/ae_page_objects/exceptions.rb +9 -0
- data/lib/ae_page_objects/multiple_windows/window_handle_manager.rb +7 -0
- data/lib/ae_page_objects/multiple_windows/window_list.rb +23 -6
- data/lib/ae_page_objects/node.rb +2 -6
- data/lib/ae_page_objects/util/waiter.rb +3 -3
- data/lib/ae_page_objects/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5eeebecb74ccaec9739afd6183c3d8906ce2b9e
|
4
|
+
data.tar.gz: 6752901420af4fe99325e9735cbc3a5e9ddf68de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b420a7c14fcde32afb609815550643a84b828f58654ebee477e4ef3bbf762ef70ff01ad16d09f174a68eddaa881cb706e3656fc7153a2ed1df401cb409f28ea
|
7
|
+
data.tar.gz: 25adc0b0e01e95ed700ee6a1bae61544662441b877778609db2449c091e36bb419c45ed5459a68e7a435b3ddd1d2391d9ab392cd5a41d9c6d3ba8cf60dba818c
|
@@ -16,10 +16,24 @@ module AePageObjects
|
|
16
16
|
class Rails23 < Base
|
17
17
|
def recognizes?(path, url)
|
18
18
|
["GET", "PUT", "POST", "DELETE", "PATCH"].map(&:downcase).map(&:to_sym).each do |method|
|
19
|
-
|
20
|
-
|
19
|
+
path_route_result = ActionController::Routing::Routes.named_routes[path].requirements
|
20
|
+
recognized_result = nil
|
21
|
+
|
22
|
+
begin
|
23
|
+
recognized_result = ActionController::Routing::Routes.recognize_path(url, {:method => method}).select do
|
24
|
+
|key, _|
|
25
|
+
key.to_s.match(/(controller|action)/)
|
26
|
+
end
|
27
|
+
rescue ActionController::MethodNotAllowed
|
28
|
+
end
|
21
29
|
|
22
|
-
|
30
|
+
# Only the first recognized path returned by Rails is considered,
|
31
|
+
# which means, we only want highest prioritized route.
|
32
|
+
if recognized_result && path_route_result == Hash[recognized_result]
|
33
|
+
return true
|
34
|
+
else
|
35
|
+
next
|
36
|
+
end
|
23
37
|
end
|
24
38
|
|
25
39
|
false
|
@@ -44,14 +58,18 @@ module AePageObjects
|
|
44
58
|
|
45
59
|
["GET", "PUT", "POST", "DELETE", "PATCH"].each do |method|
|
46
60
|
router.recognize(request_for(url, method)) do |route, matches, params|
|
47
|
-
|
61
|
+
if route.name.to_s == path.to_s
|
62
|
+
return true
|
63
|
+
else
|
64
|
+
# We break the inner loop here because only the first recognized path returned by Rails is considered,
|
65
|
+
# which means, we only want highest prioritized route.
|
66
|
+
break
|
67
|
+
end
|
48
68
|
end
|
49
69
|
end
|
50
|
-
|
51
70
|
false
|
52
71
|
end
|
53
72
|
|
54
|
-
|
55
73
|
private
|
56
74
|
|
57
75
|
def request_for(url, method)
|
@@ -86,6 +104,7 @@ module AePageObjects
|
|
86
104
|
class Rails32 < Rails3
|
87
105
|
|
88
106
|
private
|
107
|
+
|
89
108
|
def url_and_router(url)
|
90
109
|
url = Journey::Router::Utils.normalize_path(url) unless url =~ %r{://}
|
91
110
|
router = ::Rails.application.routes.router
|
@@ -96,7 +115,8 @@ module AePageObjects
|
|
96
115
|
|
97
116
|
class Rails4 < Rails32
|
98
117
|
|
99
|
-
|
118
|
+
private
|
119
|
+
|
100
120
|
def url_and_router(url)
|
101
121
|
require 'action_dispatch/journey'
|
102
122
|
url = ActionDispatch::Journey::Router::Utils.normalize_path(url) unless url =~ %r{://}
|
@@ -105,7 +125,6 @@ module AePageObjects
|
|
105
125
|
[url, router]
|
106
126
|
end
|
107
127
|
end
|
108
|
-
|
109
128
|
end
|
110
129
|
|
111
130
|
def path_recognizes_url?(path, url)
|
@@ -143,14 +143,14 @@ module AePageObjects
|
|
143
143
|
|
144
144
|
item_class = options.delete(:contains) || options[:is].item_class
|
145
145
|
if block_given?
|
146
|
-
item_class =
|
146
|
+
item_class = Class.new(item_class, &block).tap do |new_item_class|
|
147
147
|
new_item_class.element_attributes.merge!(item_class.element_attributes)
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
151
|
# since we are creating a new item class, we need to subclass the collection class
|
152
152
|
# so we can parameterize the collection class with an item class
|
153
|
-
options[:is] = options[:is]
|
153
|
+
options[:is] = Class.new(options[:is])
|
154
154
|
options[:is].item_class = item_class
|
155
155
|
|
156
156
|
element(name, options)
|
@@ -162,7 +162,7 @@ module AePageObjects
|
|
162
162
|
raise ArgumentError, ":is option not supported" if options[:is]
|
163
163
|
raise ArgumentError, "Block required." if block.nil?
|
164
164
|
|
165
|
-
klass = ::AePageObjects::Form
|
165
|
+
klass = Class.new(::AePageObjects::Form, &block)
|
166
166
|
|
167
167
|
options = options.dup
|
168
168
|
options[:is] = klass
|
@@ -186,7 +186,7 @@ module AePageObjects
|
|
186
186
|
klass = options.delete(:is) || ::AePageObjects::Element
|
187
187
|
|
188
188
|
if block_given?
|
189
|
-
|
189
|
+
Class.new(klass, &block)
|
190
190
|
else
|
191
191
|
klass
|
192
192
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'timeout'
|
2
|
-
|
3
1
|
module AePageObjects
|
4
2
|
class ElementProxy
|
5
3
|
|
@@ -14,6 +12,8 @@ module AePageObjects
|
|
14
12
|
def initialize(element_class, *args)
|
15
13
|
@element_class = element_class
|
16
14
|
@args = args
|
15
|
+
|
16
|
+
@loaded_element = nil
|
17
17
|
end
|
18
18
|
|
19
19
|
# Provided so that visible? can be asked without
|
@@ -33,21 +33,45 @@ module AePageObjects
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def present?
|
36
|
-
|
36
|
+
wait_for_presence
|
37
|
+
true
|
38
|
+
rescue ElementNotPresent
|
39
|
+
false
|
37
40
|
end
|
38
41
|
|
39
42
|
def not_present?
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
wait_for_absence
|
44
|
+
true
|
45
|
+
rescue ElementNotAbsent
|
46
|
+
false
|
43
47
|
end
|
44
48
|
|
45
49
|
def presence
|
46
|
-
|
47
|
-
rescue
|
50
|
+
implicit_element
|
51
|
+
rescue LoadingElementFailed
|
48
52
|
nil
|
49
53
|
end
|
50
54
|
|
55
|
+
def wait_for_presence(timeout = nil)
|
56
|
+
is_present = Waiter.wait_for(timeout) do
|
57
|
+
! presence.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
unless is_present
|
61
|
+
raise ElementNotPresent, "element_class: #{@element_class}, options: #{@options.inspect}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def wait_for_absence(timeout = nil)
|
66
|
+
is_absent = Waiter.wait_for(timeout) do
|
67
|
+
check_absence
|
68
|
+
end
|
69
|
+
|
70
|
+
unless is_absent
|
71
|
+
raise ElementNotAbsent, "element_class: #{@element_class}, options: #{@options.inspect}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
51
75
|
def is_a?(type)
|
52
76
|
type == @element_class || type == ElementProxy
|
53
77
|
end
|
@@ -61,7 +85,7 @@ module AePageObjects
|
|
61
85
|
return @element_class
|
62
86
|
end
|
63
87
|
|
64
|
-
|
88
|
+
implicit_element.__send__(name, *args, &block)
|
65
89
|
end
|
66
90
|
|
67
91
|
def respond_to?(*args)
|
@@ -70,8 +94,28 @@ module AePageObjects
|
|
70
94
|
|
71
95
|
private
|
72
96
|
|
73
|
-
def
|
74
|
-
@
|
97
|
+
def load_element
|
98
|
+
@element_class.new(*@args)
|
99
|
+
end
|
100
|
+
|
101
|
+
def implicit_element
|
102
|
+
@loaded_element ||= load_element
|
103
|
+
end
|
104
|
+
|
105
|
+
def check_absence
|
106
|
+
load_element
|
107
|
+
|
108
|
+
false
|
109
|
+
rescue LoadingElementFailed
|
110
|
+
true
|
111
|
+
rescue => e
|
112
|
+
if Capybara.current_session.driver.is_a?(Capybara::Selenium::Driver) &&
|
113
|
+
e.is_a?(Selenium::WebDriver::Error::StaleElementReferenceError)
|
114
|
+
# ignore and spin around for another check
|
115
|
+
false
|
116
|
+
else
|
117
|
+
raise
|
118
|
+
end
|
75
119
|
end
|
76
120
|
end
|
77
121
|
end
|
@@ -13,6 +13,12 @@ module AePageObjects
|
|
13
13
|
class LoadingElementFailed < LoadingFailed
|
14
14
|
end
|
15
15
|
|
16
|
+
class ElementNotPresent < Error
|
17
|
+
end
|
18
|
+
|
19
|
+
class ElementNotAbsent < Error
|
20
|
+
end
|
21
|
+
|
16
22
|
class PathNotResolvable < Error
|
17
23
|
end
|
18
24
|
|
@@ -21,4 +27,7 @@ module AePageObjects
|
|
21
27
|
|
22
28
|
class CastError < Error
|
23
29
|
end
|
30
|
+
|
31
|
+
class WindowNotFound < Error
|
32
|
+
end
|
24
33
|
end
|
@@ -13,6 +13,13 @@ module AePageObjects
|
|
13
13
|
else
|
14
14
|
browser.window_handle
|
15
15
|
end
|
16
|
+
rescue => e
|
17
|
+
if Capybara.current_session.driver.is_a?(Capybara::Selenium::Driver) &&
|
18
|
+
e.is_a?(Selenium::WebDriver::Error::NoSuchWindowError)
|
19
|
+
raise WindowNotFound
|
20
|
+
end
|
21
|
+
|
22
|
+
raise
|
16
23
|
end
|
17
24
|
|
18
25
|
def self.switch_to(handle)
|
@@ -15,14 +15,21 @@ module AePageObjects
|
|
15
15
|
|
16
16
|
def opened
|
17
17
|
WindowHandleManager.all.map do |handle|
|
18
|
-
|
18
|
+
window_for(handle)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def current_window
|
23
23
|
current_handle = WindowHandleManager.current
|
24
24
|
|
25
|
-
|
25
|
+
window_for(current_handle) if current_handle
|
26
|
+
rescue WindowNotFound
|
27
|
+
synchronize_windows
|
28
|
+
|
29
|
+
if current_window = @windows[@windows.keys.sort.first]
|
30
|
+
current_window.switch_to
|
31
|
+
current_window
|
32
|
+
end
|
26
33
|
end
|
27
34
|
|
28
35
|
def close_all
|
@@ -31,12 +38,22 @@ module AePageObjects
|
|
31
38
|
|
32
39
|
private
|
33
40
|
|
34
|
-
def
|
35
|
-
@windows
|
41
|
+
def synchronize_windows
|
42
|
+
existence_unverified_window_handles = @windows.keys
|
43
|
+
|
44
|
+
WindowHandleManager.all.map do |handle|
|
45
|
+
# If it exists in the browser, it's been verified
|
46
|
+
existence_unverified_window_handles.delete(handle)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Remove the windows that no longer exist.
|
50
|
+
existence_unverified_window_handles.each do |non_existing_window_handle|
|
51
|
+
@windows.delete(non_existing_window_handle)
|
52
|
+
end
|
36
53
|
end
|
37
54
|
|
38
|
-
def
|
39
|
-
Window.new(self, handle)
|
55
|
+
def window_for(handle)
|
56
|
+
@windows[handle] ||= Window.new(self, handle)
|
40
57
|
end
|
41
58
|
end
|
42
59
|
end
|
data/lib/ae_page_objects/node.rb
CHANGED
@@ -26,6 +26,8 @@ module AePageObjects
|
|
26
26
|
class_eval <<-RUBY
|
27
27
|
def #{m}(*args, &block)
|
28
28
|
node.send(:#{m}, *args, &block)
|
29
|
+
rescue Capybara::ElementNotFound
|
30
|
+
raise AePageObjects::LoadingElementFailed
|
29
31
|
end
|
30
32
|
RUBY
|
31
33
|
end
|
@@ -51,12 +53,6 @@ module AePageObjects
|
|
51
53
|
def current_url_without_params
|
52
54
|
current_url.sub(/\?.*/, '')
|
53
55
|
end
|
54
|
-
|
55
|
-
def new_subclass(&block)
|
56
|
-
klass = Class.new(self)
|
57
|
-
klass.class_eval(&block) if block
|
58
|
-
klass
|
59
|
-
end
|
60
56
|
end
|
61
57
|
|
62
58
|
extend Dsl
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module AePageObjects
|
2
2
|
module Waiter
|
3
|
-
def self.wait_for(&block)
|
4
|
-
seconds_to_wait = Capybara.default_wait_time
|
3
|
+
def self.wait_for(wait_time = nil, &block)
|
4
|
+
seconds_to_wait = wait_time || Capybara.default_wait_time
|
5
5
|
start_time = Time.now
|
6
6
|
|
7
7
|
until result = Capybara.using_wait_time(0, &block)
|
@@ -17,4 +17,4 @@ module AePageObjects
|
|
17
17
|
result
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ae_page_objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Donnie Tognazzini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.1'
|
20
|
-
- -
|
20
|
+
- - <
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2.3'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '1.1'
|
30
|
-
- -
|
30
|
+
- - <
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.3'
|
33
33
|
description: Capybara Page Objects pattern
|
@@ -85,17 +85,17 @@ require_paths:
|
|
85
85
|
- lib
|
86
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- -
|
88
|
+
- - '>='
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- -
|
93
|
+
- - '>='
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: '0'
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.
|
98
|
+
rubygems_version: 2.1.11
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
101
|
summary: Capybara Page Objects pattern
|