page_object 1.1.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 (272) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -0
  7. data/ChangeLog +809 -0
  8. data/Gemfile +14 -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 +98 -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 +55 -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 +207 -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 +117 -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/section.feature +132 -0
  81. data/features/select_list.feature +86 -0
  82. data/features/span.feature +37 -0
  83. data/features/step_definitions/accessor_steps.rb +64 -0
  84. data/features/step_definitions/area_steps.rb +19 -0
  85. data/features/step_definitions/async_steps.rb +83 -0
  86. data/features/step_definitions/audio_steps.rb +27 -0
  87. data/features/step_definitions/bold_steps.rb +12 -0
  88. data/features/step_definitions/button_steps.rb +48 -0
  89. data/features/step_definitions/canvas_steps.rb +15 -0
  90. data/features/step_definitions/check_box_steps.rb +35 -0
  91. data/features/step_definitions/div_steps.rb +19 -0
  92. data/features/step_definitions/element_steps.rb +266 -0
  93. data/features/step_definitions/file_field_steps.rb +19 -0
  94. data/features/step_definitions/form_steps.rb +19 -0
  95. data/features/step_definitions/frames_steps.rb +159 -0
  96. data/features/step_definitions/generic_element_steps.rb +31 -0
  97. data/features/step_definitions/gxt_table_steps.rb +58 -0
  98. data/features/step_definitions/headings_steps.rb +12 -0
  99. data/features/step_definitions/hidden_field_steps.rb +27 -0
  100. data/features/step_definitions/image_steps.rb +27 -0
  101. data/features/step_definitions/indexed_property_steps.rb +163 -0
  102. data/features/step_definitions/javascript_steps.rb +53 -0
  103. data/features/step_definitions/label_steps.rb +19 -0
  104. data/features/step_definitions/link_steps.rb +40 -0
  105. data/features/step_definitions/list_item_steps.rb +19 -0
  106. data/features/step_definitions/modal_dialog_steps.rb +62 -0
  107. data/features/step_definitions/multi_elements_steps.rb +541 -0
  108. data/features/step_definitions/nested_elements_steps.rb +212 -0
  109. data/features/step_definitions/ordered_list_steps.rb +23 -0
  110. data/features/step_definitions/page_level_actions_steps.rb +135 -0
  111. data/features/step_definitions/page_traversal_steps.rb +4 -0
  112. data/features/step_definitions/paragraph_steps.rb +28 -0
  113. data/features/step_definitions/radio_button_group_steps.rb +36 -0
  114. data/features/step_definitions/radio_button_steps.rb +27 -0
  115. data/features/step_definitions/section_steps.rb +268 -0
  116. data/features/step_definitions/select_list_steps.rb +65 -0
  117. data/features/step_definitions/span_steps.rb +19 -0
  118. data/features/step_definitions/table_cell_steps.rb +15 -0
  119. data/features/step_definitions/table_row_steps.rb +23 -0
  120. data/features/step_definitions/table_steps.rb +70 -0
  121. data/features/step_definitions/text_area_steps.rb +35 -0
  122. data/features/step_definitions/text_field_steps.rb +35 -0
  123. data/features/step_definitions/unordered_list_steps.rb +23 -0
  124. data/features/step_definitions/video_steps.rb +45 -0
  125. data/features/support/ajax_text_environment.rb +26 -0
  126. data/features/support/env.rb +8 -0
  127. data/features/support/hooks.rb +8 -0
  128. data/features/support/page.rb +382 -0
  129. data/features/support/persistent_browser.rb +70 -0
  130. data/features/support/targets/firefox14_osx.rb +6 -0
  131. data/features/support/targets/firefox14_windows7.rb +6 -0
  132. data/features/support/url_helper.rb +57 -0
  133. data/features/table.feature +122 -0
  134. data/features/table_cell.feature +45 -0
  135. data/features/table_row.feature +43 -0
  136. data/features/text_area.feature +51 -0
  137. data/features/text_field.feature +70 -0
  138. data/features/unordered_list.feature +56 -0
  139. data/features/video.feature +73 -0
  140. data/lib/page-object.rb +421 -0
  141. data/lib/page-object/accessors.rb +1412 -0
  142. data/lib/page-object/core_ext/string.rb +5 -0
  143. data/lib/page-object/element_locators.rb +21 -0
  144. data/lib/page-object/elements.rb +60 -0
  145. data/lib/page-object/elements/area.rb +31 -0
  146. data/lib/page-object/elements/audio.rb +9 -0
  147. data/lib/page-object/elements/bold.rb +11 -0
  148. data/lib/page-object/elements/button.rb +35 -0
  149. data/lib/page-object/elements/canvas.rb +23 -0
  150. data/lib/page-object/elements/check_box.rb +37 -0
  151. data/lib/page-object/elements/div.rb +19 -0
  152. data/lib/page-object/elements/element.rb +226 -0
  153. data/lib/page-object/elements/file_field.rb +38 -0
  154. data/lib/page-object/elements/form.rb +36 -0
  155. data/lib/page-object/elements/heading.rb +15 -0
  156. data/lib/page-object/elements/hidden_field.rb +22 -0
  157. data/lib/page-object/elements/image.rb +36 -0
  158. data/lib/page-object/elements/label.rb +19 -0
  159. data/lib/page-object/elements/link.rb +46 -0
  160. data/lib/page-object/elements/list_item.rb +19 -0
  161. data/lib/page-object/elements/media.rb +45 -0
  162. data/lib/page-object/elements/option.rb +10 -0
  163. data/lib/page-object/elements/ordered_list.rb +50 -0
  164. data/lib/page-object/elements/paragraph.rb +9 -0
  165. data/lib/page-object/elements/radio_button.rb +37 -0
  166. data/lib/page-object/elements/select_list.rb +42 -0
  167. data/lib/page-object/elements/span.rb +19 -0
  168. data/lib/page-object/elements/table.rb +79 -0
  169. data/lib/page-object/elements/table_cell.rb +28 -0
  170. data/lib/page-object/elements/table_row.rb +50 -0
  171. data/lib/page-object/elements/text_area.rb +38 -0
  172. data/lib/page-object/elements/text_field.rb +42 -0
  173. data/lib/page-object/elements/unordered_list.rb +51 -0
  174. data/lib/page-object/elements/video.rb +18 -0
  175. data/lib/page-object/indexed_properties.rb +40 -0
  176. data/lib/page-object/javascript/angularjs.rb +14 -0
  177. data/lib/page-object/javascript/jquery.rb +14 -0
  178. data/lib/page-object/javascript/prototype.rb +14 -0
  179. data/lib/page-object/javascript/yui.rb +19 -0
  180. data/lib/page-object/javascript_framework_facade.rb +80 -0
  181. data/lib/page-object/loads_platform.rb +45 -0
  182. data/lib/page-object/locator_generator.rb +131 -0
  183. data/lib/page-object/nested_elements.rb +17 -0
  184. data/lib/page-object/page_factory.rb +108 -0
  185. data/lib/page-object/page_populator.rb +83 -0
  186. data/lib/page-object/platforms.rb +18 -0
  187. data/lib/page-object/platforms/selenium_webdriver.rb +30 -0
  188. data/lib/page-object/platforms/selenium_webdriver/button.rb +15 -0
  189. data/lib/page-object/platforms/selenium_webdriver/check_box.rb +29 -0
  190. data/lib/page-object/platforms/selenium_webdriver/element.rb +291 -0
  191. data/lib/page-object/platforms/selenium_webdriver/file_field.rb +16 -0
  192. data/lib/page-object/platforms/selenium_webdriver/form.rb +16 -0
  193. data/lib/page-object/platforms/selenium_webdriver/image.rb +28 -0
  194. data/lib/page-object/platforms/selenium_webdriver/link.rb +23 -0
  195. data/lib/page-object/platforms/selenium_webdriver/ordered_list.rb +39 -0
  196. data/lib/page-object/platforms/selenium_webdriver/page_object.rb +1237 -0
  197. data/lib/page-object/platforms/selenium_webdriver/radio_button.rb +22 -0
  198. data/lib/page-object/platforms/selenium_webdriver/select_list.rb +93 -0
  199. data/lib/page-object/platforms/selenium_webdriver/surrogate_selenium_element.rb +42 -0
  200. data/lib/page-object/platforms/selenium_webdriver/table.rb +42 -0
  201. data/lib/page-object/platforms/selenium_webdriver/table_row.rb +43 -0
  202. data/lib/page-object/platforms/selenium_webdriver/text_area.rb +17 -0
  203. data/lib/page-object/platforms/selenium_webdriver/text_field.rb +17 -0
  204. data/lib/page-object/platforms/selenium_webdriver/unordered_list.rb +39 -0
  205. data/lib/page-object/platforms/watir_webdriver.rb +30 -0
  206. data/lib/page-object/platforms/watir_webdriver/check_box.rb +29 -0
  207. data/lib/page-object/platforms/watir_webdriver/element.rb +249 -0
  208. data/lib/page-object/platforms/watir_webdriver/file_field.rb +16 -0
  209. data/lib/page-object/platforms/watir_webdriver/form.rb +16 -0
  210. data/lib/page-object/platforms/watir_webdriver/image.rb +22 -0
  211. data/lib/page-object/platforms/watir_webdriver/link.rb +15 -0
  212. data/lib/page-object/platforms/watir_webdriver/ordered_list.rb +35 -0
  213. data/lib/page-object/platforms/watir_webdriver/page_object.rb +1082 -0
  214. data/lib/page-object/platforms/watir_webdriver/radio_button.rb +22 -0
  215. data/lib/page-object/platforms/watir_webdriver/select_list.rb +74 -0
  216. data/lib/page-object/platforms/watir_webdriver/table.rb +38 -0
  217. data/lib/page-object/platforms/watir_webdriver/table_row.rb +37 -0
  218. data/lib/page-object/platforms/watir_webdriver/text_area.rb +23 -0
  219. data/lib/page-object/platforms/watir_webdriver/text_field.rb +16 -0
  220. data/lib/page-object/platforms/watir_webdriver/unordered_list.rb +36 -0
  221. data/lib/page-object/sections.rb +29 -0
  222. data/lib/page-object/version.rb +4 -0
  223. data/lib/page-object/widgets.rb +133 -0
  224. data/page_object.gemspec +31 -0
  225. data/pageobject.gems +1 -0
  226. data/spec/page-object/accessors_spec.rb +40 -0
  227. data/spec/page-object/element_locators_spec.rb +1122 -0
  228. data/spec/page-object/elements/area_spec.rb +45 -0
  229. data/spec/page-object/elements/bold_spec.rb +29 -0
  230. data/spec/page-object/elements/button_spec.rb +64 -0
  231. data/spec/page-object/elements/canvas_spec.rb +40 -0
  232. data/spec/page-object/elements/check_box_spec.rb +49 -0
  233. data/spec/page-object/elements/div_spec.rb +28 -0
  234. data/spec/page-object/elements/element_spec.rb +114 -0
  235. data/spec/page-object/elements/file_field_spec.rb +39 -0
  236. data/spec/page-object/elements/form_spec.rb +28 -0
  237. data/spec/page-object/elements/heading_spec.rb +48 -0
  238. data/spec/page-object/elements/hidden_field_spec.rb +28 -0
  239. data/spec/page-object/elements/image_spec.rb +66 -0
  240. data/spec/page-object/elements/label_spec.rb +29 -0
  241. data/spec/page-object/elements/link_spec.rb +49 -0
  242. data/spec/page-object/elements/list_item_spec.rb +29 -0
  243. data/spec/page-object/elements/nested_element_spec.rb +254 -0
  244. data/spec/page-object/elements/option_spec.rb +11 -0
  245. data/spec/page-object/elements/ordered_list_spec.rb +94 -0
  246. data/spec/page-object/elements/paragraph_spec.rb +27 -0
  247. data/spec/page-object/elements/select_list_spec.rb +142 -0
  248. data/spec/page-object/elements/selenium/radio_button_spec.rb +44 -0
  249. data/spec/page-object/elements/selenium/text_field_spec.rb +49 -0
  250. data/spec/page-object/elements/selenium_element_spec.rb +177 -0
  251. data/spec/page-object/elements/span_spec.rb +26 -0
  252. data/spec/page-object/elements/table_cell_spec.rb +21 -0
  253. data/spec/page-object/elements/table_row_spec.rb +70 -0
  254. data/spec/page-object/elements/table_spec.rb +98 -0
  255. data/spec/page-object/elements/text_area_spec.rb +39 -0
  256. data/spec/page-object/elements/unordered_list_spec.rb +94 -0
  257. data/spec/page-object/elements/watir_element_spec.rb +145 -0
  258. data/spec/page-object/javascript_framework_facade_spec.rb +61 -0
  259. data/spec/page-object/loads_platform_spec.rb +53 -0
  260. data/spec/page-object/page-object_spec.rb +407 -0
  261. data/spec/page-object/page_factory_spec.rb +238 -0
  262. data/spec/page-object/page_populator_spec.rb +122 -0
  263. data/spec/page-object/page_section_spec.rb +73 -0
  264. data/spec/page-object/platforms/selenium_webdriver/selenium_page_object_spec.rb +68 -0
  265. data/spec/page-object/platforms/selenium_webdriver_spec.rb +29 -0
  266. data/spec/page-object/platforms/watir_webdriver/watir_page_object_spec.rb +29 -0
  267. data/spec/page-object/platforms/watir_webdriver_spec.rb +9 -0
  268. data/spec/page-object/selenium_accessors_spec.rb +609 -0
  269. data/spec/page-object/watir_accessors_spec.rb +1134 -0
  270. data/spec/page-object/widget_spec.rb +226 -0
  271. data/spec/spec_helper.rb +47 -0
  272. metadata +601 -0
@@ -0,0 +1,1412 @@
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
+ #
642
+ # adds three methods - one to retrieve the text from a table row,
643
+ # another to return the table row element, and another to check the row's
644
+ # existence.
645
+ #
646
+ # @example
647
+ # row(:sums, :id => 'sum_row')
648
+ # # will generate 'sums', 'sums_element', and 'sums?' methods
649
+ #
650
+ # @param [Symbol] the name used for the generated methods
651
+ # @param [Hash] identifier how we find a cell. You can use a multiple parameters
652
+ # by combining of any of the following except xpath. The valid keys are:
653
+ # * :class => Watir and Selenium
654
+ # * :css => Watir and Selenium
655
+ # * :id => Watir and Selenium
656
+ # * :index => Watir and Selenium
657
+ # * :text => Watir only
658
+ # * :xpath => Watir and Selenium
659
+ # * :css => Watir and Selenium
660
+ # @param optional block to be invoked when element method is called
661
+ #
662
+ def row(name, identifier={:index => 0}, &block)
663
+ standard_methods(name, identifier, 'row_for', &block)
664
+ define_method("#{name}") do
665
+ return platform.row_text_for identifier.clone unless block_given?
666
+ self.send("#{name}_element").text
667
+ end
668
+ end
669
+
670
+ #
671
+ # adds two methods - one to retrieve the image element, and another to
672
+ # check the image's existence.
673
+ #
674
+ # @example
675
+ # image(:logo, :id => 'logo')
676
+ # # will generate 'logo_element' and 'logo?' methods
677
+ #
678
+ # @param [Symbol] the name used for the generated methods
679
+ # @param [Hash] identifier how we find an image. You can use a multiple parameters
680
+ # by combining of any of the following except xpath. The valid keys are:
681
+ # * :alt => Watir and Selenium
682
+ # * :class => Watir and Selenium
683
+ # * :css => Selenium only
684
+ # * :id => Watir and Selenium
685
+ # * :index => Watir and Selenium
686
+ # * :name => Watir and Selenium
687
+ # * :src => Watir and Selenium
688
+ # * :xpath => Watir and Selenium
689
+ # @param optional block to be invoked when element method is called
690
+ #
691
+ def image(name, identifier={:index => 0}, &block)
692
+ standard_methods(name, identifier, 'image_for', &block)
693
+ end
694
+ alias_method :img, :image
695
+
696
+ #
697
+ # adds two methods - one to retrieve the form element, and another to
698
+ # check the form's existence.
699
+ #
700
+ # @example
701
+ # form(:login, :id => 'login')
702
+ # # will generate 'login_element' and 'login?' methods
703
+ #
704
+ # @param [Symbol] the name used for the generated methods
705
+ # @param [Hash] identifier how we find a form. You can use a multiple parameters
706
+ # by combining of any of the following except xpath. The valid keys are:
707
+ # * :action => Watir and Selenium
708
+ # * :class => Watir and Selenium
709
+ # * :css => Selenium only
710
+ # * :id => Watir and Selenium
711
+ # * :index => Watir and Selenium
712
+ # * :xpath => Watir and Selenium
713
+ # @param optional block to be invoked when element method is called
714
+ #
715
+ def form(name, identifier={:index => 0}, &block)
716
+ standard_methods(name, identifier, 'form_for', &block)
717
+ end
718
+
719
+ #
720
+ # adds three methods - one to retrieve the text from a list item,
721
+ # another to return the list item element, and another to check the list item's
722
+ # existence.
723
+ #
724
+ # @example
725
+ # list_item(:item_one, :id => 'one')
726
+ # # will generate 'item_one', 'item_one_element', and 'item_one?' methods
727
+ #
728
+ # @param [Symbol] the name used for the generated methods
729
+ # @param [Hash] identifier how we find a list item. 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 => Watir and Selenium
733
+ # * :id => Watir and Selenium
734
+ # * :index => Watir and Selenium
735
+ # * :name => Watir and Selenium
736
+ # * :text => Watir and Selenium
737
+ # * :xpath => Watir and Selenium
738
+ # @param optional block to be invoked when element method is called
739
+ #
740
+ def list_item(name, identifier={:index => 0}, &block)
741
+ standard_methods(name, identifier, 'list_item_for', &block)
742
+ define_method(name) do
743
+ return platform.list_item_text_for identifier.clone unless block_given?
744
+ self.send("#{name}_element").text
745
+ end
746
+ end
747
+ alias_method :li, :list_item
748
+
749
+ #
750
+ # adds three methods - one to return the text within the unordered
751
+ # list, one to retrieve the unordered list element, and another to
752
+ # check it's existence.
753
+ #
754
+ # @example
755
+ # unordered_list(:menu, :id => 'main_menu')
756
+ # # will generate 'menu', 'menu_element' and 'menu?' methods
757
+ #
758
+ # @param [Symbol] the name used for the generated methods
759
+ # @param [Hash] identifier how we find an unordered list. You can use a multiple parameters
760
+ # by combining of any of the following except xpath. The valid keys are:
761
+ # * :class => Watir and Selenium
762
+ # * :css => Selenium only
763
+ # * :id => Watir and Selenium
764
+ # * :index => Watir and Selenium
765
+ # * :name => Watir and Selenium
766
+ # * :xpath => Watir and Selenium
767
+ # @param optional block to be invoked when element method is called
768
+ #
769
+ def unordered_list(name, identifier={:index => 0}, &block)
770
+ standard_methods(name, identifier, 'unordered_list_for', &block)
771
+ define_method(name) do
772
+ return platform.unordered_list_text_for identifier.clone unless block_given?
773
+ self.send("#{name}_element").text
774
+ end
775
+ end
776
+ alias_method :ul, :unordered_list
777
+
778
+ #
779
+ # adds three methods - one to return the text within the ordered
780
+ # list, one to retrieve the ordered list element, and another to
781
+ # test it's existence.
782
+ #
783
+ # @example
784
+ # ordered_list(:top_five, :id => 'top')
785
+ # # will generate 'top_five', 'top_five_element' and 'top_five?' methods
786
+ #
787
+ # @param [Symbol] the name used for the generated methods
788
+ # @param [Hash] identifier how we find an ordered list. You can use a multiple parameters
789
+ # by combining of any of the following except xpath. The valid keys are:
790
+ # * :class => Watir and Selenium
791
+ # * :css => Selenium only
792
+ # * :id => Watir and Selenium
793
+ # * :index => Watir and Selenium
794
+ # * :name => Watir and Selenium
795
+ # * :xpath => Watir and Selenium
796
+ # @param optional block to be invoked when element method is called
797
+ #
798
+ def ordered_list(name, identifier={:index => 0}, &block)
799
+ standard_methods(name, identifier, 'ordered_list_for', &block)
800
+ define_method(name) do
801
+ return platform.ordered_list_text_for identifier.clone unless block_given?
802
+ self.send("#{name}_element").text
803
+ end
804
+ end
805
+ alias_method :ol, :ordered_list
806
+
807
+ #
808
+ # adds three methods - one to retrieve the text of a h1 element, another to
809
+ # retrieve a h1 element, and another to check for it's existence.
810
+ #
811
+ # @example
812
+ # h1(:title, :id => 'title')
813
+ # # will generate 'title', 'title_element', and 'title?' methods
814
+ #
815
+ # @param [Symbol] the name used for the generated methods
816
+ # @param [Hash] identifier how we find a H1. You can use a multiple parameters
817
+ # by combining of any of the following except xpath. The valid keys are:
818
+ # * :class => Watir and Selenium
819
+ # * :css => Watir and Selenium
820
+ # * :id => Watir and Selenium
821
+ # * :index => Watir and Selenium
822
+ # * :name => Watir and Selenium
823
+ # * :xpath => Watir and Selenium
824
+ # @param optional block to be invoked when element method is called
825
+ #
826
+ def h1(name, identifier={:index => 0}, &block)
827
+ standard_methods(name, identifier,'h1_for', &block)
828
+ define_method(name) do
829
+ return platform.h1_text_for identifier.clone unless block_given?
830
+ self.send("#{name}_element").text
831
+ end
832
+ end
833
+
834
+ #
835
+ # adds three methods - one to retrieve the text of a h2 element, another
836
+ # to retrieve a h2 element, and another to check for it's existence.
837
+ #
838
+ # @example
839
+ # h2(:title, :id => 'title')
840
+ # # will generate 'title', 'title_element', and 'title?' methods
841
+ #
842
+ # @param [Symbol] the name used for the generated methods
843
+ # @param [Hash] identifier how we find a H2. You can use a multiple parameters
844
+ # by combining of any of the following except xpath. The valid keys are:
845
+ # * :class => Watir and Selenium
846
+ # * :css => Watir and Selenium
847
+ # * :id => Watir and Selenium
848
+ # * :index => Watir and Selenium
849
+ # * :name => Watir and Selenium
850
+ # * :xpath => Watir and Selenium
851
+ # @param optional block to be invoked when element method is called
852
+ #
853
+ def h2(name, identifier={:index => 0}, &block)
854
+ standard_methods(name, identifier, 'h2_for', &block)
855
+ define_method(name) do
856
+ return platform.h2_text_for identifier.clone unless block_given?
857
+ self.send("#{name}_element").text
858
+ end
859
+ end
860
+
861
+ #
862
+ # adds three methods - one to retrieve the text of a h3 element,
863
+ # another to return a h3 element, and another to check for it's existence.
864
+ #
865
+ # @example
866
+ # h3(:title, :id => 'title')
867
+ # # will generate 'title', 'title_element', and 'title?' methods
868
+ #
869
+ # @param [Symbol] the name used for the generated methods
870
+ # @param [Hash] identifier how we find a H3. You can use a multiple parameters
871
+ # by combining of any of the following except xpath. The valid keys are:
872
+ # * :class => Watir and Selenium
873
+ # * :css => Watir and Selenium
874
+ # * :id => Watir and Selenium
875
+ # * :index => Watir and Selenium
876
+ # * :name => Watir and Selenium
877
+ # * :xpath => Watir and Selenium
878
+ # @param optional block to be invoked when element method is called
879
+ #
880
+ def h3(name, identifier={:index => 0}, &block)
881
+ standard_methods(name, identifier, 'h3_for', &block)
882
+ define_method(name) do
883
+ return platform.h3_text_for identifier.clone unless block_given?
884
+ self.send("#{name}_element").text
885
+ end
886
+ end
887
+
888
+ #
889
+ # adds three methods - one to retrieve the text of a h4 element,
890
+ # another to return a h4 element, and another to check for it's existence.
891
+ #
892
+ # @example
893
+ # h4(:title, :id => 'title')
894
+ # # will generate 'title', 'title_element', and 'title?' methods
895
+ #
896
+ # @param [Symbol] the name used for the generated methods
897
+ # @param [Hash] identifier how we find a H4. You can use a multiple parameters
898
+ # by combining of any of the following except xpath. The valid keys are:
899
+ # * :class => Watir and Selenium
900
+ # * :css => Watir and Selenium
901
+ # * :id => Watir and Selenium
902
+ # * :index => Watir and Selenium
903
+ # * :name => Watir and Selenium
904
+ # * :xpath => Watir and Selenium
905
+ # @param optional block to be invoked when element method is called
906
+ #
907
+ def h4(name, identifier={:index => 0}, &block)
908
+ standard_methods(name, identifier, 'h4_for', &block)
909
+ define_method(name) do
910
+ return platform.h4_text_for identifier.clone unless block_given?
911
+ self.send("#{name}_element").text
912
+ end
913
+ end
914
+
915
+ #
916
+ # adds three methods - one to retrieve the text of a h5 element,
917
+ # another to return a h5 element, and another to check for it's existence.
918
+ #
919
+ # @example
920
+ # h5(:title, :id => 'title')
921
+ # # will generate 'title', 'title_element', and 'title?' methods
922
+ #
923
+ # @param [Symbol] the name used for the generated methods
924
+ # @param [Hash] identifier how we find a H5. You can use a multiple parameters
925
+ # by combining of any of the following except xpath. The valid keys are:
926
+ # * :class => Watir and Selenium
927
+ # * :css => Watir and Selenium
928
+ # * :id => Watir and Selenium
929
+ # * :index => Watir and Selenium
930
+ # * :name => Watir and Selenium
931
+ # * :xpath => Watir and Selenium
932
+ # @param optional block to be invoked when element method is called
933
+ #
934
+ def h5(name, identifier={:index => 0}, &block)
935
+ standard_methods(name, identifier, 'h5_for', &block)
936
+ define_method(name) do
937
+ return platform.h5_text_for identifier.clone unless block_given?
938
+ self.send("#{name}_element").text
939
+ end
940
+ end
941
+
942
+ #
943
+ # adds three methods - one to retrieve the text of a h6 element,
944
+ # another to return a h6 element, and another to check for it's existence.
945
+ #
946
+ # @example
947
+ # h6(:title, :id => 'title')
948
+ # # will generate 'title', 'title_element', and 'title?' methods
949
+ #
950
+ # @param [Symbol] the name used for the generated methods
951
+ # @param [Hash] identifier how we find a H6. You can use a multiple parameters
952
+ # by combining of any of the following except xpath. The valid keys are:
953
+ # * :class => Watir and Selenium
954
+ # * :css => Watir and Selenium
955
+ # * :id => Watir and Selenium
956
+ # * :index => Watir and Selenium
957
+ # * :name => Watir and Selenium
958
+ # * :xpath => Watir and Selenium
959
+ # @param optional block to be invoked when element method is called
960
+ #
961
+ def h6(name, identifier={:index => 0}, &block)
962
+ standard_methods(name, identifier, 'h6_for', &block)
963
+ define_method(name) do
964
+ return platform.h6_text_for identifier.clone unless block_given?
965
+ self.send("#{name}_element").text
966
+ end
967
+ end
968
+
969
+ #
970
+ # adds three methods - one to retrieve the text of a paragraph, another
971
+ # to retrieve a paragraph element, and another to check the paragraph's existence.
972
+ #
973
+ # @example
974
+ # paragraph(:title, :id => 'title')
975
+ # # will generate 'title', 'title_element', and 'title?' methods
976
+ #
977
+ # @param [Symbol] the name used for the generated methods
978
+ # @param [Hash] identifier how we find a paragraph. You can use a multiple parameters
979
+ # by combining of any of the following except xpath. The valid keys are:
980
+ # * :class => Watir and Selenium
981
+ # * :css => Watir and Selenium
982
+ # * :id => Watir and Selenium
983
+ # * :index => Watir and Selenium
984
+ # * :name => Watir and Selenium
985
+ # * :xpath => Watir and Selenium
986
+ # @param optional block to be invoked when element method is called
987
+ #
988
+ def paragraph(name, identifier={:index => 0}, &block)
989
+ standard_methods(name, identifier, 'paragraph_for', &block)
990
+ define_method(name) do
991
+ return platform.paragraph_text_for identifier.clone unless block_given?
992
+ self.send("#{name}_element").text
993
+ end
994
+ end
995
+ alias_method :p, :paragraph
996
+
997
+ #
998
+ # adds three methods - one to set the file for a file field, another to retrieve
999
+ # the file field element, and another to check it's existence.
1000
+ #
1001
+ # @example
1002
+ # file_field(:the_file, :id => 'file_to_upload')
1003
+ # # will generate 'the_file=', 'the_file_element', and 'the_file?' methods
1004
+ #
1005
+ # @param [Symbol] the name used for the generated methods
1006
+ # @param [Hash] identifier how we find a file_field. You can use a multiple parameters
1007
+ # by combining of any of the following except xpath. The valid keys are:
1008
+ # * :class => Watir and Selenium
1009
+ # * :css => Selenium only
1010
+ # * :id => Watir and Selenium
1011
+ # * :index => Watir and Selenium
1012
+ # * :name => Watir and Selenium
1013
+ # * :title => Watir and Selenium
1014
+ # * :xpath => Watir and Selenium
1015
+ # * :label => Watir and Selenium
1016
+ # @param optional block to be invoked when element method is called
1017
+ #
1018
+ def file_field(name, identifier={:index => 0}, &block)
1019
+ standard_methods(name, identifier, 'file_field_for', &block)
1020
+ define_method("#{name}=") do |value|
1021
+ return platform.file_field_value_set(identifier.clone, value) unless block_given?
1022
+ self.send("#{name}_element").value = value
1023
+ end
1024
+ end
1025
+
1026
+ #
1027
+ # adds three methods - one to retrieve the text from a label,
1028
+ # another to return the label element, and another to check the label's existence.
1029
+ #
1030
+ # @example
1031
+ # label(:message, :id => 'message')
1032
+ # # will generate 'message', 'message_element', and 'message?' methods
1033
+ #
1034
+ # @param [Symbol] the name used for the generated methods
1035
+ # @param [Hash] identifier how we find a label. You can use a multiple parameters
1036
+ # by combining of any of the following except xpath. The valid keys are:
1037
+ # * :class => Watir and Selenium
1038
+ # * :css => Watir and Selenium
1039
+ # * :id => Watir and Selenium
1040
+ # * :index => Watir and Selenium
1041
+ # * :name => Watir and Selenium
1042
+ # * :text => Watir and Selenium
1043
+ # * :xpath => Watir and Selenium
1044
+ # @param optional block to be invoked when element method is called
1045
+ #
1046
+ def label(name, identifier={:index => 0}, &block)
1047
+ standard_methods(name, identifier, 'label_for', &block)
1048
+ define_method(name) do
1049
+ return platform.label_text_for identifier.clone unless block_given?
1050
+ self.send("#{name}_element").text
1051
+ end
1052
+ end
1053
+
1054
+ #
1055
+ # adds three methods - one to click the area,
1056
+ # another to return the area element, and another to check the area's existence.
1057
+ #
1058
+ # @example
1059
+ # area(:message, :id => 'message')
1060
+ # # will generate 'message', 'message_element', and 'message?' methods
1061
+ #
1062
+ # @param [Symbol] the name used for the generated methods
1063
+ # @param [Hash] identifier how we find an area. You can use a multiple parameters
1064
+ # by combining of any of the following except xpath. The valid keys are:
1065
+ # * :class => Watir and Selenium
1066
+ # * :css => Watir and Selenium
1067
+ # * :id => Watir and Selenium
1068
+ # * :index => Watir and Selenium
1069
+ # * :name => Watir and Selenium
1070
+ # * :text => Watir and Selenium
1071
+ # * :xpath => Watir and Selenium
1072
+ # @param optional block to be invoked when element method is called
1073
+ #
1074
+ def area(name, identifier={:index => 0}, &block)
1075
+ standard_methods(name, identifier, 'area_for', &block)
1076
+ define_method(name) do
1077
+ return platform.click_area_for identifier.clone unless block_given?
1078
+ self.send("#{name}_element").click
1079
+ end
1080
+ end
1081
+
1082
+ #
1083
+ # adds two methods - one to return the canvas element and another to check
1084
+ # the canvas's existence.
1085
+ #
1086
+ # @example
1087
+ # canvas(:my_canvas, :id => 'canvas_id')
1088
+ # # will generate 'my_canvas_element' and 'my_canvas?' methods
1089
+ #
1090
+ # @param [Symbol] the name used for the generated methods
1091
+ # @param [Hash] identifier how we find a canvas. You can use a multiple parameters
1092
+ # by combining of any of the following except xpath. The valid keys are:
1093
+ # * :class => Watir and Selenium
1094
+ # * :css => Watir and Selenium
1095
+ # * :id => Watir and Selenium
1096
+ # * :index => Watir and Selenium
1097
+ # * :name => Watir and Selenium
1098
+ # * :xpath => Watir and Selenium
1099
+ # @param optional block to be invoked when element method is called
1100
+ #
1101
+ def canvas(name, identifier={:index => 0}, &block)
1102
+ standard_methods(name, identifier, 'canvas_for', &block)
1103
+ end
1104
+
1105
+ #
1106
+ # adds two methods - one to return the audio element and another to check
1107
+ # the audio's existence.
1108
+ #
1109
+ # @example
1110
+ # audio(:acdc, :id => 'audio_id')
1111
+ # # will generate 'acdc_element' and 'acdc?' methods
1112
+ #
1113
+ # @param [Symbol] the name used for the generated methods
1114
+ # @param [Hash] identifier how we find an audio element. You can use a multiple parameters
1115
+ # by combining of any of the following except xpath. The valid keys are:
1116
+ # * :class => Watir and Selenium
1117
+ # * :css => Watir and Selenium
1118
+ # * :id => Watir and Selenium
1119
+ # * :index => Watir and Selenium
1120
+ # * :name => Watir and Selenium
1121
+ # * :xpath => Watir and Selenium
1122
+ # @param optional block to be invoked when element method is called
1123
+ #
1124
+ def audio(name, identifier={:index => 0}, &block)
1125
+ standard_methods(name, identifier, 'audio_for', &block)
1126
+ end
1127
+
1128
+ #
1129
+ # adds two methods - one to return the video element and another to check
1130
+ # the video's existence.
1131
+ #
1132
+ # @example
1133
+ # video(:movie, :id => 'video_id')
1134
+ # # will generate 'movie_element' and 'movie?' methods
1135
+ #
1136
+ # @param [Symbol] the name used for the generated methods
1137
+ # @param [Hash] identifier how we find a video element. You can use a multiple parameters
1138
+ # by combining of any of the following except xpath. The valid keys are:
1139
+ # * :class => Watir and Selenium
1140
+ # * :css => Watir and Selenium
1141
+ # * :id => Watir and Selenium
1142
+ # * :index => Watir and Selenium
1143
+ # * :name => Watir and Selenium
1144
+ # * :xpath => Watir and Selenium
1145
+ # @param optional block to be invoked when element method is called
1146
+ #
1147
+ def video(name, identifier={:index => 0}, &block)
1148
+ standard_methods(name, identifier, 'video_for', &block)
1149
+ end
1150
+
1151
+ #
1152
+ # adds three methods - one to retrieve the text of a b element, another to
1153
+ # retrieve a b element, and another to check for it's existence.
1154
+ #
1155
+ # @example
1156
+ # b(:bold, :id => 'title')
1157
+ # # will generate 'bold', 'bold_element', and 'bold?' methods
1158
+ #
1159
+ # @param [Symbol] the name used for the generated methods
1160
+ # @param [Hash] identifier how we find a b. You can use a multiple parameters
1161
+ # by combining of any of the following except xpath. The valid keys are:
1162
+ # * :class => Watir and Selenium
1163
+ # * :css => Watir and Selenium
1164
+ # * :id => Watir and Selenium
1165
+ # * :index => Watir and Selenium
1166
+ # * :name => Watir and Selenium
1167
+ # * :xpath => Watir and Selenium
1168
+ # @param optional block to be invoked when element method is called
1169
+ #
1170
+ def b(name, identifier={:index => 0}, &block)
1171
+ standard_methods(name, identifier,'b_for', &block)
1172
+ define_method(name) do
1173
+ return platform.b_text_for identifier.clone unless block_given?
1174
+ self.send("#{name}_element").text
1175
+ end
1176
+ end
1177
+
1178
+ #
1179
+ # adds two methods - one to retrieve a svg, and another to check
1180
+ # the svg's existence.
1181
+ #
1182
+ # @example
1183
+ # svg(:circle, :id => 'circle')
1184
+ # # will generate 'circle_element', and 'circle?' methods
1185
+ #
1186
+ # @param [Symbol] the name used for the generated methods
1187
+ # @param [Hash] identifier how we find a svg. You can use a multiple parameters
1188
+ # by combining of any of the following except xpath. The valid keys are:
1189
+ # * :class => Watir and Selenium
1190
+ # * :css => Selenium only
1191
+ # * :id => Watir and Selenium
1192
+ # * :index => Watir and Selenium
1193
+ # * :name => Watir and Selenium
1194
+ # * :xpath => Watir and Selenium
1195
+ # @param optional block to be invoked when element method is called
1196
+ #
1197
+ def svg(name, identifier={:index => 0}, &block)
1198
+ standard_methods(name, identifier, 'svg_for', &block)
1199
+ end
1200
+
1201
+
1202
+ #
1203
+ # adds three methods - one to retrieve the text of an element, another
1204
+ # to retrieve an element, and another to check the element's existence.
1205
+ #
1206
+ # @example
1207
+ # element(:title, :header, :id => 'title')
1208
+ # # will generate 'title', 'title_element', and 'title?' methods
1209
+ #
1210
+ # @param [Symbol] the name used for the generated methods
1211
+ # @param [Symbol] the name of the tag for the element
1212
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1213
+ # by combining of any of the following except xpath. The valid keys are:
1214
+ # * :class => Watir and Selenium
1215
+ # * :css => Selenium only
1216
+ # * :id => Watir and Selenium
1217
+ # * :index => Watir and Selenium
1218
+ # * :name => Watir and Selenium
1219
+ # * :xpath => Watir and Selenium
1220
+ # @param optional block to be invoked when element method is called
1221
+ #
1222
+ def element(name, tag, identifier={:index => 0}, &block)
1223
+ define_method("#{name}") do
1224
+ self.send("#{name}_element").text
1225
+ end
1226
+ define_method("#{name}_element") do
1227
+ return call_block(&block) if block_given?
1228
+ platform.element_for(tag, identifier.clone)
1229
+ end
1230
+ define_method("#{name}?") do
1231
+ self.send("#{name}_element").exists?
1232
+ end
1233
+ end
1234
+
1235
+ #
1236
+ # adds a method to return a collection of generic Element objects
1237
+ # for a specific tag.
1238
+ #
1239
+ # @example
1240
+ # elements(:title, :header, :id => 'title')
1241
+ # # will generate ''title_elements'
1242
+ #
1243
+ # @param [Symbol] the name used for the generated methods
1244
+ # @param [Symbol] the name of the tag for the element
1245
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1246
+ # by combining of any of the following except xpath. The valid keys are:
1247
+ # * :class => Watir and Selenium
1248
+ # * :css => Selenium only
1249
+ # * :id => Watir and Selenium
1250
+ # * :index => Watir and Selenium
1251
+ # * :name => Watir and Selenium
1252
+ # * :xpath => Watir and Selenium
1253
+ # @param optional block to be invoked when element method is called
1254
+ #
1255
+ def elements(name, tag, identifier={:index => 0}, &block)
1256
+ define_method("#{name}_elements") do
1257
+ return call_block(&block) if block_given?
1258
+ platform.elements_for(tag, identifier.clone)
1259
+ end
1260
+ end
1261
+
1262
+ #
1263
+ # adds a method to return a page object rooted at an element
1264
+ #
1265
+ # @example
1266
+ # page_section(:navigation_bar, NavigationBar, :id => 'nav-bar')
1267
+ # # will generate 'navigation_bar' and 'navigation_bar?'
1268
+ #
1269
+ # @param [Symbol] the name used for the generated methods
1270
+ # @param [Class] the class to instantiate for the element
1271
+ # @param [Hash] identifier how we find an element. You can use multiple parameters
1272
+ # by combining of any of the following except xpath. The valid keys are:
1273
+ # * :class => Watir and Selenium
1274
+ # * :css => Selenium only
1275
+ # * :id => Watir and Selenium
1276
+ # * :index => Watir and Selenium
1277
+ # * :name => Watir and Selenium
1278
+ # * :xpath => Watir and Selenium
1279
+ #
1280
+ def page_section(name, section_class, identifier)
1281
+ define_method(name) do
1282
+ platform.page_for(identifier, section_class)
1283
+ end
1284
+ end
1285
+
1286
+ #
1287
+ # adds a method to return a collection of page objects rooted at elements
1288
+ #
1289
+ # @example
1290
+ # page_sections(:articles, Article, :class => 'article')
1291
+ # # will generate 'articles'
1292
+ #
1293
+ # @param [Symbol] the name used for the generated method
1294
+ # @param [Class] the class to instantiate for each element
1295
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1296
+ # by combining of any of the following except xpath. The valid keys are:
1297
+ # * :class => Watir and Selenium
1298
+ # * :css => Selenium only
1299
+ # * :id => Watir and Selenium
1300
+ # * :index => Watir and Selenium
1301
+ # * :name => Watir and Selenium
1302
+ # * :xpath => Watir and Selenium
1303
+ #
1304
+ def page_sections(name, section_class, identifier)
1305
+ define_method(name) do
1306
+ platform.pages_for(identifier, section_class)
1307
+ end
1308
+ end
1309
+
1310
+ #
1311
+ # methods to generate accessors for types that follow the same
1312
+ # pattern as element
1313
+ #
1314
+ # @example
1315
+ # article(:my_article, :id => "article_id")
1316
+ # will generate 'my_article', 'my_article_element' and 'my_article?'
1317
+ # articles(:my_article, :id => 'article_id')
1318
+ # will generate 'my_article_elements'
1319
+ #
1320
+ # @param [Symbol] the name used for the generated methods
1321
+ # @param [Symbol] the name of the tag for the element
1322
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1323
+ # by combining of any of the following except xpath. The valid keys are:
1324
+ # * :class => Watir and Selenium
1325
+ # * :css => Selenium only
1326
+ # * :id => Watir and Selenium
1327
+ # * :index => Watir and Selenium
1328
+ # * :name => Watir and Selenium
1329
+ # * :xpath => Watir and Selenium
1330
+ # @param optional block to be invoked when element method is called
1331
+ #
1332
+ LocatorGenerator::BASIC_ELEMENTS.each do |tag|
1333
+ define_method(tag) do |name, *identifier, &block|
1334
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1335
+ element(name, tag, identifier, &block)
1336
+ end
1337
+ define_method("#{tag}s") do |name, *identifier, &block|
1338
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1339
+ elements(name, tag, identifier, &block)
1340
+ end unless tag == :param
1341
+ end
1342
+
1343
+ def standard_methods(name, identifier, method, &block)
1344
+ define_method("#{name}_element") do
1345
+ return call_block(&block) if block_given?
1346
+ platform.send(method, identifier.clone)
1347
+ end
1348
+ define_method("#{name}?") do
1349
+ return call_block(&block).exists? if block_given?
1350
+ platform.send(method, identifier.clone).exists?
1351
+ end
1352
+ end
1353
+
1354
+ #
1355
+ # adds a method that will return an indexed property. The property will respond to
1356
+ # the [] method with an object that has a set of normal page_object properties that
1357
+ # correspond to the definitions included in the identifier_list parameter, with the
1358
+ # "what" of the "how and what" substituted based on the index provided to the []
1359
+ # method.
1360
+ #
1361
+ # @example
1362
+ # indexed_property(:title, [
1363
+ # [:text_field, :field_1, :id => 'table[%s].field_1'],
1364
+ # [:button, :button_1, :id => 'table[%s].button_1'],
1365
+ # [:text_field, :field_2, :name => 'table[%s].field_2']
1366
+ # ])
1367
+ # # will generate a title method that responds to []. title['foo'] will return an object
1368
+ # # that responds to the normal methods expected for two text_fields and a button with the
1369
+ # # given names, using the given how and what with 'foo' substituted for the %s. title[123]
1370
+ # # will do the same, using the integer 123 instead.
1371
+ #
1372
+ # @param [Symbol] the name used for the generated method
1373
+ # @param [Array] definitions an array of definitions to define on the indexed property. Each
1374
+ # entry in the array should contain two symbols and a hash, corresponding to one of the standard
1375
+ # page_object properties with a single substitution marker in each value in the hash,
1376
+ # e.g. [:text_field, :field_1, :id => 'table[%s].field_1']
1377
+ #
1378
+ def indexed_property (name, identifier_list)
1379
+ define_method("#{name}") do
1380
+ IndexedProperties::TableOfElements.new(@browser, identifier_list)
1381
+ end
1382
+ end
1383
+
1384
+ #
1385
+ # methods to fetch multiple elements of the same type
1386
+ #
1387
+ # adds a method to the page object to return all of the matching elements
1388
+ #
1389
+ # @example
1390
+ # text_fields(:first_name, :id => "first_name")
1391
+ # # will generate 'first_name_elements'
1392
+ #
1393
+ # @param [String] the name used for the generated methods
1394
+ # @param [Hash] identifier how we find a text field. You can use a multiple parameters
1395
+ # by combining of any of the following except xpath. The valid
1396
+ # keys are the same ones supported by the standard methods.
1397
+ # @param optional block to be invoked when element method is called
1398
+ #
1399
+ idx = LocatorGenerator::ADVANCED_ELEMENTS.find_index { |type| type == :checkbox }
1400
+ elements = LocatorGenerator::ADVANCED_ELEMENTS.clone
1401
+ elements[idx] = :checkboxe
1402
+ elements.each do |method_name|
1403
+ define_method("#{method_name}s") do |name, *identifier, &block|
1404
+ define_method("#{name}_elements") do
1405
+ return call_block(&block) unless block.nil?
1406
+ platform_method = (method_name == :checkboxe) ? 'checkboxs_for' : "#{method_name.to_s}s_for"
1407
+ platform.send platform_method, (identifier.first ? identifier.first.clone : {})
1408
+ end
1409
+ end
1410
+ end
1411
+ end
1412
+ end