page-object 2.0.0 → 2.1
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/.travis.yml +1 -2
- data/ChangeLog +10 -0
- data/README.md +12 -0
- data/Rakefile +2 -12
- data/cucumber.yml +2 -4
- data/lib/page-object.rb +12 -20
- data/lib/page-object/accessors.rb +50 -363
- data/lib/page-object/elements/bold.rb +0 -1
- data/lib/page-object/elements/button.rb +0 -4
- data/lib/page-object/elements/check_box.rb +19 -7
- data/lib/page-object/elements/div.rb +0 -4
- data/lib/page-object/elements/element.rb +159 -90
- data/lib/page-object/elements/file_field.rb +5 -7
- data/lib/page-object/elements/form.rb +0 -8
- data/lib/page-object/elements/hidden_field.rb +1 -4
- data/lib/page-object/elements/image.rb +13 -7
- data/lib/page-object/elements/label.rb +0 -4
- data/lib/page-object/elements/link.rb +0 -13
- data/lib/page-object/elements/list_item.rb +0 -3
- data/lib/page-object/elements/ordered_list.rb +30 -5
- data/lib/page-object/elements/radio_button.rb +12 -7
- data/lib/page-object/elements/select_list.rb +40 -8
- data/lib/page-object/elements/span.rb +0 -3
- data/lib/page-object/elements/table.rb +26 -5
- data/lib/page-object/elements/table_cell.rb +0 -4
- data/lib/page-object/elements/table_row.rb +30 -5
- data/lib/page-object/elements/text_area.rb +7 -7
- data/lib/page-object/elements/text_field.rb +5 -11
- data/lib/page-object/elements/unordered_list.rb +30 -5
- data/lib/page-object/indexed_properties.rb +1 -0
- data/lib/page-object/platforms.rb +0 -1
- data/lib/page-object/platforms/watir.rb +26 -4
- data/lib/page-object/platforms/watir/page_object.rb +4 -4
- data/lib/page-object/version.rb +1 -1
- data/lib/page-object/widgets.rb +0 -1
- data/page-object.gemspec +1 -15
- metadata +5 -47
- data/lib/page-object/platforms/selenium_webdriver.rb +0 -30
- data/lib/page-object/platforms/selenium_webdriver/button.rb +0 -15
- data/lib/page-object/platforms/selenium_webdriver/check_box.rb +0 -29
- data/lib/page-object/platforms/selenium_webdriver/element.rb +0 -335
- data/lib/page-object/platforms/selenium_webdriver/file_field.rb +0 -16
- data/lib/page-object/platforms/selenium_webdriver/form.rb +0 -16
- data/lib/page-object/platforms/selenium_webdriver/image.rb +0 -28
- data/lib/page-object/platforms/selenium_webdriver/link.rb +0 -23
- data/lib/page-object/platforms/selenium_webdriver/ordered_list.rb +0 -41
- data/lib/page-object/platforms/selenium_webdriver/page_object.rb +0 -1297
- data/lib/page-object/platforms/selenium_webdriver/radio_button.rb +0 -22
- data/lib/page-object/platforms/selenium_webdriver/select_list.rb +0 -93
- data/lib/page-object/platforms/selenium_webdriver/surrogate_selenium_element.rb +0 -42
- data/lib/page-object/platforms/selenium_webdriver/table.rb +0 -42
- data/lib/page-object/platforms/selenium_webdriver/table_row.rb +0 -43
- data/lib/page-object/platforms/selenium_webdriver/text_area.rb +0 -17
- data/lib/page-object/platforms/selenium_webdriver/text_field.rb +0 -17
- data/lib/page-object/platforms/selenium_webdriver/unordered_list.rb +0 -37
- data/lib/page-object/platforms/watir/check_box.rb +0 -29
- data/lib/page-object/platforms/watir/element.rb +0 -295
- data/lib/page-object/platforms/watir/file_field.rb +0 -16
- data/lib/page-object/platforms/watir/form.rb +0 -16
- data/lib/page-object/platforms/watir/image.rb +0 -22
- data/lib/page-object/platforms/watir/link.rb +0 -15
- data/lib/page-object/platforms/watir/ordered_list.rb +0 -40
- data/lib/page-object/platforms/watir/radio_button.rb +0 -22
- data/lib/page-object/platforms/watir/select_list.rb +0 -74
- data/lib/page-object/platforms/watir/table.rb +0 -38
- data/lib/page-object/platforms/watir/table_row.rb +0 -37
- data/lib/page-object/platforms/watir/text_area.rb +0 -23
- data/lib/page-object/platforms/watir/text_field.rb +0 -16
- data/lib/page-object/platforms/watir/unordered_list.rb +0 -42
@@ -2,9 +2,25 @@ module PageObject
|
|
2
2
|
module Elements
|
3
3
|
class CheckBox < Element
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
#
|
6
|
+
# check the checkbox
|
7
|
+
#
|
8
|
+
def check
|
9
|
+
element.set
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# uncheck the checkbox
|
14
|
+
#
|
15
|
+
def uncheck
|
16
|
+
element.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# return true if checkbox is checked
|
21
|
+
#
|
22
|
+
def checked?
|
23
|
+
element.set?
|
8
24
|
end
|
9
25
|
|
10
26
|
protected
|
@@ -13,10 +29,6 @@ module PageObject
|
|
13
29
|
super + [:value, :label]
|
14
30
|
end
|
15
31
|
|
16
|
-
def self.selenium_finders
|
17
|
-
super + [:value, :label, :css]
|
18
|
-
end
|
19
|
-
|
20
32
|
end
|
21
33
|
|
22
34
|
::PageObject::Elements.type_to_class[:checkbox] = ::PageObject::Elements::CheckBox
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'page-object/nested_elements'
|
2
|
+
require 'watir/extensions/select_text'
|
2
3
|
|
3
4
|
module PageObject
|
4
5
|
module Elements
|
@@ -6,7 +7,6 @@ module PageObject
|
|
6
7
|
# Contains functionality that is common across all elements.
|
7
8
|
#
|
8
9
|
# @see PageObject::Platforms::WatirWebDriver::Element for the Watir version of all common methods
|
9
|
-
# @see PageObject::Platforms::SeleniumWebDriver::Element for the Selenium version of all common methods
|
10
10
|
#
|
11
11
|
class Element
|
12
12
|
include ::PageObject::NestedElements
|
@@ -18,22 +18,6 @@ module PageObject
|
|
18
18
|
include_platform_for platform
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
22
|
-
# click the element
|
23
|
-
#
|
24
|
-
def click
|
25
|
-
element.click
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
# return true if the element is enabled
|
32
|
-
#
|
33
|
-
def enabled?
|
34
|
-
element.enabled?
|
35
|
-
end
|
36
|
-
|
37
21
|
#
|
38
22
|
# return true if the element is not enabled
|
39
23
|
#
|
@@ -41,12 +25,6 @@ module PageObject
|
|
41
25
|
not enabled?
|
42
26
|
end
|
43
27
|
|
44
|
-
#
|
45
|
-
# get the value of the given CSS property
|
46
|
-
#
|
47
|
-
def style(property = nil)
|
48
|
-
element.style property
|
49
|
-
end
|
50
28
|
|
51
29
|
def inspect
|
52
30
|
element.inspect
|
@@ -81,12 +59,169 @@ module PageObject
|
|
81
59
|
end
|
82
60
|
end
|
83
61
|
|
62
|
+
#
|
63
|
+
# Keeps checking until the element exists
|
64
|
+
#
|
65
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
66
|
+
#
|
84
67
|
def check_exists(timeout=::PageObject.default_element_wait)
|
85
68
|
timed_loop(timeout) do |element|
|
86
69
|
element.exists?
|
87
70
|
end
|
88
71
|
end
|
89
72
|
|
73
|
+
#
|
74
|
+
# return true if an element is visible
|
75
|
+
#
|
76
|
+
# def visible?
|
77
|
+
# element.present?
|
78
|
+
# end
|
79
|
+
|
80
|
+
#
|
81
|
+
# compare this element to another to determine if they are equal
|
82
|
+
#
|
83
|
+
def ==(other)
|
84
|
+
other.is_a? self.class and element == other.element
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Get the value of a the given attribute of the element. Will
|
89
|
+
# return the current value, even if this has been modified
|
90
|
+
# after the page has been loaded. More exactly, this method
|
91
|
+
# will return the value of the given attribute, unless that
|
92
|
+
# attribute is not present, in which case the value of the
|
93
|
+
# property with the same name is returned. If neither value is
|
94
|
+
# set, nil is returned. The "style" attribute is converted as
|
95
|
+
# best can be to a text representation with a trailing
|
96
|
+
# semi-colon. The following are deemed to be "boolean"
|
97
|
+
# attributes, and will return either "true" or "false":
|
98
|
+
#
|
99
|
+
# async, autofocus, autoplay, checked, compact, complete,
|
100
|
+
# controls, declare, defaultchecked, defaultselected, defer,
|
101
|
+
# disabled, draggable, ended, formnovalidate, hidden, indeterminate,
|
102
|
+
# iscontenteditable, ismap, itemscope, loop, multiple, muted,
|
103
|
+
# nohref, noresize, noshade, novalidate, nowrap, open, paused,
|
104
|
+
# pubdate, readonly, required, reversed, scoped, seamless, seeking,
|
105
|
+
# selected, spellcheck, truespeed, willvalidate
|
106
|
+
#
|
107
|
+
# Finally, the following commonly mis-capitalized
|
108
|
+
# attribute/property names are evaluated as expected:
|
109
|
+
#
|
110
|
+
# class, readonly
|
111
|
+
#
|
112
|
+
# @param [String]
|
113
|
+
# attribute name
|
114
|
+
# @return [String,nil]
|
115
|
+
# attribute value
|
116
|
+
#
|
117
|
+
def attribute(attribute_name)
|
118
|
+
element.attribute_value attribute_name
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# find the parent element
|
123
|
+
#
|
124
|
+
def parent
|
125
|
+
parent = element.parent
|
126
|
+
type = element.type if parent.tag_name.to_sym == :input
|
127
|
+
cls = ::PageObject::Elements.element_class_for(parent.tag_name, type)
|
128
|
+
cls.new(parent, :platform => :watir)
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Waits until the element is present
|
133
|
+
#
|
134
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
135
|
+
#
|
136
|
+
def when_present(timeout=::PageObject.default_element_wait)
|
137
|
+
element.wait_until(timeout: timeout, message: "Element not present in #{timeout} seconds", &:present?)
|
138
|
+
self
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Waits until the element is not present
|
143
|
+
#
|
144
|
+
# @param [Integer] (defaults to: 5) seconds to wait before
|
145
|
+
# timing out
|
146
|
+
#
|
147
|
+
def when_not_present(timeout=::PageObject.default_element_wait)
|
148
|
+
element.wait_while(timeout: timeout, message: "Element still present in #{timeout} seconds", &:present?)
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# Waits until the element is visible
|
153
|
+
#
|
154
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
155
|
+
#
|
156
|
+
def when_visible(timeout=::PageObject.default_element_wait)
|
157
|
+
element.wait_until(timeout: timeout, message: "Element not visible in #{timeout} seconds", &:visible?)
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Waits until the element is not visible
|
163
|
+
#
|
164
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
165
|
+
#
|
166
|
+
def when_not_visible(timeout=::PageObject.default_element_wait)
|
167
|
+
element.wait_while(timeout: timeout, message: "Element still visible after #{timeout} seconds", &:visible?)
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# Waits until the block returns true
|
172
|
+
#
|
173
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
174
|
+
# @param [String] the message to display if the event timeouts
|
175
|
+
# @param the block to execute when the event occurs
|
176
|
+
#
|
177
|
+
def wait_until(timeout=::PageObject.default_element_wait, message=nil, &block)
|
178
|
+
element.wait_until(timeout: timeout, message: message, &block)
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# Scroll until the element is viewable
|
183
|
+
#
|
184
|
+
def scroll_into_view
|
185
|
+
element.wd.location_once_scrolled_into_view
|
186
|
+
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# location of element (x, y)
|
190
|
+
#
|
191
|
+
def location
|
192
|
+
element.wd.location
|
193
|
+
end
|
194
|
+
|
195
|
+
#
|
196
|
+
# size of element (width, height)
|
197
|
+
#
|
198
|
+
def size
|
199
|
+
element.wd.size
|
200
|
+
end
|
201
|
+
|
202
|
+
#
|
203
|
+
# Get height of element
|
204
|
+
#
|
205
|
+
def height
|
206
|
+
element.wd.size['height']
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# Get width of element
|
211
|
+
#
|
212
|
+
def width
|
213
|
+
element.wd.size['width']
|
214
|
+
end
|
215
|
+
|
216
|
+
#
|
217
|
+
# Get centre coordinates of element
|
218
|
+
#
|
219
|
+
def centre
|
220
|
+
location = element.wd.location
|
221
|
+
size = element.wd.size
|
222
|
+
{'y' => (location['y'] + (size['height']/2)), 'x' => (location['x'] + (size['width']/2))}
|
223
|
+
end
|
224
|
+
|
90
225
|
# @private
|
91
226
|
def self.watir_identifier_for identifier
|
92
227
|
if should_build_watir_xpath(identifier)
|
@@ -103,33 +238,11 @@ module PageObject
|
|
103
238
|
all_identities
|
104
239
|
end
|
105
240
|
|
106
|
-
# @private
|
107
|
-
def self.selenium_identifier_for identifier
|
108
|
-
if identifier.length == 1
|
109
|
-
identifier = identifier_for identifier, selenium_finders, selenium_mapping
|
110
|
-
return identifier.keys.first, identifier.values.first
|
111
|
-
elsif identifier.length > 1
|
112
|
-
how = :xpath
|
113
|
-
what = build_xpath_for identifier
|
114
|
-
return how, what
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
241
|
# @private
|
119
242
|
# delegate calls to driver element
|
120
243
|
def method_missing(*args, &block)
|
121
244
|
m = args.shift
|
122
|
-
|
123
|
-
$stderr.puts "*** You are calling a method named #{m} at #{caller[0]}."
|
124
|
-
$stderr.puts "*** This method does not exist in page-object so it is being passed to the driver."
|
125
|
-
$stderr.puts "*** This feature will be removed in the near future."
|
126
|
-
$stderr.puts "*** Please change your code to call the correct page-object method."
|
127
|
-
$stderr.puts "*** If you are using functionality that does not exist in page-object please request it be added."
|
128
|
-
begin
|
129
|
-
element.send m, *args, &block
|
130
|
-
rescue Exception => e
|
131
|
-
raise
|
132
|
-
end
|
245
|
+
element.send m, *args, &block
|
133
246
|
end
|
134
247
|
|
135
248
|
protected
|
@@ -215,14 +328,6 @@ module PageObject
|
|
215
328
|
{}
|
216
329
|
end
|
217
330
|
|
218
|
-
def self.selenium_finders
|
219
|
-
[:class, :css, :id, :index, :name, :xpath]
|
220
|
-
end
|
221
|
-
|
222
|
-
def self.selenium_mapping
|
223
|
-
{}
|
224
|
-
end
|
225
|
-
|
226
331
|
def include_platform_for platform
|
227
332
|
platform_information = PageObject::Platforms.get
|
228
333
|
raise ArgumentError,"Expected hash with at least a key :platform for platform information! (#{platform.inspect})" unless platform.class == Hash && platform.has_key?(:platform)
|
@@ -231,29 +336,7 @@ module PageObject
|
|
231
336
|
raise ArgumentError, "Unknown platform #{platform_name}! Expect platform to be one of the following: #{platform_information.keys.inspect}" unless platform_information.keys.include?(platform_name)
|
232
337
|
base_platform_class = "#{platform_information[platform_name]}::"
|
233
338
|
|
234
|
-
self.send :extend, constantize_classname(base_platform_class + "Element")
|
235
339
|
@platform = constantize_classname(base_platform_class+ "PageObject").new(@element)
|
236
|
-
|
237
|
-
# include class specific code
|
238
|
-
class_to_include = case
|
239
|
-
when self.class == PageObject::Elements::Element
|
240
|
-
# already loaded
|
241
|
-
return true
|
242
|
-
when self.class.name =~/PageObject:Elements::/
|
243
|
-
self.class
|
244
|
-
# inherited classes for example the widgets
|
245
|
-
else
|
246
|
-
parent_classes = self.class.ancestors.select { |item| item.name =~/PageObject::Elements::/ }
|
247
|
-
raise RuntimeError,"Could not identify page-object inherited class for #{self.class}!" if parent_classes.empty?
|
248
|
-
parent_classes.first
|
249
|
-
end
|
250
|
-
|
251
|
-
element_type_specific_code = File.expand_path(File.dirname(__FILE__) + "../../platforms/#{platform_name}/"+ get_element_type_underscored(class_to_include) )
|
252
|
-
if File.exist? element_type_specific_code + '.rb'
|
253
|
-
require element_type_specific_code
|
254
|
-
self.send :extend, constantize_classname( base_platform_class + get_element_type(class_to_include) )
|
255
|
-
end
|
256
|
-
|
257
340
|
end
|
258
341
|
|
259
342
|
def to_ary
|
@@ -276,20 +359,6 @@ module PageObject
|
|
276
359
|
name.split("::").inject(Object) { |k,n| k.const_get(n) }
|
277
360
|
end
|
278
361
|
|
279
|
-
|
280
|
-
def get_element_type(class_name = self.class)
|
281
|
-
class_name.name.split('::').last
|
282
|
-
end
|
283
|
-
|
284
|
-
# retrieved from ruby on rails underscore method
|
285
|
-
def get_element_type_underscored(class_name = self.class)
|
286
|
-
get_element_type(class_name).to_s.gsub(/::/, '/').
|
287
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
288
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
289
|
-
tr("-", "_").
|
290
|
-
downcase
|
291
|
-
end
|
292
|
-
|
293
362
|
end
|
294
363
|
end
|
295
364
|
end
|
@@ -3,9 +3,11 @@ module PageObject
|
|
3
3
|
module Elements
|
4
4
|
class FileField < Element
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
#
|
7
|
+
# Set the value of the FileField
|
8
|
+
#
|
9
|
+
def value=(new_value)
|
10
|
+
element.set(new_value)
|
9
11
|
end
|
10
12
|
|
11
13
|
protected
|
@@ -14,10 +16,6 @@ module PageObject
|
|
14
16
|
super + [:title, :label]
|
15
17
|
end
|
16
18
|
|
17
|
-
def self.selenium_finders
|
18
|
-
super + [:title, :label]
|
19
|
-
end
|
20
|
-
|
21
19
|
end
|
22
20
|
|
23
21
|
::PageObject::Elements.type_to_class[:file] = ::PageObject::Elements::FileField
|
@@ -2,10 +2,6 @@
|
|
2
2
|
module PageObject
|
3
3
|
module Elements
|
4
4
|
class Form < Element
|
5
|
-
def initialize(element, platform)
|
6
|
-
@element = element
|
7
|
-
include_platform_for platform
|
8
|
-
end
|
9
5
|
|
10
6
|
protected
|
11
7
|
|
@@ -13,10 +9,6 @@ module PageObject
|
|
13
9
|
super + [:action]
|
14
10
|
end
|
15
11
|
|
16
|
-
def self.selenium_finders
|
17
|
-
super + [:action]
|
18
|
-
end
|
19
|
-
|
20
12
|
end
|
21
13
|
|
22
14
|
::PageObject::Elements.tag_to_class[:form] = ::PageObject::Elements::Form
|
@@ -3,7 +3,7 @@ module PageObject
|
|
3
3
|
class HiddenField < Element
|
4
4
|
|
5
5
|
def click
|
6
|
-
raise "click is not available on hidden field element
|
6
|
+
raise "click is not available on the hidden field element"
|
7
7
|
end
|
8
8
|
|
9
9
|
protected
|
@@ -12,9 +12,6 @@ module PageObject
|
|
12
12
|
super + [:text, :value]
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.selenium_finders
|
16
|
-
super + [:value]
|
17
|
-
end
|
18
15
|
end
|
19
16
|
|
20
17
|
::PageObject::Elements.type_to_class[:hidden] = ::PageObject::Elements::HiddenField
|