druid-ts 0.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +1 -2
  6. data/ChangeLog +218 -0
  7. data/Gemfile +2 -1
  8. data/README.md +64 -7
  9. data/Rakefile +1 -1
  10. data/druid.gemspec +25 -0
  11. data/features/async.feature +18 -0
  12. data/features/button.feature +42 -1
  13. data/features/checkbox.feature +7 -1
  14. data/features/div.feature +6 -0
  15. data/features/element.feature +100 -0
  16. data/features/file_field.feature +35 -0
  17. data/features/form.feature +12 -6
  18. data/features/frames.feature +57 -0
  19. data/features/heading.feature +164 -0
  20. data/features/hidden_field.feature +6 -0
  21. data/features/html/async.html +18 -0
  22. data/features/html/frame_1.html +18 -0
  23. data/features/html/frame_2.html +16 -0
  24. data/features/html/frame_3.html +14 -0
  25. data/features/html/frames.html +12 -0
  26. data/features/html/iframes.html +12 -0
  27. data/features/html/modal.html +17 -0
  28. data/features/html/modal_1.html +38 -0
  29. data/features/html/modal_2.html +27 -0
  30. data/features/html/nested_elements.html +52 -0
  31. data/features/html/nested_frame_1.html +1 -0
  32. data/features/html/nested_frame_2.html +11 -0
  33. data/features/html/nested_frame_3.html +14 -0
  34. data/features/html/nested_frames.html +10 -0
  35. data/features/html/static_elements.html +29 -23
  36. data/features/image.feature +8 -0
  37. data/features/link.feature +5 -0
  38. data/features/list_item.feature +5 -0
  39. data/features/modal_dialog.feature +9 -0
  40. data/features/nested_elements.feature +105 -0
  41. data/features/ordered_list.feature +6 -0
  42. data/features/page_level_actions.feature +48 -0
  43. data/features/paragraph.feature +33 -0
  44. data/features/radio_button.feature +6 -0
  45. data/features/select_list.feature +6 -1
  46. data/features/span.feature +6 -1
  47. data/features/step_definations/async_steps.rb +63 -0
  48. data/features/step_definations/button_steps.rb +25 -1
  49. data/features/step_definations/checkbox_steps.rb +5 -1
  50. data/features/step_definations/div_steps.rb +6 -1
  51. data/features/step_definations/element_steps.rb +55 -1
  52. data/features/step_definations/file_field_steps.rb +27 -0
  53. data/features/step_definations/form_steps.rb +8 -0
  54. data/features/step_definations/frame_steps.rb +112 -0
  55. data/features/step_definations/heading_steps.rb +39 -0
  56. data/features/step_definations/hidden_field_steps.rb +7 -3
  57. data/features/step_definations/image_steps.rb +7 -3
  58. data/features/step_definations/link_steps.rb +8 -3
  59. data/features/step_definations/list_item_steps.rb +9 -1
  60. data/features/step_definations/modal_dialog_steps.rb +38 -0
  61. data/features/step_definations/nested_elements_steps.rb +196 -0
  62. data/features/step_definations/ordered_list_steps.rb +11 -3
  63. data/features/step_definations/page_level_actions_steps.rb +72 -0
  64. data/features/step_definations/paragraph_steps.rb +15 -0
  65. data/features/step_definations/radio_button_steps.rb +5 -1
  66. data/features/step_definations/select_list_steps.rb +10 -2
  67. data/features/step_definations/span_steps.rb +5 -1
  68. data/features/step_definations/table_cell_steps.rb +5 -1
  69. data/features/step_definations/table_steps.rb +17 -3
  70. data/features/step_definations/text_area_steps.rb +18 -2
  71. data/features/step_definations/text_field_steps.rb +9 -1
  72. data/features/step_definations/unordered_list_steps.rb +11 -3
  73. data/features/support/env.rb +0 -15
  74. data/features/support/hooks.rb +7 -0
  75. data/features/support/page.rb +98 -1
  76. data/features/support/persistent_browser.rb +15 -0
  77. data/features/support/url_helper.rb +24 -1
  78. data/features/table.feature +7 -0
  79. data/features/table_cell.feature +6 -0
  80. data/features/text_area.feature +11 -0
  81. data/features/text_field.feature +6 -1
  82. data/features/unordered_list.feature +6 -0
  83. data/lib/druid.rb +251 -3
  84. data/lib/druid/accessors.rb +446 -158
  85. data/lib/druid/assist.rb +394 -0
  86. data/lib/druid/core_ext/string.rb +5 -0
  87. data/lib/druid/element_locators.rb +405 -0
  88. data/lib/druid/elements.rb +28 -0
  89. data/lib/druid/elements/button.rb +6 -1
  90. data/lib/druid/elements/check_box.rb +26 -0
  91. data/lib/druid/elements/div.rb +3 -1
  92. data/lib/druid/elements/element.rb +170 -5
  93. data/lib/druid/elements/file_field.rb +18 -0
  94. data/lib/druid/elements/form.rb +11 -0
  95. data/lib/druid/elements/heading.rb +14 -0
  96. data/lib/druid/elements/hidden_field.rb +12 -2
  97. data/lib/druid/elements/image.rb +13 -0
  98. data/lib/druid/elements/link.rb +2 -0
  99. data/lib/druid/elements/list_item.rb +3 -1
  100. data/lib/druid/elements/option.rb +9 -0
  101. data/lib/druid/elements/ordered_list.rb +4 -5
  102. data/lib/druid/elements/paragraph.rb +9 -0
  103. data/lib/druid/elements/radio_button.rb +25 -0
  104. data/lib/druid/elements/select_list.rb +10 -1
  105. data/lib/druid/elements/span.rb +3 -1
  106. data/lib/druid/elements/table.rb +20 -1
  107. data/lib/druid/elements/table_cell.rb +7 -0
  108. data/lib/druid/elements/table_row.rb +5 -1
  109. data/lib/druid/elements/text_area.rb +15 -1
  110. data/lib/druid/elements/text_field.rb +11 -1
  111. data/lib/druid/elements/unordered_list.rb +5 -5
  112. data/lib/druid/nested_elements.rb +103 -0
  113. data/lib/druid/page_factory.rb +4 -4
  114. data/lib/druid/page_populator.rb +71 -0
  115. data/spec/druid/accessors_spec.rb +789 -0
  116. data/spec/druid/druid_spec.rb +130 -7
  117. data/spec/druid/element_locators_spec.rb +160 -0
  118. data/spec/druid/elements/button_spec.rb +31 -0
  119. data/spec/druid/elements/check_box_spec.rb +38 -0
  120. data/spec/druid/elements/div_spec.rb +19 -0
  121. data/spec/druid/elements/element_spec.rb +150 -0
  122. data/spec/druid/elements/file_field_spec.rb +27 -0
  123. data/spec/druid/elements/form_spec.rb +27 -0
  124. data/spec/druid/elements/heading_spec.rb +39 -0
  125. data/spec/druid/elements/hidden_field_spec.rb +24 -0
  126. data/spec/druid/elements/image_spec.rb +32 -0
  127. data/spec/druid/elements/link_spec.rb +26 -0
  128. data/spec/druid/elements/list_item_spec.rb +19 -0
  129. data/spec/druid/elements/option_spec.rb +10 -0
  130. data/spec/druid/elements/ordered_list_spec.rb +42 -0
  131. data/spec/druid/elements/page_factory_spec.rb +40 -0
  132. data/spec/druid/elements/paragraph_spec.rb +21 -0
  133. data/spec/druid/elements/radio_button_spec.rb +38 -0
  134. data/spec/druid/elements/select_list_spec.rb +37 -0
  135. data/spec/druid/elements/span_spec.rb +19 -0
  136. data/spec/druid/elements/table_cell_spec.rb +23 -0
  137. data/spec/druid/elements/table_row_spec.rb +41 -0
  138. data/spec/druid/elements/table_spec.rb +52 -0
  139. data/spec/druid/elements/text_area_spec.rb +31 -0
  140. data/spec/druid/elements/text_field_spec.rb +31 -0
  141. data/spec/druid/elements/unordered_list_spec.rb +42 -0
  142. data/spec/druid/nested_element_spec.rb +128 -0
  143. data/spec/druid/page_populator_spec.rb +92 -0
  144. data/spec/spec_helper.rb +2 -1
  145. metadata +147 -27
@@ -0,0 +1,15 @@
1
+ module Druid
2
+ module PersistantBrowser
3
+ @@driver = false
4
+ def self.get_browser
5
+ if !@@driver
6
+ @@driver = Watir::Browser.new :firefox if ENV['DRIVER'] == 'WATIR'
7
+ end
8
+ @@driver
9
+ end
10
+
11
+ def self.quit
12
+ @@driver.quit
13
+ end
14
+ end
15
+ end
@@ -8,9 +8,32 @@ module UrlHelper
8
8
  "file://#{html}"
9
9
  end
10
10
 
11
-
12
11
  def static_elements
13
12
  "#{files}/static_elements.html"
14
13
  end
14
+
15
+ def frame_elements
16
+ "#{files}/frames.html"
17
+ end
18
+
19
+ def iframe_elements
20
+ "#{files}/iframes.html"
21
+ end
22
+
23
+ def nested_frame_elements
24
+ "#{files}/nested_frames.html"
25
+ end
26
+
27
+ def nested_elements
28
+ "#{files}/nested_elements.html"
29
+ end
30
+
31
+ def modal
32
+ "#{files}/modal.html"
33
+ end
34
+
35
+ def async
36
+ "#{files}/async.html"
37
+ end
15
38
  end
16
39
  end
@@ -31,6 +31,8 @@ Feature: Table
31
31
  And each row should contain "Data"
32
32
  And row "1" should have "2" columns
33
33
  And each column should contain "Data"
34
+ And the data for the first row should be "Data1" and "Data2"
35
+ And the data for the last row should be "Data3" and "Data4"
34
36
 
35
37
  @multi
36
38
  Scenario Outline: Locating table using multiple parameters
@@ -41,3 +43,8 @@ Feature: Table
41
43
  | param1 | param2 |
42
44
  | class | index |
43
45
  | name | index |
46
+
47
+ @locator
48
+ Scenario: Finding a table dynamically
49
+ When I retrieve a table element while the script is executing
50
+ Then the data for row "1" should be "Data1" and "Data2"
@@ -19,6 +19,7 @@ Feature: Table Cell
19
19
  | xpath |
20
20
  | index |
21
21
  | name |
22
+ | text |
22
23
 
23
24
  Scenario: Retrieve a cell from a table by id
24
25
  When I retrieve table cell
@@ -34,3 +35,8 @@ Feature: Table Cell
34
35
  | param1 | param2 |
35
36
  | class | index |
36
37
  | name | index |
38
+
39
+ @locator
40
+ Scenario: Finding a table cell dynamically
41
+ When I retrieve a table cell element while the script is executing
42
+ Then the cell data should be 'Data4'
@@ -30,3 +30,14 @@ Feature: Text Area
30
30
  | param1 | param2 |
31
31
  | class | index |
32
32
  | name | index |
33
+
34
+ @locator
35
+ Scenario: Finding a text area dynamically
36
+ When I find a text area while the script is executing
37
+ Then I should be able to type "I found it" into the area element
38
+
39
+ Scenario: Clearing the text area
40
+ When I type "abcdefghijklmnop" into the text area
41
+ Then the text area should contain "abcdefghijklmnop"
42
+ When I clear the text area
43
+ Then the text area should contain ""
@@ -24,7 +24,7 @@ Feature: Text Fields
24
24
  | tag_name |
25
25
  | index |
26
26
  | text |
27
- #| value |
27
+ | title |
28
28
 
29
29
  Scenario: Retrieve a text field
30
30
  When I retrieve a text field
@@ -40,3 +40,8 @@ Feature: Text Fields
40
40
  | param1 | param2 |
41
41
  | class | index |
42
42
  | name | index |
43
+
44
+ @locator
45
+ Scenario: Finding a text field dynamically
46
+ When I find a text field while the script is executing
47
+ Then I should be able to type "i found it" into the field element
@@ -34,3 +34,9 @@ Feature: Unordered list
34
34
  | class | index |
35
35
  | name | index |
36
36
  | class | name |
37
+
38
+ @locator
39
+ Scenario: Finding a unordered list dynamically
40
+ When I search for the unordered list while the script is executing
41
+ And I get the first item from the list
42
+ Then the list items text should be "Item One"
@@ -1,6 +1,11 @@
1
1
  require 'druid/accessors'
2
+ require 'druid/assist'
2
3
  require 'druid/page_factory'
4
+ require 'druid/core_ext/string'
5
+ require 'druid/element_locators'
6
+ require 'druid/page_populator'
3
7
 
8
+ # require 'watir-webdriver/extensions/alerts'
4
9
  #
5
10
  # Module that when included adds functionality to a page object. This module
6
11
  # will add numerous class and instance methods that you use to define and
@@ -30,16 +35,27 @@ require 'druid/page_factory'
30
35
  # @see Druid::Accessors to see what class level methods are added to this module at runtime.
31
36
  #
32
37
  module Druid
38
+ include Assist
39
+ include ElementLocators
40
+ include PagePopulator
41
+ # include Watir::AlertHelper
33
42
  # @return [Watir::Browser] the drvier passed to the constructor
34
43
  attr_reader :driver
35
44
  #
36
- # Construct a new druid.
45
+ # Construct a new druid. Upon initialization of the page it will call a method named
46
+ # initialize_page if it exists
37
47
  #
38
48
  # @param [Watir::Browser] the driver to use
49
+ # @param [bool] open the page if page_url is set
39
50
  #
40
51
  def initialize(driver, visit=false)
41
- @driver ||= driver
42
- goto if visit && respond_to?(:goto)
52
+ if driver.is_a? Watir::Browser
53
+ @driver ||= driver
54
+ initialize_page if respond_to?(:initialize_page)
55
+ goto if visit && respond_to?(:goto)
56
+ else
57
+ raise ArgumentError, "expect Watir::Browser"
58
+ end
43
59
  end
44
60
 
45
61
  # @private
@@ -56,6 +72,13 @@ module Druid
56
72
  driver.goto url
57
73
  end
58
74
 
75
+ #
76
+ # get the current page url
77
+ #
78
+ def current_url
79
+ driver.url
80
+ end
81
+
59
82
  #
60
83
  # Returns the text of the current page
61
84
  #
@@ -77,4 +100,229 @@ module Druid
77
100
  driver.title
78
101
  end
79
102
 
103
+ #
104
+ # Refresh current page
105
+ #
106
+ def refresh
107
+ driver.refresh
108
+ end
109
+
110
+ #
111
+ # Go back to the previous page
112
+ #
113
+ def back
114
+ driver.back
115
+ end
116
+
117
+ #
118
+ # Go forward to the next page
119
+ #
120
+ def forward
121
+ driver.forward
122
+ end
123
+ #
124
+ # Wait until the block returns true or times out
125
+ #
126
+ # @example
127
+ # @page.wait_until(5, 'Success not found on page') do
128
+ # @page.text.include? 'Success'
129
+ # end
130
+ #
131
+ # @param [Numeric] the amount of time to wait for the block to return true
132
+ # @param [String] the message to include with the error if we exceed the timeout duration
133
+ # @param block the block to execute. It should return true when successful.
134
+ #
135
+ def wait_until(timeout = 30, message = nil, &block)
136
+ driver.wait_until(timeout, message, &block)
137
+ end
138
+
139
+ #
140
+ # Override the normal alert popup so it does not occurr.
141
+ #
142
+ # @example
143
+ # message = @page.alert do
144
+ # @page.button_that_causes_alert
145
+ # end
146
+ #
147
+ # @param block a block that has the call that will cause the alert to display
148
+ # @return [String] the message that was contained in the alert
149
+ #
150
+ def alert(&block)
151
+ # switch_to_frame(frame)
152
+ yield
153
+ value = nil
154
+ if driver.alert.exists?
155
+ value = driver.alert.text
156
+ driver.alert.ok
157
+ end
158
+ # switch_to_default_content(frame)
159
+ value
160
+ end
161
+
162
+ #
163
+ # Override the normal confirm popup so it does not occurr
164
+ #
165
+ # @example
166
+ # message = @popup.confirm(true) do
167
+ # @page.button_that_causes_confirm
168
+ # end
169
+ #
170
+ # @param [boolean] what response you want to return back from the confirm popup
171
+ # @param block a block that has the call that will cause the confirm to display
172
+ # @return [String] the message that was contained in the confirm
173
+ #
174
+ def confirm(response, &block)
175
+ yield
176
+ value = nil
177
+ if driver.alert.exists?
178
+ value = driver.alert.text
179
+ response ? driver.alert.ok : driver.alert.close
180
+ end
181
+ value
182
+ end
183
+
184
+ #
185
+ # Override the normal prompt popup so it does not occurr
186
+ #
187
+ # @example
188
+ # message = @popup.prompt("Some Value") do
189
+ # @page.button_that_causes_prompt
190
+ # end
191
+ #
192
+ # @param [String] the value will be setted in the prompt field
193
+ # @param block a block that has the call that will cause the prompt to display
194
+ # @return [String] the message that was contained in the prompt
195
+ #
196
+ def prompt(answer, &block)
197
+ yield
198
+ value = nil
199
+ if driver.alert.exists?
200
+ value = driver.alert.text
201
+ driver.alert.set answer
202
+ driver.alert.ok
203
+ end
204
+ value
205
+ end
206
+
207
+ #
208
+ # Attach to a running window. You can locate the window using either
209
+ # the window's title or url or index, If it failes to connect to a window it will
210
+ # pause for 1 second and try again.
211
+ #
212
+ # @example
213
+ # @page.attach_to_window(:title => "other window's title")
214
+ #
215
+ # @param [Hash] either :title or :url or index of the other window. The url does not need to
216
+ # be the entire url - it can just be the page name like index.html
217
+ #
218
+ def attach_to_window(identifier, &block)
219
+ if identifier.keys.first == :url
220
+ win_id = {identifier.keys.first => /#{Regexp.escape(identifier.values.first)}/}
221
+ else
222
+ win_id = {identifier.keys.first => identifier.values.first}
223
+ end
224
+ begin
225
+ driver.window(win_id).use &block
226
+ rescue
227
+ sleep 1
228
+ driver.window(win_id).use &block
229
+ end
230
+ end
231
+
232
+ #
233
+ # Override the normal showModalDialog call is it opens a window instead of a dialog.
234
+ # You will need to attach to the new window in order to continue.
235
+ #
236
+ # @example
237
+ # @page.modal_dialog do
238
+ # @page.action_that_spawns_the_modal
239
+ # end
240
+ #
241
+ # @param block a block that contains the call that will cause the modal dialog.
242
+ #
243
+ def modal_dialog(&block)
244
+ script =
245
+ %Q{
246
+ window.showModalDialog = function(sURL, vArguments, sFeatures) {
247
+ window.dialogArguments = vArguments;
248
+ modalWin = window.open(sURL, 'modal', sFeatures);
249
+ return modalWin;
250
+ }
251
+ }
252
+ driver.execute_script script
253
+ yield if block_given?
254
+ end
255
+
256
+ #
257
+ # Clear the cookies from the browser
258
+ #
259
+ def clear_cookies
260
+ driver.clear_cookies
261
+ end
262
+
263
+ #
264
+ # Save the current screenshot to the provided path. File is saved as a png file.
265
+
266
+ def save_screenshot(file_name)
267
+ driver.screenshot.save(file_name)
268
+ end
269
+
270
+ #
271
+ # Identify an element as existing within a frame or iframe. A frame parameter is
272
+ # passed to the block and must be passed to the other calls to Druid.
273
+ # You can nest calls to in_frame by passing the frame to the next level.
274
+ #
275
+ # @example
276
+ # @page.in_frame(:id => 'frame_id') do |frame|
277
+ # @page.text_field_element(:id=> 'fname', :frame => frame)
278
+ # end
279
+ #
280
+ # @param [Hash] identifier how we find the frame. The valid keys are:
281
+ # * :id
282
+ # * :index
283
+ # * :name
284
+ # @param block that contains the calls to elements that exist inside the frame.
285
+ #
286
+ def in_frame(identifier, frame=nil, &block)
287
+ frame = [] if frame.nil?
288
+ frame << {frame: identifier}
289
+ block.call(frame)
290
+ end
291
+
292
+ #
293
+ # Identify an element as existing within a frame or iframe. A frame parameter is
294
+ # passed to the block and must be passed to the other calls to Druid.
295
+ # You can nest calls to in_frame by passing the frame to the next level.
296
+ #
297
+ # @example
298
+ # @page.in_iframe(:id => 'frame_id') do |frame|
299
+ # @page.text_field_element(:id=> 'fname', :frame => frame)
300
+ # end
301
+ #
302
+ # @param [Hash] identifier how we find the frame. The valid keys are:
303
+ # * :id
304
+ # * :index
305
+ # * :name
306
+ # @param block that contains the calls to elements that exist inside the frame.
307
+ #
308
+ def in_iframe(identifier, frame=nil, &block)
309
+ frame = [] if frame.nil?
310
+ frame << {iframe: identifier}
311
+ block.call(frame)
312
+ end
313
+
314
+ # def switch_to_frame(frame_identifiers)
315
+ # unless frame_identifiers.nil?
316
+ # frame_identifiers.each do |frame|
317
+ # frame_id = frame.values.first
318
+ # value = frame_id.values.first
319
+ # driver.wd.switch_to.frame(value)
320
+ # end
321
+ # end
322
+ # end
323
+
324
+ def call_block(&block)
325
+ block.arity == 1 ? block.call(self) : self.instance_eval(&block)
326
+ end
327
+
80
328
  end
@@ -17,12 +17,51 @@ module Druid
17
17
  driver.goto url
18
18
  end
19
19
  end
20
+
21
+ #
22
+ # Identify an element as existing within a frame or iframe.
23
+ #
24
+ # @example
25
+ # in_frame(:id => 'frame_id') do |frame|
26
+ # text_field(:first_name, :id=> 'fname', :frame => frame)
27
+ # end
28
+ #
29
+ # @param [Hash] identifier how we find the frame. The valid keys are:
30
+ # * :id
31
+ # * :index
32
+ # * :name
33
+ # @param block that contains the calls to elements that exist inside the frame.
34
+ #
35
+ def in_frame(identifier, frame=nil, &block)
36
+ frame = [] if frame.nil?
37
+ frame << {frame: identifier}
38
+ block.call(frame)
39
+ end
40
+ #
41
+ # Identify an element as existing within a frame or iframe.
42
+ #
43
+ # @example
44
+ # in_iframe(:id => 'frame_id') do |frame|
45
+ # text_field(:first_name, :id=> 'fname', :frame => frame)
46
+ # end
47
+ #
48
+ # @param [Hash] identifier how we find the frame. The valid keys are:
49
+ # * :id
50
+ # * :index
51
+ # * :name
52
+ # @param block that contains the calls to elements that exist inside the frame.
53
+ #
54
+ def in_iframe(identifier, frame=nil, &block)
55
+ frame = [] if frame.nil?
56
+ frame << {iframe: identifier}
57
+ block.call(frame)
58
+ end
20
59
  #
21
- # add two methods - one to select a link and another
22
- # to return a link element
60
+ # add three methods - one to select a link and another
61
+ # to return a link element, and another one to select a link and not wait for the corresponding action to complete
23
62
  #
24
63
  # Example: link(:add_to_cart, :text => "Add to Cart")
25
- # will generate the 'add_to_cart' and 'add_to_cart_link'
64
+ # will generate the 'add_to_cart' and 'add_to_cart_element', 'add_to_cart_no_wait'
26
65
  # methods.
27
66
  #
28
67
  # @param the name used for the generated methods
@@ -36,24 +75,26 @@ module Druid
36
75
  # :xpath
37
76
  # :link
38
77
  # :link_text
39
- def link(name, identifier)
40
- identifier = Elements::Link.identifier_for identifier
78
+ def link(name, identifier=nil, &block)
41
79
  define_method(name) do
42
- puts "#{name} method generated"
43
- driver.link(identifier).click
80
+ return click_link_for identifier.clone unless block_given?
81
+ self.send("#{name}_element").click
44
82
  end
45
- define_method("#{name}_link") do
46
- puts "#{name}_link method generated"
47
- driver.link(identifier)
83
+ define_method("#{name}_element") do
84
+ return call_block(&block) if block_given?
85
+ link_for(identifier.clone)
86
+ # block ? call_block(&block) : link_for(identifier.clone)
48
87
  end
88
+ alias_method "#{name}_link".to_sym, "#{name}_element".to_sym
49
89
  end
90
+
50
91
  #
51
92
  # adds three methods to the page object - one to set text in a text field,
52
93
  # another to retrieve text from a text field and another to return the text
53
94
  # field element.
54
95
  #
55
96
  # Example: text_field(:first_name, {:id => "first_name"})
56
- # will generate the 'first_name', 'first_name=' and 'first_name_text_field methods.
97
+ # will generate the 'first_name', 'first_name=' and 'first_name_element methods.
57
98
  #
58
99
  # @param the name used for the generated methods
59
100
  # @param identifier how we find a text_field. The valid values are:
@@ -64,20 +105,23 @@ module Druid
64
105
  # :name
65
106
  # :tag_name
66
107
  # :xpath
67
- def text_field(name, identifier)
68
- identifier = Elements::TextField.identifier_for identifier
108
+ # :text
109
+ # :title
110
+ def text_field(name, identifier=nil, &block)
69
111
  define_method(name) do
70
- puts "#{name} method generated"
71
- driver.text_field(identifier).value
112
+ return text_field_value_for identifier.clone unless block_given?
113
+ self.send("#{name}_element").value
72
114
  end
73
115
  define_method("#{name}=") do |value|
74
- puts "#{name}= method generated"
75
- driver.text_field(identifier).set value
116
+ return text_field_value_set(identifier.clone, value) unless block_given?
117
+ self.send("#{name}_element").value = value
76
118
  end
77
- define_method("#{name}_text_field") do
78
- puts "#{name}_element method generated"
79
- driver.text_field(identifier)
119
+ define_method("#{name}_element") do
120
+ return call_block(&block) if block_given?
121
+ text_field_for(identifier.clone)
122
+ # block ? call_block(&block) : text_field_for(identifier.clone)
80
123
  end
124
+ alias_method "#{name}_text_field".to_sym, "#{name}_element".to_sym
81
125
  end
82
126
  #
83
127
  # adds four methods - one to check, another to uncheck, another
@@ -86,7 +130,7 @@ module Druid
86
130
  #
87
131
  # Example: checkbox(:active, {:name => "is_active"})
88
132
  # will generate the 'check_active', 'uncheck_active',
89
- # 'active_checked?' and 'active_checkbox' methods.
133
+ # 'active_checked?' and 'active_element' methods.
90
134
  #
91
135
  # @param the name used for the generated methods
92
136
  # @param identifier how we find a checkbox. The valid values are:
@@ -95,25 +139,27 @@ module Druid
95
139
  # :index
96
140
  # :name
97
141
  # :xpath
142
+ # :value
98
143
  #
99
- def checkbox(name, identifier)
100
- identifier = Elements::CheckBox.identifier_for identifier
144
+ def checkbox(name, identifier=nil, &block)
101
145
  define_method("check_#{name}") do
102
- puts "check_#{name} method generated"
103
- driver.checkbox(identifier).set
146
+ return check_checkbox identifier.clone unless block_given?
147
+ self.send("#{name}_element").check
104
148
  end
105
149
  define_method("uncheck_#{name}") do
106
- puts "uncheck_#{name} method generated"
107
- driver.checkbox(identifier).clear
150
+ return uncheck_checkbox identifier.clone unless block_given?
151
+ self.send("#{name}_element").uncheck
108
152
  end
109
153
  define_method("#{name}_checked?") do
110
- puts "#{name}_checked? method generated"
111
- driver.checkbox(identifier).set?
154
+ return checkbox_checked? identifier.clone unless block_given?
155
+ self.send("#{name}_element").checked?
112
156
  end
113
- define_method("#{name}_checkbox") do
114
- puts "#{name}_checkbox method generated"
115
- driver.checkbox(identifier)
157
+ define_method("#{name}_element") do
158
+ return call_block(&block) if block_given?
159
+ checkbox_for(identifier.clone)
160
+ # block ? call_block(&block) : checkbox_for(identifier.clone)
116
161
  end
162
+ alias_method "#{name}_checkbox".to_sym, "#{name}_element".to_sym
117
163
  end
118
164
  #
119
165
  # adds three methods - one to select an item in a drop-down,
@@ -121,7 +167,7 @@ module Druid
121
167
  # to retrieve the select list element.
122
168
  #
123
169
  # Example: select_list(:state, {:id => "state"})
124
- # will generate the 'state', 'state=' and 'state_select_list' methods
170
+ # will generate the 'state', 'state=' and 'state_element' methods
125
171
  #
126
172
  # @param the name used for the generated methods
127
173
  # @param identifier how we find a select_list. The valid values are:
@@ -131,21 +177,21 @@ module Druid
131
177
  # :name
132
178
  # :xpath
133
179
  #
134
- def select_list(name, identifier)
135
- identifier = Elements::SelectList.identifier_for identifier
180
+ def select_list(name, identifier=nil, &block)
136
181
  define_method(name) do
137
- puts "#{name} method generated"
138
- driver.select_list(identifier).value
182
+ return select_list_value_for identifier.clone unless block_given?
183
+ self.send("#{name}_element").value
139
184
  end
140
185
  define_method("#{name}=") do |value|
141
- puts "#{name}= method generated"
142
- driver.select_list(identifier).select value
186
+ return select_list_value_set(identifier.clone, value) unless block_given?
187
+ self.send("#{name}_element").select(value)
143
188
  end
144
- define_method("#{name}_select_list") do
145
- puts "#{name}_select_list method generated"
146
- element = driver.select_list(identifier)
147
- Druid::Elements::SelectList.new(element)
189
+ define_method("#{name}_element") do
190
+ return call_block(&block) if block_given?
191
+ select_list_for(identifier.clone)
192
+ # block ? call_block(&block) : select_list_for(identifier.clone)
148
193
  end
194
+ alias_method "#{name}_select_list".to_sym, "#{name}_element".to_sym
149
195
  end
150
196
  #
151
197
  # adds three methods - one to select
@@ -154,7 +200,7 @@ module Druid
154
200
  #
155
201
  # Example: radio_button(:north, {:id => "north"})
156
202
  # will generate 'select_north'
157
- # 'north_selected?' and 'north_radio_button' methods
203
+ # 'north_selected?' and 'north_element' methods
158
204
  #
159
205
  # @param the name used for the generated methods
160
206
  # @param identifier how we find a radio_button. The valid values are:
@@ -163,28 +209,34 @@ module Druid
163
209
  # :index
164
210
  # :name
165
211
  # :xpath
212
+ # :value
166
213
  #
167
- def radio_button(name, identifier)
168
- identifier = Elements::RadioButton.identifier_for identifier
214
+ def radio_button(name, identifier=nil, &block)
169
215
  define_method("select_#{name}") do
170
- puts "select_#{name} method generated"
171
- driver.radio(identifier).set
216
+ return select_radio identifier.clone unless block_given?
217
+ self.send("#{name}_element").select
218
+ end
219
+ define_method("clear_#{name}") do
220
+ return clear_radio identifier.clone unless block_given?
221
+ self.send("#{name}_element").clear
172
222
  end
173
223
  define_method("#{name}_selected?") do
174
- puts "#{name}_selected method generated"
175
- driver.radio(identifier).set?
224
+ return radio_selected? identifier.clone unless block_given?
225
+ self.send("#{name}_element").selected?
176
226
  end
177
- define_method("#{name}_radio_button") do
178
- puts "#{name}_radio_button method generated"
179
- driver.radio(identifier)
227
+ define_method("#{name}_element") do
228
+ return call_block(&block) if block_given?
229
+ radio_button_for(identifier.clone)
230
+ # block ? call_block(&block) : radio_button_for(identifier.clone)
180
231
  end
232
+ alias_method "#{name}_radio_button".to_sym, "#{name}_element".to_sym
181
233
  end
182
234
  #
183
235
  # adds two methods - one to click a button and another to
184
236
  # return the button element.
185
237
  #
186
238
  # Example: button(:purchase, :id => 'purchase')
187
- # will generate a 'purchase' and 'purchase_button' methods.
239
+ # will generate a 'purchase' and 'purchase_element' methods.
188
240
  #
189
241
  # @param the name used for the generated methods
190
242
  # @param identifier how we find a button. The valid values are:
@@ -194,24 +246,27 @@ module Druid
194
246
  # :name
195
247
  # :text
196
248
  # :xpath
249
+ # :src
250
+ # :alt
197
251
  #
198
- def button(name, identifier)
199
- identifier = Elements::Button.identifier_for identifier
252
+ def button(name, identifier=nil, &block)
200
253
  define_method(name) do
201
- puts "#{name} method generated"
202
- driver.button(identifier).click
254
+ return click_button_for identifier.clone unless block_given?
255
+ self.send("#{name}_element").click
203
256
  end
204
- define_method("#{name}_button") do
205
- puts "#{name}_button method generated"
206
- driver.button(identifier)
257
+ define_method("#{name}_element") do
258
+ return call_block(&block) if block_given?
259
+ button_for(identifier.clone)
260
+ # block ? call_block(&block) : button_for(identifier.clone)
207
261
  end
262
+ alias_method "#{name}_button".to_sym, "#{name}_element".to_sym
208
263
  end
209
264
  #
210
265
  # adds two methods - one to retrieve the text from a div
211
266
  # and another to return the div element
212
267
  #
213
268
  # Example: div(:message, {:id => 'message'})
214
- # will generate a 'message' and 'message_div' methods
269
+ # will generate a 'message' and 'message_element' methods
215
270
  #
216
271
  # @param the name used for the generated methods
217
272
  # @param identifier how we find a div. The valid values are:
@@ -220,24 +275,26 @@ module Druid
220
275
  # :index
221
276
  # :xpath
222
277
  # :name
278
+ # :text
279
+ # :value
223
280
  #
224
- def div(name, identifier)
225
- identifier = add_tagname_if_needed identifier, "div"
226
- identifier = Elements::Div.identifier_for identifier
281
+ def div(name, identifier=nil, &block)
227
282
  define_method(name) do
228
- puts "#{name} method generated"
229
- driver.div(identifier).text
283
+ return div_text_for identifier.clone unless block_given?
284
+ self.send("#{name}_element").text
230
285
  end
231
- define_method("#{name}_div") do
232
- puts "#{name}_div method generated"
233
- driver.div(identifier)
286
+ define_method("#{name}_element") do
287
+ return call_block(&block) if block_given?
288
+ div_for(identifier.clone)
289
+ # block ? call_block(&block) : div_for(identifier.clone)
234
290
  end
291
+ alias_method "#{name}_div".to_sym, "#{name}_element".to_sym
235
292
  end
236
293
  #
237
294
  # adds a method to retrieve the table element
238
295
  #
239
296
  # Example: table(:cart, :id => 'shopping_cart')
240
- # will generate a 'cart_table' method.
297
+ # will generate a 'cart_element' method.
241
298
  #
242
299
  # @param the name used for the generated methods
243
300
  # @param identifier how we find a table. The valid values are:
@@ -247,21 +304,20 @@ module Druid
247
304
  # :xpath
248
305
  # :name
249
306
  #
250
- def table(name, identifier)
251
- identifier = add_tagname_if_needed identifier, "table"
252
- identifier = Elements::Table.identifier_for identifier
253
- define_method("#{name}_table") do
254
- puts "#{name}_table method generated"
255
- element = driver.table(identifier)
256
- Druid::Elements::Table.new(element)
307
+ def table(name, identifier=nil, &block)
308
+ define_method("#{name}_element") do
309
+ return call_block(&block) if block_given?
310
+ table_for(identifier.clone)
311
+ # block ? call_block(&block) : table_for(identifier.clone)
257
312
  end
313
+ alias_method "#{name}_table".to_sym, "#{name}_element".to_sym
258
314
  end
259
315
  #
260
316
  # adds two methods one to retrieve the text from a table cell
261
317
  # and another to return the table cell element
262
318
  #
263
319
  # Example: cell(:total, :id => 'total_cell')
264
- # will generate a 'total' and 'total_cell' methods
320
+ # will generate a 'total' and 'total_element' methods
265
321
  #
266
322
  # @param the name used for the generated methods
267
323
  # @param identifier how we find a cell. The valid values are:
@@ -270,25 +326,26 @@ module Druid
270
326
  # :index
271
327
  # :xpath
272
328
  # :name
329
+ # :text
273
330
  #
274
- def cell(name, identifier)
275
- identifier = add_tagname_if_needed identifier, "td"
276
- identifier = Elements::TableCell.identifier_for identifier
331
+ def cell(name, identifier=nil, &block)
277
332
  define_method(name) do
278
- puts "#{name} method generated"
279
- driver.td(identifier).text
333
+ return cell_text_for identifier.clone unless block_given?
334
+ self.send("#{name}_element").text
280
335
  end
281
- define_method("#{name}_cell") do
282
- puts "#{name}_cell method generated"
283
- driver.td(identifier)
336
+ define_method("#{name}_element") do
337
+ return call_block(&block) if block_given?
338
+ cell_for(identifier.clone)
339
+ # block ? call_block(&block) : cell_for(identifier.clone)
284
340
  end
341
+ alias_method "#{name}_cell".to_sym, "#{name}_element".to_sym
285
342
  end
286
343
  #
287
344
  # adds two methods - one to retrieve the text from a span
288
345
  # and another to return the span element
289
346
  #
290
347
  # Example: span(:alert, {:id => 'alert'})
291
- # will generate a 'alert' and 'alert_div' methods
348
+ # will generate a 'alert' and 'alert_element' methods
292
349
  #
293
350
  # @param the name used for the generated methods
294
351
  # @param identifier how we find a span. The valid values are:
@@ -297,24 +354,25 @@ module Druid
297
354
  # :index
298
355
  # :xpath
299
356
  # :name
357
+ # :text
300
358
  #
301
- def span(name, identifier)
302
- identifier = add_tagname_if_needed identifier, "span"
303
- identifier = Elements::Span.identifier_for identifier
359
+ def span(name, identifier=nil, &block)
304
360
  define_method(name) do
305
- puts "#{name} method generated"
306
- driver.span(identifier).text
361
+ return span_text_for identifier.clone unless block_given?
362
+ self.send("#{name}_element").text
307
363
  end
308
- define_method("#{name}_span") do
309
- puts "#{name}_span method generated"
310
- driver.span(identifier)
364
+ define_method("#{name}_element") do
365
+ return call_block(&block) if block_given?
366
+ span_for(identifier.clone)
367
+ # block ? call_block(&block) : span_for(identifier.clone)
311
368
  end
369
+ alias_method "#{name}_span".to_sym, "#{name}_element".to_sym
312
370
  end
313
371
  #
314
372
  # adds a method to retrieve the image element
315
373
  #
316
374
  # Example: image(:photo, :id => 'photo_id')
317
- # will generate a 'photo_image' method.
375
+ # will generate a 'photo_element' method.
318
376
  #
319
377
  # @param the name used for the generated methods
320
378
  # @param identifier how we find a image. The valid values are:
@@ -323,20 +381,23 @@ module Druid
323
381
  # :index
324
382
  # :name
325
383
  # :xpath
384
+ # :alt
385
+ # :src
326
386
  #
327
- def image(name, identifier)
328
- identifier = Elements::Image.identifier_for identifier
329
- define_method("#{name}_image") do
330
- puts "#{name}_image method generated"
331
- driver.image(identifier)
387
+ def image(name, identifier=nil, &block)
388
+ define_method("#{name}_element") do
389
+ return call_block(&block) if block_given?
390
+ image_for(identifier.clone)
391
+ # block ? call_block(&block) : image_for(identifier.clone)
332
392
  end
393
+ alias_method "#{name}_image".to_sym, "#{name}_element".to_sym
333
394
  end
334
395
  #
335
396
  # adds a method to retrieve the form element
336
397
  #
337
398
  # @example
338
399
  # form(:login, :id => 'login')
339
- # # will generate a 'login_form' method
400
+ # # will generate a 'login_element' method
340
401
  #
341
402
  # @param [String] the name used for the generated methods
342
403
  # @param [Hash] identifier how we find a form. The valid keys are:
@@ -345,13 +406,15 @@ module Druid
345
406
  # * :index
346
407
  # * :xpath
347
408
  # * :name
409
+ # * :action
348
410
  #
349
- def form(name, identifier)
350
- identifier = Elements::Form.identifier_for identifier
351
- define_method("#{name}_form") do
352
- puts "#{name}_form method generated"
353
- driver.form(identifier)
411
+ def form(name, identifier=nil, &block)
412
+ define_method("#{name}_element") do
413
+ return call_block(&block) if block_given?
414
+ form_for(identifier.clone)
415
+ # block ? call_block(&block) : form_for(identifier.clone)
354
416
  end
417
+ alias_method "#{name}_form".to_sym, "#{name}_element".to_sym
355
418
  end
356
419
  #
357
420
  # adds two methods to the page object - one to get the text from a hidden field
@@ -359,7 +422,7 @@ module Druid
359
422
  #
360
423
  # @example
361
424
  # hidden_field(:user_id, :id => "user_identity")
362
- # # will generate 'user_id' and 'user_id_hidden_field' methods
425
+ # # will generate 'user_id' and 'user_id_element' methods
363
426
  #
364
427
  # @param [String] the name used for the generated methods
365
428
  # @param [Hash] identifier how we find a hidden field. The valid keys are:
@@ -371,17 +434,19 @@ module Druid
371
434
  # * :tag_name
372
435
  # * :text
373
436
  # * :xpath
437
+ # * :value
374
438
  #
375
- def hidden_field(name, identifier)
376
- identifier = Elements::HiddenField.identifier_for identifier
377
- define_method("#{name}_hidden_field") do
378
- puts "#{name}_hidden_field method generated"
379
- driver.hidden(identifier)
439
+ def hidden_field(name, identifier=nil, &block)
440
+ define_method("#{name}_element") do
441
+ return call_block(&block) if block_given?
442
+ hidden_field_for(identifier.clone)
443
+ # block ? call_block(&block) : hidden_field_for(identifier.clone)
380
444
  end
381
445
  define_method(name) do
382
- puts "#{name} method generated"
383
- driver.hidden(identifier).value
446
+ return hidden_field_value_for identifier.clone unless block_given?
447
+ self.send("#{name}_element").value
384
448
  end
449
+ alias_method "#{name}_hidden_field".to_sym, "#{name}_element".to_sym
385
450
  end
386
451
  #
387
452
  # adds two methods - one to retrieve the text from a list item
@@ -389,7 +454,7 @@ module Druid
389
454
  #
390
455
  # @example
391
456
  # list_item(:item_one, :id => 'one')
392
- # # will generate 'item_one' and 'item_one_list_item' methods
457
+ # # will generate 'item_one' and 'item_one_element' methods
393
458
  #
394
459
  # @param [String] the name used for the generated methods
395
460
  # @param [Hash] identifier how we find a list item. The valid keys are:
@@ -399,24 +464,24 @@ module Druid
399
464
  # * :xpath
400
465
  # * :name
401
466
  #
402
- def list_item(name, identifier)
403
- identifier = add_tagname_if_needed identifier, "li"
404
- identifier = Elements::ListItem.identifier_for identifier
467
+ def list_item(name, identifier=nil, &block)
405
468
  define_method(name) do
406
- puts "#{name} method generated"
407
- driver.li(identifier).text
469
+ return list_item_text_for identifier.clone unless block_given?
470
+ self.send("#{name}_element").text
408
471
  end
409
- define_method("#{name}_list_item") do
410
- puts "#{name}_list_item method generated"
411
- driver.li(identifier)
472
+ define_method("#{name}_element") do
473
+ return call_block(&block) if block_given?
474
+ list_item_for(identifier.clone)
475
+ # block ? call_block(&block) : list_item_for(identifier.clone)
412
476
  end
477
+ alias_method "#{name}_list_item".to_sym, "#{name}_element".to_sym
413
478
  end
414
479
  #
415
480
  # adds a method to retrieve the ordered list element
416
481
  #
417
482
  # @example
418
483
  # ordered_list(:top_five, :id => 'top')
419
- # # will generate a 'top_five_ordered_list' method
484
+ # # will generate a 'top_five_element' method
420
485
  #
421
486
  # @param [String] the name used for the generated methods
422
487
  # @param [Hash] identifier how we find an ordered list. The valid keys are:
@@ -426,14 +491,13 @@ module Druid
426
491
  # * :xpath
427
492
  # * :name
428
493
  #
429
- def ordered_list(name, identifier)
430
- identifier = add_tagname_if_needed identifier, "ol"
431
- identifier = Elements::OrderedList.identifier_for identifier
432
- define_method("#{name}_ordered_list") do
433
- puts "#{name}_ordered_list method generated"
434
- element = driver.ol(identifier)
435
- Druid::Elements::OrderedList.new(element)
494
+ def ordered_list(name, identifier=nil, &block)
495
+ define_method("#{name}_element") do
496
+ return call_block(&block) if block_given?
497
+ ordered_list_for(identifier.clone)
498
+ # block ? call_block(&block) : ordered_list_for(identifier.clone)
436
499
  end
500
+ alias_method "#{name}_ordered_list".to_sym, "#{name}_element".to_sym
437
501
  end
438
502
  #
439
503
  # adds three methods to the page object - one to set text in a text area,
@@ -442,7 +506,7 @@ module Druid
442
506
  #
443
507
  # @example
444
508
  # text_area(:address, :id => "address")
445
- # # will generate 'address', 'address=' and 'address_text_area methods
509
+ # # will generate 'address', 'address=' and 'address_element' methods
446
510
  #
447
511
  # @param [String] the name used for the generated methods
448
512
  # @param [Hash] identifier how we find a text area. The valid keys are:
@@ -454,27 +518,28 @@ module Druid
454
518
  # * :tag_name
455
519
  # * :xpath
456
520
  #
457
- def text_area(name, identifier)
458
- identifier = Elements::TextArea.identifier_for identifier
521
+ def text_area(name, identifier=nil, &block)
459
522
  define_method("#{name}=") do |value|
460
- puts "#{name}= method generated"
461
- driver.textarea(identifier).send_keys value
523
+ return text_area_value_set(identifier.clone, value) unless block_given?
524
+ self.send("#{name}_element").value = value
462
525
  end
463
- define_method("#{name}") do
464
- puts "#{name} method generated"
465
- driver.textarea(identifier).value
526
+ define_method(name) do
527
+ return text_area_value_for identifier.clone unless block_given?
528
+ self.send("#{name}_element").value
466
529
  end
467
- define_method("#{name}_text_area") do
468
- puts "#{name}_text_area method generated"
469
- driver.textarea(identifier)
530
+ define_method("#{name}_element") do
531
+ return call_block(&block) if block_given?
532
+ text_area_for(identifier.clone)
533
+ # block ? call_block(&block) : text_area_for(identifier.clone)
470
534
  end
535
+ alias_method "#{name}_text_area".to_sym, "#{name}_element".to_sym
471
536
  end
472
537
  #
473
538
  # adds a method to retrieve the unordered list element
474
539
  #
475
540
  # @example
476
541
  # unordered_list(:menu, :id => 'main_menu')
477
- # # will generate a 'menu_unordered_list' method
542
+ # # will generate a 'menu_element' method
478
543
  #
479
544
  # @param [String] the name used for the generated methods
480
545
  # @param [Hash] identifier how we find an unordered list. The valid keys are:
@@ -484,23 +549,246 @@ module Druid
484
549
  # * :xpath
485
550
  # * :name
486
551
  #
487
- def unordered_list(name, identifier)
488
- identifier = add_tagname_if_needed identifier, "ul"
489
- identifier = Elements::UnOrderedList.identifier_for identifier
490
- define_method("#{name}_unordered_list") do
491
- puts "#{name}_unordered_list method generated"
492
- element = driver.ul(identifier)
493
- Druid::Elements::UnOrderedList.new(element)
552
+ def unordered_list(name, identifier=nil, &block)
553
+ define_method("#{name}_element") do
554
+ return call_block(&block) if block_given?
555
+ unordered_list_for(identifier.clone)
556
+ # block ? call_block(&block) : unordered_list_for(identifier.clone)
494
557
  end
558
+ alias_method "#{name}_unordered_list".to_sym, "#{name}_element".to_sym
495
559
  end
496
560
 
497
- private
561
+ #
562
+ # adds a method to retrieve the text of a h1 and a h1 element
563
+ #
564
+ # @example
565
+ # h1(:title, :id => 'title')
566
+ # # will generate a 'title' and 'title_element' method
567
+ #
568
+ # @param [String] the name used for the generated methods
569
+ # @param [Hash] identifier how we find a H1. You can use a multiple paramaters
570
+ # by combining of any of the following except xpath. The valid keys are:
571
+ # * :class
572
+ # * :id
573
+ # * :index
574
+ # * :name
575
+ # * :xpath
576
+ # @param optional block to be invoked when element method is called
577
+ #
578
+ def h1(name, identifier=nil, &block)
579
+ define_method(name) do
580
+ return h1_text_for identifier.clone unless block_given?
581
+ self.send("#{name}_element").text
582
+ end
583
+ define_method("#{name}_element") do
584
+ return call_block(&block) if block_given?
585
+ h1_for(identifier.clone)
586
+ end
587
+ alias_method "#{name}_h1".to_sym, "#{name}_element".to_sym
588
+ end
498
589
 
499
- def add_tagname_if_needed identifier, tag
500
- return identifier if identifier.length < 2 and not identifier[:name]
501
- identifier[:tag_name] = tag if identifier[:name]
502
- identifier
590
+ #
591
+ # adds a method to retrieve the text of a h2 and a h2 element
592
+ #
593
+ # @example
594
+ # h2(:title, :id => 'title')
595
+ # # will generate a 'title' and 'title_element' method
596
+ #
597
+ # @param [String] the name used for the generated methods
598
+ # @param [Hash] identifier how we find a H2. You can use a multiple paramaters
599
+ # by combining of any of the following except xpath. The valid keys are:
600
+ # * :class
601
+ # * :id
602
+ # * :index
603
+ # * :name
604
+ # * :xpath
605
+ # @param optional block to be invoked when element method is called
606
+ #
607
+ def h2(name, identifier=nil, &block)
608
+ define_method(name) do
609
+ return h2_text_for identifier.clone unless block_given?
610
+ self.send("#{name}_element").text
611
+ end
612
+ define_method("#{name}_element") do
613
+ return call_block(&block) if block_given?
614
+ h2_for(identifier.clone)
615
+ end
616
+ alias_method "#{name}_h2".to_sym, "#{name}_element".to_sym
617
+ end
618
+
619
+ #
620
+ # adds a method to retrieve the text of a h3 and a h3 element
621
+ #
622
+ # @example
623
+ # h3(:title, :id => 'title')
624
+ # # will generate a 'title' and 'title_element' method
625
+ #
626
+ # @param [String] the name used for the generated methods
627
+ # @param [Hash] identifier how we find a H3. You can use a multiple paramaters
628
+ # by combining of any of the following except xpath. The valid keys are:
629
+ # * :class
630
+ # * :id
631
+ # * :index
632
+ # * :name
633
+ # * :xpath
634
+ # @param optional block to be invoked when element method is called
635
+ #
636
+ def h3(name, identifier=nil, &block)
637
+ define_method(name) do
638
+ return h3_text_for identifier.clone unless block_given?
639
+ self.send("#{name}_element").text
640
+ end
641
+ define_method("#{name}_element") do
642
+ return call_block(&block) if block_given?
643
+ h3_for(identifier.clone)
644
+ end
645
+ alias_method "#{name}_h3".to_sym, "#{name}_element".to_sym
646
+ end
647
+
648
+ #
649
+ # adds a method to retrieve the text of a h4 and a h4 element
650
+ #
651
+ # @example
652
+ # h4(:title, :id => 'title')
653
+ # # will generate a 'title' and 'title_element' method
654
+ #
655
+ # @param [String] the name used for the generated methods
656
+ # @param [Hash] identifier how we find a H4. You can use a multiple paramaters
657
+ # by combining of any of the following except xpath. The valid keys are:
658
+ # * :class
659
+ # * :id
660
+ # * :index
661
+ # * :name
662
+ # * :xpath
663
+ # @param optional block to be invoked when element method is called
664
+ #
665
+ def h4(name, identifier=nil, &block)
666
+ define_method(name) do
667
+ return h4_text_for identifier.clone unless block_given?
668
+ self.send("#{name}_element").text
669
+ end
670
+ define_method("#{name}_element") do
671
+ return call_block(&block) if block_given?
672
+ h4_for(identifier.clone)
673
+ end
674
+ alias_method "#{name}_h4".to_sym, "#{name}_element".to_sym
675
+ end
676
+
677
+ #
678
+ # adds a method to retrieve the text of a h5 and a h5 element
679
+ #
680
+ # @example
681
+ # h5(:title, :id => 'title')
682
+ # # will generate a 'title' and 'title_element' method
683
+ #
684
+ # @param [String] the name used for the generated methods
685
+ # @param [Hash] identifier how we find a H5. You can use a multiple paramaters
686
+ # by combining of any of the following except xpath. The valid keys are:
687
+ # * :class
688
+ # * :id
689
+ # * :index
690
+ # * :name
691
+ # * :xpath
692
+ # @param optional block to be invoked when element method is called
693
+ #
694
+ def h5(name, identifier=nil, &block)
695
+ define_method(name) do
696
+ return h5_text_for identifier.clone unless block_given?
697
+ self.send("#{name}_element").text
698
+ end
699
+ define_method("#{name}_element") do
700
+ return call_block(&block) if block_given?
701
+ h5_for(identifier.clone)
702
+ end
703
+ alias_method "#{name}_h5".to_sym, "#{name}_element".to_sym
503
704
  end
504
- end
505
705
 
706
+ #
707
+ # adds a method to retrieve the text of a h6 and a h6 element
708
+ #
709
+ # @example
710
+ # h6(:title, :id => 'title')
711
+ # # will generate a 'title' and 'title_element' method
712
+ #
713
+ # @param [String] the name used for the generated methods
714
+ # @param [Hash] identifier how we find a H6. You can use a multiple paramaters
715
+ # by combining of any of the following except xpath. The valid keys are:
716
+ # * :class
717
+ # * :id
718
+ # * :index
719
+ # * :name
720
+ # * :xpath
721
+ # @param optional block to be invoked when element method is called
722
+ #
723
+ def h6(name, identifier=nil, &block)
724
+ define_method(name) do
725
+ return h6_text_for identifier.clone unless block_given?
726
+ self.send("#{name}_element").text
727
+ end
728
+ define_method("#{name}_element") do
729
+ return call_block(&block) if block_given?
730
+ h6_for(identifier.clone)
731
+ end
732
+ alias_method "#{name}_h6".to_sym, "#{name}_element".to_sym
733
+ end
734
+
735
+ #
736
+ # adds a method to retrieve the text of a paragraph and a paragraph element
737
+ #
738
+ # @example
739
+ # paragraph(:title, :id => 'title')
740
+ # # will generate a 'title' and 'title_element' method
741
+ #
742
+ # @param [String] the name used for the generated methods
743
+ # @param [Hash] identifier how we find a paragraph. You can use a multiple paramaters
744
+ # by combining of any of the following except xpath. The valid keys are:
745
+ # * :class
746
+ # * :id
747
+ # * :index
748
+ # * :name
749
+ # * :xpath
750
+ # @param optional block to be invoked when element method is called
751
+ #
752
+ def paragraph(name, identifier=nil, &block)
753
+ define_method(name) do
754
+ return paragraph_text_for identifier.clone unless block_given?
755
+ self.send("#{name}_element").text
756
+ end
757
+ define_method("#{name}_element") do
758
+ return call_block(&block) if block_given?
759
+ paragraph_for(identifier.clone)
760
+ end
761
+ alias_method "#{name}_paragraph".to_sym, "#{name}_element".to_sym
762
+ end
763
+
764
+ #
765
+ # adds a method to set the file for a file field and to retrieve
766
+ # the file field element
767
+ #
768
+ # @example
769
+ # file_field(:the_file, :id => 'file_to_upload')
770
+ # # will generate a 'the_file=' and 'the_file_element' method
771
+ #
772
+ # @param [String] the name used for the generated methods
773
+ # @param [Hash] identifier how we find a file_field. You can use a multiple paramaters
774
+ # by combining of any of the following except xpath. The valid keys are:
775
+ # * :class
776
+ # * :id
777
+ # * :index
778
+ # * :name
779
+ # * :title
780
+ # * :xpath
781
+ # @param optional block to be invoked when element method is called
782
+ #
783
+ def file_field(name, identifier=nil, &block)
784
+ define_method("#{name}=") do |value|
785
+ return file_field_value_set(identifier.clone, value) unless block_given?
786
+ self.send("#{name}_element").value = value
787
+ end
788
+ define_method("#{name}_element") do
789
+ return call_block(&block) if block_given?
790
+ file_field_for(identifier.clone)
791
+ end
792
+ end
793
+ end
506
794
  end