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.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +1 -2
- data/ChangeLog +218 -0
- data/Gemfile +2 -1
- data/README.md +64 -7
- data/Rakefile +1 -1
- data/druid.gemspec +25 -0
- data/features/async.feature +18 -0
- data/features/button.feature +42 -1
- data/features/checkbox.feature +7 -1
- data/features/div.feature +6 -0
- data/features/element.feature +100 -0
- data/features/file_field.feature +35 -0
- data/features/form.feature +12 -6
- data/features/frames.feature +57 -0
- data/features/heading.feature +164 -0
- data/features/hidden_field.feature +6 -0
- data/features/html/async.html +18 -0
- data/features/html/frame_1.html +18 -0
- data/features/html/frame_2.html +16 -0
- data/features/html/frame_3.html +14 -0
- data/features/html/frames.html +12 -0
- data/features/html/iframes.html +12 -0
- data/features/html/modal.html +17 -0
- data/features/html/modal_1.html +38 -0
- data/features/html/modal_2.html +27 -0
- data/features/html/nested_elements.html +52 -0
- data/features/html/nested_frame_1.html +1 -0
- data/features/html/nested_frame_2.html +11 -0
- data/features/html/nested_frame_3.html +14 -0
- data/features/html/nested_frames.html +10 -0
- data/features/html/static_elements.html +29 -23
- data/features/image.feature +8 -0
- data/features/link.feature +5 -0
- data/features/list_item.feature +5 -0
- data/features/modal_dialog.feature +9 -0
- data/features/nested_elements.feature +105 -0
- data/features/ordered_list.feature +6 -0
- data/features/page_level_actions.feature +48 -0
- data/features/paragraph.feature +33 -0
- data/features/radio_button.feature +6 -0
- data/features/select_list.feature +6 -1
- data/features/span.feature +6 -1
- data/features/step_definations/async_steps.rb +63 -0
- data/features/step_definations/button_steps.rb +25 -1
- data/features/step_definations/checkbox_steps.rb +5 -1
- data/features/step_definations/div_steps.rb +6 -1
- data/features/step_definations/element_steps.rb +55 -1
- data/features/step_definations/file_field_steps.rb +27 -0
- data/features/step_definations/form_steps.rb +8 -0
- data/features/step_definations/frame_steps.rb +112 -0
- data/features/step_definations/heading_steps.rb +39 -0
- data/features/step_definations/hidden_field_steps.rb +7 -3
- data/features/step_definations/image_steps.rb +7 -3
- data/features/step_definations/link_steps.rb +8 -3
- data/features/step_definations/list_item_steps.rb +9 -1
- data/features/step_definations/modal_dialog_steps.rb +38 -0
- data/features/step_definations/nested_elements_steps.rb +196 -0
- data/features/step_definations/ordered_list_steps.rb +11 -3
- data/features/step_definations/page_level_actions_steps.rb +72 -0
- data/features/step_definations/paragraph_steps.rb +15 -0
- data/features/step_definations/radio_button_steps.rb +5 -1
- data/features/step_definations/select_list_steps.rb +10 -2
- data/features/step_definations/span_steps.rb +5 -1
- data/features/step_definations/table_cell_steps.rb +5 -1
- data/features/step_definations/table_steps.rb +17 -3
- data/features/step_definations/text_area_steps.rb +18 -2
- data/features/step_definations/text_field_steps.rb +9 -1
- data/features/step_definations/unordered_list_steps.rb +11 -3
- data/features/support/env.rb +0 -15
- data/features/support/hooks.rb +7 -0
- data/features/support/page.rb +98 -1
- data/features/support/persistent_browser.rb +15 -0
- data/features/support/url_helper.rb +24 -1
- data/features/table.feature +7 -0
- data/features/table_cell.feature +6 -0
- data/features/text_area.feature +11 -0
- data/features/text_field.feature +6 -1
- data/features/unordered_list.feature +6 -0
- data/lib/druid.rb +251 -3
- data/lib/druid/accessors.rb +446 -158
- data/lib/druid/assist.rb +394 -0
- data/lib/druid/core_ext/string.rb +5 -0
- data/lib/druid/element_locators.rb +405 -0
- data/lib/druid/elements.rb +28 -0
- data/lib/druid/elements/button.rb +6 -1
- data/lib/druid/elements/check_box.rb +26 -0
- data/lib/druid/elements/div.rb +3 -1
- data/lib/druid/elements/element.rb +170 -5
- data/lib/druid/elements/file_field.rb +18 -0
- data/lib/druid/elements/form.rb +11 -0
- data/lib/druid/elements/heading.rb +14 -0
- data/lib/druid/elements/hidden_field.rb +12 -2
- data/lib/druid/elements/image.rb +13 -0
- data/lib/druid/elements/link.rb +2 -0
- data/lib/druid/elements/list_item.rb +3 -1
- data/lib/druid/elements/option.rb +9 -0
- data/lib/druid/elements/ordered_list.rb +4 -5
- data/lib/druid/elements/paragraph.rb +9 -0
- data/lib/druid/elements/radio_button.rb +25 -0
- data/lib/druid/elements/select_list.rb +10 -1
- data/lib/druid/elements/span.rb +3 -1
- data/lib/druid/elements/table.rb +20 -1
- data/lib/druid/elements/table_cell.rb +7 -0
- data/lib/druid/elements/table_row.rb +5 -1
- data/lib/druid/elements/text_area.rb +15 -1
- data/lib/druid/elements/text_field.rb +11 -1
- data/lib/druid/elements/unordered_list.rb +5 -5
- data/lib/druid/nested_elements.rb +103 -0
- data/lib/druid/page_factory.rb +4 -4
- data/lib/druid/page_populator.rb +71 -0
- data/spec/druid/accessors_spec.rb +789 -0
- data/spec/druid/druid_spec.rb +130 -7
- data/spec/druid/element_locators_spec.rb +160 -0
- data/spec/druid/elements/button_spec.rb +31 -0
- data/spec/druid/elements/check_box_spec.rb +38 -0
- data/spec/druid/elements/div_spec.rb +19 -0
- data/spec/druid/elements/element_spec.rb +150 -0
- data/spec/druid/elements/file_field_spec.rb +27 -0
- data/spec/druid/elements/form_spec.rb +27 -0
- data/spec/druid/elements/heading_spec.rb +39 -0
- data/spec/druid/elements/hidden_field_spec.rb +24 -0
- data/spec/druid/elements/image_spec.rb +32 -0
- data/spec/druid/elements/link_spec.rb +26 -0
- data/spec/druid/elements/list_item_spec.rb +19 -0
- data/spec/druid/elements/option_spec.rb +10 -0
- data/spec/druid/elements/ordered_list_spec.rb +42 -0
- data/spec/druid/elements/page_factory_spec.rb +40 -0
- data/spec/druid/elements/paragraph_spec.rb +21 -0
- data/spec/druid/elements/radio_button_spec.rb +38 -0
- data/spec/druid/elements/select_list_spec.rb +37 -0
- data/spec/druid/elements/span_spec.rb +19 -0
- data/spec/druid/elements/table_cell_spec.rb +23 -0
- data/spec/druid/elements/table_row_spec.rb +41 -0
- data/spec/druid/elements/table_spec.rb +52 -0
- data/spec/druid/elements/text_area_spec.rb +31 -0
- data/spec/druid/elements/text_field_spec.rb +31 -0
- data/spec/druid/elements/unordered_list_spec.rb +42 -0
- data/spec/druid/nested_element_spec.rb +128 -0
- data/spec/druid/page_populator_spec.rb +92 -0
- data/spec/spec_helper.rb +2 -1
- metadata +147 -27
|
@@ -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
|
data/features/table.feature
CHANGED
|
@@ -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"
|
data/features/table_cell.feature
CHANGED
|
@@ -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'
|
data/features/text_area.feature
CHANGED
|
@@ -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 ""
|
data/features/text_field.feature
CHANGED
|
@@ -24,7 +24,7 @@ Feature: Text Fields
|
|
|
24
24
|
| tag_name |
|
|
25
25
|
| index |
|
|
26
26
|
| text |
|
|
27
|
-
|
|
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"
|
data/lib/druid.rb
CHANGED
|
@@ -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
|
-
|
|
42
|
-
|
|
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
|
data/lib/druid/accessors.rb
CHANGED
|
@@ -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
|
|
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 '
|
|
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
|
-
|
|
43
|
-
|
|
80
|
+
return click_link_for identifier.clone unless block_given?
|
|
81
|
+
self.send("#{name}_element").click
|
|
44
82
|
end
|
|
45
|
-
define_method("#{name}
|
|
46
|
-
|
|
47
|
-
|
|
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 '
|
|
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
|
-
|
|
68
|
-
|
|
108
|
+
# :text
|
|
109
|
+
# :title
|
|
110
|
+
def text_field(name, identifier=nil, &block)
|
|
69
111
|
define_method(name) do
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
75
|
-
|
|
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}
|
|
78
|
-
|
|
79
|
-
|
|
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 '
|
|
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
|
-
|
|
103
|
-
|
|
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
|
-
|
|
107
|
-
|
|
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
|
-
|
|
111
|
-
|
|
154
|
+
return checkbox_checked? identifier.clone unless block_given?
|
|
155
|
+
self.send("#{name}_element").checked?
|
|
112
156
|
end
|
|
113
|
-
define_method("#{name}
|
|
114
|
-
|
|
115
|
-
|
|
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 '
|
|
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
|
-
|
|
138
|
-
|
|
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
|
-
|
|
142
|
-
|
|
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}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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 '
|
|
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
|
-
|
|
171
|
-
|
|
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
|
-
|
|
175
|
-
|
|
224
|
+
return radio_selected? identifier.clone unless block_given?
|
|
225
|
+
self.send("#{name}_element").selected?
|
|
176
226
|
end
|
|
177
|
-
define_method("#{name}
|
|
178
|
-
|
|
179
|
-
|
|
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 '
|
|
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
|
-
|
|
202
|
-
|
|
254
|
+
return click_button_for identifier.clone unless block_given?
|
|
255
|
+
self.send("#{name}_element").click
|
|
203
256
|
end
|
|
204
|
-
define_method("#{name}
|
|
205
|
-
|
|
206
|
-
|
|
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 '
|
|
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
|
-
|
|
229
|
-
|
|
283
|
+
return div_text_for identifier.clone unless block_given?
|
|
284
|
+
self.send("#{name}_element").text
|
|
230
285
|
end
|
|
231
|
-
define_method("#{name}
|
|
232
|
-
|
|
233
|
-
|
|
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 '
|
|
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
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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 '
|
|
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
|
-
|
|
279
|
-
|
|
333
|
+
return cell_text_for identifier.clone unless block_given?
|
|
334
|
+
self.send("#{name}_element").text
|
|
280
335
|
end
|
|
281
|
-
define_method("#{name}
|
|
282
|
-
|
|
283
|
-
|
|
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 '
|
|
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
|
-
|
|
306
|
-
|
|
361
|
+
return span_text_for identifier.clone unless block_given?
|
|
362
|
+
self.send("#{name}_element").text
|
|
307
363
|
end
|
|
308
|
-
define_method("#{name}
|
|
309
|
-
|
|
310
|
-
|
|
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 '
|
|
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
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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 '
|
|
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
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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 '
|
|
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
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
383
|
-
|
|
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 '
|
|
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
|
-
|
|
407
|
-
|
|
469
|
+
return list_item_text_for identifier.clone unless block_given?
|
|
470
|
+
self.send("#{name}_element").text
|
|
408
471
|
end
|
|
409
|
-
define_method("#{name}
|
|
410
|
-
|
|
411
|
-
|
|
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 '
|
|
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
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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 '
|
|
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
|
-
|
|
461
|
-
|
|
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(
|
|
464
|
-
|
|
465
|
-
|
|
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}
|
|
468
|
-
|
|
469
|
-
|
|
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 '
|
|
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
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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
|
-
|
|
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
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|