page-object 1.0 → 1.0.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/.rspec +1 -1
- data/ChangeLog +7 -0
- data/features/frames.feature +5 -0
- data/features/step_definitions/element_steps.rb +2 -2
- data/features/step_definitions/frames_steps.rb +12 -0
- data/features/step_definitions/gxt_table_steps.rb +12 -2
- data/features/step_definitions/indexed_property_steps.rb +22 -18
- data/features/support/page.rb +0 -5
- data/lib/page-object.rb +22 -1
- data/lib/page-object/accessors.rb +33 -28
- data/lib/page-object/indexed_properties.rb +2 -2
- data/lib/page-object/platforms/watir_webdriver/page_object.rb +0 -26
- data/lib/page-object/version.rb +1 -1
- data/lib/page-object/widgets.rb +1 -0
- data/page-object.gemspec +1 -1
- data/spec/page-object/accessors_spec.rb +60 -0
- data/spec/page-object/selenium_accessors_spec.rb +4 -4
- data/spec/page-object/watir_accessors_spec.rb +7 -7
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 386482bc19d329a8cd1189c91a689fca46fc9a8e
|
4
|
+
data.tar.gz: cb8e35e8ec52b8b5e776d9122ef7d7e02ce4e14d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b061306394d35e32ca3c44a18b27ee3909c0d8cdd983debbe3d0e0307d55707bf2f4b2b8386cbef267f7becc2da53e83ff78e1e12d56f50f03d116ad552ffe89
|
7
|
+
data.tar.gz: e8373204c8b363185d094987ffa51e1d2518281b38ffddd6ebd868192e1fa48b07686a0829549db31223bc1086b376823c106c411cd90f33c10903a5897db749
|
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--format
|
2
|
+
--format documentation
|
data/ChangeLog
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== Version 1.0.1
|
2
|
+
* Enhancements
|
3
|
+
* Checks the name of generated methods to ensure they do not colide with existing page-object methods
|
4
|
+
* Removed old legacy css code and now delegate everything to Watir
|
5
|
+
* Fixes
|
6
|
+
* Added support for dynamically finding elements inside iframes (Thanks Justin Ko)
|
7
|
+
|
1
8
|
=== Version 1.0 / 2014-6-1
|
2
9
|
* Enhancements
|
3
10
|
* Better support for using Regexp
|
data/features/frames.feature
CHANGED
@@ -48,6 +48,11 @@ Feature: Handling frames
|
|
48
48
|
When I type "page-object" into the text field from frame 1 identified dynamically
|
49
49
|
Then I should verify "page-object" in the text field for frame 1 identified dynamically
|
50
50
|
|
51
|
+
Scenario: Identifying items in iframes at runtime
|
52
|
+
Given I am on the iframe elements page
|
53
|
+
When I type "page-object" into the text field from iframe 1 identified dynamically
|
54
|
+
Then I should verify "page-object" in the text field for iframe 1 identified dynamically
|
55
|
+
|
51
56
|
Scenario: Handling alerts inside frames
|
52
57
|
Given I am on the frame elements page
|
53
58
|
When I trigger an alert within a frame
|
@@ -220,7 +220,7 @@ end
|
|
220
220
|
class DoubleClickPage
|
221
221
|
include PageObject
|
222
222
|
button(:click)
|
223
|
-
paragraph(:
|
223
|
+
paragraph(:p_text)
|
224
224
|
end
|
225
225
|
|
226
226
|
Given /^I am on the Double Click page$/ do
|
@@ -233,7 +233,7 @@ When /^I double click the button$/ do
|
|
233
233
|
end
|
234
234
|
|
235
235
|
Then /^the paragraph should read "([^\"]*)"$/ do |expected_text|
|
236
|
-
@page.
|
236
|
+
@page.p_text.should == expected_text
|
237
237
|
end
|
238
238
|
|
239
239
|
When /^I scroll the heading element into view$/ do
|
@@ -119,6 +119,18 @@ Then /^I should verify "([^\"]*)" in the text field for frame 1 identified dynam
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
+
When /^I type "([^\"]*)" into the text field from iframe 1 identified dynamically$/ do |value|
|
123
|
+
@page.in_iframe(:id => 'frame_one_1') do |frame|
|
124
|
+
@page.text_field_element(:name => 'senderElement', :frame => frame).value = value
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
Then /^I should verify "([^\"]*)" in the text field for iframe 1 identified dynamically$/ do |value|
|
129
|
+
@page.in_iframe(:id => 'frame_one_1') do |frame|
|
130
|
+
@page.text_field_element(:name => 'senderElement', :frame => frame).value.should == value
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
122
134
|
When /^I trigger an alert within a frame$/ do
|
123
135
|
@page.in_frame(:id => 'frame_three_3') do |frame|
|
124
136
|
@msg = @page.alert(frame) do
|
@@ -1,3 +1,13 @@
|
|
1
|
+
|
2
|
+
def class_exists?(class_name)
|
3
|
+
begin
|
4
|
+
klass = Module.const_get(class_name)
|
5
|
+
return klass.is_a?(Class)
|
6
|
+
rescue NameError
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
1
11
|
Given /^I am on the Gxt Examples page$/ do
|
2
12
|
visit GxtSamplePageObject
|
3
13
|
end
|
@@ -28,9 +38,9 @@ When /^I define a page-object using that widget$/ do
|
|
28
38
|
|
29
39
|
page_url "http://gxtexamplegallery.appspot.com/"
|
30
40
|
|
31
|
-
div(:basic_grid, :class => "label_basic_grid")
|
41
|
+
div(:basic_grid, :class => "label_basic_grid")
|
32
42
|
gxt_table(:gxt_table, :class => "x-grid3")
|
33
|
-
end
|
43
|
+
end unless class_exists? 'GxtSamplePageObject'
|
34
44
|
end
|
35
45
|
|
36
46
|
When /^I have registered the GxtTable with PageObject$/ do
|
@@ -1,20 +1,24 @@
|
|
1
1
|
class IndexedPropertyPage
|
2
2
|
include PageObject
|
3
3
|
|
4
|
-
indexed_property :table, [[:text_field, :
|
4
|
+
indexed_property :table, [[:text_field, :text_table, {:id => 'table[%s].text'}],
|
5
5
|
[:text_field, :text_name, {:name => 'tableName[%s].text'}],
|
6
6
|
[:radio_button, :radio, {:id => 'table[%s].radio'}],
|
7
7
|
[:checkbox, :check, {:id => 'table[%s].check'}],
|
8
8
|
[:text_area, :area, {:id => 'table[%s].area'}],
|
9
9
|
[:button, :button, {:id => 'table[%s].button'}]]
|
10
10
|
|
11
|
-
indexed_property :nottable, [[:text_field, :
|
11
|
+
indexed_property :nottable, [[:text_field, :text_nottable, {:id => 'nottable[%s].text'}]]
|
12
12
|
|
13
13
|
end
|
14
14
|
|
15
|
+
def page
|
16
|
+
@page ||= IndexedPropertyPage.new(@browser)
|
17
|
+
end
|
18
|
+
|
15
19
|
Given /^I am on the indexed property page$/ do
|
16
|
-
@page = IndexedPropertyPage.new(@browser)
|
17
|
-
|
20
|
+
# @page = IndexedPropertyPage.new(@browser)
|
21
|
+
page.navigate_to(UrlHelper.indexed)
|
18
22
|
end
|
19
23
|
|
20
24
|
When /^I search for the elements for index "([^\"]*)"$/ do |index|
|
@@ -22,58 +26,58 @@ When /^I search for the elements for index "([^\"]*)"$/ do |index|
|
|
22
26
|
end
|
23
27
|
|
24
28
|
Then /^I type "([^\"]*)" into the table's indexed text field by id$/ do |val|
|
25
|
-
|
29
|
+
page.table[@index].text_table = val
|
26
30
|
end
|
27
31
|
|
28
32
|
Then /^The table's indexed text field by id should contain "([^\"]*)"$/ do |val|
|
29
|
-
|
33
|
+
page.table[@index].text_table.should == val
|
30
34
|
end
|
31
35
|
|
32
36
|
Then /^I type "([^\"]*)" into the table's indexed text field by name$/ do |val|
|
33
|
-
|
37
|
+
page.table[@index].text_name = val
|
34
38
|
end
|
35
39
|
|
36
40
|
Then /^The table's indexed text field by name should contain "([^\"]*)"$/ do |val|
|
37
|
-
|
41
|
+
page.table[@index].text_name.should == val
|
38
42
|
end
|
39
43
|
|
40
44
|
Then /^I select the indexed radio button$/ do
|
41
|
-
|
45
|
+
page.table[@index].select_radio
|
42
46
|
end
|
43
47
|
|
44
48
|
Then /^The indexed radio button should be selected$/ do
|
45
|
-
|
49
|
+
page.table[@index].radio_selected?.should == true
|
46
50
|
end
|
47
51
|
|
48
52
|
Then /^I check the indexed checkbox$/ do
|
49
|
-
|
53
|
+
page.table[@index].check_check
|
50
54
|
end
|
51
55
|
|
52
56
|
Then /^The indexed checkbox should be checked$/ do
|
53
|
-
|
57
|
+
page.table[@index].check_checked?.should == true
|
54
58
|
end
|
55
59
|
|
56
60
|
Then /^I type "([^\"]*)" into the table's indexed text area$/ do |val|
|
57
|
-
|
61
|
+
page.table[@index].area = val
|
58
62
|
end
|
59
63
|
|
60
64
|
Then /^The table's indexed text area should contain "([^\"]*)"$/ do |val|
|
61
|
-
|
65
|
+
page.table[@index].area.should == val
|
62
66
|
end
|
63
67
|
|
64
68
|
Then /^I should see that the indexed button exists$/ do
|
65
|
-
|
69
|
+
page.table[@index].button?.should == true
|
66
70
|
end
|
67
71
|
|
68
72
|
Then /^I should be able to click the indexed button$/ do
|
69
|
-
|
73
|
+
page.table[@index].button
|
70
74
|
end
|
71
75
|
|
72
76
|
Then /^I type "([^\"]*)" into the regular indexed text field by id$/ do |val|
|
73
|
-
|
77
|
+
page.nottable[@index].text_nottable = val
|
74
78
|
end
|
75
79
|
|
76
80
|
Then /^The regular indexed text field by id should contain "([^\"]*)"$/ do |val|
|
77
|
-
|
81
|
+
page.nottable[@index].text_nottable.should == val
|
78
82
|
end
|
79
83
|
|
data/features/support/page.rb
CHANGED
@@ -28,7 +28,6 @@ class Page
|
|
28
28
|
text_area(:text_area_css, :css => ".text_area_class")
|
29
29
|
text_area(:text_area_name, :name => "text_area_name")
|
30
30
|
text_area(:text_area_xpath, :xpath => "//textarea")
|
31
|
-
text_area(:text_area_css, :css => "textarea")
|
32
31
|
text_area(:text_area_tag_name, :tag_name => "textarea")
|
33
32
|
text_area(:text_area_index, :index => 0)
|
34
33
|
text_area(:text_area_text, :text => "")
|
@@ -42,7 +41,6 @@ class Page
|
|
42
41
|
hidden_field(:hidden_field_css, :css => ".hidden_field_class")
|
43
42
|
hidden_field(:hidden_field_name, :name => "hidden_field_name")
|
44
43
|
hidden_field(:hidden_field_xpath, :xpath => "//input[@type='hidden']")
|
45
|
-
hidden_field(:hidden_field_css, :css => "input[type='hidden']")
|
46
44
|
hidden_field(:hidden_field_tag_name, :tag_name => "input[type='hidden']")
|
47
45
|
hidden_field(:hidden_field_index, :index => 0)
|
48
46
|
hidden_field(:hidden_field_text, :text => "")
|
@@ -60,7 +58,6 @@ class Page
|
|
60
58
|
link(:google_search_href, :href => "success.html")
|
61
59
|
link(:google_search_text, :text => "Google Search")
|
62
60
|
link(:google_search_index, :index => 0)
|
63
|
-
link(:google_search_css, :css => "a.link_class")
|
64
61
|
link(:google_search_title, :title => "link_title")
|
65
62
|
|
66
63
|
select_list(:sel_list_id, :id => "sel_list_id")
|
@@ -112,7 +109,6 @@ class Page
|
|
112
109
|
div(:div_title, :title => 'div_title')
|
113
110
|
div(:div_class_index, :class => "div_class", :index => 0)
|
114
111
|
div(:div_name_index, :name => "div_name", :index => 0)
|
115
|
-
div(:div_css, :css => ".div_class")
|
116
112
|
|
117
113
|
div(:div_data_entity, :data_entity => "test")
|
118
114
|
|
@@ -155,7 +151,6 @@ class Page
|
|
155
151
|
button(:button_xpath, :xpath=> "//input[@type='submit']")
|
156
152
|
button(:button_text, :text => 'Click Me')
|
157
153
|
button(:button_value, :value => 'Click Me')
|
158
|
-
button(:button_css, :css => "input[type='submit']")
|
159
154
|
button(:button_class_index, :class => "button_class", :index => 0)
|
160
155
|
button(:button_name_index, :name => "button_name", :index => 0)
|
161
156
|
|
data/lib/page-object.rb
CHANGED
@@ -260,7 +260,7 @@ module PageObject
|
|
260
260
|
end
|
261
261
|
|
262
262
|
#
|
263
|
-
# Identify an element as existing within a frame
|
263
|
+
# Identify an element as existing within a frame. A frame parameter
|
264
264
|
# is passed to the block and must be passed to the other calls to PageObject.
|
265
265
|
# You can nest calls to in_frame by passing the frame to the next level.
|
266
266
|
#
|
@@ -281,6 +281,27 @@ module PageObject
|
|
281
281
|
platform.in_frame(identifier, frame, &block)
|
282
282
|
end
|
283
283
|
|
284
|
+
# Identify an element as existing within an iframe. A frame parameter
|
285
|
+
# is passed to the block and must be passed to the other calls to PageObject.
|
286
|
+
# You can nest calls to in_iframe by passing the frame to the next level.
|
287
|
+
#
|
288
|
+
# @example
|
289
|
+
# in_iframe(:id => 'iframe_id') do |iframe|
|
290
|
+
# text_field_element(:id => 'ifname', :frame => iframe)
|
291
|
+
# end
|
292
|
+
#
|
293
|
+
# @param [Hash] identifier how we find the iframe. The valid keys are:
|
294
|
+
# * :id => Watir and Selenium
|
295
|
+
# * :index => Watir and Selenium
|
296
|
+
# * :name => Watir and Selenium
|
297
|
+
# * :class => Watir only
|
298
|
+
# @param frame passed from a previous call to in_iframe. Used to nest calls
|
299
|
+
# @param block that contains the calls to elements that exist inside the iframe.
|
300
|
+
#
|
301
|
+
def in_iframe(identifier, frame=nil, &block)
|
302
|
+
platform.in_iframe(identifier, frame, &block)
|
303
|
+
end
|
304
|
+
|
284
305
|
#
|
285
306
|
# Override the normal showModalDialog call is it opens a window instead
|
286
307
|
# of a dialog. You will need to attach to the new window in order to
|
@@ -209,7 +209,8 @@ module PageObject
|
|
209
209
|
# * :xpath => Watir and Selenium
|
210
210
|
# @param optional block to be invoked when element method is called
|
211
211
|
#
|
212
|
-
def text_field(name, identifier={:index => 0}, &block)
|
212
|
+
def text_field(name, identifier={:index => 0}, &block)
|
213
|
+
standard_methods(name, identifier, 'text_field_for', &block)
|
213
214
|
define_method(name) do
|
214
215
|
return platform.text_field_value_for identifier.clone unless block_given?
|
215
216
|
self.send("#{name}_element").value
|
@@ -218,7 +219,6 @@ module PageObject
|
|
218
219
|
return platform.text_field_value_set(identifier.clone, value) unless block_given?
|
219
220
|
self.send("#{name}_element").value = value
|
220
221
|
end
|
221
|
-
standard_methods(name, identifier, 'text_field_for', &block)
|
222
222
|
end
|
223
223
|
|
224
224
|
#
|
@@ -244,11 +244,11 @@ module PageObject
|
|
244
244
|
# @param optional block to be invoked when element method is called
|
245
245
|
#
|
246
246
|
def hidden_field(name, identifier={:index => 0}, &block)
|
247
|
+
standard_methods(name, identifier, 'hidden_field_for', &block)
|
247
248
|
define_method(name) do
|
248
249
|
return platform.hidden_field_value_for identifier.clone unless block_given?
|
249
250
|
self.send("#{name}_element").value
|
250
251
|
end
|
251
|
-
standard_methods(name, identifier, 'hidden_field_for', &block)
|
252
252
|
end
|
253
253
|
alias_method :hidden, :hidden_field
|
254
254
|
|
@@ -275,6 +275,7 @@ module PageObject
|
|
275
275
|
# @param optional block to be invoked when element method is called
|
276
276
|
#
|
277
277
|
def text_area(name, identifier={:index => 0}, &block)
|
278
|
+
standard_methods(name, identifier, 'text_area_for', &block)
|
278
279
|
define_method(name) do
|
279
280
|
return platform.text_area_value_for identifier.clone unless block_given?
|
280
281
|
self.send("#{name}_element").value
|
@@ -283,7 +284,6 @@ module PageObject
|
|
283
284
|
return platform.text_area_value_set(identifier.clone, value) unless block_given?
|
284
285
|
self.send("#{name}_element").value = value
|
285
286
|
end
|
286
|
-
standard_methods(name, identifier, 'text_area_for', &block)
|
287
287
|
end
|
288
288
|
alias_method :textarea, :text_area
|
289
289
|
|
@@ -313,6 +313,7 @@ module PageObject
|
|
313
313
|
# @param optional block to be invoked when element method is called
|
314
314
|
#
|
315
315
|
def select_list(name, identifier={:index => 0}, &block)
|
316
|
+
standard_methods(name, identifier, 'select_list_for', &block)
|
316
317
|
define_method(name) do
|
317
318
|
return platform.select_list_value_for identifier.clone unless block_given?
|
318
319
|
self.send("#{name}_element").value
|
@@ -321,13 +322,10 @@ module PageObject
|
|
321
322
|
return platform.select_list_value_set(identifier.clone, value) unless block_given?
|
322
323
|
self.send("#{name}_element").select(value)
|
323
324
|
end
|
324
|
-
|
325
325
|
define_method("#{name}_options") do
|
326
326
|
element = self.send("#{name}_element")
|
327
327
|
(element && element.options) ? element.options.collect(&:text) : []
|
328
328
|
end
|
329
|
-
|
330
|
-
standard_methods(name, identifier, 'select_list_for', &block)
|
331
329
|
end
|
332
330
|
alias_method :select, :select_list
|
333
331
|
|
@@ -357,11 +355,11 @@ module PageObject
|
|
357
355
|
# @param optional block to be invoked when element method is called
|
358
356
|
#
|
359
357
|
def link(name, identifier={:index => 0}, &block)
|
358
|
+
standard_methods(name, identifier, 'link_for', &block)
|
360
359
|
define_method(name) do
|
361
360
|
return platform.click_link_for identifier.clone unless block_given?
|
362
361
|
self.send("#{name}_element").click
|
363
362
|
end
|
364
|
-
standard_methods(name, identifier, 'link_for', &block)
|
365
363
|
end
|
366
364
|
alias_method :a, :link
|
367
365
|
|
@@ -390,6 +388,7 @@ module PageObject
|
|
390
388
|
# @param optional block to be invoked when element method is called
|
391
389
|
#
|
392
390
|
def checkbox(name, identifier={:index => 0}, &block)
|
391
|
+
standard_methods(name, identifier, 'checkbox_for', &block)
|
393
392
|
define_method("check_#{name}") do
|
394
393
|
return platform.check_checkbox(identifier.clone) unless block_given?
|
395
394
|
self.send("#{name}_element").check
|
@@ -402,7 +401,6 @@ module PageObject
|
|
402
401
|
return platform.checkbox_checked?(identifier.clone) unless block_given?
|
403
402
|
self.send("#{name}_element").checked?
|
404
403
|
end
|
405
|
-
standard_methods(name, identifier, 'checkbox_for', &block)
|
406
404
|
end
|
407
405
|
|
408
406
|
#
|
@@ -431,6 +429,7 @@ module PageObject
|
|
431
429
|
# @param optional block to be invoked when element method is called
|
432
430
|
#
|
433
431
|
def radio_button(name, identifier={:index => 0}, &block)
|
432
|
+
standard_methods(name, identifier, 'radio_button_for', &block)
|
434
433
|
define_method("select_#{name}") do
|
435
434
|
return platform.select_radio(identifier.clone) unless block_given?
|
436
435
|
self.send("#{name}_element").select
|
@@ -443,7 +442,6 @@ module PageObject
|
|
443
442
|
return platform.radio_selected?(identifier.clone) unless block_given?
|
444
443
|
self.send("#{name}_element").selected?
|
445
444
|
end
|
446
|
-
standard_methods(name, identifier, 'radio_button_for', &block)
|
447
445
|
end
|
448
446
|
alias_method :radio, :radio_button
|
449
447
|
|
@@ -468,6 +466,7 @@ module PageObject
|
|
468
466
|
# * :name => Watir and Selenium
|
469
467
|
#
|
470
468
|
def radio_button_group(name, identifier)
|
469
|
+
check_name(name)
|
471
470
|
define_method("select_#{name}") do |value|
|
472
471
|
platform.radio_buttons_for(identifier.clone).each do |radio_elem|
|
473
472
|
if radio_elem.value == value
|
@@ -521,11 +520,11 @@ module PageObject
|
|
521
520
|
# @param optional block to be invoked when element method is called
|
522
521
|
#
|
523
522
|
def button(name, identifier={:index => 0}, &block)
|
523
|
+
standard_methods(name, identifier, 'button_for', &block)
|
524
524
|
define_method(name) do
|
525
525
|
return platform.click_button_for identifier.clone unless block_given?
|
526
526
|
self.send("#{name}_element").click
|
527
527
|
end
|
528
|
-
standard_methods(name, identifier, 'button_for', &block)
|
529
528
|
end
|
530
529
|
|
531
530
|
#
|
@@ -550,11 +549,11 @@ module PageObject
|
|
550
549
|
# @param optional block to be invoked when element method is called
|
551
550
|
#
|
552
551
|
def div(name, identifier={:index => 0}, &block)
|
552
|
+
standard_methods(name, identifier, 'div_for', &block)
|
553
553
|
define_method(name) do
|
554
554
|
return platform.div_text_for identifier.clone unless block_given?
|
555
555
|
self.send("#{name}_element").text
|
556
556
|
end
|
557
|
-
standard_methods(name, identifier, 'div_for', &block)
|
558
557
|
end
|
559
558
|
|
560
559
|
#
|
@@ -579,11 +578,11 @@ module PageObject
|
|
579
578
|
# @param optional block to be invoked when element method is called
|
580
579
|
#
|
581
580
|
def span(name, identifier={:index => 0}, &block)
|
581
|
+
standard_methods(name, identifier, 'span_for', &block)
|
582
582
|
define_method(name) do
|
583
583
|
return platform.span_text_for identifier.clone unless block_given?
|
584
584
|
self.send("#{name}_element").text
|
585
585
|
end
|
586
|
-
standard_methods(name, identifier, 'span_for', &block)
|
587
586
|
end
|
588
587
|
|
589
588
|
#
|
@@ -608,11 +607,11 @@ module PageObject
|
|
608
607
|
# @param optional block to be invoked when element method is called
|
609
608
|
#
|
610
609
|
def table(name, identifier={:index => 0}, &block)
|
610
|
+
standard_methods(name, identifier, 'table_for', &block)
|
611
611
|
define_method(name) do
|
612
612
|
return platform.table_text_for identifier.clone unless block_given?
|
613
613
|
self.send("#{name}_element").text
|
614
614
|
end
|
615
|
-
standard_methods(name, identifier, 'table_for', &block)
|
616
615
|
end
|
617
616
|
|
618
617
|
#
|
@@ -638,11 +637,11 @@ module PageObject
|
|
638
637
|
# @param optional block to be invoked when element method is called
|
639
638
|
#
|
640
639
|
def cell(name, identifier={:index => 0}, &block)
|
640
|
+
standard_methods(name, identifier, 'cell_for', &block)
|
641
641
|
define_method("#{name}") do
|
642
642
|
return platform.cell_text_for identifier.clone unless block_given?
|
643
643
|
self.send("#{name}_element").text
|
644
644
|
end
|
645
|
-
standard_methods(name, identifier, 'cell_for', &block)
|
646
645
|
end
|
647
646
|
alias_method :td, :cell
|
648
647
|
|
@@ -717,11 +716,11 @@ module PageObject
|
|
717
716
|
# @param optional block to be invoked when element method is called
|
718
717
|
#
|
719
718
|
def list_item(name, identifier={:index => 0}, &block)
|
719
|
+
standard_methods(name, identifier, 'list_item_for', &block)
|
720
720
|
define_method(name) do
|
721
721
|
return platform.list_item_text_for identifier.clone unless block_given?
|
722
722
|
self.send("#{name}_element").text
|
723
723
|
end
|
724
|
-
standard_methods(name, identifier, 'list_item_for', &block)
|
725
724
|
end
|
726
725
|
alias_method :li, :list_item
|
727
726
|
|
@@ -746,11 +745,11 @@ module PageObject
|
|
746
745
|
# @param optional block to be invoked when element method is called
|
747
746
|
#
|
748
747
|
def unordered_list(name, identifier={:index => 0}, &block)
|
748
|
+
standard_methods(name, identifier, 'unordered_list_for', &block)
|
749
749
|
define_method(name) do
|
750
750
|
return platform.unordered_list_text_for identifier.clone unless block_given?
|
751
751
|
self.send("#{name}_element").text
|
752
752
|
end
|
753
|
-
standard_methods(name, identifier, 'unordered_list_for', &block)
|
754
753
|
end
|
755
754
|
alias_method :ul, :unordered_list
|
756
755
|
|
@@ -775,11 +774,11 @@ module PageObject
|
|
775
774
|
# @param optional block to be invoked when element method is called
|
776
775
|
#
|
777
776
|
def ordered_list(name, identifier={:index => 0}, &block)
|
777
|
+
standard_methods(name, identifier, 'ordered_list_for', &block)
|
778
778
|
define_method(name) do
|
779
779
|
return platform.ordered_list_text_for identifier.clone unless block_given?
|
780
780
|
self.send("#{name}_element").text
|
781
781
|
end
|
782
|
-
standard_methods(name, identifier, 'ordered_list_for', &block)
|
783
782
|
end
|
784
783
|
alias_method :ol, :ordered_list
|
785
784
|
|
@@ -803,11 +802,11 @@ module PageObject
|
|
803
802
|
# @param optional block to be invoked when element method is called
|
804
803
|
#
|
805
804
|
def h1(name, identifier={:index => 0}, &block)
|
805
|
+
standard_methods(name, identifier,'h1_for', &block)
|
806
806
|
define_method(name) do
|
807
807
|
return platform.h1_text_for identifier.clone unless block_given?
|
808
808
|
self.send("#{name}_element").text
|
809
809
|
end
|
810
|
-
standard_methods(name, identifier,'h1_for', &block)
|
811
810
|
end
|
812
811
|
|
813
812
|
#
|
@@ -830,11 +829,11 @@ module PageObject
|
|
830
829
|
# @param optional block to be invoked when element method is called
|
831
830
|
#
|
832
831
|
def h2(name, identifier={:index => 0}, &block)
|
832
|
+
standard_methods(name, identifier, 'h2_for', &block)
|
833
833
|
define_method(name) do
|
834
834
|
return platform.h2_text_for identifier.clone unless block_given?
|
835
835
|
self.send("#{name}_element").text
|
836
836
|
end
|
837
|
-
standard_methods(name, identifier, 'h2_for', &block)
|
838
837
|
end
|
839
838
|
|
840
839
|
#
|
@@ -857,11 +856,11 @@ module PageObject
|
|
857
856
|
# @param optional block to be invoked when element method is called
|
858
857
|
#
|
859
858
|
def h3(name, identifier={:index => 0}, &block)
|
859
|
+
standard_methods(name, identifier, 'h3_for', &block)
|
860
860
|
define_method(name) do
|
861
861
|
return platform.h3_text_for identifier.clone unless block_given?
|
862
862
|
self.send("#{name}_element").text
|
863
863
|
end
|
864
|
-
standard_methods(name, identifier, 'h3_for', &block)
|
865
864
|
end
|
866
865
|
|
867
866
|
#
|
@@ -884,11 +883,11 @@ module PageObject
|
|
884
883
|
# @param optional block to be invoked when element method is called
|
885
884
|
#
|
886
885
|
def h4(name, identifier={:index => 0}, &block)
|
886
|
+
standard_methods(name, identifier, 'h4_for', &block)
|
887
887
|
define_method(name) do
|
888
888
|
return platform.h4_text_for identifier.clone unless block_given?
|
889
889
|
self.send("#{name}_element").text
|
890
890
|
end
|
891
|
-
standard_methods(name, identifier, 'h4_for', &block)
|
892
891
|
end
|
893
892
|
|
894
893
|
#
|
@@ -911,11 +910,11 @@ module PageObject
|
|
911
910
|
# @param optional block to be invoked when element method is called
|
912
911
|
#
|
913
912
|
def h5(name, identifier={:index => 0}, &block)
|
913
|
+
standard_methods(name, identifier, 'h5_for', &block)
|
914
914
|
define_method(name) do
|
915
915
|
return platform.h5_text_for identifier.clone unless block_given?
|
916
916
|
self.send("#{name}_element").text
|
917
917
|
end
|
918
|
-
standard_methods(name, identifier, 'h5_for', &block)
|
919
918
|
end
|
920
919
|
|
921
920
|
#
|
@@ -938,11 +937,11 @@ module PageObject
|
|
938
937
|
# @param optional block to be invoked when element method is called
|
939
938
|
#
|
940
939
|
def h6(name, identifier={:index => 0}, &block)
|
940
|
+
standard_methods(name, identifier, 'h6_for', &block)
|
941
941
|
define_method(name) do
|
942
942
|
return platform.h6_text_for identifier.clone unless block_given?
|
943
943
|
self.send("#{name}_element").text
|
944
944
|
end
|
945
|
-
standard_methods(name, identifier, 'h6_for', &block)
|
946
945
|
end
|
947
946
|
|
948
947
|
#
|
@@ -965,11 +964,11 @@ module PageObject
|
|
965
964
|
# @param optional block to be invoked when element method is called
|
966
965
|
#
|
967
966
|
def paragraph(name, identifier={:index => 0}, &block)
|
967
|
+
standard_methods(name, identifier, 'paragraph_for', &block)
|
968
968
|
define_method(name) do
|
969
969
|
return platform.paragraph_text_for identifier.clone unless block_given?
|
970
970
|
self.send("#{name}_element").text
|
971
971
|
end
|
972
|
-
standard_methods(name, identifier, 'paragraph_for', &block)
|
973
972
|
end
|
974
973
|
alias_method :p, :paragraph
|
975
974
|
|
@@ -995,11 +994,11 @@ module PageObject
|
|
995
994
|
# @param optional block to be invoked when element method is called
|
996
995
|
#
|
997
996
|
def file_field(name, identifier={:index => 0}, &block)
|
997
|
+
standard_methods(name, identifier, 'file_field_for', &block)
|
998
998
|
define_method("#{name}=") do |value|
|
999
999
|
return platform.file_field_value_set(identifier.clone, value) unless block_given?
|
1000
1000
|
self.send("#{name}_element").value = value
|
1001
1001
|
end
|
1002
|
-
standard_methods(name, identifier, 'file_field_for', &block)
|
1003
1002
|
end
|
1004
1003
|
|
1005
1004
|
#
|
@@ -1023,11 +1022,11 @@ module PageObject
|
|
1023
1022
|
# @param optional block to be invoked when element method is called
|
1024
1023
|
#
|
1025
1024
|
def label(name, identifier={:index => 0}, &block)
|
1025
|
+
standard_methods(name, identifier, 'label_for', &block)
|
1026
1026
|
define_method(name) do
|
1027
1027
|
return platform.label_text_for identifier.clone unless block_given?
|
1028
1028
|
self.send("#{name}_element").text
|
1029
1029
|
end
|
1030
|
-
standard_methods(name, identifier, 'label_for', &block)
|
1031
1030
|
end
|
1032
1031
|
|
1033
1032
|
#
|
@@ -1051,11 +1050,11 @@ module PageObject
|
|
1051
1050
|
# @param optional block to be invoked when element method is called
|
1052
1051
|
#
|
1053
1052
|
def area(name, identifier={:index => 0}, &block)
|
1053
|
+
standard_methods(name, identifier, 'area_for', &block)
|
1054
1054
|
define_method(name) do
|
1055
1055
|
return platform.click_area_for identifier.clone unless block_given?
|
1056
1056
|
self.send("#{name}_element").click
|
1057
1057
|
end
|
1058
|
-
standard_methods(name, identifier, 'area_for', &block)
|
1059
1058
|
end
|
1060
1059
|
|
1061
1060
|
#
|
@@ -1172,6 +1171,7 @@ module PageObject
|
|
1172
1171
|
# @param optional block to be invoked when element method is called
|
1173
1172
|
#
|
1174
1173
|
def element(name, tag, identifier={:index => 0}, &block)
|
1174
|
+
check_name(name)
|
1175
1175
|
define_method("#{name}") do
|
1176
1176
|
self.send("#{name}_element").text
|
1177
1177
|
end
|
@@ -1205,6 +1205,7 @@ module PageObject
|
|
1205
1205
|
# @param optional block to be invoked when element method is called
|
1206
1206
|
#
|
1207
1207
|
def elements(name, tag, identifier={:index => 0}, &block)
|
1208
|
+
check_name(name)
|
1208
1209
|
define_method("#{name}_elements") do
|
1209
1210
|
return call_block(&block) if block_given?
|
1210
1211
|
platform.elements_for(tag, identifier.clone)
|
@@ -1245,6 +1246,7 @@ module PageObject
|
|
1245
1246
|
end
|
1246
1247
|
|
1247
1248
|
def standard_methods(name, identifier, method, &block)
|
1249
|
+
check_name(name)
|
1248
1250
|
define_method("#{name}_element") do
|
1249
1251
|
return call_block(&block) if block_given?
|
1250
1252
|
platform.send(method, identifier.clone)
|
@@ -1313,5 +1315,8 @@ module PageObject
|
|
1313
1315
|
end
|
1314
1316
|
end
|
1315
1317
|
|
1318
|
+
def check_name(name)
|
1319
|
+
raise NameError, "Identifier '#{name}' conflicts with page-object method of the same name" if self.instance_methods.include? name
|
1320
|
+
end
|
1316
1321
|
end
|
1317
1322
|
end
|
@@ -15,7 +15,7 @@ module PageObject
|
|
15
15
|
how_and_what.each do |key, value|
|
16
16
|
how_and_what[key] = value % index
|
17
17
|
end
|
18
|
-
self.class.send type, name, how_and_what
|
18
|
+
self.class.send type, name, how_and_what unless self.class.instance_methods.include? name
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -34,4 +34,4 @@ module PageObject
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
@@ -941,32 +941,8 @@ module PageObject
|
|
941
941
|
|
942
942
|
private
|
943
943
|
|
944
|
-
def move_element_to_css_selector(the_call, identifier)
|
945
|
-
valid_elements = %w(
|
946
|
-
area audio canvas div
|
947
|
-
h1 h2 h3 h4 h5 h6
|
948
|
-
label li p span td video
|
949
|
-
)
|
950
|
-
element = the_call.split('(').first
|
951
|
-
if identifier.keys.include?(:css) and valid_elements.include? element
|
952
|
-
the_call[element] = 'element'
|
953
|
-
selectors = identifier[:css].split(/,\s*/).map { |selector|
|
954
|
-
modified_selector = selector.split /\s+/
|
955
|
-
last = modified_selector.pop
|
956
|
-
if last.index(element) == 0
|
957
|
-
selector
|
958
|
-
else
|
959
|
-
modified_selector.push(element + last)
|
960
|
-
end
|
961
|
-
}
|
962
|
-
identifier[:css] = selectors.join(', ')
|
963
|
-
end
|
964
|
-
[the_call, identifier]
|
965
|
-
end
|
966
|
-
|
967
944
|
def find_watir_elements(the_call, type, identifier, tag_name=nil)
|
968
945
|
identifier, frame_identifiers = parse_identifiers(identifier, type, tag_name)
|
969
|
-
the_call, identifier = move_element_to_css_selector(the_call, identifier)
|
970
946
|
elements = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}"
|
971
947
|
switch_to_default_content(frame_identifiers)
|
972
948
|
elements.map { |element| type.new(element, :platform => :watir_webdriver) }
|
@@ -974,7 +950,6 @@ module PageObject
|
|
974
950
|
|
975
951
|
def find_watir_element(the_call, type, identifier, tag_name=nil)
|
976
952
|
identifier, frame_identifiers = parse_identifiers(identifier, type, tag_name)
|
977
|
-
the_call, identifier = move_element_to_css_selector(the_call, identifier)
|
978
953
|
element = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}"
|
979
954
|
switch_to_default_content(frame_identifiers)
|
980
955
|
type.new(element, :platform => :watir_webdriver)
|
@@ -982,7 +957,6 @@ module PageObject
|
|
982
957
|
|
983
958
|
def process_watir_call(the_call, type, identifier, value=nil, tag_name=nil)
|
984
959
|
identifier, frame_identifiers = parse_identifiers(identifier, type, tag_name)
|
985
|
-
the_call, identifier = move_element_to_css_selector(the_call, identifier)
|
986
960
|
value = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}"
|
987
961
|
switch_to_default_content(frame_identifiers)
|
988
962
|
value
|
data/lib/page-object/version.rb
CHANGED
data/lib/page-object/widgets.rb
CHANGED
@@ -30,6 +30,7 @@ module PageObject
|
|
30
30
|
def self.define_accessors(base, widget_tag, widget_class)
|
31
31
|
accessors_module = Module.new do
|
32
32
|
define_method widget_tag do |name, *identifier_args, &block|
|
33
|
+
check_name(name)
|
33
34
|
|
34
35
|
identifier = identifier_args.first
|
35
36
|
identifier = {:index => 0} if identifier.nil?
|
data/page-object.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_dependency 'selenium-webdriver', '>= 2.42.0'
|
25
25
|
s.add_dependency 'page_navigation', '>= 0.9'
|
26
26
|
|
27
|
-
s.add_development_dependency 'rspec', '
|
27
|
+
s.add_development_dependency 'rspec', '< 3.0'
|
28
28
|
s.add_development_dependency 'cucumber', '>= 1.3.0'
|
29
29
|
s.add_development_dependency 'yard', '>= 0.7.2'
|
30
30
|
s.add_development_dependency 'rack', '>= 1.0'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include RSpec::Matchers
|
4
|
+
|
5
|
+
describe PageObject::Accessors do
|
6
|
+
context 'when declaring new elements on the page' do
|
7
|
+
|
8
|
+
it "should check the name when adding an element" do
|
9
|
+
class TestPage
|
10
|
+
include PageObject
|
11
|
+
|
12
|
+
def self.elements
|
13
|
+
[
|
14
|
+
'text_field',
|
15
|
+
'hidden_field',
|
16
|
+
'text_area',
|
17
|
+
'select_list',
|
18
|
+
'link',
|
19
|
+
'checkbox',
|
20
|
+
'radio_button',
|
21
|
+
'radio_button_group',
|
22
|
+
'button',
|
23
|
+
'div',
|
24
|
+
'span',
|
25
|
+
'table',
|
26
|
+
'cell',
|
27
|
+
'image',
|
28
|
+
'form',
|
29
|
+
'list_item',
|
30
|
+
'unordered_list',
|
31
|
+
'ordered_list',
|
32
|
+
'h1',
|
33
|
+
'h2',
|
34
|
+
'h3',
|
35
|
+
'h4',
|
36
|
+
'h5',
|
37
|
+
'h6',
|
38
|
+
'paragraph',
|
39
|
+
'file_field',
|
40
|
+
'label',
|
41
|
+
'area',
|
42
|
+
'canvas',
|
43
|
+
'audio',
|
44
|
+
'video',
|
45
|
+
'svg',
|
46
|
+
'address',
|
47
|
+
'figure'
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
elements.each do |ele|
|
52
|
+
expect {
|
53
|
+
self.send ele, :platform, :id => 'foo'
|
54
|
+
}.to raise_error(NameError, "Identifier \'platform\' conflicts with page-object method of the same name")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -17,7 +17,7 @@ class SeleniumAccessorsTestPageObject
|
|
17
17
|
div(:message, :id => 'message_id')
|
18
18
|
table(:cart, :id => 'cart_id')
|
19
19
|
cell(:total, :id => 'total')
|
20
|
-
span(:
|
20
|
+
span(:alert_span, :id => 'alert_id')
|
21
21
|
image(:logo, :id => 'logo')
|
22
22
|
form(:login, :id => 'login')
|
23
23
|
list_item(:item_one, :id => 'one')
|
@@ -69,7 +69,7 @@ class SeleniumBlockPageObject
|
|
69
69
|
div :footer do |element|
|
70
70
|
"div"
|
71
71
|
end
|
72
|
-
span :
|
72
|
+
span :alert_span do |element|
|
73
73
|
"span"
|
74
74
|
end
|
75
75
|
table :cart do |element|
|
@@ -342,12 +342,12 @@ describe PageObject::Accessors do
|
|
342
342
|
it "should retrieve the text from a span" do
|
343
343
|
selenium_browser.should_receive(:find_element).and_return(selenium_browser)
|
344
344
|
selenium_browser.should_receive(:text).and_return("Alert")
|
345
|
-
selenium_page_object.
|
345
|
+
selenium_page_object.alert_span.should == "Alert"
|
346
346
|
end
|
347
347
|
|
348
348
|
it "should retrieve the span element from the page" do
|
349
349
|
selenium_browser.should_receive(:find_element).and_return(selenium_browser)
|
350
|
-
element = selenium_page_object.
|
350
|
+
element = selenium_page_object.alert_span_element
|
351
351
|
element.should be_instance_of PageObject::Elements::Span
|
352
352
|
end
|
353
353
|
end
|
@@ -17,7 +17,7 @@ class WatirAccessorsTestPageObject
|
|
17
17
|
div(:message, :id => 'message_id')
|
18
18
|
table(:cart, :id => 'cart_id')
|
19
19
|
cell(:total, :id => 'total')
|
20
|
-
span(:
|
20
|
+
span(:alert_span, :id => 'alert_id')
|
21
21
|
image(:logo, :id => 'logo')
|
22
22
|
form(:login, :id => 'login')
|
23
23
|
list_item(:item_one, :id => 'one')
|
@@ -69,7 +69,7 @@ class WatirBlockPageObject
|
|
69
69
|
div :footer do |element|
|
70
70
|
"div"
|
71
71
|
end
|
72
|
-
span :
|
72
|
+
span :alert_span do |element|
|
73
73
|
"span"
|
74
74
|
end
|
75
75
|
table :cart do |element|
|
@@ -687,24 +687,24 @@ describe PageObject::Accessors do
|
|
687
687
|
describe "span accessors" do
|
688
688
|
context "when called on a page object" do
|
689
689
|
it "should generate accessor methods" do
|
690
|
-
watir_page_object.should respond_to(:
|
691
|
-
watir_page_object.should respond_to(:
|
690
|
+
watir_page_object.should respond_to(:alert_span)
|
691
|
+
watir_page_object.should respond_to(:alert_span_element)
|
692
692
|
end
|
693
693
|
|
694
694
|
it "should call a block on the element method when present" do
|
695
|
-
block_page_object.
|
695
|
+
block_page_object.alert_span_element.should == "span"
|
696
696
|
end
|
697
697
|
end
|
698
698
|
|
699
699
|
it "should retrieve the text from a span" do
|
700
700
|
watir_browser.should_receive(:span).and_return(watir_browser)
|
701
701
|
watir_browser.should_receive(:text).and_return("Alert")
|
702
|
-
watir_page_object.
|
702
|
+
watir_page_object.alert_span.should == "Alert"
|
703
703
|
end
|
704
704
|
|
705
705
|
it "should retrieve the span element from the page" do
|
706
706
|
watir_browser.should_receive(:span).and_return(watir_browser)
|
707
|
-
element = watir_page_object.
|
707
|
+
element = watir_page_object.alert_span_element
|
708
708
|
element.should be_instance_of PageObject::Elements::Span
|
709
709
|
end
|
710
710
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: page-object
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Morgan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: watir-webdriver
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "<"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '3.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "<"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '3.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: cucumber
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -330,6 +330,7 @@ files:
|
|
330
330
|
- lib/page-object/widgets.rb
|
331
331
|
- page-object.gemspec
|
332
332
|
- pageobject.gems
|
333
|
+
- spec/page-object/accessors_spec.rb
|
333
334
|
- spec/page-object/element_locators_spec.rb
|
334
335
|
- spec/page-object/elements/area_spec.rb
|
335
336
|
- spec/page-object/elements/button_spec.rb
|
@@ -518,6 +519,7 @@ test_files:
|
|
518
519
|
- features/text_field.feature
|
519
520
|
- features/unordered_list.feature
|
520
521
|
- features/video.feature
|
522
|
+
- spec/page-object/accessors_spec.rb
|
521
523
|
- spec/page-object/element_locators_spec.rb
|
522
524
|
- spec/page-object/elements/area_spec.rb
|
523
525
|
- spec/page-object/elements/button_spec.rb
|