druid-ts 0.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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