page-object 2.0.0 → 2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|