page-object-lds 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +10 -0
  7. data/ChangeLog +799 -0
  8. data/Gemfile +13 -0
  9. data/Guardfile +20 -0
  10. data/LICENSE +20 -0
  11. data/README.md +111 -0
  12. data/Rakefile +35 -0
  13. data/cucumber.yml +10 -0
  14. data/features/area.feature +35 -0
  15. data/features/async.feature +30 -0
  16. data/features/audio.feature +68 -0
  17. data/features/bold.feature +21 -0
  18. data/features/button.feature +88 -0
  19. data/features/canvas.feature +37 -0
  20. data/features/check_box.feature +55 -0
  21. data/features/div.feature +45 -0
  22. data/features/element.feature +322 -0
  23. data/features/file_field.feature +40 -0
  24. data/features/form.feature +43 -0
  25. data/features/frames.feature +75 -0
  26. data/features/generic_elements.feature +29 -0
  27. data/features/gxt_table_extension.feature +24 -0
  28. data/features/headings.feature +97 -0
  29. data/features/hidden_field.feature +45 -0
  30. data/features/html/04-Death_Becomes_Fur.mp4 +0 -0
  31. data/features/html/04-Death_Becomes_Fur.oga +0 -0
  32. data/features/html/async.html +36 -0
  33. data/features/html/double_click.html +13 -0
  34. data/features/html/failure.html +8 -0
  35. data/features/html/frame_1.html +18 -0
  36. data/features/html/frame_2.html +16 -0
  37. data/features/html/frame_3.html +14 -0
  38. data/features/html/frames.html +12 -0
  39. data/features/html/hover.html +12 -0
  40. data/features/html/iframes.html +12 -0
  41. data/features/html/images/circle.png +0 -0
  42. data/features/html/images/img_pulpit.jpg +0 -0
  43. data/features/html/images/submit.gif +0 -0
  44. data/features/html/indexed_property.html +52 -0
  45. data/features/html/modal.html +17 -0
  46. data/features/html/modal_1.html +38 -0
  47. data/features/html/modal_2.html +27 -0
  48. data/features/html/movie.mp4 +0 -0
  49. data/features/html/movie.ogg +0 -0
  50. data/features/html/multi_elements.html +144 -0
  51. data/features/html/nested_elements.html +77 -0
  52. data/features/html/nested_frame_1.html +1 -0
  53. data/features/html/nested_frame_2.html +11 -0
  54. data/features/html/nested_frame_3.html +14 -0
  55. data/features/html/nested_frames.html +10 -0
  56. data/features/html/planets.gif +0 -0
  57. data/features/html/static_elements.html +205 -0
  58. data/features/html/success.html +8 -0
  59. data/features/html/sun.gif +0 -0
  60. data/features/html/sun.html +7 -0
  61. data/features/image.feature +50 -0
  62. data/features/indexed_property.feature +98 -0
  63. data/features/javascript.feature +28 -0
  64. data/features/label.feature +46 -0
  65. data/features/link.feature +52 -0
  66. data/features/list_item.feature +36 -0
  67. data/features/modal_dialog.feature +15 -0
  68. data/features/multi_elements.feature +492 -0
  69. data/features/nested_elements.feature +117 -0
  70. data/features/ordered_list.feature +56 -0
  71. data/features/page_level_actions.feature +90 -0
  72. data/features/paragraph.feature +35 -0
  73. data/features/radio_button.feature +58 -0
  74. data/features/radio_button_group.feature +29 -0
  75. data/features/sample-app/public/jquery-1.3.2.js +4376 -0
  76. data/features/sample-app/public/jquery.html +30 -0
  77. data/features/sample-app/public/prototype-1.6.0.3.js +4320 -0
  78. data/features/sample-app/public/prototype.html +35 -0
  79. data/features/sample-app/sample_app.rb +35 -0
  80. data/features/select_list.feature +86 -0
  81. data/features/span.feature +37 -0
  82. data/features/step_definitions/accessor_steps.rb +60 -0
  83. data/features/step_definitions/area_steps.rb +19 -0
  84. data/features/step_definitions/async_steps.rb +83 -0
  85. data/features/step_definitions/audio_steps.rb +27 -0
  86. data/features/step_definitions/bold_steps.rb +12 -0
  87. data/features/step_definitions/button_steps.rb +43 -0
  88. data/features/step_definitions/canvas_steps.rb +15 -0
  89. data/features/step_definitions/check_box_steps.rb +35 -0
  90. data/features/step_definitions/div_steps.rb +19 -0
  91. data/features/step_definitions/element_steps.rb +266 -0
  92. data/features/step_definitions/file_field_steps.rb +19 -0
  93. data/features/step_definitions/form_steps.rb +19 -0
  94. data/features/step_definitions/frames_steps.rb +159 -0
  95. data/features/step_definitions/generic_element_steps.rb +31 -0
  96. data/features/step_definitions/gxt_table_steps.rb +58 -0
  97. data/features/step_definitions/headings_steps.rb +12 -0
  98. data/features/step_definitions/hidden_field_steps.rb +27 -0
  99. data/features/step_definitions/image_steps.rb +27 -0
  100. data/features/step_definitions/indexed_property_steps.rb +129 -0
  101. data/features/step_definitions/javascript_steps.rb +53 -0
  102. data/features/step_definitions/label_steps.rb +19 -0
  103. data/features/step_definitions/link_steps.rb +40 -0
  104. data/features/step_definitions/list_item_steps.rb +19 -0
  105. data/features/step_definitions/modal_dialog_steps.rb +62 -0
  106. data/features/step_definitions/multi_elements_steps.rb +541 -0
  107. data/features/step_definitions/nested_elements_steps.rb +212 -0
  108. data/features/step_definitions/ordered_list_steps.rb +23 -0
  109. data/features/step_definitions/page_level_actions_steps.rb +135 -0
  110. data/features/step_definitions/page_traversal_steps.rb +4 -0
  111. data/features/step_definitions/paragraph_steps.rb +28 -0
  112. data/features/step_definitions/radio_button_group_steps.rb +36 -0
  113. data/features/step_definitions/radio_button_steps.rb +27 -0
  114. data/features/step_definitions/select_list_steps.rb +65 -0
  115. data/features/step_definitions/span_steps.rb +19 -0
  116. data/features/step_definitions/table_cell_steps.rb +15 -0
  117. data/features/step_definitions/table_steps.rb +70 -0
  118. data/features/step_definitions/text_area_steps.rb +35 -0
  119. data/features/step_definitions/text_field_steps.rb +35 -0
  120. data/features/step_definitions/unordered_list_steps.rb +23 -0
  121. data/features/step_definitions/video_steps.rb +45 -0
  122. data/features/support/ajax_text_environment.rb +26 -0
  123. data/features/support/env.rb +8 -0
  124. data/features/support/hooks.rb +8 -0
  125. data/features/support/page.rb +373 -0
  126. data/features/support/persistent_browser.rb +70 -0
  127. data/features/support/targets/firefox14_osx.rb +6 -0
  128. data/features/support/targets/firefox14_windows7.rb +6 -0
  129. data/features/support/url_helper.rb +57 -0
  130. data/features/table.feature +122 -0
  131. data/features/table_cell.feature +45 -0
  132. data/features/text_area.feature +51 -0
  133. data/features/text_field.feature +70 -0
  134. data/features/unordered_list.feature +56 -0
  135. data/features/video.feature +73 -0
  136. data/lib/page-object-lds.rb +421 -0
  137. data/lib/page-object/accessors.rb +1334 -0
  138. data/lib/page-object/core_ext/string.rb +5 -0
  139. data/lib/page-object/element_locators.rb +21 -0
  140. data/lib/page-object/elements/area.rb +31 -0
  141. data/lib/page-object/elements/audio.rb +9 -0
  142. data/lib/page-object/elements/bold.rb +11 -0
  143. data/lib/page-object/elements/button.rb +35 -0
  144. data/lib/page-object/elements/canvas.rb +23 -0
  145. data/lib/page-object/elements/check_box.rb +40 -0
  146. data/lib/page-object/elements/div.rb +19 -0
  147. data/lib/page-object/elements/element.rb +225 -0
  148. data/lib/page-object/elements/file_field.rb +41 -0
  149. data/lib/page-object/elements/form.rb +39 -0
  150. data/lib/page-object/elements/heading.rb +15 -0
  151. data/lib/page-object/elements/hidden_field.rb +22 -0
  152. data/lib/page-object/elements/image.rb +39 -0
  153. data/lib/page-object/elements/label.rb +19 -0
  154. data/lib/page-object/elements/link.rb +49 -0
  155. data/lib/page-object/elements/list_item.rb +19 -0
  156. data/lib/page-object/elements/media.rb +45 -0
  157. data/lib/page-object/elements/option.rb +10 -0
  158. data/lib/page-object/elements/ordered_list.rb +53 -0
  159. data/lib/page-object/elements/paragraph.rb +9 -0
  160. data/lib/page-object/elements/radio_button.rb +40 -0
  161. data/lib/page-object/elements/select_list.rb +45 -0
  162. data/lib/page-object/elements/span.rb +19 -0
  163. data/lib/page-object/elements/table.rb +82 -0
  164. data/lib/page-object/elements/table_cell.rb +28 -0
  165. data/lib/page-object/elements/table_row.rb +53 -0
  166. data/lib/page-object/elements/text_area.rb +41 -0
  167. data/lib/page-object/elements/text_field.rb +45 -0
  168. data/lib/page-object/elements/unordered_list.rb +54 -0
  169. data/lib/page-object/elements/video.rb +18 -0
  170. data/lib/page-object/indexed_properties.rb +36 -0
  171. data/lib/page-object/javascript/angularjs.rb +14 -0
  172. data/lib/page-object/javascript/jquery.rb +14 -0
  173. data/lib/page-object/javascript/prototype.rb +14 -0
  174. data/lib/page-object/javascript/yui.rb +19 -0
  175. data/lib/page-object/javascript_framework_facade.rb +80 -0
  176. data/lib/page-object/loads_platform.rb +26 -0
  177. data/lib/page-object/locator_generator.rb +130 -0
  178. data/lib/page-object/nested_elements.rb +17 -0
  179. data/lib/page-object/page_factory.rb +108 -0
  180. data/lib/page-object/page_populator.rb +83 -0
  181. data/lib/page-object/platforms.rb +19 -0
  182. data/lib/page-object/platforms/lds_watir_webdriver.rb +17 -0
  183. data/lib/page-object/platforms/lds_watir_webdriver/check_box.rb +29 -0
  184. data/lib/page-object/platforms/lds_watir_webdriver/element.rb +249 -0
  185. data/lib/page-object/platforms/lds_watir_webdriver/file_field.rb +16 -0
  186. data/lib/page-object/platforms/lds_watir_webdriver/form.rb +16 -0
  187. data/lib/page-object/platforms/lds_watir_webdriver/image.rb +22 -0
  188. data/lib/page-object/platforms/lds_watir_webdriver/link.rb +15 -0
  189. data/lib/page-object/platforms/lds_watir_webdriver/ordered_list.rb +35 -0
  190. data/lib/page-object/platforms/lds_watir_webdriver/page_object.rb +1044 -0
  191. data/lib/page-object/platforms/lds_watir_webdriver/radio_button.rb +22 -0
  192. data/lib/page-object/platforms/lds_watir_webdriver/select_list.rb +74 -0
  193. data/lib/page-object/platforms/lds_watir_webdriver/table.rb +38 -0
  194. data/lib/page-object/platforms/lds_watir_webdriver/table_row.rb +37 -0
  195. data/lib/page-object/platforms/lds_watir_webdriver/text_area.rb +23 -0
  196. data/lib/page-object/platforms/lds_watir_webdriver/text_field.rb +16 -0
  197. data/lib/page-object/platforms/lds_watir_webdriver/unordered_list.rb +36 -0
  198. data/lib/page-object/platforms/selenium_webdriver.rb +17 -0
  199. data/lib/page-object/platforms/selenium_webdriver/button.rb +15 -0
  200. data/lib/page-object/platforms/selenium_webdriver/check_box.rb +29 -0
  201. data/lib/page-object/platforms/selenium_webdriver/element.rb +291 -0
  202. data/lib/page-object/platforms/selenium_webdriver/file_field.rb +16 -0
  203. data/lib/page-object/platforms/selenium_webdriver/form.rb +16 -0
  204. data/lib/page-object/platforms/selenium_webdriver/image.rb +28 -0
  205. data/lib/page-object/platforms/selenium_webdriver/link.rb +23 -0
  206. data/lib/page-object/platforms/selenium_webdriver/ordered_list.rb +39 -0
  207. data/lib/page-object/platforms/selenium_webdriver/page_object.rb +1162 -0
  208. data/lib/page-object/platforms/selenium_webdriver/radio_button.rb +22 -0
  209. data/lib/page-object/platforms/selenium_webdriver/select_list.rb +93 -0
  210. data/lib/page-object/platforms/selenium_webdriver/surrogate_selenium_element.rb +42 -0
  211. data/lib/page-object/platforms/selenium_webdriver/table.rb +42 -0
  212. data/lib/page-object/platforms/selenium_webdriver/table_row.rb +43 -0
  213. data/lib/page-object/platforms/selenium_webdriver/text_area.rb +17 -0
  214. data/lib/page-object/platforms/selenium_webdriver/text_field.rb +17 -0
  215. data/lib/page-object/platforms/selenium_webdriver/unordered_list.rb +39 -0
  216. data/lib/page-object/platforms/watir_webdriver.rb +17 -0
  217. data/lib/page-object/platforms/watir_webdriver/check_box.rb +29 -0
  218. data/lib/page-object/platforms/watir_webdriver/element.rb +249 -0
  219. data/lib/page-object/platforms/watir_webdriver/file_field.rb +16 -0
  220. data/lib/page-object/platforms/watir_webdriver/form.rb +16 -0
  221. data/lib/page-object/platforms/watir_webdriver/image.rb +22 -0
  222. data/lib/page-object/platforms/watir_webdriver/link.rb +15 -0
  223. data/lib/page-object/platforms/watir_webdriver/ordered_list.rb +35 -0
  224. data/lib/page-object/platforms/watir_webdriver/page_object.rb +1044 -0
  225. data/lib/page-object/platforms/watir_webdriver/radio_button.rb +22 -0
  226. data/lib/page-object/platforms/watir_webdriver/select_list.rb +74 -0
  227. data/lib/page-object/platforms/watir_webdriver/table.rb +38 -0
  228. data/lib/page-object/platforms/watir_webdriver/table_row.rb +37 -0
  229. data/lib/page-object/platforms/watir_webdriver/text_area.rb +23 -0
  230. data/lib/page-object/platforms/watir_webdriver/text_field.rb +16 -0
  231. data/lib/page-object/platforms/watir_webdriver/unordered_list.rb +36 -0
  232. data/lib/page-object/version.rb +4 -0
  233. data/lib/page-object/widgets.rb +134 -0
  234. data/page-object-lds.gemspec +33 -0
  235. data/pageobject.gems +1 -0
  236. data/spec/page-object/accessors_spec.rb +40 -0
  237. data/spec/page-object/element_locators_spec.rb +1100 -0
  238. data/spec/page-object/elements/area_spec.rb +45 -0
  239. data/spec/page-object/elements/bold_spec.rb +29 -0
  240. data/spec/page-object/elements/button_spec.rb +50 -0
  241. data/spec/page-object/elements/canvas_spec.rb +40 -0
  242. data/spec/page-object/elements/check_box_spec.rb +49 -0
  243. data/spec/page-object/elements/div_spec.rb +28 -0
  244. data/spec/page-object/elements/element_spec.rb +114 -0
  245. data/spec/page-object/elements/file_field_spec.rb +39 -0
  246. data/spec/page-object/elements/form_spec.rb +28 -0
  247. data/spec/page-object/elements/heading_spec.rb +48 -0
  248. data/spec/page-object/elements/hidden_field_spec.rb +28 -0
  249. data/spec/page-object/elements/image_spec.rb +66 -0
  250. data/spec/page-object/elements/label_spec.rb +29 -0
  251. data/spec/page-object/elements/link_spec.rb +49 -0
  252. data/spec/page-object/elements/list_item_spec.rb +29 -0
  253. data/spec/page-object/elements/nested_element_spec.rb +254 -0
  254. data/spec/page-object/elements/option_spec.rb +11 -0
  255. data/spec/page-object/elements/ordered_list_spec.rb +94 -0
  256. data/spec/page-object/elements/paragraph_spec.rb +27 -0
  257. data/spec/page-object/elements/select_list_spec.rb +142 -0
  258. data/spec/page-object/elements/selenium/radio_button_spec.rb +44 -0
  259. data/spec/page-object/elements/selenium/text_field_spec.rb +49 -0
  260. data/spec/page-object/elements/selenium_element_spec.rb +172 -0
  261. data/spec/page-object/elements/span_spec.rb +26 -0
  262. data/spec/page-object/elements/table_cell_spec.rb +21 -0
  263. data/spec/page-object/elements/table_row_spec.rb +70 -0
  264. data/spec/page-object/elements/table_spec.rb +98 -0
  265. data/spec/page-object/elements/text_area_spec.rb +39 -0
  266. data/spec/page-object/elements/unordered_list_spec.rb +94 -0
  267. data/spec/page-object/elements/watir_element_spec.rb +141 -0
  268. data/spec/page-object/javascript_framework_facade_spec.rb +61 -0
  269. data/spec/page-object/loads_platform_spec.rb +53 -0
  270. data/spec/page-object/page-object_spec.rb +413 -0
  271. data/spec/page-object/page_factory_spec.rb +238 -0
  272. data/spec/page-object/page_populator_spec.rb +122 -0
  273. data/spec/page-object/platforms/selenium_webdriver/selenium_page_object_spec.rb +68 -0
  274. data/spec/page-object/platforms/selenium_webdriver_spec.rb +29 -0
  275. data/spec/page-object/platforms/watir_webdriver/watir_page_object_spec.rb +29 -0
  276. data/spec/page-object/platforms/watir_webdriver_spec.rb +9 -0
  277. data/spec/page-object/selenium_accessors_spec.rb +609 -0
  278. data/spec/page-object/watir_accessors_spec.rb +1134 -0
  279. data/spec/page-object/widget_spec.rb +226 -0
  280. data/spec/spec_helper.rb +44 -0
  281. metadata +430 -0
@@ -0,0 +1,1334 @@
1
+ require 'erb'
2
+ require 'page-object/locator_generator'
3
+
4
+ module PageObject
5
+ #
6
+ # Contains the class level methods that are inserted into your page objects
7
+ # when you include the PageObject module. These methods will generate another
8
+ # set of methods that provide access to the elements on the web pages.
9
+ #
10
+ # @see PageObject::WatirPageObject for the watir implementation of the platform delegate
11
+ # @see PageObject::SeleniumPageObject for the selenium implementation of the platform delegate
12
+ #
13
+ module Accessors
14
+
15
+ #
16
+ # Set some values that can be used within the class. This is
17
+ # typically used to provide values that help build dynamic urls in
18
+ # the page_url method
19
+ #
20
+ # @param [Hash] the value to set the params
21
+ #
22
+ def params=(the_params)
23
+ @params = the_params
24
+ end
25
+
26
+ #
27
+ # Return the params that exist on this page class
28
+ #
29
+ def params
30
+ @params ||= {}
31
+ end
32
+
33
+ #
34
+ # Specify the url for the page. A call to this method will generate a
35
+ # 'goto' method to take you to the page.
36
+ #
37
+ # @param [String] the url for the page.
38
+ # @param [Symbol] a method name to call to get the url
39
+ #
40
+ def page_url(url)
41
+ define_method("goto") do
42
+ platform.navigate_to self.page_url_value
43
+ end
44
+
45
+ define_method('page_url_value') do
46
+ lookup = url.kind_of?(Symbol) ? self.send(url) : url
47
+ erb = ERB.new(%Q{#{lookup}})
48
+ merged_params = self.class.instance_variable_get("@merged_params")
49
+ params = merged_params ? merged_params : self.class.params
50
+ erb.result(binding)
51
+ end
52
+ end
53
+ alias_method :direct_url, :page_url
54
+
55
+ #
56
+ # Creates a method that waits the expected_title of a page to match the actual.
57
+ # @param [String] expected_title the literal expected title for the page
58
+ # @param [Regexp] expected_title the expected title pattern for the page
59
+ # @param [optional, Integer] timeout default value is nil - do not wait
60
+ # @return [boolean]
61
+ # @raise An exception if expected_title does not match actual title
62
+ #
63
+ # @example Specify 'Google' as the expected title of a page
64
+ # expected_title "Google"
65
+ # page.has_expected_title?
66
+ #
67
+ def wait_for_expected_title(expected_title, timeout=::PageObject.default_element_wait)
68
+ define_method("wait_for_expected_title?") do
69
+ error_message = lambda { "Expected title '#{expected_title}' instead of '#{title}'" }
70
+
71
+ has_expected_title = (expected_title === title)
72
+ wait_until(timeout, error_message.call) do
73
+ has_expected_title = (expected_title === title)
74
+ end unless has_expected_title
75
+
76
+ raise error_message.call unless has_expected_title
77
+ has_expected_title
78
+ end
79
+ end
80
+
81
+ #
82
+ # Creates a method that compares the expected_title of a page against the actual.
83
+ # @param [String] expected_title the literal expected title for the page
84
+ # @param [Regexp] expected_title the expected title pattern for the page
85
+ # @return [boolean]
86
+ # @raise An exception if expected_title does not match actual title
87
+ #
88
+ # @example Specify 'Google' as the expected title of a page
89
+ # expected_title "Google"
90
+ # page.has_expected_title?
91
+ #
92
+ def expected_title(expected_title)
93
+ define_method("has_expected_title?") do
94
+ page_title = title
95
+ has_expected_title = (expected_title === page_title)
96
+ raise "Expected title '#{expected_title}' instead of '#{page_title}'" unless has_expected_title
97
+ has_expected_title
98
+ end
99
+ end
100
+
101
+ #
102
+ # Creates a method that provides a way to initialize a page based upon an expected element.
103
+ # This is useful for pages that load dynamic content.
104
+ # @param [Symbol] the name given to the element in the declaration
105
+ # @param [optional, Integer] timeout default value is 5 seconds
106
+ # @return [boolean]
107
+ #
108
+ # @example Specify a text box named :address expected on the page within 10 seconds
109
+ # expected_element(:address, 10)
110
+ # page.has_expected_element?
111
+ #
112
+ def expected_element(element_name, timeout=::PageObject.default_element_wait)
113
+ define_method("has_expected_element?") do
114
+ self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_present timeout
115
+ end
116
+ end
117
+
118
+ #
119
+ # Creates a method that provides a way to initialize a page based upon an expected element to become visible.
120
+ # This is useful for pages that load dynamic content and might have hidden elements that are not shown.
121
+ # @param [Symbol] the name given to the element in the declaration
122
+ # @param [optional, Integer] timeout default value is 5 seconds
123
+ # @param [optional, boolean] also check that element to be visible if set to true
124
+ # @return [boolean]
125
+ #
126
+ # @example Specify a text box named :address expected on the page within 10 seconds
127
+ # expected_element_visible(:address, 10)
128
+ # page.has_expected_element_visible?
129
+ #
130
+ def expected_element_visible(element_name, timeout=::PageObject.default_element_wait, check_visible=false)
131
+ define_method("has_expected_element_visible?") do
132
+ self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_present timeout
133
+ self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_visible timeout
134
+ end
135
+ end
136
+
137
+ #
138
+ # Identify an element as existing within a frame . A frame parameter
139
+ # is passed to the block and must be passed to the other calls to PageObject.
140
+ # You can nest calls to in_frame by passing the frame to the next level.
141
+ #
142
+ # @example
143
+ # in_frame(:id => 'frame_id') do |frame|
144
+ # text_field(:first_name, :id => 'fname', :frame => frame)
145
+ # end
146
+ #
147
+ # @param [Hash] identifier how we find the frame. The valid keys are:
148
+ # * :id => Watir and Selenium
149
+ # * :index => Watir and Selenium
150
+ # * :name => Watir and Selenium
151
+ # * :regexp => Watir only
152
+ # @param frame passed from a previous call to in_frame. Used to nest calls
153
+ # @param block that contains the calls to elements that exist inside the frame.
154
+ #
155
+ def in_frame(identifier, frame=nil, &block)
156
+ frame = [] if frame.nil?
157
+ frame << {frame: identifier}
158
+ block.call(frame)
159
+ end
160
+
161
+ #
162
+ # Identify an element as existing within an iframe. A frame parameter
163
+ # is passed to the block and must be passed to the other calls to PageObject.
164
+ # You can nest calls to in_frame by passing the frame to the next level.
165
+ #
166
+ # @example
167
+ # in_iframe(:id => 'frame_id') do |frame|
168
+ # text_field(:first_name, :id => 'fname', :frame => frame)
169
+ # end
170
+ #
171
+ # @param [Hash] identifier how we find the frame. The valid keys are:
172
+ # * :id => Watir and Selenium
173
+ # * :index => Watir and Selenium
174
+ # * :name => Watir and Selenium
175
+ # * :regexp => Watir only
176
+ # @param frame passed from a previous call to in_iframe. Used to nest calls
177
+ # @param block that contains the calls to elements that exist inside the iframe.
178
+ #
179
+ def in_iframe(identifier, frame=nil, &block)
180
+ frame = [] if frame.nil?
181
+ frame << {iframe: identifier}
182
+ block.call(frame)
183
+ end
184
+
185
+ #
186
+ # adds four methods to the page object - one to set text in a text field,
187
+ # another to retrieve text from a text field, another to return the text
188
+ # field element, another to check the text field's existence.
189
+ #
190
+ # @example
191
+ # text_field(:first_name, :id => "first_name")
192
+ # # will generate 'first_name', 'first_name=', 'first_name_element',
193
+ # # 'first_name?' methods
194
+ #
195
+ # @param [String] the name used for the generated methods
196
+ # @param [Hash] identifier how we find a text field. You can use a multiple parameters
197
+ # by combining of any of the following except xpath. The valid keys are:
198
+ # * :class => Watir and Selenium
199
+ # * :css => Selenium only
200
+ # * :id => Watir and Selenium
201
+ # * :index => Watir and Selenium
202
+ # * :label => Watir and Selenium
203
+ # * :name => Watir and Selenium
204
+ # * :text => Watir and Selenium
205
+ # * :title => Watir and Selenium
206
+ # * :value => Watir only
207
+ # * :xpath => Watir and Selenium
208
+ # @param optional block to be invoked when element method is called
209
+ #
210
+ def text_field(name, identifier={:index => 0}, &block)
211
+ standard_methods(name, identifier, 'text_field_for', &block)
212
+ define_method(name) do
213
+ return platform.text_field_value_for identifier.clone unless block_given?
214
+ self.send("#{name}_element").value
215
+ end
216
+ define_method("#{name}=") do |value|
217
+ return platform.text_field_value_set(identifier.clone, value) unless block_given?
218
+ self.send("#{name}_element").value = value
219
+ end
220
+ end
221
+
222
+ #
223
+ # adds three methods to the page object - one to get the text from a hidden field,
224
+ # another to retrieve the hidden field element, and another to check the hidden
225
+ # field's existence.
226
+ #
227
+ # @example
228
+ # hidden_field(:user_id, :id => "user_identity")
229
+ # # will generate 'user_id', 'user_id_element' and 'user_id?' methods
230
+ #
231
+ # @param [String] the name used for the generated methods
232
+ # @param [Hash] identifier how we find a hidden field. You can use a multiple parameters
233
+ # by combining of any of the following except xpath. The valid keys are:
234
+ # * :class => Watir and Selenium
235
+ # * :css => Selenium only
236
+ # * :id => Watir and Selenium
237
+ # * :index => Watir and Selenium
238
+ # * :name => Watir and Selenium
239
+ # * :text => Watir and Selenium
240
+ # * :value => Watir and Selenium
241
+ # * :xpath => Watir and Selenium
242
+ # @param optional block to be invoked when element method is called
243
+ #
244
+ def hidden_field(name, identifier={:index => 0}, &block)
245
+ standard_methods(name, identifier, 'hidden_field_for', &block)
246
+ define_method(name) do
247
+ return platform.hidden_field_value_for identifier.clone unless block_given?
248
+ self.send("#{name}_element").value
249
+ end
250
+ end
251
+ alias_method :hidden, :hidden_field
252
+
253
+ #
254
+ # adds four methods to the page object - one to set text in a text area,
255
+ # another to retrieve text from a text area, another to return the text
256
+ # area element, and another to check the text area's existence.
257
+ #
258
+ # @example
259
+ # text_area(:address, :id => "address")
260
+ # # will generate 'address', 'address=', 'address_element',
261
+ # # 'address?' methods
262
+ #
263
+ # @param [String] the name used for the generated methods
264
+ # @param [Hash] identifier how we find a text area. You can use a multiple parameters
265
+ # by combining of any of the following except xpath. The valid keys are:
266
+ # * :class => Watir and Selenium
267
+ # * :css => Selenium only
268
+ # * :id => Watir and Selenium
269
+ # * :index => Watir and Selenium
270
+ # * :name => Watir and Selenium
271
+ # * :xpath => Watir and Selenium
272
+ # * :label => Watir and Selenium
273
+ # @param optional block to be invoked when element method is called
274
+ #
275
+ def text_area(name, identifier={:index => 0}, &block)
276
+ standard_methods(name, identifier, 'text_area_for', &block)
277
+ define_method(name) do
278
+ return platform.text_area_value_for identifier.clone unless block_given?
279
+ self.send("#{name}_element").value
280
+ end
281
+ define_method("#{name}=") do |value|
282
+ return platform.text_area_value_set(identifier.clone, value) unless block_given?
283
+ self.send("#{name}_element").value = value
284
+ end
285
+ end
286
+ alias_method :textarea, :text_area
287
+
288
+ #
289
+ # adds five methods - one to select an item in a drop-down,
290
+ # another to fetch the currently selected item text, another
291
+ # to retrieve the select list element, another to check the
292
+ # drop down's existence and another to get all the available options
293
+ # to select from.
294
+ #
295
+ # @example
296
+ # select_list(:state, :id => "state")
297
+ # # will generate 'state', 'state=', 'state_element', 'state?', "state_options" methods
298
+ #
299
+ # @param [Symbol] the name used for the generated methods
300
+ # @param [Hash] identifier how we find a select list. You can use a multiple parameters
301
+ # by combining of any of the following except xpath. The valid keys are:
302
+ # * :class => Watir and Selenium
303
+ # * :css => Selenium only
304
+ # * :id => Watir and Selenium
305
+ # * :index => Watir and Selenium
306
+ # * :name => Watir and Selenium
307
+ # * :text => Watir only
308
+ # * :value => Watir only
309
+ # * :xpath => Watir and Selenium
310
+ # * :label => Watir and Selenium
311
+ # @param optional block to be invoked when element method is called
312
+ #
313
+ def select_list(name, identifier={:index => 0}, &block)
314
+ standard_methods(name, identifier, 'select_list_for', &block)
315
+ define_method(name) do
316
+ return platform.select_list_value_for identifier.clone unless block_given?
317
+ self.send("#{name}_element").value
318
+ end
319
+ define_method("#{name}=") do |value|
320
+ return platform.select_list_value_set(identifier.clone, value) unless block_given?
321
+ self.send("#{name}_element").select(value)
322
+ end
323
+ define_method("#{name}_options") do
324
+ element = self.send("#{name}_element")
325
+ (element && element.options) ? element.options.collect(&:text) : []
326
+ end
327
+ end
328
+ alias_method :select, :select_list
329
+
330
+ #
331
+ # adds three methods - one to select a link, another
332
+ # to return a PageObject::Elements::Link object representing
333
+ # the link, and another that checks the link's existence.
334
+ #
335
+ # @example
336
+ # link(:add_to_cart, :text => "Add to Cart")
337
+ # # will generate 'add_to_cart', 'add_to_cart_element', and 'add_to_cart?' methods
338
+ #
339
+ # @param [Symbol] the name used for the generated methods
340
+ # @param [Hash] identifier how we find a link. You can use a multiple parameters
341
+ # by combining of any of the following except xpath. The valid keys are:
342
+ # * :class => Watir and Selenium
343
+ # * :css => Watir and Selenium
344
+ # * :href => Watir and Selenium
345
+ # * :id => Watir and Selenium
346
+ # * :index => Watir and Selenium
347
+ # * :link => Watir and Selenium
348
+ # * :link_text => Watir and Selenium
349
+ # * :name => Watir and Selenium
350
+ # * :text => Watir and Selenium
351
+ # * :title => Watir and Selenium
352
+ # * :xpath => Watir and Selenium
353
+ # @param optional block to be invoked when element method is called
354
+ #
355
+ def link(name, identifier={:index => 0}, &block)
356
+ standard_methods(name, identifier, 'link_for', &block)
357
+ define_method(name) do
358
+ return platform.click_link_for identifier.clone unless block_given?
359
+ self.send("#{name}_element").click
360
+ end
361
+ end
362
+ alias_method :a, :link
363
+
364
+ #
365
+ # adds five methods - one to check, another to uncheck, another
366
+ # to return the state of a checkbox, another to return
367
+ # a PageObject::Elements::CheckBox object representing the checkbox, and
368
+ # a final method to check the checkbox's existence.
369
+ #
370
+ # @example
371
+ # checkbox(:active, :name => "is_active")
372
+ # # will generate 'check_active', 'uncheck_active', 'active_checked?',
373
+ # # 'active_element', and 'active?' methods
374
+ #
375
+ # @param [Symbol] the name used for the generated methods
376
+ # @param [Hash] identifier how we find a checkbox. You can use a multiple parameters
377
+ # by combining of any of the following except xpath. The valid keys are:
378
+ # * :class => Watir and Selenium
379
+ # * :css => Selenium only
380
+ # * :id => Watir and Selenium
381
+ # * :index => Watir and Selenium
382
+ # * :name => Watir and Selenium
383
+ # * :value => Watir and Selenium
384
+ # * :xpath => Watir and Selenium
385
+ # * :label => Watir and Selenium
386
+ # @param optional block to be invoked when element method is called
387
+ #
388
+ def checkbox(name, identifier={:index => 0}, &block)
389
+ standard_methods(name, identifier, 'checkbox_for', &block)
390
+ define_method("check_#{name}") do
391
+ return platform.check_checkbox(identifier.clone) unless block_given?
392
+ self.send("#{name}_element").check
393
+ end
394
+ define_method("uncheck_#{name}") do
395
+ return platform.uncheck_checkbox(identifier.clone) unless block_given?
396
+ self.send("#{name}_element").uncheck
397
+ end
398
+ define_method("#{name}_checked?") do
399
+ return platform.checkbox_checked?(identifier.clone) unless block_given?
400
+ self.send("#{name}_element").checked?
401
+ end
402
+ end
403
+
404
+ #
405
+ # adds four methods - one to select, another to return if a radio button
406
+ # is selected, another method to return a PageObject::Elements::RadioButton
407
+ # object representing the radio button element, and another to check
408
+ # the radio button's existence.
409
+ #
410
+ # @example
411
+ # radio_button(:north, :id => "north")
412
+ # # will generate 'select_north', 'north_selected?',
413
+ # # 'north_element', and 'north?' methods
414
+ #
415
+ # @param [Symbol] the name used for the generated methods
416
+ # @param [Hash] identifier how we find a radio button. You can use a multiple parameters
417
+ # by combining of any of the following except xpath. The valid keys are:
418
+ # * :class => Watir and Selenium
419
+ # * :css => Selenium only
420
+ # * :id => Watir and Selenium
421
+ # * :index => Watir and Selenium
422
+ # * :name => Watir and Selenium
423
+ # * :value => Watir and Selenium
424
+ # * :xpath => Watir and Selenium
425
+ # * :label => Watir and Selenium
426
+ # @param optional block to be invoked when element method is called
427
+ #
428
+ def radio_button(name, identifier={:index => 0}, &block)
429
+ standard_methods(name, identifier, 'radio_button_for', &block)
430
+ define_method("select_#{name}") do
431
+ return platform.select_radio(identifier.clone) unless block_given?
432
+ self.send("#{name}_element").select
433
+ end
434
+ define_method("#{name}_selected?") do
435
+ return platform.radio_selected?(identifier.clone) unless block_given?
436
+ self.send("#{name}_element").selected?
437
+ end
438
+ end
439
+ alias_method :radio, :radio_button
440
+
441
+ #
442
+ # adds five methods to help interact with a radio button group -
443
+ # a method to select a radio button in the group by given value/text,
444
+ # a method to return the values of all radio buttons in the group, a method
445
+ # to return if a radio button in the group is selected (will return
446
+ # the text of the selected radio button, if true), a method to return
447
+ # an array of PageObject::Elements::RadioButton objects representing
448
+ # the radio button group, and finally a method to check the existence
449
+ # of the radio button group.
450
+ #
451
+ # @example
452
+ # radio_button_group(:color, :name => "preferred_color")
453
+ # will generate 'select_color', 'color_values', 'color_selected?',
454
+ # 'color_elements', and 'color?' methods
455
+ #
456
+ # @param [Symbol] the name used for the generated methods
457
+ # @param [Hash] shared identifier for the radio button group. Typically, a 'name' attribute.
458
+ # The valid keys are:
459
+ # * :name => Watir and Selenium
460
+ #
461
+ def radio_button_group(name, identifier)
462
+ define_method("select_#{name}") do |value|
463
+ platform.radio_buttons_for(identifier.clone).each do |radio_elem|
464
+ if radio_elem.value == value
465
+ return radio_elem.select
466
+ end
467
+ end
468
+ end
469
+ define_method("#{name}_values") do
470
+ result = []
471
+ platform.radio_buttons_for(identifier.clone).each do |radio_elem|
472
+ result << radio_elem.value
473
+ end
474
+ return result
475
+ end
476
+ define_method("#{name}_selected?") do
477
+ platform.radio_buttons_for(identifier.clone).each do |radio_elem|
478
+ return radio_elem.value if radio_elem.selected?
479
+ end
480
+ return false
481
+ end
482
+ define_method("#{name}_elements") do
483
+ return platform.radio_buttons_for(identifier.clone)
484
+ end
485
+ define_method("#{name}?") do
486
+ return platform.radio_buttons_for(identifier.clone).any?
487
+ end
488
+ end
489
+ alias_method :radio_group, :radio_button_group
490
+
491
+ #
492
+ # adds three methods - one to click a button, another to
493
+ # return the button element, and another to check the button's existence.
494
+ #
495
+ # @example
496
+ # button(:purchase, :id => 'purchase')
497
+ # # will generate 'purchase', 'purchase_element', and 'purchase?' methods
498
+ #
499
+ # @param [Symbol] the name used for the generated methods
500
+ # @param [Hash] identifier how we find a button. You can use a multiple parameters
501
+ # by combining of any of the following except xpath. The valid keys are:
502
+ # * :class => Watir and Selenium
503
+ # * :css => Watir and Selenium
504
+ # * :id => Watir and Selenium
505
+ # * :index => Watir and Selenium
506
+ # * :name => Watir and Selenium
507
+ # * :text => Watir only
508
+ # * :value => Watir and Selenium
509
+ # * :xpath => Watir and Selenium
510
+ # * :src => Watir and Selenium (input type=image only)
511
+ # * :alt => Watir and Selenium (input type=image only)
512
+ # @param optional block to be invoked when element method is called
513
+ #
514
+ def button(name, identifier={:index => 0}, &block)
515
+ standard_methods(name, identifier, 'button_for', &block)
516
+ define_method(name) do
517
+ return platform.click_button_for identifier.clone unless block_given?
518
+ self.send("#{name}_element").click
519
+ end
520
+ end
521
+
522
+ #
523
+ # adds three methods - one to retrieve the text from a div,
524
+ # another to return the div element, and another to check the div's existence.
525
+ #
526
+ # @example
527
+ # div(:message, :id => 'message')
528
+ # # will generate 'message', 'message_element', and 'message?' methods
529
+ #
530
+ # @param [Symbol] the name used for the generated methods
531
+ # @param [Hash] identifier how we find a div. You can use a multiple parameters
532
+ # by combining of any of the following except xpath. The valid keys are:
533
+ # * :class => Watir and Selenium
534
+ # * :css => Watir and Selenium
535
+ # * :id => Watir and Selenium
536
+ # * :index => Watir and Selenium
537
+ # * :name => Watir and Selenium
538
+ # * :text => Watir and Selenium
539
+ # * :title => Watir and Selenium
540
+ # * :xpath => Watir and Selenium
541
+ # @param optional block to be invoked when element method is called
542
+ #
543
+ def div(name, identifier={:index => 0}, &block)
544
+ standard_methods(name, identifier, 'div_for', &block)
545
+ define_method(name) do
546
+ return platform.div_text_for identifier.clone unless block_given?
547
+ self.send("#{name}_element").text
548
+ end
549
+ end
550
+
551
+ #
552
+ # adds three methods - one to retrieve the text from a span,
553
+ # another to return the span element, and another to check the span's existence.
554
+ #
555
+ # @example
556
+ # span(:alert, :id => 'alert')
557
+ # # will generate 'alert', 'alert_element', and 'alert?' methods
558
+ #
559
+ # @param [Symbol] the name used for the generated methods
560
+ # @param [Hash] identifier how we find a span. You can use a multiple parameters
561
+ # by combining of any of the following except xpath. The valid keys are:
562
+ # * :class => Watir and Selenium
563
+ # * :css => Watir and Selenium
564
+ # * :id => Watir and Selenium
565
+ # * :index => Watir and Selenium
566
+ # * :name => Watir and Selenium
567
+ # * :text => Watir and Selenium
568
+ # * :title => Watir and Selenium
569
+ # * :xpath => Watir and Selenium
570
+ # @param optional block to be invoked when element method is called
571
+ #
572
+ def span(name, identifier={:index => 0}, &block)
573
+ standard_methods(name, identifier, 'span_for', &block)
574
+ define_method(name) do
575
+ return platform.span_text_for identifier.clone unless block_given?
576
+ self.send("#{name}_element").text
577
+ end
578
+ end
579
+
580
+ #
581
+ # adds three methods - one to return the text for the table, one
582
+ # to retrieve the table element, and another to
583
+ # check the table's existence. The existence method does not work
584
+ # on Selenium so it should not be called.
585
+ #
586
+ # @example
587
+ # table(:cart, :id => 'shopping_cart')
588
+ # # will generate a 'cart', 'cart_element' and 'cart?' method
589
+ #
590
+ # @param [Symbol] the name used for the generated methods
591
+ # @param [Hash] identifier how we find a table. You can use a multiple parameters
592
+ # by combining of any of the following except xpath. The valid keys are:
593
+ # * :class => Watir and Selenium
594
+ # * :css => Selenium only
595
+ # * :id => Watir and Selenium
596
+ # * :index => Watir and Selenium
597
+ # * :name => Watir and Selenium
598
+ # * :xpath => Watir and Selenium
599
+ # @param optional block to be invoked when element method is called
600
+ #
601
+ def table(name, identifier={:index => 0}, &block)
602
+ standard_methods(name, identifier, 'table_for', &block)
603
+ define_method(name) do
604
+ return platform.table_text_for identifier.clone unless block_given?
605
+ self.send("#{name}_element").text
606
+ end
607
+ end
608
+
609
+ #
610
+ # adds three methods - one to retrieve the text from a table cell,
611
+ # another to return the table cell element, and another to check the cell's
612
+ # existence.
613
+ #
614
+ # @example
615
+ # cell(:total, :id => 'total_cell')
616
+ # # will generate 'total', 'total_element', and 'total?' methods
617
+ #
618
+ # @param [Symbol] the name used for the generated methods
619
+ # @param [Hash] identifier how we find a cell. You can use a multiple parameters
620
+ # by combining of any of the following except xpath. The valid keys are:
621
+ # * :class => Watir and Selenium
622
+ # * :css => Watir and Selenium
623
+ # * :id => Watir and Selenium
624
+ # * :index => Watir and Selenium
625
+ # * :name => Watir and Selenium
626
+ # * :text => Watir and Selenium
627
+ # * :xpath => Watir and Selenium
628
+ # * :css => Selenium only
629
+ # @param optional block to be invoked when element method is called
630
+ #
631
+ def cell(name, identifier={:index => 0}, &block)
632
+ standard_methods(name, identifier, 'cell_for', &block)
633
+ define_method("#{name}") do
634
+ return platform.cell_text_for identifier.clone unless block_given?
635
+ self.send("#{name}_element").text
636
+ end
637
+ end
638
+ alias_method :td, :cell
639
+
640
+ #
641
+ # adds two methods - one to retrieve the image element, and another to
642
+ # check the image's existence.
643
+ #
644
+ # @example
645
+ # image(:logo, :id => 'logo')
646
+ # # will generate 'logo_element' and 'logo?' methods
647
+ #
648
+ # @param [Symbol] the name used for the generated methods
649
+ # @param [Hash] identifier how we find an image. You can use a multiple parameters
650
+ # by combining of any of the following except xpath. The valid keys are:
651
+ # * :alt => Watir and Selenium
652
+ # * :class => Watir and Selenium
653
+ # * :css => Selenium only
654
+ # * :id => Watir and Selenium
655
+ # * :index => Watir and Selenium
656
+ # * :name => Watir and Selenium
657
+ # * :src => Watir and Selenium
658
+ # * :xpath => Watir and Selenium
659
+ # @param optional block to be invoked when element method is called
660
+ #
661
+ def image(name, identifier={:index => 0}, &block)
662
+ standard_methods(name, identifier, 'image_for', &block)
663
+ end
664
+ alias_method :img, :image
665
+
666
+ #
667
+ # adds two methods - one to retrieve the form element, and another to
668
+ # check the form's existence.
669
+ #
670
+ # @example
671
+ # form(:login, :id => 'login')
672
+ # # will generate 'login_element' and 'login?' methods
673
+ #
674
+ # @param [Symbol] the name used for the generated methods
675
+ # @param [Hash] identifier how we find a form. You can use a multiple parameters
676
+ # by combining of any of the following except xpath. The valid keys are:
677
+ # * :action => Watir and Selenium
678
+ # * :class => Watir and Selenium
679
+ # * :css => Selenium only
680
+ # * :id => Watir and Selenium
681
+ # * :index => Watir and Selenium
682
+ # * :xpath => Watir and Selenium
683
+ # @param optional block to be invoked when element method is called
684
+ #
685
+ def form(name, identifier={:index => 0}, &block)
686
+ standard_methods(name, identifier, 'form_for', &block)
687
+ end
688
+
689
+ #
690
+ # adds three methods - one to retrieve the text from a list item,
691
+ # another to return the list item element, and another to check the list item's
692
+ # existence.
693
+ #
694
+ # @example
695
+ # list_item(:item_one, :id => 'one')
696
+ # # will generate 'item_one', 'item_one_element', and 'item_one?' methods
697
+ #
698
+ # @param [Symbol] the name used for the generated methods
699
+ # @param [Hash] identifier how we find a list item. You can use a multiple parameters
700
+ # by combining of any of the following except xpath. The valid keys are:
701
+ # * :class => Watir and Selenium
702
+ # * :css => Watir and Selenium
703
+ # * :id => Watir and Selenium
704
+ # * :index => Watir and Selenium
705
+ # * :name => Watir and Selenium
706
+ # * :text => Watir and Selenium
707
+ # * :xpath => Watir and Selenium
708
+ # @param optional block to be invoked when element method is called
709
+ #
710
+ def list_item(name, identifier={:index => 0}, &block)
711
+ standard_methods(name, identifier, 'list_item_for', &block)
712
+ define_method(name) do
713
+ return platform.list_item_text_for identifier.clone unless block_given?
714
+ self.send("#{name}_element").text
715
+ end
716
+ end
717
+ alias_method :li, :list_item
718
+
719
+ #
720
+ # adds three methods - one to return the text within the unordered
721
+ # list, one to retrieve the unordered list element, and another to
722
+ # check it's existence.
723
+ #
724
+ # @example
725
+ # unordered_list(:menu, :id => 'main_menu')
726
+ # # will generate 'menu', 'menu_element' and 'menu?' methods
727
+ #
728
+ # @param [Symbol] the name used for the generated methods
729
+ # @param [Hash] identifier how we find an unordered list. You can use a multiple parameters
730
+ # by combining of any of the following except xpath. The valid keys are:
731
+ # * :class => Watir and Selenium
732
+ # * :css => Selenium only
733
+ # * :id => Watir and Selenium
734
+ # * :index => Watir and Selenium
735
+ # * :name => Watir and Selenium
736
+ # * :xpath => Watir and Selenium
737
+ # @param optional block to be invoked when element method is called
738
+ #
739
+ def unordered_list(name, identifier={:index => 0}, &block)
740
+ standard_methods(name, identifier, 'unordered_list_for', &block)
741
+ define_method(name) do
742
+ return platform.unordered_list_text_for identifier.clone unless block_given?
743
+ self.send("#{name}_element").text
744
+ end
745
+ end
746
+ alias_method :ul, :unordered_list
747
+
748
+ #
749
+ # adds three methods - one to return the text within the ordered
750
+ # list, one to retrieve the ordered list element, and another to
751
+ # test it's existence.
752
+ #
753
+ # @example
754
+ # ordered_list(:top_five, :id => 'top')
755
+ # # will generate 'top_five', 'top_five_element' and 'top_five?' methods
756
+ #
757
+ # @param [Symbol] the name used for the generated methods
758
+ # @param [Hash] identifier how we find an ordered list. You can use a multiple parameters
759
+ # by combining of any of the following except xpath. The valid keys are:
760
+ # * :class => Watir and Selenium
761
+ # * :css => Selenium only
762
+ # * :id => Watir and Selenium
763
+ # * :index => Watir and Selenium
764
+ # * :name => Watir and Selenium
765
+ # * :xpath => Watir and Selenium
766
+ # @param optional block to be invoked when element method is called
767
+ #
768
+ def ordered_list(name, identifier={:index => 0}, &block)
769
+ standard_methods(name, identifier, 'ordered_list_for', &block)
770
+ define_method(name) do
771
+ return platform.ordered_list_text_for identifier.clone unless block_given?
772
+ self.send("#{name}_element").text
773
+ end
774
+ end
775
+ alias_method :ol, :ordered_list
776
+
777
+ #
778
+ # adds three methods - one to retrieve the text of a h1 element, another to
779
+ # retrieve a h1 element, and another to check for it's existence.
780
+ #
781
+ # @example
782
+ # h1(:title, :id => 'title')
783
+ # # will generate 'title', 'title_element', and 'title?' methods
784
+ #
785
+ # @param [Symbol] the name used for the generated methods
786
+ # @param [Hash] identifier how we find a H1. You can use a multiple parameters
787
+ # by combining of any of the following except xpath. The valid keys are:
788
+ # * :class => Watir and Selenium
789
+ # * :css => Watir and Selenium
790
+ # * :id => Watir and Selenium
791
+ # * :index => Watir and Selenium
792
+ # * :name => Watir and Selenium
793
+ # * :xpath => Watir and Selenium
794
+ # @param optional block to be invoked when element method is called
795
+ #
796
+ def h1(name, identifier={:index => 0}, &block)
797
+ standard_methods(name, identifier,'h1_for', &block)
798
+ define_method(name) do
799
+ return platform.h1_text_for identifier.clone unless block_given?
800
+ self.send("#{name}_element").text
801
+ end
802
+ end
803
+
804
+ #
805
+ # adds three methods - one to retrieve the text of a h2 element, another
806
+ # to retrieve a h2 element, and another to check for it's existence.
807
+ #
808
+ # @example
809
+ # h2(:title, :id => 'title')
810
+ # # will generate 'title', 'title_element', and 'title?' methods
811
+ #
812
+ # @param [Symbol] the name used for the generated methods
813
+ # @param [Hash] identifier how we find a H2. You can use a multiple parameters
814
+ # by combining of any of the following except xpath. The valid keys are:
815
+ # * :class => Watir and Selenium
816
+ # * :css => Watir and Selenium
817
+ # * :id => Watir and Selenium
818
+ # * :index => Watir and Selenium
819
+ # * :name => Watir and Selenium
820
+ # * :xpath => Watir and Selenium
821
+ # @param optional block to be invoked when element method is called
822
+ #
823
+ def h2(name, identifier={:index => 0}, &block)
824
+ standard_methods(name, identifier, 'h2_for', &block)
825
+ define_method(name) do
826
+ return platform.h2_text_for identifier.clone unless block_given?
827
+ self.send("#{name}_element").text
828
+ end
829
+ end
830
+
831
+ #
832
+ # adds three methods - one to retrieve the text of a h3 element,
833
+ # another to return a h3 element, and another to check for it's existence.
834
+ #
835
+ # @example
836
+ # h3(:title, :id => 'title')
837
+ # # will generate 'title', 'title_element', and 'title?' methods
838
+ #
839
+ # @param [Symbol] the name used for the generated methods
840
+ # @param [Hash] identifier how we find a H3. You can use a multiple parameters
841
+ # by combining of any of the following except xpath. The valid keys are:
842
+ # * :class => Watir and Selenium
843
+ # * :css => Watir and Selenium
844
+ # * :id => Watir and Selenium
845
+ # * :index => Watir and Selenium
846
+ # * :name => Watir and Selenium
847
+ # * :xpath => Watir and Selenium
848
+ # @param optional block to be invoked when element method is called
849
+ #
850
+ def h3(name, identifier={:index => 0}, &block)
851
+ standard_methods(name, identifier, 'h3_for', &block)
852
+ define_method(name) do
853
+ return platform.h3_text_for identifier.clone unless block_given?
854
+ self.send("#{name}_element").text
855
+ end
856
+ end
857
+
858
+ #
859
+ # adds three methods - one to retrieve the text of a h4 element,
860
+ # another to return a h4 element, and another to check for it's existence.
861
+ #
862
+ # @example
863
+ # h4(:title, :id => 'title')
864
+ # # will generate 'title', 'title_element', and 'title?' methods
865
+ #
866
+ # @param [Symbol] the name used for the generated methods
867
+ # @param [Hash] identifier how we find a H4. You can use a multiple parameters
868
+ # by combining of any of the following except xpath. The valid keys are:
869
+ # * :class => Watir and Selenium
870
+ # * :css => Watir and Selenium
871
+ # * :id => Watir and Selenium
872
+ # * :index => Watir and Selenium
873
+ # * :name => Watir and Selenium
874
+ # * :xpath => Watir and Selenium
875
+ # @param optional block to be invoked when element method is called
876
+ #
877
+ def h4(name, identifier={:index => 0}, &block)
878
+ standard_methods(name, identifier, 'h4_for', &block)
879
+ define_method(name) do
880
+ return platform.h4_text_for identifier.clone unless block_given?
881
+ self.send("#{name}_element").text
882
+ end
883
+ end
884
+
885
+ #
886
+ # adds three methods - one to retrieve the text of a h5 element,
887
+ # another to return a h5 element, and another to check for it's existence.
888
+ #
889
+ # @example
890
+ # h5(:title, :id => 'title')
891
+ # # will generate 'title', 'title_element', and 'title?' methods
892
+ #
893
+ # @param [Symbol] the name used for the generated methods
894
+ # @param [Hash] identifier how we find a H5. You can use a multiple parameters
895
+ # by combining of any of the following except xpath. The valid keys are:
896
+ # * :class => Watir and Selenium
897
+ # * :css => Watir and Selenium
898
+ # * :id => Watir and Selenium
899
+ # * :index => Watir and Selenium
900
+ # * :name => Watir and Selenium
901
+ # * :xpath => Watir and Selenium
902
+ # @param optional block to be invoked when element method is called
903
+ #
904
+ def h5(name, identifier={:index => 0}, &block)
905
+ standard_methods(name, identifier, 'h5_for', &block)
906
+ define_method(name) do
907
+ return platform.h5_text_for identifier.clone unless block_given?
908
+ self.send("#{name}_element").text
909
+ end
910
+ end
911
+
912
+ #
913
+ # adds three methods - one to retrieve the text of a h6 element,
914
+ # another to return a h6 element, and another to check for it's existence.
915
+ #
916
+ # @example
917
+ # h6(:title, :id => 'title')
918
+ # # will generate 'title', 'title_element', and 'title?' methods
919
+ #
920
+ # @param [Symbol] the name used for the generated methods
921
+ # @param [Hash] identifier how we find a H6. You can use a multiple parameters
922
+ # by combining of any of the following except xpath. The valid keys are:
923
+ # * :class => Watir and Selenium
924
+ # * :css => Watir and Selenium
925
+ # * :id => Watir and Selenium
926
+ # * :index => Watir and Selenium
927
+ # * :name => Watir and Selenium
928
+ # * :xpath => Watir and Selenium
929
+ # @param optional block to be invoked when element method is called
930
+ #
931
+ def h6(name, identifier={:index => 0}, &block)
932
+ standard_methods(name, identifier, 'h6_for', &block)
933
+ define_method(name) do
934
+ return platform.h6_text_for identifier.clone unless block_given?
935
+ self.send("#{name}_element").text
936
+ end
937
+ end
938
+
939
+ #
940
+ # adds three methods - one to retrieve the text of a paragraph, another
941
+ # to retrieve a paragraph element, and another to check the paragraph's existence.
942
+ #
943
+ # @example
944
+ # paragraph(:title, :id => 'title')
945
+ # # will generate 'title', 'title_element', and 'title?' methods
946
+ #
947
+ # @param [Symbol] the name used for the generated methods
948
+ # @param [Hash] identifier how we find a paragraph. You can use a multiple parameters
949
+ # by combining of any of the following except xpath. The valid keys are:
950
+ # * :class => Watir and Selenium
951
+ # * :css => Watir and Selenium
952
+ # * :id => Watir and Selenium
953
+ # * :index => Watir and Selenium
954
+ # * :name => Watir and Selenium
955
+ # * :xpath => Watir and Selenium
956
+ # @param optional block to be invoked when element method is called
957
+ #
958
+ def paragraph(name, identifier={:index => 0}, &block)
959
+ standard_methods(name, identifier, 'paragraph_for', &block)
960
+ define_method(name) do
961
+ return platform.paragraph_text_for identifier.clone unless block_given?
962
+ self.send("#{name}_element").text
963
+ end
964
+ end
965
+ alias_method :p, :paragraph
966
+
967
+ #
968
+ # adds three methods - one to set the file for a file field, another to retrieve
969
+ # the file field element, and another to check it's existence.
970
+ #
971
+ # @example
972
+ # file_field(:the_file, :id => 'file_to_upload')
973
+ # # will generate 'the_file=', 'the_file_element', and 'the_file?' methods
974
+ #
975
+ # @param [Symbol] the name used for the generated methods
976
+ # @param [Hash] identifier how we find a file_field. You can use a multiple parameters
977
+ # by combining of any of the following except xpath. The valid keys are:
978
+ # * :class => Watir and Selenium
979
+ # * :css => Selenium only
980
+ # * :id => Watir and Selenium
981
+ # * :index => Watir and Selenium
982
+ # * :name => Watir and Selenium
983
+ # * :title => Watir and Selenium
984
+ # * :xpath => Watir and Selenium
985
+ # * :label => Watir and Selenium
986
+ # @param optional block to be invoked when element method is called
987
+ #
988
+ def file_field(name, identifier={:index => 0}, &block)
989
+ standard_methods(name, identifier, 'file_field_for', &block)
990
+ define_method("#{name}=") do |value|
991
+ return platform.file_field_value_set(identifier.clone, value) unless block_given?
992
+ self.send("#{name}_element").value = value
993
+ end
994
+ end
995
+
996
+ #
997
+ # adds three methods - one to retrieve the text from a label,
998
+ # another to return the label element, and another to check the label's existence.
999
+ #
1000
+ # @example
1001
+ # label(:message, :id => 'message')
1002
+ # # will generate 'message', 'message_element', and 'message?' methods
1003
+ #
1004
+ # @param [Symbol] the name used for the generated methods
1005
+ # @param [Hash] identifier how we find a label. You can use a multiple parameters
1006
+ # by combining of any of the following except xpath. The valid keys are:
1007
+ # * :class => Watir and Selenium
1008
+ # * :css => Watir and Selenium
1009
+ # * :id => Watir and Selenium
1010
+ # * :index => Watir and Selenium
1011
+ # * :name => Watir and Selenium
1012
+ # * :text => Watir and Selenium
1013
+ # * :xpath => Watir and Selenium
1014
+ # @param optional block to be invoked when element method is called
1015
+ #
1016
+ def label(name, identifier={:index => 0}, &block)
1017
+ standard_methods(name, identifier, 'label_for', &block)
1018
+ define_method(name) do
1019
+ return platform.label_text_for identifier.clone unless block_given?
1020
+ self.send("#{name}_element").text
1021
+ end
1022
+ end
1023
+
1024
+ #
1025
+ # adds three methods - one to click the area,
1026
+ # another to return the area element, and another to check the area's existence.
1027
+ #
1028
+ # @example
1029
+ # area(:message, :id => 'message')
1030
+ # # will generate 'message', 'message_element', and 'message?' methods
1031
+ #
1032
+ # @param [Symbol] the name used for the generated methods
1033
+ # @param [Hash] identifier how we find an area. You can use a multiple parameters
1034
+ # by combining of any of the following except xpath. The valid keys are:
1035
+ # * :class => Watir and Selenium
1036
+ # * :css => Watir and Selenium
1037
+ # * :id => Watir and Selenium
1038
+ # * :index => Watir and Selenium
1039
+ # * :name => Watir and Selenium
1040
+ # * :text => Watir and Selenium
1041
+ # * :xpath => Watir and Selenium
1042
+ # @param optional block to be invoked when element method is called
1043
+ #
1044
+ def area(name, identifier={:index => 0}, &block)
1045
+ standard_methods(name, identifier, 'area_for', &block)
1046
+ define_method(name) do
1047
+ return platform.click_area_for identifier.clone unless block_given?
1048
+ self.send("#{name}_element").click
1049
+ end
1050
+ end
1051
+
1052
+ #
1053
+ # adds two methods - one to return the canvas element and another to check
1054
+ # the canvas's existence.
1055
+ #
1056
+ # @example
1057
+ # canvas(:my_canvas, :id => 'canvas_id')
1058
+ # # will generate 'my_canvas_element' and 'my_canvas?' methods
1059
+ #
1060
+ # @param [Symbol] the name used for the generated methods
1061
+ # @param [Hash] identifier how we find a canvas. You can use a multiple parameters
1062
+ # by combining of any of the following except xpath. The valid keys are:
1063
+ # * :class => Watir and Selenium
1064
+ # * :css => Watir and Selenium
1065
+ # * :id => Watir and Selenium
1066
+ # * :index => Watir and Selenium
1067
+ # * :name => Watir and Selenium
1068
+ # * :xpath => Watir and Selenium
1069
+ # @param optional block to be invoked when element method is called
1070
+ #
1071
+ def canvas(name, identifier={:index => 0}, &block)
1072
+ standard_methods(name, identifier, 'canvas_for', &block)
1073
+ end
1074
+
1075
+ #
1076
+ # adds two methods - one to return the audio element and another to check
1077
+ # the audio's existence.
1078
+ #
1079
+ # @example
1080
+ # audio(:acdc, :id => 'audio_id')
1081
+ # # will generate 'acdc_element' and 'acdc?' methods
1082
+ #
1083
+ # @param [Symbol] the name used for the generated methods
1084
+ # @param [Hash] identifier how we find an audio element. You can use a multiple parameters
1085
+ # by combining of any of the following except xpath. The valid keys are:
1086
+ # * :class => Watir and Selenium
1087
+ # * :css => Watir and Selenium
1088
+ # * :id => Watir and Selenium
1089
+ # * :index => Watir and Selenium
1090
+ # * :name => Watir and Selenium
1091
+ # * :xpath => Watir and Selenium
1092
+ # @param optional block to be invoked when element method is called
1093
+ #
1094
+ def audio(name, identifier={:index => 0}, &block)
1095
+ standard_methods(name, identifier, 'audio_for', &block)
1096
+ end
1097
+
1098
+ #
1099
+ # adds two methods - one to return the video element and another to check
1100
+ # the video's existence.
1101
+ #
1102
+ # @example
1103
+ # video(:movie, :id => 'video_id')
1104
+ # # will generate 'movie_element' and 'movie?' methods
1105
+ #
1106
+ # @param [Symbol] the name used for the generated methods
1107
+ # @param [Hash] identifier how we find a video element. You can use a multiple parameters
1108
+ # by combining of any of the following except xpath. The valid keys are:
1109
+ # * :class => Watir and Selenium
1110
+ # * :css => Watir and Selenium
1111
+ # * :id => Watir and Selenium
1112
+ # * :index => Watir and Selenium
1113
+ # * :name => Watir and Selenium
1114
+ # * :xpath => Watir and Selenium
1115
+ # @param optional block to be invoked when element method is called
1116
+ #
1117
+ def video(name, identifier={:index => 0}, &block)
1118
+ standard_methods(name, identifier, 'video_for', &block)
1119
+ end
1120
+
1121
+ #
1122
+ # adds three methods - one to retrieve the text of a b element, another to
1123
+ # retrieve a b element, and another to check for it's existence.
1124
+ #
1125
+ # @example
1126
+ # b(:bold, :id => 'title')
1127
+ # # will generate 'bold', 'bold_element', and 'bold?' methods
1128
+ #
1129
+ # @param [Symbol] the name used for the generated methods
1130
+ # @param [Hash] identifier how we find a b. You can use a multiple parameters
1131
+ # by combining of any of the following except xpath. The valid keys are:
1132
+ # * :class => Watir and Selenium
1133
+ # * :css => Watir and Selenium
1134
+ # * :id => Watir and Selenium
1135
+ # * :index => Watir and Selenium
1136
+ # * :name => Watir and Selenium
1137
+ # * :xpath => Watir and Selenium
1138
+ # @param optional block to be invoked when element method is called
1139
+ #
1140
+ def b(name, identifier={:index => 0}, &block)
1141
+ standard_methods(name, identifier,'b_for', &block)
1142
+ define_method(name) do
1143
+ return platform.b_text_for identifier.clone unless block_given?
1144
+ self.send("#{name}_element").text
1145
+ end
1146
+ end
1147
+
1148
+ #
1149
+ # adds two methods - one to retrieve a svg, and another to check
1150
+ # the svg's existence.
1151
+ #
1152
+ # @example
1153
+ # svg(:circle, :id => 'circle')
1154
+ # # will generate 'circle_element', and 'circle?' methods
1155
+ #
1156
+ # @param [Symbol] the name used for the generated methods
1157
+ # @param [Hash] identifier how we find a svg. You can use a multiple parameters
1158
+ # by combining of any of the following except xpath. The valid keys are:
1159
+ # * :class => Watir and Selenium
1160
+ # * :css => Selenium only
1161
+ # * :id => Watir and Selenium
1162
+ # * :index => Watir and Selenium
1163
+ # * :name => Watir and Selenium
1164
+ # * :xpath => Watir and Selenium
1165
+ # @param optional block to be invoked when element method is called
1166
+ #
1167
+ def svg(name, identifier={:index => 0}, &block)
1168
+ standard_methods(name, identifier, 'svg_for', &block)
1169
+ end
1170
+
1171
+
1172
+ #
1173
+ # adds three methods - one to retrieve the text of an element, another
1174
+ # to retrieve an element, and another to check the element's existence.
1175
+ #
1176
+ # @example
1177
+ # element(:title, :header, :id => 'title')
1178
+ # # will generate 'title', 'title_element', and 'title?' methods
1179
+ #
1180
+ # @param [Symbol] the name used for the generated methods
1181
+ # @param [Symbol] the name of the tag for the element
1182
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1183
+ # by combining of any of the following except xpath. The valid keys are:
1184
+ # * :class => Watir and Selenium
1185
+ # * :css => Selenium only
1186
+ # * :id => Watir and Selenium
1187
+ # * :index => Watir and Selenium
1188
+ # * :name => Watir and Selenium
1189
+ # * :xpath => Watir and Selenium
1190
+ # @param optional block to be invoked when element method is called
1191
+ #
1192
+ def element(name, tag, identifier={:index => 0}, &block)
1193
+ define_method("#{name}") do
1194
+ self.send("#{name}_element").text
1195
+ end
1196
+ define_method("#{name}_element") do
1197
+ return call_block(&block) if block_given?
1198
+ platform.element_for(tag, identifier.clone)
1199
+ end
1200
+ define_method("#{name}?") do
1201
+ self.send("#{name}_element").exists?
1202
+ end
1203
+ end
1204
+
1205
+ #
1206
+ # adds a method to return a collection of generic Element objects
1207
+ # for a specific tag.
1208
+ #
1209
+ # @example
1210
+ # elements(:title, :header, :id => 'title')
1211
+ # # will generate ''title_elements'
1212
+ #
1213
+ # @param [Symbol] the name used for the generated methods
1214
+ # @param [Symbol] the name of the tag for the element
1215
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1216
+ # by combining of any of the following except xpath. The valid keys are:
1217
+ # * :class => Watir and Selenium
1218
+ # * :css => Selenium only
1219
+ # * :id => Watir and Selenium
1220
+ # * :index => Watir and Selenium
1221
+ # * :name => Watir and Selenium
1222
+ # * :xpath => Watir and Selenium
1223
+ # @param optional block to be invoked when element method is called
1224
+ #
1225
+ def elements(name, tag, identifier={:index => 0}, &block)
1226
+ define_method("#{name}_elements") do
1227
+ return call_block(&block) if block_given?
1228
+ platform.elements_for(tag, identifier.clone)
1229
+ end
1230
+ end
1231
+
1232
+ #
1233
+ # methods to generate accessors for types that follow the same
1234
+ # pattern as element
1235
+ #
1236
+ # @example
1237
+ # article(:my_article, :id => "article_id")
1238
+ # will generate 'my_article', 'my_article_element' and 'my_article?'
1239
+ # articles(:my_article, :id => 'article_id')
1240
+ # will generate 'my_article_elements'
1241
+ #
1242
+ # @param [Symbol] the name used for the generated methods
1243
+ # @param [Symbol] the name of the tag for the element
1244
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1245
+ # by combining of any of the following except xpath. The valid keys are:
1246
+ # * :class => Watir and Selenium
1247
+ # * :css => Selenium only
1248
+ # * :id => Watir and Selenium
1249
+ # * :index => Watir and Selenium
1250
+ # * :name => Watir and Selenium
1251
+ # * :xpath => Watir and Selenium
1252
+ # @param optional block to be invoked when element method is called
1253
+ #
1254
+ LocatorGenerator::BASIC_ELEMENTS.each do |tag|
1255
+ define_method(tag) do |name, *identifier, &block|
1256
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1257
+ element(name, tag, identifier, &block)
1258
+ end
1259
+ define_method("#{tag}s") do |name, *identifier, &block|
1260
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1261
+ elements(name, tag, identifier, &block)
1262
+ end unless tag == :param
1263
+ end
1264
+
1265
+ def standard_methods(name, identifier, method, &block)
1266
+ define_method("#{name}_element") do
1267
+ return call_block(&block) if block_given?
1268
+ platform.send(method, identifier.clone)
1269
+ end
1270
+ define_method("#{name}?") do
1271
+ return call_block(&block).exists? if block_given?
1272
+ platform.send(method, identifier.clone).exists?
1273
+ end
1274
+ end
1275
+
1276
+ #
1277
+ # adds a method that will return an indexed property. The property will respond to
1278
+ # the [] method with an object that has a set of normal page_object properties that
1279
+ # correspond to the definitions included in the identifier_list parameter, with the
1280
+ # "what" of the "how and what" substituted based on the index provided to the []
1281
+ # method.
1282
+ #
1283
+ # @example
1284
+ # indexed_property(:title, [
1285
+ # [:text_field, :field_1, :id => 'table[%s].field_1'],
1286
+ # [:button, :button_1, :id => 'table[%s].button_1'],
1287
+ # [:text_field, :field_2, :name => 'table[%s].field_2']
1288
+ # ])
1289
+ # # will generate a title method that responds to []. title['foo'] will return an object
1290
+ # # that responds to the normal methods expected for two text_fields and a button with the
1291
+ # # given names, using the given how and what with 'foo' substituted for the %s. title[123]
1292
+ # # will do the same, using the integer 123 instead.
1293
+ #
1294
+ # @param [Symbol] the name used for the generated method
1295
+ # @param [Array] definitions an array of definitions to define on the indexed property. Each
1296
+ # entry in the array should contain two symbols and a hash, corresponding to one of the standard
1297
+ # page_object properties with a single substitution marker in each value in the hash,
1298
+ # e.g. [:text_field, :field_1, :id => 'table[%s].field_1']
1299
+ #
1300
+ def indexed_property (name, identifier_list)
1301
+ define_method("#{name}") do
1302
+ IndexedProperties::TableOfElements.new(@browser, identifier_list)
1303
+ end
1304
+ end
1305
+
1306
+ #
1307
+ # methods to fetch multiple elements of the same type
1308
+ #
1309
+ # adds a method to the page object to return all of the matching elements
1310
+ #
1311
+ # @example
1312
+ # text_fields(:first_name, :id => "first_name")
1313
+ # # will generate 'first_name_elements'
1314
+ #
1315
+ # @param [String] the name used for the generated methods
1316
+ # @param [Hash] identifier how we find a text field. You can use a multiple parameters
1317
+ # by combining of any of the following except xpath. The valid
1318
+ # keys are the same ones supported by the standard methods.
1319
+ # @param optional block to be invoked when element method is called
1320
+ #
1321
+ idx = LocatorGenerator::ADVANCED_ELEMENTS.find_index { |type| type == :checkbox }
1322
+ elements = LocatorGenerator::ADVANCED_ELEMENTS.clone
1323
+ elements[idx] = :checkboxe
1324
+ elements.each do |method_name|
1325
+ define_method("#{method_name}s") do |name, *identifier, &block|
1326
+ define_method("#{name}_elements") do
1327
+ return call_block(&block) unless block.nil?
1328
+ platform_method = (method_name == :checkboxe) ? 'checkboxs_for' : "#{method_name.to_s}s_for"
1329
+ platform.send platform_method, (identifier.first ? identifier.first.clone : {})
1330
+ end
1331
+ end
1332
+ end
1333
+ end
1334
+ end