page_object 1.1.1

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