page-object 0.8.1 → 0.8.2

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.
Files changed (36) hide show
  1. data/ChangeLog +39 -0
  2. data/Gemfile +1 -0
  3. data/Rakefile +2 -2
  4. data/cucumber.yml +4 -4
  5. data/features/element.feature +5 -0
  6. data/features/{sample-app/public → html}/04-Death_Becomes_Fur.mp4 +0 -0
  7. data/features/{sample-app/public → html}/04-Death_Becomes_Fur.oga +0 -0
  8. data/features/{sample-app/public → html}/movie.mp4 +0 -0
  9. data/features/{sample-app/public → html}/movie.ogg +0 -0
  10. data/features/html/static_elements.html +7 -7
  11. data/features/sample-app/sample_app.rb +1 -1
  12. data/features/step_definitions/element_steps.rb +7 -0
  13. data/features/step_definitions/image_steps.rb +1 -1
  14. data/features/step_definitions/javascript_steps.rb +8 -2
  15. data/features/support/persistent_browser.rb +56 -3
  16. data/features/support/targets/firefox14_osx.rb +6 -0
  17. data/features/support/targets/firefox14_windows7.rb +6 -0
  18. data/features/support/url_helper.rb +3 -1
  19. data/lib/page-object/accessors.rb +131 -1003
  20. data/lib/page-object/element_locators.rb +9 -1008
  21. data/lib/page-object/locator_generator.rb +77 -0
  22. data/lib/page-object/nested_elements.rb +7 -230
  23. data/lib/page-object/page_factory.rb +10 -6
  24. data/lib/page-object/platforms/selenium_webdriver/element.rb +7 -0
  25. data/lib/page-object/platforms/selenium_webdriver/page_object.rb +2 -2
  26. data/lib/page-object/platforms/watir_webdriver/element.rb +7 -0
  27. data/lib/page-object/platforms/watir_webdriver/page_object.rb +2 -2
  28. data/lib/page-object/version.rb +1 -1
  29. data/spec/page-object/elements/selenium_element_spec.rb +5 -0
  30. data/spec/page-object/elements/watir_element_spec.rb +6 -0
  31. data/spec/page-object/page_factory_spec.rb +9 -0
  32. data/spec/page-object/platforms/watir_webdriver/watir_page_object_spec.rb +29 -0
  33. data/spec/page-object/platforms/watir_webdriver_spec.rb +0 -24
  34. data/spec/page-object/selenium_accessors_spec.rb +14 -0
  35. data/spec/page-object/watir_accessors_spec.rb +16 -17
  36. metadata +19 -12
data/ChangeLog CHANGED
@@ -1,3 +1,42 @@
1
+ === Version 0.8.2 / 2013-1-13
2
+ * Enhancements
3
+ * Updated expected_element to ue the global default element wait by default
4
+ * Updated routes to accept more than two entries in the array which are passed as arguments
5
+ * Added new generated method for select_list to return options -> <name>_options (X Zhang)
6
+ * Added scroll_into_view method to Element
7
+ * Added *_element and *_elements methods to PageObject and Element for the following types
8
+ * addr
9
+ * address
10
+ * article
11
+ * aside
12
+ * bdi
13
+ * bdo
14
+ * cite
15
+ * code
16
+ * dd
17
+ * dfn
18
+ * dt
19
+ * em
20
+ * figcaption
21
+ * figure
22
+ * footer
23
+ * header
24
+ * hgroup
25
+ * kbd
26
+ * mark
27
+ * nav
28
+ * noscript
29
+ * rp
30
+ * rt
31
+ * ruby
32
+ * samp
33
+ * section
34
+ * sub
35
+ * summary
36
+ * sup
37
+ * var
38
+ * wbr
39
+
1
40
  === Version 0.8.1 / 2012-12-28
2
41
  * Fixes
3
42
  * Fixed issue when calling new multi-element class methods using a block
data/Gemfile CHANGED
@@ -8,5 +8,6 @@ gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
8
8
  gem 'growl'
9
9
  gem 'guard-rspec'
10
10
  gem 'guard-cucumber'
11
+ gem 'net-http-persistent'
11
12
 
12
13
  gemspec
data/Rakefile CHANGED
@@ -14,11 +14,11 @@ task :spec
14
14
 
15
15
  namespace :features do
16
16
  Cucumber::Rake::Task.new(:watir_webdriver, "Run features with Watir") do |t|
17
- t.profile = "watir"
17
+ t.profile = "watir_webdriver"
18
18
  end
19
19
 
20
20
  Cucumber::Rake::Task.new(:selenium_webdriver, "Run features with Selenium") do |t|
21
- t.profile = "selenium"
21
+ t.profile = "selenium_webdriver"
22
22
  end
23
23
 
24
24
  desc 'Run all features'
data/cucumber.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  <%
2
- std_opts = "BROWSER=firefox --no-source --color --format Cucumber::Formatter::Fuubar"
2
+ std_opts = "--no-source --color --format Cucumber::Formatter::Fuubar"
3
3
  %>
4
4
 
5
5
  default: DRIVER=WATIR <%= std_opts %> --tags ~@selenium_only
6
- watir: DRIVER=WATIR <%= std_opts %> --tags ~@selenium_only
7
- selenium: DRIVER=SELENIUM <%= std_opts %> --tags ~@watir_only
8
- focus: DRIVER=WATIR <%= std_opts %> --tags ~@selenium_only --tags @focus
6
+ watir_webdriver: DRIVER=WATIR <%= std_opts %> --tags ~@selenium_only
7
+ selenium_webdriver: DRIVER=SELENIUM <%= std_opts %> --tags ~@watir_only
8
+ focus: DRIVER=WATIR <%= std_opts %> --tags ~@selenium_only --tags @focus
9
9
  #focus: DRIVER=SELENIUM <%= std_opts %> --tags ~@watir_only --tags @focus
10
10
 
@@ -291,3 +291,8 @@ Feature: Elements
291
291
  Given I am on the Double Click page
292
292
  When I double click the button
293
293
  Then the paragraph should read "Double Click Received"
294
+
295
+ Scenario: Scrolling so an element is visible
296
+ When I retrieve a heading element
297
+ And I scroll the heading element into view
298
+ Then the heading element should be visible
File without changes
File without changes
@@ -41,16 +41,16 @@
41
41
  </script>
42
42
 
43
43
  <audio controls id="audio" name="audio" class="audio">
44
- <source src="http://localhost:4567/04-Death_Becomes_Fur.mp4"
45
- type='audio/mp4'>
46
- <source src="http://localhost:4567/04-Death_Becomes_Fur.oga"
47
- type='audio/ogg; codecs=vorbis'>
48
- <p>Your user agent does not support the HTML5 Audio element.</p>
44
+ <source src="04-Death_Becomes_Fur.mp4"
45
+ type='audio/mp4'/>
46
+ <source src="04-Death_Becomes_Fur.oga"
47
+ type='audio/ogg; codecs=vorbis'/>
48
+ <p>Your user agent does not support the HTML5 Audio element.</p>
49
49
  </audio>
50
50
 
51
51
  <video width="320" height="240" controls="controls" id="video" name="video" class="video">
52
- <source src="http://localhost:4567/movie.mp4" type="video/mp4" />
53
- <source src="http://localhost:4567/movie.ogg" type="video/ogg" />
52
+ <source src="movie.mp4" type="video/mp4" />
53
+ <source src="movie.ogg" type="video/ogg" />
54
54
  Your browser does not support the video tag.
55
55
  </video>
56
56
 
@@ -9,7 +9,7 @@ class SampleApp
9
9
  Rack::Handler::WEBrick.run new,
10
10
  :Host => host,
11
11
  :Port => port,
12
- :Logger => ::WEBrick::Log.new('/dev/null'),
12
+ :Logger => ::WEBrick::Log.new(RUBY_PLATFORM =~ /mswin|mingw/ ? 'NUL:' : '/dev/null'),
13
13
  :AccessLog => [nil, nil]
14
14
  end
15
15
 
@@ -236,3 +236,10 @@ Then /^the paragraph should read "([^\"]*)"$/ do |expected_text|
236
236
  @page.text.should == expected_text
237
237
  end
238
238
 
239
+ When /^I scroll the heading element into view$/ do
240
+ @element.scroll_into_view
241
+ end
242
+
243
+ Then /^the heading element should be visible$/ do
244
+ @element.should be_visible
245
+ end
@@ -1,5 +1,5 @@
1
1
  When /^I get the image element$/ do
2
- @element = @page.image_id_image
2
+ @element = @page.image_id_element
3
3
  end
4
4
 
5
5
  Then /^the image should be "([^\"]*)" pixels wide$/ do |width|
@@ -7,16 +7,22 @@ class JavascriptPage
7
7
 
8
8
  end
9
9
 
10
+ def build_url(page)
11
+ target = ENV['BROWSER']
12
+ return "http://localhost:4567/#{page}" if target.nil? or target.include? 'local'
13
+ "http://ec2-107-22-131-88.compute-1.amazonaws.com:4567/#{page}"
14
+ end
15
+
10
16
  Given /^I am on jQuery example page$/ do
11
17
  PageObject.javascript_framework = :jquery
12
18
  @page = JavascriptPage.new(@browser)
13
- @page.navigate_to "http://localhost:4567/jquery.html"
19
+ @page.navigate_to build_url("jquery.html")
14
20
  end
15
21
 
16
22
  Given /^I am on the Prototype example page$/ do
17
23
  PageObject.javascript_framework = :prototype
18
24
  @page = JavascriptPage.new(@browser)
19
- @page.navigate_to "http://localhost:4567/prototype.html"
25
+ @page.navigate_to build_url('prototype.html')
20
26
  end
21
27
 
22
28
  When /^I ask to compute "([^\"]*)"$/ do |expression|
@@ -1,17 +1,70 @@
1
+ require 'selenium/webdriver/remote/http/persistent'
1
2
 
2
3
  module PageObject
3
4
  module PersistantBrowser
4
5
  @@browser = false
5
6
  def self.get_browser
6
7
  if !@@browser
7
- target_browser = ENV['BROWSER'].to_sym
8
- @@browser = Watir::Browser.new target_browser if ENV['DRIVER'] == 'WATIR'
9
- @@browser = Selenium::WebDriver.for target_browser if ENV['DRIVER'] == 'SELENIUM'
8
+ target = ENV['BROWSER']
9
+ target = 'firefox_local' unless target
10
+
11
+ if is_remote?(target)
12
+ require File.dirname(__FILE__) + "/targets/#{target}"
13
+ extend Target
14
+ end
15
+
16
+ @@browser = watir_browser(target) if ENV['DRIVER'] == 'WATIR'
17
+ @@browser = selenium_browser(target) if ENV['DRIVER'] == 'SELENIUM'
10
18
  end
11
19
  @@browser
12
20
  end
21
+
13
22
  def self.quit
14
23
  @@browser.quit
15
24
  end
25
+
26
+ private
27
+
28
+ def self.is_remote?(target)
29
+ not target.include? 'local'
30
+ end
31
+
32
+ def self.watir_browser(target)
33
+ if is_remote?(target)
34
+ Watir::Browser.new(:remote,
35
+ :http_client => client,
36
+ :url => url,
37
+ :desired_capabilities => desired_capabilities)
38
+ else
39
+ Watir::Browser.new :firefox, :http_client => client
40
+ end
41
+ end
42
+
43
+ def self.selenium_browser(target)
44
+ if is_remote?(target)
45
+ Selenium::WebDriver.for(:remote,
46
+ :http_client => client,
47
+ :url => url,
48
+ :desired_capabilities => desired_capabilities)
49
+ else
50
+ Selenium::WebDriver.for :firefox, :http_client => client
51
+ end
52
+ end
53
+
54
+ def self.client
55
+ Selenium::WebDriver::Remote::Http::Persistent.new
56
+ end
57
+
58
+ def self.capabilities(browser, version, platform, name)
59
+ caps = Selenium::WebDriver::Remote::Capabilities.send browser
60
+ caps.version = version
61
+ caps.platform = platform
62
+ caps[:name] = name
63
+ caps
64
+ end
65
+
66
+ def self.url
67
+ "http://pageobject:18002ee8-963b-472e-9425-2baf0a2b6d95@ondemand.saucelabs.com:80/wd/hub"
68
+ end
16
69
  end
17
70
  end
@@ -0,0 +1,6 @@
1
+ module Target
2
+ def desired_capabilities
3
+ capabilities(:firefox, '14', 'Mac 10.6', 'Testing page-object with Firefox 14 on OS X')
4
+ end
5
+ end
6
+
@@ -0,0 +1,6 @@
1
+ module Target
2
+ def desired_capabilities
3
+ capabilities(:firefox, '14', 'Windows 2008', 'Testing page-object with Firefox 14 on Windows 7')
4
+ end
5
+ end
6
+
@@ -5,7 +5,9 @@ module UrlHelper
5
5
  end
6
6
 
7
7
  def files
8
- "file://#{html}"
8
+ target = ENV['BROWSER']
9
+ return "file://#{html}" if target.nil? or target.include? 'local'
10
+ 'http://ec2-107-22-131-88.compute-1.amazonaws.com'
9
11
  end
10
12
 
11
13
  def static_elements
@@ -77,7 +77,7 @@ module PageObject
77
77
  # expected_element(:address, 10)
78
78
  # page.has_expected_element?
79
79
  #
80
- def expected_element(element_name, timeout=5)
80
+ def expected_element(element_name, timeout=::PageObject.default_element_wait)
81
81
  define_method("has_expected_element?") do
82
82
  self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_present timeout
83
83
  end
@@ -140,15 +140,7 @@ module PageObject
140
140
  return platform.text_field_value_set(identifier.clone, value) unless block_given?
141
141
  self.send("#{name}_element").value = value
142
142
  end
143
- define_method("#{name}_element") do
144
- return call_block(&block) if block_given?
145
- platform.text_field_for(identifier.clone)
146
- end
147
- define_method("#{name}?") do
148
- return call_block(&block).exists? if block_given?
149
- platform.text_field_for(identifier.clone).exists?
150
- end
151
- alias_method "#{name}_text_field".to_sym, "#{name}_element".to_sym
143
+ standard_methods(name, identifier, 'text_field_for', &block)
152
144
  end
153
145
 
154
146
  #
@@ -178,15 +170,7 @@ module PageObject
178
170
  return platform.hidden_field_value_for identifier.clone unless block_given?
179
171
  self.send("#{name}_element").value
180
172
  end
181
- define_method("#{name}_element") do
182
- return call_block(&block) if block_given?
183
- platform.hidden_field_for(identifier.clone)
184
- end
185
- define_method("#{name}?") do
186
- return call_block(&block).exists? if block_given?
187
- platform.hidden_field_for(identifier.clone).exists?
188
- end
189
- alias_method "#{name}_hidden_field".to_sym, "#{name}_element".to_sym
173
+ standard_methods(name, identifier, 'hidden_field_for', &block)
190
174
  end
191
175
  alias_method :hidden, :hidden_field
192
176
 
@@ -220,27 +204,20 @@ module PageObject
220
204
  return platform.text_area_value_set(identifier.clone, value) unless block_given?
221
205
  self.send("#{name}_element").value = value
222
206
  end
223
- define_method("#{name}_element") do
224
- return call_block(&block) if block_given?
225
- platform.text_area_for(identifier.clone)
226
- end
227
- define_method("#{name}?") do
228
- return call_block(&block).exists? if block_given?
229
- platform.text_area_for(identifier.clone).exists?
230
- end
231
- alias_method "#{name}_text_area".to_sym, "#{name}_element".to_sym
207
+ standard_methods(name, identifier, 'text_area_for', &block)
232
208
  end
233
209
  alias_method :textarea, :text_area
234
210
 
235
211
  #
236
- # adds four methods - one to select an item in a drop-down,
212
+ # adds five methods - one to select an item in a drop-down,
237
213
  # another to fetch the currently selected item text, another
238
- # to retrieve the select list element, and another to check the
239
- # drop down's existence.
214
+ # to retrieve the select list element, another to check the
215
+ # drop down's existence and another to get all the available options
216
+ # to select from.
240
217
  #
241
218
  # @example
242
219
  # select_list(:state, :id => "state")
243
- # # will generate 'state', 'state=', 'state_element', 'state?' methods
220
+ # # will generate 'state', 'state=', 'state_element', 'state?', "state_options" methods
244
221
  #
245
222
  # @param [Symbol] the name used for the generated methods
246
223
  # @param [Hash] identifier how we find a select list. You can use a multiple paramaters
@@ -264,15 +241,13 @@ module PageObject
264
241
  return platform.select_list_value_set(identifier.clone, value) unless block_given?
265
242
  self.send("#{name}_element").select(value)
266
243
  end
267
- define_method("#{name}_element") do
268
- return call_block(&block) if block_given?
269
- platform.select_list_for(identifier.clone)
270
- end
271
- define_method("#{name}?") do
272
- return call_block(&block).exists? if block_given?
273
- platform.select_list_for(identifier.clone).exists?
244
+
245
+ define_method("#{name}_options") do
246
+ element = self.send("#{name}_element")
247
+ (element && element.options) ? element.options.collect(&:text) : []
274
248
  end
275
- alias_method "#{name}_select_list".to_sym, "#{name}_element".to_sym
249
+
250
+ standard_methods(name, identifier, 'select_list_for', &block)
276
251
  end
277
252
  alias_method :select, :select_list
278
253
 
@@ -306,15 +281,7 @@ module PageObject
306
281
  return platform.click_link_for identifier.clone unless block_given?
307
282
  self.send("#{name}_element").click
308
283
  end
309
- define_method("#{name}_element") do
310
- return call_block(&block) if block_given?
311
- platform.link_for(identifier.clone)
312
- end
313
- define_method("#{name}?") do
314
- return call_block(&block).exists? if block_given?
315
- platform.link_for(identifier.clone).exists?
316
- end
317
- alias_method "#{name}_link".to_sym, "#{name}_element".to_sym
284
+ standard_methods(name, identifier, 'link_for', &block)
318
285
  end
319
286
  alias_method :a, :link
320
287
 
@@ -354,15 +321,7 @@ module PageObject
354
321
  return platform.checkbox_checked?(identifier.clone) unless block_given?
355
322
  self.send("#{name}_element").checked?
356
323
  end
357
- define_method("#{name}_element") do
358
- return call_block(&block) if block_given?
359
- platform.checkbox_for(identifier.clone)
360
- end
361
- define_method("#{name}?") do
362
- return call_block(&block).exists? if block_given?
363
- platform.checkbox_for(identifier.clone).exists?
364
- end
365
- alias_method "#{name}_checkbox".to_sym, "#{name}_element".to_sym
324
+ standard_methods(name, identifier, 'checkbox_for', &block)
366
325
  end
367
326
 
368
327
  #
@@ -402,15 +361,7 @@ module PageObject
402
361
  return platform.radio_selected?(identifier.clone) unless block_given?
403
362
  self.send("#{name}_element").selected?
404
363
  end
405
- define_method("#{name}_element") do
406
- return call_block(&block) if block_given?
407
- platform.radio_button_for(identifier.clone)
408
- end
409
- define_method("#{name}?") do
410
- return call_block(&block).exists? if block_given?
411
- platform.radio_button_for(identifier.clone).exists?
412
- end
413
- alias_method "#{name}_radio_button".to_sym, "#{name}_element".to_sym
364
+ standard_methods(name, identifier, 'radio_button_for', &block)
414
365
  end
415
366
  alias_method :radio, :radio_button
416
367
 
@@ -442,15 +393,7 @@ module PageObject
442
393
  return platform.click_button_for identifier.clone unless block_given?
443
394
  self.send("#{name}_element").click
444
395
  end
445
- define_method("#{name}_element") do
446
- return call_block(&block) if block_given?
447
- platform.button_for(identifier.clone)
448
- end
449
- define_method("#{name}?") do
450
- return call_block(&block).exists? if block_given?
451
- platform.button_for(identifier.clone).exists?
452
- end
453
- alias_method "#{name}_button".to_sym, "#{name}_element".to_sym
396
+ standard_methods(name, identifier, 'button_for', &block)
454
397
  end
455
398
 
456
399
  #
@@ -479,15 +422,7 @@ module PageObject
479
422
  return platform.div_text_for identifier.clone unless block_given?
480
423
  self.send("#{name}_element").text
481
424
  end
482
- define_method("#{name}_element") do
483
- return call_block(&block) if block_given?
484
- platform.div_for(identifier.clone)
485
- end
486
- define_method("#{name}?") do
487
- return call_block(&block).exists? if block_given?
488
- platform.div_for(identifier.clone).exists?
489
- end
490
- alias_method "#{name}_div".to_sym, "#{name}_element".to_sym
425
+ standard_methods(name, identifier, 'div_for', &block)
491
426
  end
492
427
 
493
428
  #
@@ -516,15 +451,7 @@ module PageObject
516
451
  return platform.span_text_for identifier.clone unless block_given?
517
452
  self.send("#{name}_element").text
518
453
  end
519
- define_method("#{name}_element") do
520
- return call_block(&block) if block_given?
521
- platform.span_for(identifier.clone)
522
- end
523
- define_method("#{name}?") do
524
- return call_block(&block).exists? if block_given?
525
- platform.span_for(identifier.clone).exists?
526
- end
527
- alias_method "#{name}_span".to_sym, "#{name}_element".to_sym
454
+ standard_methods(name, identifier, 'span_for', &block)
528
455
  end
529
456
 
530
457
  #
@@ -553,15 +480,7 @@ module PageObject
553
480
  return platform.table_text_for identifier.clone unless block_given?
554
481
  self.send("#{name}_element").text
555
482
  end
556
- define_method("#{name}_element") do
557
- return call_block(&block) if block_given?
558
- platform.table_for(identifier.clone)
559
- end
560
- define_method("#{name}?") do
561
- return call_block(&block).exists? if block_given?
562
- platform.table_for(identifier.clone).exists?
563
- end
564
- alias_method "#{name}_table".to_sym, "#{name}_element".to_sym
483
+ standard_methods(name, identifier, 'table_for', &block)
565
484
  end
566
485
 
567
486
  #
@@ -590,15 +509,7 @@ module PageObject
590
509
  return platform.cell_text_for identifier.clone unless block_given?
591
510
  self.send("#{name}_element").text
592
511
  end
593
- define_method("#{name}_element") do
594
- return call_block(&block) if block_given?
595
- platform.cell_for(identifier.clone)
596
- end
597
- define_method("#{name}?") do
598
- return call_block(&block).exists? if block_given?
599
- platform.cell_for(identifier.clone).exists?
600
- end
601
- alias_method "#{name}_cell".to_sym, "#{name}_element".to_sym
512
+ standard_methods(name, identifier, 'cell_for', &block)
602
513
  end
603
514
  alias_method :td, :cell
604
515
 
@@ -624,15 +535,7 @@ module PageObject
624
535
  # @param optional block to be invoked when element method is called
625
536
  #
626
537
  def image(name, identifier={:index => 0}, &block)
627
- define_method("#{name}_element") do
628
- return call_block(&block) if block_given?
629
- platform.image_for(identifier.clone)
630
- end
631
- define_method("#{name}?") do
632
- return call_block(&block).exists? if block_given?
633
- platform.image_for(identifier.clone).exists?
634
- end
635
- alias_method "#{name}_image".to_sym, "#{name}_element".to_sym
538
+ standard_methods(name, identifier, 'image_for', &block)
636
539
  end
637
540
  alias_method :img, :image
638
541
 
@@ -656,15 +559,7 @@ module PageObject
656
559
  # @param optional block to be invoked when element method is called
657
560
  #
658
561
  def form(name, identifier={:index => 0}, &block)
659
- define_method("#{name}_element") do
660
- return call_block(&block) if block_given?
661
- platform.form_for(identifier.clone)
662
- end
663
- define_method("#{name}?") do
664
- return call_block(&block).exists? if block_given?
665
- platform.form_for(identifier.clone).exists?
666
- end
667
- alias_method "#{name}_form".to_sym, "#{name}_element".to_sym
562
+ standard_methods(name, identifier, 'form_for', &block)
668
563
  end
669
564
 
670
565
  #
@@ -693,15 +588,7 @@ module PageObject
693
588
  return platform.list_item_text_for identifier.clone unless block_given?
694
589
  self.send("#{name}_element").text
695
590
  end
696
- define_method("#{name}_element") do
697
- return call_block(&block) if block_given?
698
- platform.list_item_for(identifier.clone)
699
- end
700
- define_method("#{name}?") do
701
- return call_block(&block).exists? if block_given?
702
- platform.list_item_for(identifier.clone).exists?
703
- end
704
- alias_method "#{name}_list_item".to_sym, "#{name}_element".to_sym
591
+ standard_methods(name, identifier, 'list_item_for', &block)
705
592
  end
706
593
  alias_method :li, :list_item
707
594
 
@@ -730,15 +617,7 @@ module PageObject
730
617
  return platform.unordered_list_text_for identifier.clone unless block_given?
731
618
  self.send("#{name}_element").text
732
619
  end
733
- define_method("#{name}_element") do
734
- return call_block(&block) if block_given?
735
- platform.unordered_list_for(identifier.clone)
736
- end
737
- define_method("#{name}?") do
738
- return call_block(&block).exists? if block_given?
739
- platform.unordered_list_for(identifier.clone).exists?
740
- end
741
- alias_method "#{name}_unordered_list".to_sym, "#{name}_element".to_sym
620
+ standard_methods(name, identifier, 'unordered_list_for', &block)
742
621
  end
743
622
  alias_method :ul, :unordered_list
744
623
 
@@ -767,15 +646,7 @@ module PageObject
767
646
  return platform.ordered_list_text_for identifier.clone unless block_given?
768
647
  self.send("#{name}_element").text
769
648
  end
770
- define_method("#{name}_element") do
771
- return call_block(&block) if block_given?
772
- platform.ordered_list_for(identifier.clone)
773
- end
774
- define_method("#{name}?") do
775
- return call_block(&block).exists? if block_given?
776
- platform.ordered_list_for(identifier.clone).exists?
777
- end
778
- alias_method "#{name}_ordered_list".to_sym, "#{name}_element".to_sym
649
+ standard_methods(name, identifier, 'ordered_list_for', &block)
779
650
  end
780
651
  alias_method :ol, :ordered_list
781
652
 
@@ -803,15 +674,7 @@ module PageObject
803
674
  return platform.h1_text_for identifier.clone unless block_given?
804
675
  self.send("#{name}_element").text
805
676
  end
806
- define_method("#{name}_element") do
807
- return call_block(&block) if block_given?
808
- platform.h1_for(identifier.clone)
809
- end
810
- define_method("#{name}?") do
811
- return call_block(&block).exists? if block_given?
812
- platform.h1_for(identifier.clone).exists?
813
- end
814
- alias_method "#{name}_h1".to_sym, "#{name}_element".to_sym
677
+ standard_methods(name, identifier,'h1_for', &block)
815
678
  end
816
679
 
817
680
  #
@@ -838,15 +701,7 @@ module PageObject
838
701
  return platform.h2_text_for identifier.clone unless block_given?
839
702
  self.send("#{name}_element").text
840
703
  end
841
- define_method("#{name}_element") do
842
- return call_block(&block) if block_given?
843
- platform.h2_for(identifier.clone)
844
- end
845
- define_method("#{name}?") do
846
- return call_block(&block).exists? if block_given?
847
- platform.h2_for(identifier.clone).exists?
848
- end
849
- alias_method "#{name}_h2".to_sym, "#{name}_element".to_sym
704
+ standard_methods(name, identifier, 'h2_for', &block)
850
705
  end
851
706
 
852
707
  #
@@ -873,15 +728,7 @@ module PageObject
873
728
  return platform.h3_text_for identifier.clone unless block_given?
874
729
  self.send("#{name}_element").text
875
730
  end
876
- define_method("#{name}_element") do
877
- return call_block(&block) if block_given?
878
- platform.h3_for(identifier.clone)
879
- end
880
- define_method("#{name}?") do
881
- return call_block(&block).exists? if block_given?
882
- platform.h3_for(identifier.clone).exists?
883
- end
884
- alias_method "#{name}_h3".to_sym, "#{name}_element".to_sym
731
+ standard_methods(name, identifier, 'h3_for', &block)
885
732
  end
886
733
 
887
734
  #
@@ -908,15 +755,7 @@ module PageObject
908
755
  return platform.h4_text_for identifier.clone unless block_given?
909
756
  self.send("#{name}_element").text
910
757
  end
911
- define_method("#{name}_element") do
912
- return call_block(&block) if block_given?
913
- platform.h4_for(identifier.clone)
914
- end
915
- define_method("#{name}?") do
916
- return call_block(&block).exists? if block_given?
917
- platform.h4_for(identifier.clone).exists?
918
- end
919
- alias_method "#{name}_h4".to_sym, "#{name}_element".to_sym
758
+ standard_methods(name, identifier, 'h4_for', &block)
920
759
  end
921
760
 
922
761
  #
@@ -943,15 +782,7 @@ module PageObject
943
782
  return platform.h5_text_for identifier.clone unless block_given?
944
783
  self.send("#{name}_element").text
945
784
  end
946
- define_method("#{name}_element") do
947
- return call_block(&block) if block_given?
948
- platform.h5_for(identifier.clone)
949
- end
950
- define_method("#{name}?") do
951
- return call_block(&block).exists? if block_given?
952
- platform.h5_for(identifier.clone).exists?
953
- end
954
- alias_method "#{name}_h5".to_sym, "#{name}_element".to_sym
785
+ standard_methods(name, identifier, 'h5_for', &block)
955
786
  end
956
787
 
957
788
  #
@@ -978,15 +809,7 @@ module PageObject
978
809
  return platform.h6_text_for identifier.clone unless block_given?
979
810
  self.send("#{name}_element").text
980
811
  end
981
- define_method("#{name}_element") do
982
- return call_block(&block) if block_given?
983
- platform.h6_for(identifier.clone)
984
- end
985
- define_method("#{name}?") do
986
- return call_block(&block).exists? if block_given?
987
- platform.h6_for(identifier.clone).exists?
988
- end
989
- alias_method "#{name}_h6".to_sym, "#{name}_element".to_sym
812
+ standard_methods(name, identifier, 'h6_for', &block)
990
813
  end
991
814
 
992
815
  #
@@ -1013,15 +836,7 @@ module PageObject
1013
836
  return platform.paragraph_text_for identifier.clone unless block_given?
1014
837
  self.send("#{name}_element").text
1015
838
  end
1016
- define_method("#{name}_element") do
1017
- return call_block(&block) if block_given?
1018
- platform.paragraph_for(identifier.clone)
1019
- end
1020
- define_method("#{name}?") do
1021
- return call_block(&block).exists? if block_given?
1022
- platform.paragraph_for(identifier.clone).exists?
1023
- end
1024
- alias_method "#{name}_paragraph".to_sym, "#{name}_element".to_sym
839
+ standard_methods(name, identifier, 'paragraph_for', &block)
1025
840
  end
1026
841
  alias_method :p, :paragraph
1027
842
 
@@ -1050,14 +865,7 @@ module PageObject
1050
865
  return platform.file_field_value_set(identifier.clone, value) unless block_given?
1051
866
  self.send("#{name}_element").value = value
1052
867
  end
1053
- define_method("#{name}_element") do
1054
- return call_block(&block) if block_given?
1055
- platform.file_field_for(identifier.clone)
1056
- end
1057
- define_method("#{name}?") do
1058
- return call_block(&block).exists? if block_given?
1059
- platform.file_field_for(identifier.clone).exists?
1060
- end
868
+ standard_methods(name, identifier, 'file_field_for', &block)
1061
869
  end
1062
870
 
1063
871
  #
@@ -1085,15 +893,7 @@ module PageObject
1085
893
  return platform.label_text_for identifier.clone unless block_given?
1086
894
  self.send("#{name}_element").text
1087
895
  end
1088
- define_method("#{name}_element") do
1089
- return call_block(&block) if block_given?
1090
- platform.label_for(identifier.clone)
1091
- end
1092
- define_method("#{name}?") do
1093
- return call_block(&block).exists? if block_given?
1094
- platform.label_for(identifier.clone).exists?
1095
- end
1096
- alias_method "#{name}_label".to_sym, "#{name}_element".to_sym
896
+ standard_methods(name, identifier, 'label_for', &block)
1097
897
  end
1098
898
 
1099
899
  #
@@ -1121,14 +921,7 @@ module PageObject
1121
921
  return platform.click_area_for identifier.clone unless block_given?
1122
922
  self.send("#{name}_element").click
1123
923
  end
1124
- define_method("#{name}_element") do
1125
- return call_block(&block) if block_given?
1126
- platform.area_for(identifier.clone)
1127
- end
1128
- define_method("#{name}?") do
1129
- return call_block(&block).exists? if block_given?
1130
- platform.area_for(identifier.clone).exists?
1131
- end
924
+ standard_methods(name, identifier, 'area_for', &block)
1132
925
  end
1133
926
 
1134
927
  #
@@ -1151,14 +944,7 @@ module PageObject
1151
944
  # @param optional block to be invoked when element method is called
1152
945
  #
1153
946
  def canvas(name, identifier={:index => 0}, &block)
1154
- define_method("#{name}_element") do
1155
- return call_block(&block) if block_given?
1156
- platform.canvas_for(identifier.clone)
1157
- end
1158
- define_method("#{name}?") do
1159
- return call_block(&block).exists? if block_given?
1160
- platform.canvas_for(identifier.clone).exists?
1161
- end
947
+ standard_methods(name, identifier, 'canvas_for', &block)
1162
948
  end
1163
949
 
1164
950
  #
@@ -1181,14 +967,7 @@ module PageObject
1181
967
  # @param optional block to be invoked when element method is called
1182
968
  #
1183
969
  def audio(name, identifier={:index => 0}, &block)
1184
- define_method("#{name}_element") do
1185
- return call_block(&block) if block_given?
1186
- platform.audio_for(identifier.clone)
1187
- end
1188
- define_method("#{name}?") do
1189
- return call_block(&block).exists? if block_given?
1190
- platform.audio_for(identifier.clone).exists?
1191
- end
970
+ standard_methods(name, identifier, 'audio_for', &block)
1192
971
  end
1193
972
 
1194
973
  #
@@ -1211,14 +990,7 @@ module PageObject
1211
990
  # @param optional block to be invoked when element method is called
1212
991
  #
1213
992
  def video(name, identifier={:index => 0}, &block)
1214
- define_method("#{name}_element") do
1215
- return call_block(&block) if block_given?
1216
- platform.video_for(identifier.clone)
1217
- end
1218
- define_method("#{name}?") do
1219
- return call_block(&block).exists? if block_given?
1220
- platform.video_for(identifier.clone).exists?
1221
- end
993
+ standard_methods(name, identifier, 'video_for', &block)
1222
994
  end
1223
995
 
1224
996
  #
@@ -1255,15 +1027,16 @@ module PageObject
1255
1027
  end
1256
1028
 
1257
1029
  #
1258
- # adds three methods - one to retrieve the text of an abbr, another
1259
- # to retrieve an abbr, and another to check the abbr's existence.
1030
+ # methods to generate accessors for types that follow the same
1031
+ # pattern as element
1260
1032
  #
1261
1033
  # @example
1262
- # abbr(:title, :id => 'title')
1263
- # # will generate 'title', 'title_element', and 'title?' methods
1034
+ # address(:home_address, :id => "home_address")
1035
+ # will generate 'home_address', 'home_address_element' and 'home_address?'
1264
1036
  #
1265
1037
  # @param [Symbol] the name used for the generated methods
1266
- # @param [Hash] identifier how we find an abbr. You can use a multiple paramaters
1038
+ # @param [Symbol] the name of the tag for the element
1039
+ # @param [Hash] identifier how we find an element. You can use a multiple paramaters
1267
1040
  # by combining of any of the following except xpath. The valid keys are:
1268
1041
  # * :class => Watir and Selenium
1269
1042
  # * :css => Selenium only
@@ -1271,746 +1044,100 @@ module PageObject
1271
1044
  # * :index => Watir and Selenium
1272
1045
  # * :name => Watir and Selenium
1273
1046
  # * :xpath => Watir and Selenium
1274
- # @param optional block to be invoked when abbr method is called
1047
+ # @param optional block to be invoked when element method is called
1275
1048
  #
1276
- def abbr(name, identifier={:index => 0}, &block)
1277
- element(name, :abbr, identifier, &block)
1049
+ [:abbr,
1050
+ :address,
1051
+ :article,
1052
+ :aside,
1053
+ :bdi,
1054
+ :bdo,
1055
+ :cite,
1056
+ :code,
1057
+ :dd,
1058
+ :dfn,
1059
+ :dt,
1060
+ :em,
1061
+ :figcaption,
1062
+ :figure,
1063
+ :footer,
1064
+ :header,
1065
+ :hgroup,
1066
+ :kbd,
1067
+ :mark,
1068
+ :nav,
1069
+ :noscript,
1070
+ :rp,
1071
+ :rt,
1072
+ :ruby,
1073
+ :samp,
1074
+ :section,
1075
+ :sub,
1076
+ :summary,
1077
+ :sup,
1078
+ :var,
1079
+ :wbr].each do |type|
1080
+ define_method(type) do |name, *identifier, &block|
1081
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1082
+ element(name, type, identifier, &block)
1083
+ end
1084
+ end
1085
+
1086
+ def standard_methods(name, identifier, method, &block)
1087
+ define_method("#{name}_element") do
1088
+ return call_block(&block) if block_given?
1089
+ platform.send(method, identifier.clone)
1090
+ end
1091
+ define_method("#{name}?") do
1092
+ return call_block(&block).exists? if block_given?
1093
+ platform.send(method, identifier.clone).exists?
1094
+ end
1278
1095
  end
1279
-
1096
+
1280
1097
  #
1281
- # adds three methods - one to retrieve the text of an address, another
1282
- # to retrieve an address, and another to check the address's existence.
1098
+ # adds a method that will return an indexed property. The property will respond to
1099
+ # the [] method with an object that has a set of normal page_object properties that
1100
+ # correspond to the definitions included in the identifier_list parameter, with the
1101
+ # "what" of the "how and what" substituted based on the index provided to the []
1102
+ # method.
1283
1103
  #
1284
1104
  # @example
1285
- # address(:title, :id => 'title')
1286
- # # will generate 'title', 'title_element', and 'title?' methods
1105
+ # indexed_property(:title, [
1106
+ # [:text_field, :field_1, :id => 'table[%s].field_1'],
1107
+ # [:button, :button_1, :id => 'table[%s].button_1'],
1108
+ # [:text_field, :field_2, :name => 'table[%s].field_2']
1109
+ # ])
1110
+ # # will generate a title method that responds to []. title['foo'] will return an object
1111
+ # # that responds to the normal methods expected for two text_fields and a button with the
1112
+ # # given names, using the given how and what with 'foo' substituted for the %s. title[123]
1113
+ # # will do the same, using the integer 123 instead.
1287
1114
  #
1288
- # @param [Symbol] the name used for the generated methods
1289
- # @param [Hash] identifier how we find an address. You can use a multiple paramaters
1290
- # by combining of any of the following except xpath. The valid keys are:
1291
- # * :class => Watir and Selenium
1292
- # * :css => Selenium only
1293
- # * :id => Watir and Selenium
1294
- # * :index => Watir and Selenium
1295
- # * :name => Watir and Selenium
1296
- # * :xpath => Watir and Selenium
1297
- # @param optional block to be invoked when address method is called
1115
+ # @param [Symbol] the name used for the generated method
1116
+ # @param [Array] definitions an array of definitions to define on the indexed property. Each
1117
+ # entry in the array should contain two symbols and a hash, corresponding to one of the standard
1118
+ # page_object properties with a single substitution marker in each value in the hash,
1119
+ # e.g. [:text_field, :field_1, :id => 'table[%s].field_1']
1298
1120
  #
1299
- def address(name, identifier={:index => 0}, &block)
1300
- element(name, :address, identifier, &block)
1121
+ def indexed_property (name, identifier_list)
1122
+ define_method("#{name}") do
1123
+ IndexedProperties::TableOfElements.new(@browser, identifier_list)
1124
+ end
1301
1125
  end
1302
1126
 
1303
1127
  #
1304
- # adds three methods - one to retrieve the text of an article, another
1305
- # to retrieve an article, and another to check the article's existence.
1306
- #
1307
- # @example
1308
- # article(:title, :id => 'title')
1309
- # # will generate 'title', 'title_element', and 'title?' methods
1310
- #
1311
- # @param [Symbol] the name used for the generated methods
1312
- # @param [Hash] identifier how we find an article. You can use a multiple paramaters
1313
- # by combining of any of the following except xpath. The valid keys are:
1314
- # * :class => Watir and Selenium
1315
- # * :css => Selenium only
1316
- # * :id => Watir and Selenium
1317
- # * :index => Watir and Selenium
1318
- # * :name => Watir and Selenium
1319
- # * :xpath => Watir and Selenium
1320
- # @param optional block to be invoked when article method is called
1321
- #
1322
- def article(name, identifier={:index => 0}, &block)
1323
- element(name, :article, identifier, &block)
1324
- end
1325
-
1128
+ # methods to fetch multiple elements of the same type
1326
1129
  #
1327
- # adds three methods - one to retrieve the text of an aside, another
1328
- # to retrieve an aside, and another to check the aside's existence.
1130
+ # adds a method to the page object to retrun all of the matching elements
1329
1131
  #
1330
1132
  # @example
1331
- # aside(:title, :id => 'title')
1332
- # # will generate 'title', 'title_element', and 'title?' methods
1133
+ # text_fields(:first_name, :id => "first_name")
1134
+ # # will generate 'first_name_elements'
1333
1135
  #
1334
- # @param [Symbol] the name used for the generated methods
1335
- # @param [Hash] identifier how we find an aside. You can use a multiple paramaters
1336
- # by combining of any of the following except xpath. The valid keys are:
1337
- # * :class => Watir and Selenium
1338
- # * :css => Selenium only
1339
- # * :id => Watir and Selenium
1340
- # * :index => Watir and Selenium
1341
- # * :name => Watir and Selenium
1342
- # * :xpath => Watir and Selenium
1343
- # @param optional block to be invoked when aside method is called
1344
- #
1345
- def aside(name, identifier={:index => 0}, &block)
1346
- element(name, :aside, identifier, &block)
1347
- end
1348
-
1349
- #
1350
- # adds three methods - one to retrieve the text of an bdi, another
1351
- # to retrieve an bdi, and another to check the bdi's existence.
1352
- #
1353
- # @example
1354
- # bdi(:title, :id => 'title')
1355
- # # will generate 'title', 'title_element', and 'title?' methods
1356
- #
1357
- # @param [Symbol] the name used for the generated methods
1358
- # @param [Hash] identifier how we find an bdi. You can use a multiple paramaters
1359
- # by combining of any of the following except xpath. The valid keys are:
1360
- # * :class => Watir and Selenium
1361
- # * :css => Selenium only
1362
- # * :id => Watir and Selenium
1363
- # * :index => Watir and Selenium
1364
- # * :name => Watir and Selenium
1365
- # * :xpath => Watir and Selenium
1366
- # @param optional block to be invoked when bdi method is called
1367
- #
1368
- def bdi(name, identifier={:index => 0}, &block)
1369
- element(name, :bdi, identifier, &block)
1370
- end
1371
-
1372
- #
1373
- # adds three methods - one to retrieve the text of an bdo, another
1374
- # to retrieve an bdo, and another to check the bdo's existence.
1375
- #
1376
- # @example
1377
- # bdo(:title, :id => 'title')
1378
- # # will generate 'title', 'title_element', and 'title?' methods
1379
- #
1380
- # @param [Symbol] the name used for the generated methods
1381
- # @param [Hash] identifier how we find an bdo. You can use a multiple paramaters
1382
- # by combining of any of the following except xpath. The valid keys are:
1383
- # * :class => Watir and Selenium
1384
- # * :css => Selenium only
1385
- # * :id => Watir and Selenium
1386
- # * :index => Watir and Selenium
1387
- # * :name => Watir and Selenium
1388
- # * :xpath => Watir and Selenium
1389
- # @param optional block to be invoked when bdo method is called
1390
- #
1391
- def bdo(name, identifier={:index => 0}, &block)
1392
- element(name, :bdo, identifier, &block)
1393
- end
1394
-
1395
- #
1396
- # adds three methods - one to retrieve the text of an cite, another
1397
- # to retrieve an cite, and another to check the cite's existence.
1398
- #
1399
- # @example
1400
- # cite(:title, :id => 'title')
1401
- # # will generate 'title', 'title_element', and 'title?' methods
1402
- #
1403
- # @param [Symbol] the name used for the generated methods
1404
- # @param [Hash] identifier how we find an cite. You can use a multiple paramaters
1405
- # by combining of any of the following except xpath. The valid keys are:
1406
- # * :class => Watir and Selenium
1407
- # * :css => Selenium only
1408
- # * :id => Watir and Selenium
1409
- # * :index => Watir and Selenium
1410
- # * :name => Watir and Selenium
1411
- # * :xpath => Watir and Selenium
1412
- # @param optional block to be invoked when cite method is called
1413
- #
1414
- def cite(name, identifier={:index => 0}, &block)
1415
- element(name, :cite, identifier, &block)
1416
- end
1417
-
1418
- #
1419
- # adds three methods - one to retrieve the text of an code, another
1420
- # to retrieve an code, and another to check the code's existence.
1421
- #
1422
- # @example
1423
- # code(:title, :id => 'title')
1424
- # # will generate 'title', 'title_element', and 'title?' methods
1425
- #
1426
- # @param [Symbol] the name used for the generated methods
1427
- # @param [Hash] identifier how we find an code. You can use a multiple paramaters
1428
- # by combining of any of the following except xpath. The valid keys are:
1429
- # * :class => Watir and Selenium
1430
- # * :css => Selenium only
1431
- # * :id => Watir and Selenium
1432
- # * :index => Watir and Selenium
1433
- # * :name => Watir and Selenium
1434
- # * :xpath => Watir and Selenium
1435
- # @param optional block to be invoked when code method is called
1436
- #
1437
- def code(name, identifier={:index => 0}, &block)
1438
- element(name, :code, identifier, &block)
1439
- end
1440
-
1441
- #
1442
- # adds three methods - one to retrieve the text of an dd, another
1443
- # to retrieve an dd, and another to check the dd's existence.
1444
- #
1445
- # @example
1446
- # dd(:title, :id => 'title')
1447
- # # will generate 'title', 'title_element', and 'title?' methods
1448
- #
1449
- # @param [Symbol] the name used for the generated methods
1450
- # @param [Hash] identifier how we find an dd. You can use a multiple paramaters
1451
- # by combining of any of the following except xpath. The valid keys are:
1452
- # * :class => Watir and Selenium
1453
- # * :css => Selenium only
1454
- # * :id => Watir and Selenium
1455
- # * :index => Watir and Selenium
1456
- # * :name => Watir and Selenium
1457
- # * :xpath => Watir and Selenium
1458
- # @param optional block to be invoked when dd method is called
1459
- #
1460
- def dd(name, identifier={:index => 0}, &block)
1461
- element(name, :dd, identifier, &block)
1462
- end
1463
-
1464
- #
1465
- # adds three methods - one to retrieve the text of an dfn, another
1466
- # to retrieve an dfn, and another to check the dfn's existence.
1467
- #
1468
- # @example
1469
- # dfn(:title, :id => 'title')
1470
- # # will generate 'title', 'title_element', and 'title?' methods
1471
- #
1472
- # @param [Symbol] the name used for the generated methods
1473
- # @param [Hash] identifier how we find an dfn. You can use a multiple paramaters
1474
- # by combining of any of the following except xpath. The valid keys are:
1475
- # * :class => Watir and Selenium
1476
- # * :css => Selenium only
1477
- # * :id => Watir and Selenium
1478
- # * :index => Watir and Selenium
1479
- # * :name => Watir and Selenium
1480
- # * :xpath => Watir and Selenium
1481
- # @param optional block to be invoked when dfn method is called
1482
- #
1483
- def dfn(name, identifier={:index => 0}, &block)
1484
- element(name, :dfn, identifier, &block)
1485
- end
1486
-
1487
- #
1488
- # adds three methods - one to retrieve the text of an dt, another
1489
- # to retrieve an dt, and another to check the dt's existence.
1490
- #
1491
- # @example
1492
- # dt(:title, :id => 'title')
1493
- # # will generate 'title', 'title_element', and 'title?' methods
1494
- #
1495
- # @param [Symbol] the name used for the generated methods
1496
- # @param [Hash] identifier how we find an dt. You can use a multiple paramaters
1497
- # by combining of any of the following except xpath. The valid keys are:
1498
- # * :class => Watir and Selenium
1499
- # * :css => Selenium only
1500
- # * :id => Watir and Selenium
1501
- # * :index => Watir and Selenium
1502
- # * :name => Watir and Selenium
1503
- # * :xpath => Watir and Selenium
1504
- # @param optional block to be invoked when dt method is called
1505
- #
1506
- def dt(name, identifier={:index => 0}, &block)
1507
- element(name, :dt, identifier, &block)
1508
- end
1509
-
1510
- #
1511
- # adds three methods - one to retrieve the text of an em, another
1512
- # to retrieve an em, and another to check the em's existence.
1513
- #
1514
- # @example
1515
- # em(:title, :id => 'title')
1516
- # # will generate 'title', 'title_element', and 'title?' methods
1517
- #
1518
- # @param [Symbol] the name used for the generated methods
1519
- # @param [Hash] identifier how we find an em. You can use a multiple paramaters
1520
- # by combining of any of the following except xpath. The valid keys are:
1521
- # * :class => Watir and Selenium
1522
- # * :css => Selenium only
1523
- # * :id => Watir and Selenium
1524
- # * :index => Watir and Selenium
1525
- # * :name => Watir and Selenium
1526
- # * :xpath => Watir and Selenium
1527
- # @param optional block to be invoked when em method is called
1528
- #
1529
- def em(name, identifier={:index => 0}, &block)
1530
- element(name, :em, identifier, &block)
1531
- end
1532
-
1533
- #
1534
- # adds three methods - one to retrieve the text of an figcaption, another
1535
- # to retrieve an figcaption, and another to check the figcaption's existence.
1536
- #
1537
- # @example
1538
- # figcaption(:title, :id => 'title')
1539
- # # will generate 'title', 'title_elfigcaptionent', and 'title?' methods
1540
- #
1541
- # @param [Symbol] the name used for the generated methods
1542
- # @param [Hash] identifier how we find an figcaption. You can use a multiple paramaters
1543
- # by combining of any of the following except xpath. The valid keys are:
1544
- # * :class => Watir and Selenium
1545
- # * :css => Selenium only
1546
- # * :id => Watir and Selenium
1547
- # * :index => Watir and Selenium
1548
- # * :name => Watir and Selenium
1549
- # * :xpath => Watir and Selenium
1550
- # @param optional block to be invoked when figcaption method is called
1551
- #
1552
- def figcaption(name, identifier={:index => 0}, &block)
1553
- element(name, :figcaption, identifier, &block)
1554
- end
1555
-
1556
- #
1557
- # adds three methods - one to retrieve the text of an figure, another
1558
- # to retrieve an figure, and another to check the figure's existence.
1559
- #
1560
- # @example
1561
- # figure(:title, :id => 'title')
1562
- # # will generate 'title', 'title_elfigureent', and 'title?' methods
1563
- #
1564
- # @param [Symbol] the name used for the generated methods
1565
- # @param [Hash] identifier how we find an figure. You can use a multiple paramaters
1566
- # by combining of any of the following except xpath. The valid keys are:
1567
- # * :class => Watir and Selenium
1568
- # * :css => Selenium only
1569
- # * :id => Watir and Selenium
1570
- # * :index => Watir and Selenium
1571
- # * :name => Watir and Selenium
1572
- # * :xpath => Watir and Selenium
1573
- # @param optional block to be invoked when figure method is called
1574
- #
1575
- def figure(name, identifier={:index => 0}, &block)
1576
- element(name, :figure, identifier, &block)
1577
- end
1578
-
1579
- #
1580
- # adds three methods - one to retrieve the text of an footer, another
1581
- # to retrieve an footer, and another to check the footer's existence.
1582
- #
1583
- # @example
1584
- # footer(:title, :id => 'title')
1585
- # # will generate 'title', 'title_elfooterent', and 'title?' methods
1586
- #
1587
- # @param [Symbol] the name used for the generated methods
1588
- # @param [Hash] identifier how we find an footer. You can use a multiple paramaters
1589
- # by combining of any of the following except xpath. The valid keys are:
1590
- # * :class => Watir and Selenium
1591
- # * :css => Selenium only
1592
- # * :id => Watir and Selenium
1593
- # * :index => Watir and Selenium
1594
- # * :name => Watir and Selenium
1595
- # * :xpath => Watir and Selenium
1596
- # @param optional block to be invoked when footer method is called
1597
- #
1598
- def footer(name, identifier={:index => 0}, &block)
1599
- element(name, :footer, identifier, &block)
1600
- end
1601
-
1602
- #
1603
- # adds three methods - one to retrieve the text of an header, another
1604
- # to retrieve an header, and another to check the header's existence.
1605
- #
1606
- # @example
1607
- # header(:title, :id => 'title')
1608
- # # will generate 'title', 'title_elheaderent', and 'title?' methods
1609
- #
1610
- # @param [Symbol] the name used for the generated methods
1611
- # @param [Hash] identifier how we find an header. You can use a multiple paramaters
1612
- # by combining of any of the following except xpath. The valid keys are:
1613
- # * :class => Watir and Selenium
1614
- # * :css => Selenium only
1615
- # * :id => Watir and Selenium
1616
- # * :index => Watir and Selenium
1617
- # * :name => Watir and Selenium
1618
- # * :xpath => Watir and Selenium
1619
- # @param optional block to be invoked when header method is called
1620
- #
1621
- def header(name, identifier={:index => 0}, &block)
1622
- element(name, :header, identifier, &block)
1623
- end
1624
-
1625
- #
1626
- # adds three methods - one to retrieve the text of an hgroup, another
1627
- # to retrieve an hgroup, and another to check the hgroup's existence.
1628
- #
1629
- # @example
1630
- # hgroup(:title, :id => 'title')
1631
- # # will generate 'title', 'title_elhgroupent', and 'title?' methods
1632
- #
1633
- # @param [Symbol] the name used for the generated methods
1634
- # @param [Hash] identifier how we find an hgroup. You can use a multiple paramaters
1635
- # by combining of any of the following except xpath. The valid keys are:
1636
- # * :class => Watir and Selenium
1637
- # * :css => Selenium only
1638
- # * :id => Watir and Selenium
1639
- # * :index => Watir and Selenium
1640
- # * :name => Watir and Selenium
1641
- # * :xpath => Watir and Selenium
1642
- # @param optional block to be invoked when hgroup method is called
1643
- #
1644
- def hgroup(name, identifier={:index => 0}, &block)
1645
- element(name, :hgroup, identifier, &block)
1646
- end
1647
-
1648
- #
1649
- # adds three methods - one to retrieve the text of an kbd, another
1650
- # to retrieve an kbd, and another to check the kbd's existence.
1651
- #
1652
- # @example
1653
- # kbd(:title, :id => 'title')
1654
- # # will generate 'title', 'title_elkbdent', and 'title?' methods
1655
- #
1656
- # @param [Symbol] the name used for the generated methods
1657
- # @param [Hash] identifier how we find an kbd. You can use a multiple paramaters
1658
- # by combining of any of the following except xpath. The valid keys are:
1659
- # * :class => Watir and Selenium
1660
- # * :css => Selenium only
1661
- # * :id => Watir and Selenium
1662
- # * :index => Watir and Selenium
1663
- # * :name => Watir and Selenium
1664
- # * :xpath => Watir and Selenium
1665
- # @param optional block to be invoked when kbd method is called
1666
- #
1667
- def kbd(name, identifier={:index => 0}, &block)
1668
- element(name, :kbd, identifier, &block)
1669
- end
1670
-
1671
- #
1672
- # adds three methods - one to retrieve the text of an mark, another
1673
- # to retrieve an mark, and another to check the mark's existence.
1674
- #
1675
- # @example
1676
- # mark(:title, :id => 'title')
1677
- # # will generate 'title', 'title_elmarkent', and 'title?' methods
1678
- #
1679
- # @param [Symbol] the name used for the generated methods
1680
- # @param [Hash] identifier how we find an mark. You can use a multiple paramaters
1681
- # by combining of any of the following except xpath. The valid keys are:
1682
- # * :class => Watir and Selenium
1683
- # * :css => Selenium only
1684
- # * :id => Watir and Selenium
1685
- # * :index => Watir and Selenium
1686
- # * :name => Watir and Selenium
1687
- # * :xpath => Watir and Selenium
1688
- # @param optional block to be invoked when mark method is called
1689
- #
1690
- def mark(name, identifier={:index => 0}, &block)
1691
- element(name, :mark, identifier, &block)
1692
- end
1693
-
1694
- #
1695
- # adds three methods - one to retrieve the text of an nav, another
1696
- # to retrieve an nav, and another to check the nav's existence.
1697
- #
1698
- # @example
1699
- # nav(:title, :id => 'title')
1700
- # # will generate 'title', 'title_elnavent', and 'title?' methods
1701
- #
1702
- # @param [Symbol] the name used for the generated methods
1703
- # @param [Hash] identifier how we find an nav. You can use a multiple paramaters
1704
- # by combining of any of the following except xpath. The valid keys are:
1705
- # * :class => Watir and Selenium
1706
- # * :css => Selenium only
1707
- # * :id => Watir and Selenium
1708
- # * :index => Watir and Selenium
1709
- # * :name => Watir and Selenium
1710
- # * :xpath => Watir and Selenium
1711
- # @param optional block to be invoked when nav method is called
1712
- #
1713
- def nav(name, identifier={:index => 0}, &block)
1714
- element(name, :nav, identifier, &block)
1715
- end
1716
-
1717
- #
1718
- # adds three methods - one to retrieve the text of an noscript, another
1719
- # to retrieve an noscript, and another to check the noscript's existence.
1720
- #
1721
- # @example
1722
- # noscript(:title, :id => 'title')
1723
- # # will generate 'title', 'title_elnoscriptent', and 'title?' methods
1724
- #
1725
- # @param [Symbol] the name used for the generated methods
1726
- # @param [Hash] identifier how we find an noscript. You can use a multiple paramaters
1727
- # by combining of any of the following except xpath. The valid keys are:
1728
- # * :class => Watir and Selenium
1729
- # * :css => Selenium only
1730
- # * :id => Watir and Selenium
1731
- # * :index => Watir and Selenium
1732
- # * :name => Watir and Selenium
1733
- # * :xpath => Watir and Selenium
1734
- # @param optional block to be invoked when noscript method is called
1735
- #
1736
- def noscript(name, identifier={:index => 0}, &block)
1737
- element(name, :noscript, identifier, &block)
1738
- end
1739
-
1740
- #
1741
- # adds three methods - one to retrieve the text of an rp, another
1742
- # to retrieve an rp, and another to check the rp's existence.
1743
- #
1744
- # @example
1745
- # rp(:title, :id => 'title')
1746
- # # will generate 'title', 'title_elrpent', and 'title?' methods
1747
- #
1748
- # @param [Symbol] the name used for the generated methods
1749
- # @param [Hash] identifier how we find an rp. You can use a multiple paramaters
1750
- # by combining of any of the following except xpath. The valid keys are:
1751
- # * :class => Watir and Selenium
1752
- # * :css => Selenium only
1753
- # * :id => Watir and Selenium
1754
- # * :index => Watir and Selenium
1755
- # * :name => Watir and Selenium
1756
- # * :xpath => Watir and Selenium
1757
- # @param optional block to be invoked when rp method is called
1758
- #
1759
- def rp(name, identifier={:index => 0}, &block)
1760
- element(name, :rp, identifier, &block)
1761
- end
1762
-
1763
- #
1764
- # adds three methods - one to retrieve the text of an rt, another
1765
- # to retrieve an rt, and another to check the rt's existence.
1766
- #
1767
- # @example
1768
- # rt(:title, :id => 'title')
1769
- # # will generate 'title', 'title_elrtent', and 'title?' methods
1770
- #
1771
- # @param [Symbol] the name used for the generated methods
1772
- # @param [Hash] identifier how we find an rt. You can use a multiple paramaters
1773
- # by combining of any of the following except xpath. The valid keys are:
1774
- # * :class => Watir and Selenium
1775
- # * :css => Selenium only
1776
- # * :id => Watir and Selenium
1777
- # * :index => Watir and Selenium
1778
- # * :name => Watir and Selenium
1779
- # * :xpath => Watir and Selenium
1780
- # @param optional block to be invoked when rt method is called
1781
- #
1782
- def rt(name, identifier={:index => 0}, &block)
1783
- element(name, :rt, identifier, &block)
1784
- end
1785
-
1786
- #
1787
- # adds three methods - one to retrieve the text of an ruby, another
1788
- # to retrieve an ruby, and another to check the ruby's existence.
1789
- #
1790
- # @example
1791
- # ruby(:title, :id => 'title')
1792
- # # will generate 'title', 'title_elrubyent', and 'title?' methods
1793
- #
1794
- # @param [Symbol] the name used for the generated methods
1795
- # @param [Hash] identifier how we find an ruby. You can use a multiple paramaters
1796
- # by combining of any of the following except xpath. The valid keys are:
1797
- # * :class => Watir and Selenium
1798
- # * :css => Selenium only
1799
- # * :id => Watir and Selenium
1800
- # * :index => Watir and Selenium
1801
- # * :name => Watir and Selenium
1802
- # * :xpath => Watir and Selenium
1803
- # @param optional block to be invoked when ruby method is called
1804
- #
1805
- def ruby(name, identifier={:index => 0}, &block)
1806
- element(name, :ruby, identifier, &block)
1807
- end
1808
-
1809
- #
1810
- # adds three methods - one to retrieve the text of an samp, another
1811
- # to retrieve an samp, and another to check the samp's existence.
1812
- #
1813
- # @example
1814
- # samp(:title, :id => 'title')
1815
- # # will generate 'title', 'title_elsampent', and 'title?' methods
1816
- #
1817
- # @param [Symbol] the name used for the generated methods
1818
- # @param [Hash] identifier how we find an samp. You can use a multiple paramaters
1819
- # by combining of any of the following except xpath. The valid keys are:
1820
- # * :class => Watir and Selenium
1821
- # * :css => Selenium only
1822
- # * :id => Watir and Selenium
1823
- # * :index => Watir and Selenium
1824
- # * :name => Watir and Selenium
1825
- # * :xpath => Watir and Selenium
1826
- # @param optional block to be invoked when samp method is called
1827
- #
1828
- def samp(name, identifier={:index => 0}, &block)
1829
- element(name, :samp, identifier, &block)
1830
- end
1831
-
1832
- #
1833
- # adds three methods - one to retrieve the text of an section, another
1834
- # to retrieve an section, and another to check the section's existence.
1835
- #
1836
- # @example
1837
- # section(:title, :id => 'title')
1838
- # # will generate 'title', 'title_elsectionent', and 'title?' methods
1839
- #
1840
- # @param [Symbol] the name used for the generated methods
1841
- # @param [Hash] identifier how we find an section. You can use a multiple paramaters
1842
- # by combining of any of the following except xpath. The valid keys are:
1843
- # * :class => Watir and Selenium
1844
- # * :css => Selenium only
1845
- # * :id => Watir and Selenium
1846
- # * :index => Watir and Selenium
1847
- # * :name => Watir and Selenium
1848
- # * :xpath => Watir and Selenium
1849
- # @param optional block to be invoked when section method is called
1850
- #
1851
- def section(name, identifier={:index => 0}, &block)
1852
- element(name, :section, identifier, &block)
1853
- end
1854
-
1855
- #
1856
- # adds three methods - one to retrieve the text of an sub, another
1857
- # to retrieve an sub, and another to check the sub's existence.
1858
- #
1859
- # @example
1860
- # sub(:title, :id => 'title')
1861
- # # will generate 'title', 'title_elsubent', and 'title?' methods
1862
- #
1863
- # @param [Symbol] the name used for the generated methods
1864
- # @param [Hash] identifier how we find an sub. You can use a multiple paramaters
1865
- # by combining of any of the following except xpath. The valid keys are:
1866
- # * :class => Watir and Selenium
1867
- # * :css => Selenium only
1868
- # * :id => Watir and Selenium
1869
- # * :index => Watir and Selenium
1870
- # * :name => Watir and Selenium
1871
- # * :xpath => Watir and Selenium
1872
- # @param optional block to be invoked when sub method is called
1873
- #
1874
- def sub(name, identifier={:index => 0}, &block)
1875
- element(name, :sub, identifier, &block)
1876
- end
1877
-
1878
- #
1879
- # adds three methods - one to retrieve the text of an summary, another
1880
- # to retrieve an summary, and another to check the summary's existence.
1881
- #
1882
- # @example
1883
- # summary(:title, :id => 'title')
1884
- # # will generate 'title', 'title_elsummaryent', and 'title?' methods
1885
- #
1886
- # @param [Symbol] the name used for the generated methods
1887
- # @param [Hash] identifier how we find an summary. You can use a multiple paramaters
1888
- # by combining of any of the following except xpath. The valid keys are:
1889
- # * :class => Watir and Selenium
1890
- # * :css => Selenium only
1891
- # * :id => Watir and Selenium
1892
- # * :index => Watir and Selenium
1893
- # * :name => Watir and Selenium
1894
- # * :xpath => Watir and Selenium
1895
- # @param optional block to be invoked when summary method is called
1896
- #
1897
- def summary(name, identifier={:index => 0}, &block)
1898
- element(name, :summary, identifier, &block)
1899
- end
1900
-
1901
- #
1902
- # adds three methods - one to retrieve the text of an sup, another
1903
- # to retrieve an sup, and another to check the sup's existence.
1904
- #
1905
- # @example
1906
- # sup(:title, :id => 'title')
1907
- # # will generate 'title', 'title_elsupent', and 'title?' methods
1908
- #
1909
- # @param [Symbol] the name used for the generated methods
1910
- # @param [Hash] identifier how we find an sup. You can use a multiple paramaters
1911
- # by combining of any of the following except xpath. The valid keys are:
1912
- # * :class => Watir and Selenium
1913
- # * :css => Selenium only
1914
- # * :id => Watir and Selenium
1915
- # * :index => Watir and Selenium
1916
- # * :name => Watir and Selenium
1917
- # * :xpath => Watir and Selenium
1918
- # @param optional block to be invoked when sup method is called
1919
- #
1920
- def sup(name, identifier={:index => 0}, &block)
1921
- element(name, :sup, identifier, &block)
1922
- end
1923
-
1924
- #
1925
- # adds three methods - one to retrieve the text of an var, another
1926
- # to retrieve an var, and another to check the var's existence.
1927
- #
1928
- # @example
1929
- # var(:title, :id => 'title')
1930
- # # will generate 'title', 'title_elvarent', and 'title?' methods
1931
- #
1932
- # @param [Symbol] the name used for the generated methods
1933
- # @param [Hash] identifier how we find an var. You can use a multiple paramaters
1934
- # by combining of any of the following except xpath. The valid keys are:
1935
- # * :class => Watir and Selenium
1936
- # * :css => Selenium only
1937
- # * :id => Watir and Selenium
1938
- # * :index => Watir and Selenium
1939
- # * :name => Watir and Selenium
1940
- # * :xpath => Watir and Selenium
1941
- # @param optional block to be invoked when var method is called
1942
- #
1943
- def var(name, identifier={:index => 0}, &block)
1944
- element(name, :var, identifier, &block)
1945
- end
1946
-
1947
- #
1948
- # adds three methods - one to retrieve the text of an wbr, another
1949
- # to retrieve an wbr, and another to check the wbr's existence.
1950
- #
1951
- # @example
1952
- # wbr(:title, :id => 'title')
1953
- # # will generate 'title', 'title_elwbrent', and 'title?' methods
1954
- #
1955
- # @param [Symbol] the name used for the generated methods
1956
- # @param [Hash] identifier how we find an wbr. You can use a multiple paramaters
1957
- # by combining of any of the following except xpath. The valid keys are:
1958
- # * :class => Watir and Selenium
1959
- # * :css => Selenium only
1960
- # * :id => Watir and Selenium
1961
- # * :index => Watir and Selenium
1962
- # * :name => Watir and Selenium
1963
- # * :xpath => Watir and Selenium
1964
- # @param optional block to be invoked when wbr method is called
1965
- #
1966
- def wbr(name, identifier={:index => 0}, &block)
1967
- element(name, :wbr, identifier, &block)
1968
- end
1969
-
1970
- #
1971
- # adds a method that will return an indexed property. The property will respond to
1972
- # the [] method with an object that has a set of normal page_object properties that
1973
- # correspond to the definitions included in the identifier_list parameter, with the
1974
- # "what" of the "how and what" substituted based on the index provided to the []
1975
- # method.
1976
- #
1977
- # @example
1978
- # indexed_property(:title, [
1979
- # [:text_field, :field_1, :id => 'table[%s].field_1'],
1980
- # [:button, :button_1, :id => 'table[%s].button_1'],
1981
- # [:text_field, :field_2, :name => 'table[%s].field_2']
1982
- # ])
1983
- # # will generate a title method that responds to []. title['foo'] will return an object
1984
- # # that responds to the normal methods expected for two text_fields and a button with the
1985
- # # given names, using the given how and what with 'foo' substituted for the %s. title[123]
1986
- # # will do the same, using the integer 123 instead.
1987
- #
1988
- # @param [Symbol] the name used for the generated method
1989
- # @param [Array] definitions an array of definitions to define on the indexed property. Each
1990
- # entry in the array should contain two symbols and a hash, corresponding to one of the standard
1991
- # page_object properties with a single substitution marker in each value in the hash,
1992
- # e.g. [:text_field, :field_1, :id => 'table[%s].field_1']
1993
- #
1994
- def indexed_property (name, identifier_list)
1995
- define_method("#{name}") do
1996
- IndexedProperties::TableOfElements.new(@browser, identifier_list)
1997
- end
1998
- end
1999
-
2000
- #
2001
- # methods to fetch multiple elements of the same type
2002
- #
2003
- # adds a method to the page object to retrun all of the matching elements
2004
- #
2005
- # @example
2006
- # text_fields(:first_name, :id => "first_name")
2007
- # # will generate 'first_name_elements'
2008
- #
2009
- # @param [String] the name used for the generated methods
2010
- # @param [Hash] identifier how we find a text field. You can use a multiple paramaters
2011
- # by combining of any of the following except xpath. The valid
2012
- # keys are the same ones supported by the standard methods.
2013
- # @param optional block to be invoked when element method is called
1136
+ # @param [String] the name used for the generated methods
1137
+ # @param [Hash] identifier how we find a text field. You can use a multiple paramaters
1138
+ # by combining of any of the following except xpath. The valid
1139
+ # keys are the same ones supported by the standard methods.
1140
+ # @param optional block to be invoked when element method is called
2014
1141
  #
2015
1142
  [:text_fields,
2016
1143
  :hidden_fields,
@@ -2038,13 +1165,14 @@ module PageObject
2038
1165
  :paragraphs,
2039
1166
  :labels,
2040
1167
  :file_fields].each do |method_name|
2041
- define_method(method_name) do |name, identifier=nil, &block|
1168
+ define_method(method_name) do |name, *identifier, &block|
2042
1169
  define_method("#{name}_elements") do
2043
1170
  return call_block(&block) unless block.nil?
2044
- platform.send "#{method_name.to_s}_for", identifier.clone
1171
+ method_name = (method_name == :checkboxes) ? 'checkboxs_for' : "#{method_name.to_s}_for"
1172
+ platform.send method_name, identifier.first.clone
2045
1173
  end
2046
1174
  end
2047
1175
  end
2048
-
1176
+
2049
1177
  end
2050
1178
  end