page-object 0.8.1 → 0.8.2

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