druid-s 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +27 -0
  6. data/ChangeLog +541 -0
  7. data/Gemfile +8 -0
  8. data/README.md +78 -0
  9. data/Rakefile +33 -0
  10. data/cucumber.yml +6 -0
  11. data/druid.gemspec +30 -0
  12. data/features/area.feature +33 -0
  13. data/features/async.feature +16 -0
  14. data/features/audio.feature +61 -0
  15. data/features/bold.feature +20 -0
  16. data/features/button.feature +81 -0
  17. data/features/canvas.feature +34 -0
  18. data/features/checkbox.feature +48 -0
  19. data/features/div.feature +45 -0
  20. data/features/element.feature +281 -0
  21. data/features/file_field.feature +38 -0
  22. data/features/form.feature +37 -0
  23. data/features/frames.feature +76 -0
  24. data/features/generic_elements.feature +29 -0
  25. data/features/heading.feature +160 -0
  26. data/features/hidden_field.feature +39 -0
  27. data/features/html/async.html +31 -0
  28. data/features/html/frame_1.html +18 -0
  29. data/features/html/frame_2.html +16 -0
  30. data/features/html/frame_3.html +14 -0
  31. data/features/html/frames.html +12 -0
  32. data/features/html/hover.html +11 -0
  33. data/features/html/iframes.html +12 -0
  34. data/features/html/images/circle.png +0 -0
  35. data/features/html/images/img_pulpit.jpg +0 -0
  36. data/features/html/modal.html +17 -0
  37. data/features/html/modal_1.html +38 -0
  38. data/features/html/modal_2.html +27 -0
  39. data/features/html/multi_elements.html +145 -0
  40. data/features/html/nested_elements.html +75 -0
  41. data/features/html/nested_frame_1.html +1 -0
  42. data/features/html/nested_frame_2.html +11 -0
  43. data/features/html/nested_frame_3.html +14 -0
  44. data/features/html/nested_frames.html +10 -0
  45. data/features/html/planets.gif +0 -0
  46. data/features/html/static_elements.html +203 -0
  47. data/features/html/success.html +8 -0
  48. data/features/html/sun.gif +0 -0
  49. data/features/html/sun.html +7 -0
  50. data/features/image.feature +47 -0
  51. data/features/italic.feature +20 -0
  52. data/features/javascript.feature +28 -0
  53. data/features/label.feature +43 -0
  54. data/features/link.feature +56 -0
  55. data/features/list_item.feature +37 -0
  56. data/features/modal_dialog.feature +9 -0
  57. data/features/multi_elements.feature +498 -0
  58. data/features/nested_elements.feature +121 -0
  59. data/features/ordered_list.feature +46 -0
  60. data/features/page_level_actions.feature +116 -0
  61. data/features/paragraph.feature +33 -0
  62. data/features/populate_page_with.feature +25 -0
  63. data/features/radio_button.feature +51 -0
  64. data/features/radio_button_group.feature +28 -0
  65. data/features/sample-app/public/04-Death_Becomes_Fur.mp4 +0 -0
  66. data/features/sample-app/public/04-Death_Becomes_Fur.oga +0 -0
  67. data/features/sample-app/public/audio_video.html +19 -0
  68. data/features/sample-app/public/jquery-1.3.2.js +4376 -0
  69. data/features/sample-app/public/jquery.html +28 -0
  70. data/features/sample-app/public/movie.mp4 +0 -0
  71. data/features/sample-app/public/movie.ogg +0 -0
  72. data/features/sample-app/public/prototype-1.6.0.3.js +4320 -0
  73. data/features/sample-app/public/prototype.html +32 -0
  74. data/features/sample-app/sample_app.rb +35 -0
  75. data/features/section.feature +132 -0
  76. data/features/select_list.feature +84 -0
  77. data/features/span.feature +43 -0
  78. data/features/step_definations/area_steps.rb +23 -0
  79. data/features/step_definations/async_steps.rb +80 -0
  80. data/features/step_definations/audio_steps.rb +47 -0
  81. data/features/step_definations/bold_steps.rb +11 -0
  82. data/features/step_definations/button_steps.rb +52 -0
  83. data/features/step_definations/canvas_steps.rb +19 -0
  84. data/features/step_definations/checkbox_steps.rb +39 -0
  85. data/features/step_definations/div_steps.rb +28 -0
  86. data/features/step_definations/element_steps.rb +217 -0
  87. data/features/step_definations/file_field_steps.rb +31 -0
  88. data/features/step_definations/form_steps.rb +23 -0
  89. data/features/step_definations/frame_steps.rb +189 -0
  90. data/features/step_definations/generic_element_steps.rb +31 -0
  91. data/features/step_definations/heading_steps.rb +39 -0
  92. data/features/step_definations/hidden_field_steps.rb +27 -0
  93. data/features/step_definations/image_steps.rb +35 -0
  94. data/features/step_definations/italic_steps.rb +11 -0
  95. data/features/step_definations/javasript_steps.rb +52 -0
  96. data/features/step_definations/label_steps.rb +19 -0
  97. data/features/step_definations/link_steps.rb +42 -0
  98. data/features/step_definations/list_item_steps.rb +24 -0
  99. data/features/step_definations/modal_dialog_steps.rb +38 -0
  100. data/features/step_definations/multi_elements_steps.rb +557 -0
  101. data/features/step_definations/nested_elements_steps.rb +219 -0
  102. data/features/step_definations/ordered_list_steps.rb +49 -0
  103. data/features/step_definations/page_level_actions_steps.rb +172 -0
  104. data/features/step_definations/page_traversal_steps.rb +4 -0
  105. data/features/step_definations/paragraph_steps.rb +19 -0
  106. data/features/step_definations/populate_page_with_steps.rb +3 -0
  107. data/features/step_definations/radio_button_group_steps.rb +32 -0
  108. data/features/step_definations/radio_button_steps.rb +31 -0
  109. data/features/step_definations/section_steps.rb +271 -0
  110. data/features/step_definations/select_list_steps.rb +91 -0
  111. data/features/step_definations/span_steps.rb +23 -0
  112. data/features/step_definations/table_cell_steps.rb +27 -0
  113. data/features/step_definations/table_row_steps.rb +23 -0
  114. data/features/step_definations/table_steps.rb +109 -0
  115. data/features/step_definations/text_area_steps.rb +39 -0
  116. data/features/step_definations/text_field_steps.rb +39 -0
  117. data/features/step_definations/unordered_list_steps.rb +27 -0
  118. data/features/step_definations/video_steps.rb +27 -0
  119. data/features/support/ajax_test_environment.rb +26 -0
  120. data/features/support/audio_video_page.rb +23 -0
  121. data/features/support/env.rb +5 -0
  122. data/features/support/hooks.rb +3 -0
  123. data/features/support/page.rb +372 -0
  124. data/features/support/persistent_browser.rb +58 -0
  125. data/features/support/targets/firefox14_osx.rb +5 -0
  126. data/features/support/targets/firefox14_windows7.rb +5 -0
  127. data/features/support/url_helper.rb +50 -0
  128. data/features/table.feature +127 -0
  129. data/features/table_cell.feature +42 -0
  130. data/features/table_row.feature +30 -0
  131. data/features/text_area.feature +44 -0
  132. data/features/text_field.feature +53 -0
  133. data/features/unordered_list.feature +46 -0
  134. data/features/video.feature +66 -0
  135. data/lib/druid/accessors.rb +1082 -0
  136. data/lib/druid/assist.rb +653 -0
  137. data/lib/druid/element_locators.rb +21 -0
  138. data/lib/druid/elements/area.rb +9 -0
  139. data/lib/druid/elements/audio.rb +9 -0
  140. data/lib/druid/elements/bold.rb +8 -0
  141. data/lib/druid/elements/button.rb +12 -0
  142. data/lib/druid/elements/canvas.rb +9 -0
  143. data/lib/druid/elements/check_box.rb +9 -0
  144. data/lib/druid/elements/div.rb +9 -0
  145. data/lib/druid/elements/element.rb +187 -0
  146. data/lib/druid/elements/file_field.rb +9 -0
  147. data/lib/druid/elements/form.rb +9 -0
  148. data/lib/druid/elements/heading.rb +14 -0
  149. data/lib/druid/elements/hidden_field.rb +9 -0
  150. data/lib/druid/elements/image.rb +9 -0
  151. data/lib/druid/elements/italic.rb +9 -0
  152. data/lib/druid/elements/label.rb +8 -0
  153. data/lib/druid/elements/link.rb +9 -0
  154. data/lib/druid/elements/list_item.rb +9 -0
  155. data/lib/druid/elements/media.rb +11 -0
  156. data/lib/druid/elements/option.rb +9 -0
  157. data/lib/druid/elements/ordered_list.rb +29 -0
  158. data/lib/druid/elements/paragraph.rb +9 -0
  159. data/lib/druid/elements/radio_button.rb +9 -0
  160. data/lib/druid/elements/select_list.rb +30 -0
  161. data/lib/druid/elements/span.rb +9 -0
  162. data/lib/druid/elements/table.rb +92 -0
  163. data/lib/druid/elements/table_cell.rb +11 -0
  164. data/lib/druid/elements/table_row.rb +50 -0
  165. data/lib/druid/elements/text_area.rb +10 -0
  166. data/lib/druid/elements/text_field.rb +11 -0
  167. data/lib/druid/elements/unordered_list.rb +32 -0
  168. data/lib/druid/elements/video.rb +8 -0
  169. data/lib/druid/elements.rb +55 -0
  170. data/lib/druid/javascript/angularjs.rb +12 -0
  171. data/lib/druid/javascript/jquery.rb +12 -0
  172. data/lib/druid/javascript/prototype.rb +12 -0
  173. data/lib/druid/javascript/yui.rb +19 -0
  174. data/lib/druid/javascript_framework_facade.rb +76 -0
  175. data/lib/druid/locator_generator.rb +181 -0
  176. data/lib/druid/nested_elements.rb +56 -0
  177. data/lib/druid/page_factory.rb +115 -0
  178. data/lib/druid/page_populator.rb +104 -0
  179. data/lib/druid/section_collection.rb +17 -0
  180. data/lib/druid/version.rb +3 -0
  181. data/lib/druid.rb +452 -0
  182. data/spec/druid/accessors_spec.rb +1209 -0
  183. data/spec/druid/druid_spec.rb +295 -0
  184. data/spec/druid/element_locators_spec.rb +750 -0
  185. data/spec/druid/elements/bold_spec.rb +12 -0
  186. data/spec/druid/elements/button_spec.rb +23 -0
  187. data/spec/druid/elements/check_box_spec.rb +14 -0
  188. data/spec/druid/elements/div_spec.rb +10 -0
  189. data/spec/druid/elements/element_spec.rb +250 -0
  190. data/spec/druid/elements/file_field_spec.rb +13 -0
  191. data/spec/druid/elements/form_spec.rb +18 -0
  192. data/spec/druid/elements/heading_spec.rb +30 -0
  193. data/spec/druid/elements/hidden_field_spec.rb +10 -0
  194. data/spec/druid/elements/image_spec.rb +23 -0
  195. data/spec/druid/elements/itatic_spec.rb +11 -0
  196. data/spec/druid/elements/label_spec.rb +10 -0
  197. data/spec/druid/elements/link_spec.rb +10 -0
  198. data/spec/druid/elements/list_item_spec.rb +10 -0
  199. data/spec/druid/elements/media_spec.rb +12 -0
  200. data/spec/druid/elements/option_spec.rb +21 -0
  201. data/spec/druid/elements/ordered_list_spec.rb +38 -0
  202. data/spec/druid/elements/page_factory_spec.rb +40 -0
  203. data/spec/druid/elements/paragraph_spec.rb +12 -0
  204. data/spec/druid/elements/radio_button_spec.rb +14 -0
  205. data/spec/druid/elements/select_list_spec.rb +51 -0
  206. data/spec/druid/elements/span_spec.rb +10 -0
  207. data/spec/druid/elements/table_cell_spec.rb +14 -0
  208. data/spec/druid/elements/table_row_spec.rb +34 -0
  209. data/spec/druid/elements/table_spec.rb +47 -0
  210. data/spec/druid/elements/text_area_spec.rb +13 -0
  211. data/spec/druid/elements/text_field_spec.rb +22 -0
  212. data/spec/druid/elements/unordered_list_spec.rb +39 -0
  213. data/spec/druid/javascript_framework_facade_spec.rb +59 -0
  214. data/spec/druid/nested_element_spec.rb +128 -0
  215. data/spec/druid/page_factory_spec.rb +235 -0
  216. data/spec/druid/page_populator_spec.rb +173 -0
  217. data/spec/druid/page_section_spec.rb +70 -0
  218. data/spec/spec_helper.rb +9 -0
  219. metadata +517 -0
@@ -0,0 +1,1082 @@
1
+ require 'druid/elements'
2
+ require 'erb'
3
+ require 'druid/locator_generator'
4
+
5
+ module Druid
6
+ #
7
+ # Contains the class level methods that are inserted into your page class
8
+ # when you include the PageObject module. These methods will generate another
9
+ # set of methods that provide access to the elements on the web pages.
10
+ #
11
+ module Accessors
12
+
13
+ #
14
+ # Set some values that can be used withing the class. This is
15
+ # typically used to provided values that help build dynamic urls in
16
+ # the page_url method
17
+ #
18
+ # @param [Hash] the value to set the params
19
+ #
20
+ def params=(the_params)
21
+ @params = the_params
22
+ end
23
+
24
+ #
25
+ # Return the params that exist on this page class
26
+ #
27
+ def params
28
+ @params ||= {}
29
+ end
30
+
31
+ #
32
+ # Specify the url for the page. A call to this method will generate a
33
+ # 'goto' method to take you to the page.
34
+ #
35
+ # @param [String] the url for the page.
36
+ # @param [Symbol] a method name to call to get the url
37
+ #
38
+ def page_url(url)
39
+ define_method("goto") do
40
+ driver.goto self.page_url_value
41
+ end
42
+
43
+ define_method("page_url_value") do
44
+ lookup = url.kind_of?(Symbol) ? self.send(url) : url
45
+ erb = ERB.new(%Q{#{lookup}})
46
+ merged_params = self.class.instance_variable_get("@merged_params")
47
+ params = merged_params ? merged_params : self.class.params
48
+ erb.result(binding)
49
+ end
50
+ end
51
+ alias_method :direct_url, :page_url
52
+
53
+ #
54
+ # Creates a method that waits the expected_title of a page to match the actual.
55
+ # @param [String] expected_title the literal expected title for the page
56
+ # @param [Regexp] expected_title the expected title pattern for the page
57
+ # @param [optional, Integer] timeout default value is nil - do not wait
58
+ # @return [boolean]
59
+ # @raise An exception if expected_title does not match actual title
60
+ #
61
+ # @example Specify 'Google' as the expected title of a page
62
+ # wait_for_expected_title "Google"
63
+ # page.wait_for_expected_title?
64
+ #
65
+ def wait_for_expected_title(expected_title, timeout=Druid.default_element_wait)
66
+ define_method("wait_for_expected_title?") do
67
+ error_message = lambda { "Expected title '#{expected_title}' instead of '#{title}'" }
68
+ has_expected_title = (expected_title === title)
69
+ wait_until(timeout, error_message.call) do
70
+ has_expected_title = (expected_title === title)
71
+ end unless has_expected_title
72
+ raise error_message.call unless has_expected_title
73
+ has_expected_title
74
+ end
75
+ end
76
+
77
+ #
78
+ # Creates a method that compares the expected_title of a page against the actual.
79
+ # @param [String] expected_title the literal expected title for the page
80
+ # @param [Regexp] expected_title the expected title pattern for the page
81
+ # @return [Boolean]
82
+ # @raise An exception if expected_title does not match actual title
83
+ #
84
+ # @example Specify 'Google' as the expected title of a page
85
+ # expected_title "Google"
86
+ # page.has_expected_title?
87
+ #
88
+ def expected_title(expected_title)
89
+ define_method("has_expected_title?") do
90
+ page_title = title
91
+ has_expected_title = (expected_title === page_title)
92
+ raise "Expected title '#{expected_title}' instead of '#{page_title}'" unless has_expected_title
93
+ has_expected_title
94
+ end
95
+ end
96
+
97
+ #
98
+ # Creates a method that provides a way to initialize a page based upon an expected element
99
+ # This is useful for pages that load dynamic content
100
+ # @param [Symbol] the name given to the element in the declaration
101
+ # @param [optional, Interger] timeout default value is 5 seconds
102
+ # @return [boolean]
103
+ #
104
+ # @example Specify a text box named :address expected on the page within 10 seconds
105
+ # expected_element(:address, 10)
106
+ # page.has_expected_element?
107
+ #
108
+ def expected_element(element_name, timeout=Druid.default_element_wait)
109
+ define_method("has_expected_element?") do
110
+ self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_present timeout
111
+ end
112
+ end
113
+
114
+ def expected_element_visible(element_name, timeout=Druid.default_element_wait)
115
+ define_method("has_expected_element_visible?") do
116
+ self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_present timeout
117
+ self.respond_to? "#{element_name}_element" and self.send("#{element_name}_element").when_visible timeout
118
+ end
119
+
120
+ end
121
+
122
+ #
123
+ # Identify an element as existing within a frame or iframe. A frame parameter
124
+ # is passed to the block and must be passed to the other calls to Druid.
125
+ # You can nest calls to in_frame by passing the frame to the next level.
126
+ #
127
+ # @example
128
+ # in_frame(:id => 'frame_id') do |frame|
129
+ # text_field(:first_name, :id=> 'fname', :frame => frame)
130
+ # end
131
+ #
132
+ # @param [Hash] identifier how we find the frame. The valid keys are:
133
+ # * :id
134
+ # * :index
135
+ # * :name
136
+ # @param frame passed from a previous call to in_frame. Used to nest calls
137
+ # @param block that contains the calls to elements that exist inside the frame.
138
+ #
139
+ def in_frame(identifier, frame=nil, &block)
140
+ frame = frame.nil? ? [] : frame.dup
141
+ frame << {frame: identifier}
142
+ block.call(frame)
143
+ end
144
+ #
145
+ # Identify an element as existing within a frame or iframe. A frame parameter
146
+ # is passed to the block and must be passed to the other calls to Druid.
147
+ # You can nest calls to in_iframe by passing the frame to the next level.
148
+ #
149
+ # @example
150
+ # in_iframe(:id => 'frame_id') do |frame|
151
+ # text_field(:first_name, :id=> 'fname', :frame => frame)
152
+ # end
153
+ #
154
+ # @param [Hash] identifier how we find the frame. The valid keys are:
155
+ # * :id
156
+ # * :index
157
+ # * :name
158
+ # @param frame passed from a previous call to in_iframe. Used to nest calls
159
+ # @param block that contains the calls to elements that exist inside the frame.
160
+ #
161
+ def in_iframe(identifier, frame=nil, &block)
162
+ frame = frame.nil? ? [] : frame.dup
163
+ frame << {iframe: identifier}
164
+ block.call(frame)
165
+ end
166
+
167
+ #
168
+ # adds three methods - one to select a link, another
169
+ # to return a PageObject::Elements::Link object representing
170
+ # the link, and another that checks the link's existence.
171
+ #
172
+ # @example
173
+ # link(:add_to_cart, :text => "Add to Cart")
174
+ # # will generate 'add_to_cart', 'add_to_cart_element', and 'add_to_cart?' methods
175
+ #
176
+ # @param [Symbol] the name used for the generated methods
177
+ # @param [Hash] identifier how we find a link. You can use a multiple parameters
178
+ # by combining of any of the following except xpath. The valid values are:
179
+ # * :class
180
+ # * :href
181
+ # * :id
182
+ # * :index
183
+ # * :name
184
+ # * :text
185
+ # * :xpath
186
+ # * :link
187
+ # * :link_text
188
+ # * :css
189
+ # * :title
190
+ # @param optional block to be invoked when element method is called
191
+ #
192
+ def link(name, identifier={:index => 0}, &block)
193
+ standard_methods(name, identifier, 'link_for', &block)
194
+ define_method(name) do
195
+ return click_link_for identifier.clone unless block_given?
196
+ self.send("#{name}_element").click
197
+ end
198
+ end
199
+
200
+ alias_method :a, :link
201
+
202
+
203
+ #
204
+ # adds four methods to the page objec - one to set text in a text field,
205
+ # another to retrieve text from a text field, another to return the text
206
+ # field element, another to check the text field's existence.
207
+ #
208
+ # @example
209
+ # text_field(:first_name, :id => "first_name")
210
+ # # will generate 'first_name', 'first_name=', 'first_name_element',
211
+ # # 'first_name?' methods
212
+ #
213
+ # @param [Symbol] the name used for the generated methods
214
+ # @param [Hash] identifier how we find a text_field. You can use a multiple parameters
215
+ # @param optional block to be invoked when element method is called
216
+ #
217
+ def text_field(name, identifier={:index => 0}, &block)
218
+ standard_methods(name, identifier, 'text_field_for', &block)
219
+ define_method(name) do
220
+ return text_field_value_for identifier.clone unless block_given?
221
+ self.send("#{name}_element").value
222
+ end
223
+ define_method("#{name}=") do |value|
224
+ return text_field_value_set(identifier.clone, value) unless block_given?
225
+ self.send("#{name}_element").value = value
226
+ end
227
+ end
228
+
229
+ #
230
+ # adds five methods - one to check, another to uncheck, another
231
+ # to return the state of a checkbox, another to return
232
+ # a PageObject::Elements::CheckBox object representing the checkbox, and
233
+ # a final method to check the checkbox's existence.
234
+ #
235
+ # @example
236
+ # checkbox(:active, :name => "is_active")
237
+ # # will generate 'check_active', 'uncheck_active', 'active_checked?',
238
+ # # 'active_element', and 'active?' methods
239
+ #
240
+ # @param [Symbol] the name used for the generated methods
241
+ # @param [Hash] identifier how we find a checkbox. You can use a multiple parameters
242
+ # @param optional block to be invoked when element method is called
243
+ #
244
+ def checkbox(name, identifier={:index => 0}, &block)
245
+ standard_methods(name, identifier, 'checkbox_for', &block)
246
+ define_method("check_#{name}") do
247
+ return check_checkbox identifier.clone unless block_given?
248
+ self.send("#{name}_element").check
249
+ end
250
+ define_method("uncheck_#{name}") do
251
+ return uncheck_checkbox identifier.clone unless block_given?
252
+ self.send("#{name}_element").uncheck
253
+ end
254
+ define_method("#{name}_checked?") do
255
+ return checkbox_checked? identifier.clone unless block_given?
256
+ self.send("#{name}_element").checked?
257
+ end
258
+ end
259
+
260
+ #
261
+ # adds five methods - one to select an item in a drop-down,
262
+ # another to fetch the currently selected item text, another
263
+ # to retrieve the select list element, and another to check the
264
+ # drop down's existence and another to get all the available options
265
+ # to select from
266
+ #
267
+ # @example
268
+ # select_list(:state, :id => "state")
269
+ # # will generate 'state', 'state=', 'state_element', 'state?', 'state_options' methods
270
+ #
271
+ # @param [Symbol] the name used for the generated methods
272
+ # @param [Hash] identifier how we find a select_list. You can use a multiple parameters
273
+ # @param optional block to be invoked when element method is called
274
+ #
275
+ def select_list(name, identifier={:index => 0}, &block)
276
+ standard_methods(name, identifier, 'select_list_for', &block)
277
+ define_method(name) do
278
+ return select_list_value_for identifier.clone unless block_given?
279
+ self.send("#{name}_element").options.each {|o| return o.text if o.selected?}
280
+ end
281
+ define_method("#{name}=") do |value|
282
+ return select_list_value_set(identifier.clone, value) unless block_given?
283
+ self.send("#{name}_element").select(value)
284
+ end
285
+ define_method("#{name}_options") do
286
+ element = self.send("#{name}_element")
287
+ (element && element.options) ? element.options.collect(&:text) : []
288
+ end
289
+ end
290
+ alias_method :select, :select_list
291
+
292
+ #
293
+ # adds four methods - one to select, another to return if a radio button
294
+ # is selected, another method to return a PageObject::Elements::RadioButton
295
+ # object representing the radio button element, and another to check
296
+ # the radio button's existence.
297
+ #
298
+ # @example
299
+ # radio_button(:north, :id => "north")
300
+ # # will generate 'select_north', 'north_selected?',
301
+ # # 'north_element', and 'north?' methods
302
+ #
303
+ # @param [Symbol] the name used for the generated methods
304
+ # @param [Hash] identifier how we find a radio_button. You can use a multiple parameters
305
+ # @param optional block to be invoked when element method is called
306
+ #
307
+ def radio_button(name, identifier={:index => 0}, &block)
308
+ standard_methods(name, identifier, 'radio_button_for', &block)
309
+ define_method("select_#{name}") do
310
+ return select_radio identifier.clone unless block_given?
311
+ self.send("#{name}_element").select
312
+ end
313
+ define_method("#{name}_selected?") do
314
+ return radio_selected? identifier.clone unless block_given?
315
+ self.send("#{name}_element").selected?
316
+ end
317
+ end
318
+ alias_method :radio, :radio_button
319
+
320
+ def radio_button_group(name, identifier)
321
+ define_method("select_#{name}") do |value|
322
+ radio_buttons_for(identifier.clone).each do |radio_elem|
323
+ return radio_elem.select if radio_elem.value == value
324
+ end
325
+ end
326
+ define_method("#{name}_values") do
327
+ radio_buttons_for(identifier.clone).collect { |e| e.value}
328
+ end
329
+ define_method("#{name}_selected?") do
330
+ radio_buttons_for(identifier.clone).each do |radio_elem|
331
+ return radio_elem.value if radio_elem.selected?
332
+ end
333
+ return false
334
+ end
335
+ define_method("#{name}_elements") do
336
+ radio_buttons_for(identifier.clone)
337
+ end
338
+ define_method("#{name}?") do
339
+ radio_buttons_for(identifier.clone).any?
340
+ end
341
+ end
342
+ #
343
+ # adds three methods - one to click a button, another to
344
+ # return the button element, and another to check the button's existence.
345
+ #
346
+ # @example
347
+ # button(:purchase, :id => 'purchase')
348
+ # # will generate 'purchase', 'purchase_element', and 'purchase?' methods
349
+ #
350
+ # @param [Symbol] the name used for the generated methods
351
+ # @param [Hash] identifier how we find a button. You can use a multiple parameters
352
+ # @param optional block to be invoked when element method is called
353
+ #
354
+ def button(name, identifier={:index => 0}, &block)
355
+ standard_methods(name, identifier, 'button_for', &block)
356
+ define_method(name) do
357
+ return click_button_for identifier.clone unless block_given?
358
+ self.send("#{name}_element").click
359
+ end
360
+ end
361
+
362
+ #
363
+ # adds three methods - one to retrieve the text from a div,
364
+ # another to return the div element, and another to check the div's existence.
365
+ #
366
+ # @example
367
+ # div(:message, :id => 'message')
368
+ # # will generate 'message', 'message_element', and 'message?' methods
369
+ #
370
+ # @param [Symbol] the name used for the generated methods
371
+ # @param [Hash] identifier how we find a div. You can use a multiple parameters
372
+ # @param optional block to be invoked when element method is called
373
+ #
374
+ def div(name, identifier={:index => 0}, &block)
375
+ standard_methods(name, identifier, 'div_for', &block)
376
+ define_method(name) do
377
+ return div_text_for identifier.clone unless block_given?
378
+ self.send("#{name}_element").text
379
+ end
380
+ end
381
+
382
+ #
383
+ # adds three methods - one to retrieve the text for the table, one
384
+ # to retrieve the table element, and another to
385
+ # check the table's existence.
386
+ #
387
+ # @example
388
+ # table(:cart, :id => 'shopping_cart')
389
+ # # will generate a 'cart', 'cart_element' and 'cart?' method
390
+ #
391
+ # @param the name used for the generated methods
392
+ # @param identifier how we find a table. You can use a multiple parameters
393
+ # @param optional block to be invoked when element method is called
394
+ #
395
+ def table(name, identifier={:index => 0}, &block)
396
+ standard_methods(name, identifier, 'table_for', &block)
397
+ define_method(name) do
398
+ return table_text_for identifier.clone unless block_given?
399
+ self.send("#{name}_element").text
400
+ end
401
+ end
402
+
403
+ #
404
+ # adds three methods - one to retrieve the text from a table cell,
405
+ # another to return the table cell element, and another to check the cell's
406
+ # existence.
407
+ #
408
+ # @example
409
+ # cell(:total, :id => 'total_cell')
410
+ # # will generate 'total', 'total_element', and 'total?' methods
411
+ #
412
+ # @param [Symbol] the name used for the generated methods
413
+ # @param [Hash] identifier how we find a cell. You can use a multiple parameters
414
+ # @param optional block to be invoked when element method is called
415
+ #
416
+ def cell(name, identifier={:index => 0}, &block)
417
+ standard_methods(name, identifier, 'cell_for', &block)
418
+ define_method(name) do
419
+ return cell_text_for identifier.clone unless block_given?
420
+ self.send("#{name}_element").text
421
+ end
422
+ end
423
+ alias_method :td, :cell
424
+
425
+ #
426
+ # adds three methods - one to retrieve the text from a table row,
427
+ # another to return the table row element, and another to check the row's
428
+ # existence.
429
+ #
430
+ # @example
431
+ # row(:sums, :id => 'sum_row')
432
+ # # will generate 'sums', 'sums_element', and 'sums?' methods
433
+ #
434
+ # @param [Symbol] the name used for the generated methods
435
+ # @param [Hash] identifier how we find a cell. You can use a multiple parameters
436
+ # @param optional block to be invoked when element method is called
437
+ #
438
+ def row(name, identifier={:index => 0}, &block)
439
+ standard_methods(name, identifier, 'row_for', &block)
440
+ define_method(name) do
441
+ return row_text_for identifier.clone unless block_given?
442
+ self.send("#{name}_element").text
443
+ end
444
+ end
445
+
446
+ #
447
+ # adds three methods - one to retrieve the text from a span,
448
+ # another to return the span element, and another to check the span's existence.
449
+ #
450
+ # @example
451
+ # span(:alert, :id => 'alert')
452
+ # # will generate 'alert', 'alert_element', and 'alert?' methods
453
+ #
454
+ # @param [Symbol] the name used for the generated methods
455
+ # @param [Hash] identifier how we find a span. You can use a multiple parameters
456
+ # @param optional block to be invoked when element method is called
457
+ #
458
+ def span(name, identifier={:index => 0}, &block)
459
+ standard_methods(name, identifier, 'span_for', &block)
460
+ define_method(name) do
461
+ return span_text_for identifier.clone unless block_given?
462
+ self.send("#{name}_element").text
463
+ end
464
+ end
465
+
466
+ #
467
+ # adds two methods - one to retrieve the image element, and another to
468
+ # check the image's existence.
469
+ #
470
+ # @example
471
+ # image(:logo, :id => 'logo')
472
+ # # will generate 'logo_element', 'logo_loaded?' and 'logo?' methods
473
+ #
474
+ # @param [Symbol] the name used for the generated methods
475
+ # @param [Hash] identifier how we find a image. You can use a multiple parameters
476
+ # @param optional block to be invoked when element method is called
477
+ #
478
+ def image(name, identifier={:index => 0}, &block)
479
+ standard_methods(name, identifier, 'image_for', &block)
480
+ define_method("#{name}_loaded?") do
481
+ return image_loaded_for identifier.clone unless block_given?
482
+ self.send("#{name}_element").loaded?
483
+ end
484
+ end
485
+ alias_method :img, :image
486
+
487
+ #
488
+ # adds two methods - one to retrieve the form element, and another to
489
+ # check the form's existence.
490
+ #
491
+ # @example
492
+ # form(:login, :id => 'login')
493
+ # # will generate 'login_element' and 'login?' methods
494
+ #
495
+ # @param [Symbol] the name used for the generated methods
496
+ # @param [Hash] identifier how we find a form. You can use a multiple parameters
497
+ # @param optional block to be invoked when element method is called
498
+ #
499
+ def form(name, identifier={:index => 0}, &block)
500
+ standard_methods(name, identifier, 'form_for', &block)
501
+ end
502
+
503
+ #
504
+ # adds three methods to the page object - one to get the text from a hidden field,
505
+ # another to retrieve the hidden field element, and another to check the hidden
506
+ # field's existence.
507
+ #
508
+ # @example
509
+ # hidden_field(:user_id, :id => "user_identity")
510
+ # # will generate 'user_id', 'user_id_element' and 'user_id?' methods
511
+ #
512
+ # @param [Symbol] the name used for the generated methods
513
+ # @param [Hash] identifier how we find a hidden field. You can use a multiple parameters
514
+ # @param optional block to be invoked when element method is called
515
+ #
516
+ def hidden_field(name, identifier={:index => 0}, &block)
517
+ standard_methods(name, identifier, 'hidden_field_for', &block)
518
+ define_method(name) do
519
+ return hidden_field_value_for identifier.clone unless block_given?
520
+ self.send("#{name}_element").value
521
+ end
522
+ end
523
+ alias_method :hidden, :hidden_field
524
+
525
+ #
526
+ # adds three methods - one to retrieve the text from a list item,
527
+ # another to return the list item element, and another to check the list item's
528
+ # existence.
529
+ #
530
+ # @example
531
+ # list_item(:item_one, :id => 'one')
532
+ # # will generate 'item_one', 'item_one_element', and 'item_one?' methods
533
+ #
534
+ # @param [Symbol] the name used for the generated methods
535
+ # @param [Hash] identifier how we find a list item. You can use a multiple parameters
536
+ # @param optional block to be invoked when element method is called
537
+ #
538
+ def list_item(name, identifier={:index => 0}, &block)
539
+ standard_methods(name, identifier, 'list_item_for', &block)
540
+ define_method(name) do
541
+ return list_item_text_for identifier.clone unless block_given?
542
+ self.send("#{name}_element").text
543
+ end
544
+ end
545
+ alias_method :li, :list_item
546
+
547
+ #
548
+ # adds three methods - one to return the text within the ordered
549
+ # list, one to retrieve the ordered list element, and another to
550
+ # test it's existence.
551
+ #
552
+ # @example
553
+ # ordered_list(:top_five, :id => 'top')
554
+ # # will generate 'top_five' 'top_five_element' and 'top_five?' methods
555
+ #
556
+ # @param [Symbol] the name used for the generated methods
557
+ # @param [Hash] identifier how we find an ordered list. You can use a multiple parameters
558
+ # @param optional block to be invoked when element method is called
559
+ #
560
+ def ordered_list(name, identifier={:index => 0}, &block)
561
+ standard_methods(name, identifier, 'ordered_list_for', &block)
562
+ define_method(name) do
563
+ return ordered_list_text_for identifier.clone unless block_given?
564
+ self.send("#{name}_element").text
565
+ end
566
+ end
567
+ alias_method :ol, :ordered_list
568
+
569
+ #
570
+ # adds four methods to the page object - one to set text in a text area,
571
+ # another to retrieve text from a text area, another to return the text
572
+ # area element, and another to check the text area's existence.
573
+ #
574
+ # @example
575
+ # text_area(:address, :id => "address")
576
+ # # will generate 'address', 'address=', 'address_element',
577
+ # # 'address?' methods
578
+ #
579
+ # @param [Symbol] the name used for the generated methods
580
+ # @param [Hash] identifier how we find a text area. You can use a multiple parameters
581
+ # @param optional block to be invoked when element method is called
582
+ #
583
+ def text_area(name, identifier={:index => 0}, &block)
584
+ standard_methods(name, identifier, 'text_area_for', &block)
585
+ define_method("#{name}=") do |value|
586
+ return text_area_value_set(identifier.clone, value) unless block_given?
587
+ self.send("#{name}_element").value = value
588
+ end
589
+ define_method(name) do
590
+ return text_area_value_for identifier.clone unless block_given?
591
+ self.send("#{name}_element").value
592
+ end
593
+ end
594
+ alias_method :textarea, :text_area
595
+
596
+ #
597
+ # adds three methods - one to return the text of unordered list, another one
598
+ # retrieve the unordered list element, and another to check it's existence.
599
+ #
600
+ # @example
601
+ # unordered_list(:menu, :id => 'main_menu')
602
+ # # will generate 'menu' 'menu_element' and 'menu?' methods
603
+ #
604
+ # @param [Symbol] the name used for the generated methods
605
+ # @param [Hash] identifier how we find an unordered list. You can use a multiple parameters
606
+ # @param optional block to be invoked when element method is called
607
+ def unordered_list(name, identifier={:index => 0}, &block)
608
+ standard_methods(name, identifier, 'unordered_list_for', &block)
609
+ define_method(name) do
610
+ return unordered_list_text_for identifier.clone unless block_given?
611
+ self.send("#{name}_element").text
612
+ end
613
+ end
614
+ alias_method :ul, :unordered_list
615
+
616
+ #
617
+ # adds three methods - one to retrieve the text of a h1 element, another to
618
+ # retrieve a h1 element, and another to check for it's existence.
619
+ #
620
+ # @example
621
+ # h1(:title, :id => 'title')
622
+ # # will generate 'title', 'title_element', and 'title?' methods
623
+ #
624
+ # @param [Symbol] the name used for the generated methods
625
+ # @param [Hash] identifier how we find a H1. You can use a multiple paramaters
626
+ # @param optional block to be invoked when element method is called
627
+ #
628
+ def h1(name, identifier={:index => 0}, &block)
629
+ standard_methods(name, identifier, 'h1_for', &block)
630
+ define_method(name) do
631
+ return h1_text_for identifier.clone unless block_given?
632
+ self.send("#{name}_element").text
633
+ end
634
+ end
635
+
636
+ #
637
+ # adds three methods - one to retrieve the text of a h2 element, another
638
+ # to retrieve a h2 element, and another to check for it's existence.
639
+ #
640
+ # @example
641
+ # h2(:title, :id => 'title')
642
+ # # will generate 'title', 'title_element', and 'title?' methods
643
+ #
644
+ # @param [Symbol] the name used for the generated methods
645
+ # @param [Hash] identifier how we find a H2. You can use a multiple paramaters
646
+ # @param optional block to be invoked when element method is called
647
+ #
648
+ def h2(name, identifier={:index => 0}, &block)
649
+ standard_methods(name, identifier, 'h2_for', &block)
650
+ define_method(name) do
651
+ return h2_text_for identifier.clone unless block_given?
652
+ self.send("#{name}_element").text
653
+ end
654
+ end
655
+
656
+ #
657
+ # adds three methods - one to retrieve the text of a h3 element,
658
+ # another to return a h3 element, and another to check for it's existence.
659
+ #
660
+ # @example
661
+ # h3(:title, :id => 'title')
662
+ # # will generate 'title', 'title_element', and 'title?' methods
663
+ #
664
+ # @param [Symbol] the name used for the generated methods
665
+ # @param [Hash] identifier how we find a H3. You can use a multiple paramaters
666
+ # @param optional block to be invoked when element method is called
667
+ #
668
+ def h3(name, identifier={:index => 0}, &block)
669
+ standard_methods(name, identifier, 'h3_for', &block)
670
+ define_method(name) do
671
+ return h3_text_for identifier.clone unless block_given?
672
+ self.send("#{name}_element").text
673
+ end
674
+ end
675
+
676
+ #
677
+ # adds three methods - one to retrieve the text of a h4 element,
678
+ # another to return a h4 element, and another to check for it's existence.
679
+ #
680
+ # @example
681
+ # h4(:title, :id => 'title')
682
+ # # will generate 'title', 'title_element', and 'title?' methods
683
+ #
684
+ # @param [Symbol] the name used for the generated methods
685
+ # @param [Hash] identifier how we find a H4. You can use a multiple paramaters
686
+ # @param optional block to be invoked when element method is called
687
+ #
688
+ def h4(name, identifier={:index => 0}, &block)
689
+ standard_methods(name, identifier, 'h4_for', &block)
690
+ define_method(name) do
691
+ return h4_text_for identifier.clone unless block_given?
692
+ self.send("#{name}_element").text
693
+ end
694
+ end
695
+
696
+ #
697
+ # adds three methods - one to retrieve the text of a h5 element,
698
+ # another to return a h5 element, and another to check for it's existence.
699
+ #
700
+ # @example
701
+ # h5(:title, :id => 'title')
702
+ # # will generate 'title', 'title_element', and 'title?' methods
703
+ #
704
+ # @param [Symbol] the name used for the generated methods
705
+ # @param [Hash] identifier how we find a H5. You can use a multiple paramaters
706
+ # @param optional block to be invoked when element method is called
707
+ #
708
+ def h5(name, identifier={:index => 0}, &block)
709
+ standard_methods(name, identifier, 'h5_for', &block)
710
+ define_method(name) do
711
+ return h5_text_for identifier.clone unless block_given?
712
+ self.send("#{name}_element").text
713
+ end
714
+ end
715
+
716
+ #
717
+ # adds three methods - one to retrieve the text of a h6 element,
718
+ # another to return a h6 element, and another to check for it's existence.
719
+ #
720
+ # @example
721
+ # h6(:title, :id => 'title')
722
+ # # will generate 'title', 'title_element', and 'title?' methods
723
+ #
724
+ # @param [Symbol] the name used for the generated methods
725
+ # @param [Hash] identifier how we find a H6. You can use a multiple paramaters
726
+ # @param optional block to be invoked when element method is called
727
+ #
728
+ def h6(name, identifier={:index => 0}, &block)
729
+ standard_methods(name, identifier, 'h6_for', &block)
730
+ define_method(name) do
731
+ return h6_text_for identifier.clone unless block_given?
732
+ self.send("#{name}_element").text
733
+ end
734
+ end
735
+
736
+ #
737
+ # adds three methods - one to retrieve the text of a paragraph, another
738
+ # to retrieve a paragraph element, and another to check the paragraph's existence.
739
+ #
740
+ # @example
741
+ # paragraph(:title, :id => 'title')
742
+ # # will generate 'title', 'title_element', and 'title?' methods
743
+ #
744
+ # @param [Symbol] the name used for the generated methods
745
+ # @param [Hash] identifier how we find a paragraph. You can use a multiple paramaters
746
+ # @param optional block to be invoked when element method is called
747
+ #
748
+ def paragraph(name, identifier={:index => 0}, &block)
749
+ standard_methods(name, identifier, 'paragraph_for', &block)
750
+ define_method(name) do
751
+ return paragraph_text_for identifier.clone unless block_given?
752
+ self.send("#{name}_element").text
753
+ end
754
+ end
755
+ alias_method :p, :paragraph
756
+
757
+ #
758
+ # adds three methods - one to set the file for a file field, another to retrieve
759
+ # the file field element, and another to check it's existence.
760
+ #
761
+ # @example
762
+ # file_field(:the_file, :id => 'file_to_upload')
763
+ # # will generate 'the_file=', 'the_file_element', and 'the_file?' methods
764
+ #
765
+ # @param [Symbol] the name used for the generated methods
766
+ # @param [Hash] identifier how we find a file_field. You can use a multiple paramaters
767
+ # @param optional block to be invoked when element method is called
768
+ #
769
+ def file_field(name, identifier={:index => 0}, &block)
770
+ standard_methods(name, identifier, 'file_field_for', &block)
771
+ define_method("#{name}=") do |value|
772
+ return file_field_value_set(identifier.clone, value) unless block_given?
773
+ self.send("#{name}_element").value = value
774
+ end
775
+ end
776
+
777
+ #
778
+ # adds three methods - one to retrieve the text from a label,
779
+ # another to return the label element, and another to check the label's existence.
780
+ #
781
+ # @example
782
+ # label(:message, :id => 'message')
783
+ # # will generate 'message', 'message_element', and 'message?' methods
784
+ #
785
+ # @param [Symbol] the name used for the generated methods
786
+ # @param [Hash] identifier how we find a label. You can use a multiple parameters
787
+ # @param optional block to be invoked when element method is called
788
+ #
789
+ def label(name, identifier={:index => 0}, &block)
790
+ standard_methods(name, identifier, 'label_for', &block)
791
+ define_method(name) do
792
+ return label_text_for identifier.clone unless block_given?
793
+ self.send("#{name}_element").text
794
+ end
795
+ end
796
+
797
+ #
798
+ # adds three methods - one to click the area,
799
+ # another to return the area element, and another to check the area's existence.
800
+ #
801
+ # @example
802
+ # area(:message, :id => 'message')
803
+ # # will generate 'message', 'message_element', and 'message?' methods
804
+ #
805
+ # @param [Symbol] the name used for the generated methods
806
+ # @param [Hash] identifier how we find an area. You can use a multiple parameters
807
+ # @param optional block to be invoked when element method is called
808
+ #
809
+ def area(name, identifier={:index => 0}, &block)
810
+ standard_methods(name, identifier, 'area_for', &block)
811
+ define_method(name) do
812
+ return click_area_for identifier.clone unless block_given?
813
+ self.send("#{name}_element").click
814
+ end
815
+ end
816
+
817
+ #
818
+ # adds two method - one to return the canvas element and another to check
819
+ # the canvas's existence.
820
+ #
821
+ # @example
822
+ # canvas(:my_canvas, :id => 'canvas_id')
823
+ # # will generate 'my_canvas_element' and 'my_canvas?' methods
824
+ #
825
+ # @param [Symbol] the name used for the generated methods
826
+ # @param [Hash] identifier how we find a canvas. You can use a multiple parameters
827
+ # @param optional block to be invoked when element method is called
828
+ #
829
+ def canvas(name, identifier={:index => 0}, &block)
830
+ standard_methods(name, identifier, 'canvas_for', &block)
831
+ end
832
+
833
+ #
834
+ # adds two methods - one to return the audio element and another to check
835
+ # the audio's existence
836
+ #
837
+ # @example
838
+ # audio(:acdc, :id => 'audio_id')
839
+ # # will generate 'acdc_element' and 'acdc?' methods
840
+ #
841
+ # @param [Symbol] the name used for the generated methods
842
+ # @param [Hash] identifier how we find an audio element. You can use a multiple parameters
843
+ # @param optional block to be invoked when element method is called
844
+ #
845
+ def audio(name, identifier={:index => 0}, &block)
846
+ standard_methods(name, identifier, 'audio_for', &block)
847
+ end
848
+
849
+ #
850
+ # adds two methods - one to return the video element and another to check
851
+ # the video's existence
852
+ #
853
+ # @example
854
+ # video(:movie, :id => 'video_id')
855
+ # # will generate 'movie_element' and 'movie?' methods
856
+ #
857
+ # @param [Symbol] the name used for the generated methods
858
+ # @param [Hash] identifier how we find a video element. You can use a multiple parameters
859
+ # @param optional block to be invoked when element method is called
860
+ #
861
+ def video(name, identifier={:index => 0}, &block)
862
+ standard_methods(name, identifier, 'video_for', &block)
863
+ end
864
+
865
+ #
866
+ # adds three methods - one to retrieve the text of a b element, another to
867
+ # retrieve a b element, and another to check for it's existence.
868
+ #
869
+ # @example
870
+ # b(:blod, :id => 'title')
871
+ # # will generate 'bold', 'bold_element', 'bold?' methods
872
+ #
873
+ # @param [Symbol] the name used for the generated methods
874
+ # @param [Hash] identifier how we find a b, You can use a multiple parameters
875
+ # @param optional block to be invoked when element method is called
876
+ #
877
+ def b(name, identifier={:index => 0}, &block)
878
+ standard_methods(name, identifier, 'b_for', &block)
879
+ define_method(name) do
880
+ return b_text_for identifier.clone unless block_given?
881
+ self.send("#{name}_element").text
882
+ end
883
+ end
884
+
885
+ #
886
+ # adds three methods - one to retrieve the text of a i element, another to
887
+ # retrieve a b element, and another to check for it's existence.
888
+ #
889
+ # @example
890
+ # i(:italic, :id => 'title')
891
+ # # will generate 'italic', 'italic_element', 'italic?' methods
892
+ #
893
+ # @param [Symbol] the name used for the generated methods
894
+ # @param [Hash] identifier how we find a i, You can use a multiple parameters
895
+ # @param optional block to be invoked when element method is called
896
+ #
897
+ def i(name, identifier={:index => 0}, &block)
898
+ standard_methods(name, identifier, 'i_for', &block)
899
+ define_method(name) do
900
+ return i_text_for identifier.clone unless block_given?
901
+ self.send("#{name}_element").text
902
+ end
903
+ end
904
+ alias_method :icon, :i
905
+
906
+ #
907
+ # adds two methods - one to retrieve a svg, and another to check
908
+ # svg's existence.
909
+ #
910
+ # @example
911
+ # svg(:circle, :id => 'circle')
912
+ # # will generate 'circle_element', and 'circle?' methods
913
+ #
914
+ # @param [Symbol] the name used for the generated methods
915
+ # @param [Hash] identifier how we find a svg. You can use a multiple parameters
916
+ # @param optional block to be invoked when element method is called
917
+ #
918
+ def svg(name, identifier={:index => 0}, &block)
919
+ standard_methods(name, identifier, 'svg_for', &block)
920
+ end
921
+
922
+ #
923
+ # adds three methods - one to retrieve the text an element, another
924
+ # to retrieve an element, and another to check the element's existence.
925
+ #
926
+ # @example
927
+ # element(:titile, :id => 'title')
928
+ # # will generate 'title'm 'title_element', and 'title?' methods
929
+ #
930
+ # @param [Symbol] the name used for the generated methods
931
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
932
+ # @param optional block to be invoked when element method is called
933
+ #
934
+ def element(name, tag=:element, identifier={:index => 0}, &block)
935
+ #
936
+ # sets tag as element if not defined
937
+ #
938
+ if tag.is_a? Hash
939
+ identifier = tag
940
+ tag = :element
941
+ end
942
+
943
+ define_method("#{name}") do
944
+ self.send("#{name}_element").text
945
+ end
946
+ define_method("#{name}_element") do
947
+ return call_block(&block) if block_given?
948
+ element_for(tag, identifier.clone)
949
+ end
950
+ define_method("#{name}?") do
951
+ self.send("#{name}_element").exist?
952
+ end
953
+ end
954
+
955
+ #
956
+ # adds a method to return a collection of generic Element objects
957
+ # for a specific tag
958
+ #
959
+ # @example
960
+ # elements(:title, :header, :id => 'title')
961
+ # # will generate 'title_elements'
962
+ #
963
+ # @param [Symbol] the name used for the generated methods
964
+ # @param [Symbol] the name of the tag for the element
965
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
966
+ # @param optional block to be invoked when element method is called
967
+ #
968
+ def elements(name, tag=:element, identifier={:index => 0}, &block)
969
+ #
970
+ # sets tag as element if not defined
971
+ #
972
+ if tag.is_a? Hash
973
+ identifier = tag
974
+ tag = :element
975
+ end
976
+
977
+ define_method("#{name}_elements") do
978
+ return call_block(&block) if block_given?
979
+ elements_for(tag, identifier.clone)
980
+ end
981
+ end
982
+
983
+ def standard_methods(name, identifier, method, &block)
984
+ define_method("#{name}_element") do
985
+ return call_block(&block) if block_given?
986
+ self.send(method, identifier.clone)
987
+ end
988
+ define_method("#{name}?") do
989
+ return call_block(&block).exist? if block_given?
990
+ self.send(method, identifier.clone).exist?
991
+ end
992
+ end
993
+
994
+ #
995
+ # adds a method to return a page object rooted at the element
996
+ #
997
+ # @example
998
+ # page_section(:navigation_bar, NavigationBar, :id => 'nav-bar')
999
+ # # will generate 'navigation_bar'
1000
+ #
1001
+ # @param [Symbol] the name used for the generated methods
1002
+ # @param [Class] the class to instantiate for the element
1003
+ # @param [Hash] identifier how we find an element. You can use multiple parameters
1004
+
1005
+ def page_section(name, section_class, identifier)
1006
+ define_method(name) do
1007
+ page_for(identifier, section_class)
1008
+ end
1009
+ end
1010
+
1011
+ #
1012
+ # adds a method to return a collection of page objects rooted at elements
1013
+ #
1014
+ # @example
1015
+ # page_sections(:articles, Article, :class => 'article')
1016
+ # # will generate 'articles'
1017
+ #
1018
+ # @param [Symbol] the name used for the generated method
1019
+ # @param [Class] the class to instantiate for each element
1020
+ # @param [Hash] identifier how we find an element. You can use a multiple parameters
1021
+
1022
+ def page_sections(name, section_class, identifier)
1023
+ define_method(name) do
1024
+ pages_for(identifier, section_class)
1025
+ end
1026
+ end
1027
+
1028
+ #
1029
+ # methods to generate accessors for types that follow the same
1030
+ # pattern as element
1031
+ #
1032
+ # @example
1033
+ # address(:my_article, :id => "article_id")
1034
+ # will generate 'my_article', 'my_article_element' and 'my_article?'
1035
+ #
1036
+ # @param [Symbol] the name used for the generated methods
1037
+ # @param [Symbol] the name of the tag for the element
1038
+ # @param [Hash] identifier how we find an element. You can use a multiple paramaters
1039
+ # @param optional block to be invoked when element method is called
1040
+ #
1041
+ LocatorGenerator::BASIC_ELEMENTS.each do |tag|
1042
+ define_method(tag) do |name, *identifier, &block|
1043
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1044
+ element(name, tag, identifier, &block)
1045
+ end
1046
+
1047
+ define_method("#{tag}s") do |name, *identifier, &block|
1048
+ identifier = identifier[0] ? identifier[0] : {:index => 0}
1049
+ elements(name, tag, identifier, &block)
1050
+ end unless tag == :param
1051
+ end
1052
+
1053
+ #
1054
+ # methods to fetch multiple elements of the same type
1055
+ #
1056
+ # adds a method to the page objec to retrun all of the matching elements
1057
+ #
1058
+ # @example
1059
+ # text_fields(:first_name, :id => "first_name")
1060
+ # # will generate 'first_name_elements'
1061
+ #
1062
+ # @param [String] the name used for the generated methods
1063
+ # @param [Hash] identifier how we find a text field. You can use a multiple paramaters
1064
+ # by combining of any of the following except xpath. The valid
1065
+ # keys are the same ones supported by the standard methods.
1066
+ # @param optional block to be invoked when element method is called
1067
+ #
1068
+ idx = LocatorGenerator::ADVANCED_ELEMENTS.find_index { |type| type == :checkbox}
1069
+ elements = LocatorGenerator::ADVANCED_ELEMENTS.clone
1070
+ elements[idx] = :checkboxe
1071
+ elements.each do |method_name|
1072
+ define_method("#{method_name}s") do |name, *identifier, &block|
1073
+ define_method("#{name}_elements") do
1074
+ return call_block(&block) unless block.nil?
1075
+ platform_method = (method_name == :checkboxe) ? 'checkboxs_for' : "#{method_name.to_s}s_for"
1076
+ self.send platform_method, (identifier.first ? identifier.first.clone : {})
1077
+ end
1078
+ end
1079
+ end
1080
+
1081
+ end
1082
+ end