druid-s 1.0.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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +27 -0
- data/ChangeLog +541 -0
- data/Gemfile +8 -0
- data/README.md +78 -0
- data/Rakefile +33 -0
- data/cucumber.yml +6 -0
- data/druid.gemspec +30 -0
- data/features/area.feature +33 -0
- data/features/async.feature +16 -0
- data/features/audio.feature +61 -0
- data/features/bold.feature +20 -0
- data/features/button.feature +81 -0
- data/features/canvas.feature +34 -0
- data/features/checkbox.feature +48 -0
- data/features/div.feature +45 -0
- data/features/element.feature +281 -0
- data/features/file_field.feature +38 -0
- data/features/form.feature +37 -0
- data/features/frames.feature +76 -0
- data/features/generic_elements.feature +29 -0
- data/features/heading.feature +160 -0
- data/features/hidden_field.feature +39 -0
- data/features/html/async.html +31 -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/hover.html +11 -0
- data/features/html/iframes.html +12 -0
- data/features/html/images/circle.png +0 -0
- data/features/html/images/img_pulpit.jpg +0 -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/multi_elements.html +145 -0
- data/features/html/nested_elements.html +75 -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/planets.gif +0 -0
- data/features/html/static_elements.html +203 -0
- data/features/html/success.html +8 -0
- data/features/html/sun.gif +0 -0
- data/features/html/sun.html +7 -0
- data/features/image.feature +47 -0
- data/features/italic.feature +20 -0
- data/features/javascript.feature +28 -0
- data/features/label.feature +43 -0
- data/features/link.feature +56 -0
- data/features/list_item.feature +37 -0
- data/features/modal_dialog.feature +9 -0
- data/features/multi_elements.feature +498 -0
- data/features/nested_elements.feature +121 -0
- data/features/ordered_list.feature +46 -0
- data/features/page_level_actions.feature +116 -0
- data/features/paragraph.feature +33 -0
- data/features/populate_page_with.feature +25 -0
- data/features/radio_button.feature +51 -0
- data/features/radio_button_group.feature +28 -0
- data/features/sample-app/public/04-Death_Becomes_Fur.mp4 +0 -0
- data/features/sample-app/public/04-Death_Becomes_Fur.oga +0 -0
- data/features/sample-app/public/audio_video.html +19 -0
- data/features/sample-app/public/jquery-1.3.2.js +4376 -0
- data/features/sample-app/public/jquery.html +28 -0
- data/features/sample-app/public/movie.mp4 +0 -0
- data/features/sample-app/public/movie.ogg +0 -0
- data/features/sample-app/public/prototype-1.6.0.3.js +4320 -0
- data/features/sample-app/public/prototype.html +32 -0
- data/features/sample-app/sample_app.rb +35 -0
- data/features/section.feature +132 -0
- data/features/select_list.feature +84 -0
- data/features/span.feature +43 -0
- data/features/step_definations/area_steps.rb +23 -0
- data/features/step_definations/async_steps.rb +80 -0
- data/features/step_definations/audio_steps.rb +47 -0
- data/features/step_definations/bold_steps.rb +11 -0
- data/features/step_definations/button_steps.rb +52 -0
- data/features/step_definations/canvas_steps.rb +19 -0
- data/features/step_definations/checkbox_steps.rb +39 -0
- data/features/step_definations/div_steps.rb +28 -0
- data/features/step_definations/element_steps.rb +217 -0
- data/features/step_definations/file_field_steps.rb +31 -0
- data/features/step_definations/form_steps.rb +23 -0
- data/features/step_definations/frame_steps.rb +189 -0
- data/features/step_definations/generic_element_steps.rb +31 -0
- data/features/step_definations/heading_steps.rb +39 -0
- data/features/step_definations/hidden_field_steps.rb +27 -0
- data/features/step_definations/image_steps.rb +35 -0
- data/features/step_definations/italic_steps.rb +11 -0
- data/features/step_definations/javasript_steps.rb +52 -0
- data/features/step_definations/label_steps.rb +19 -0
- data/features/step_definations/link_steps.rb +42 -0
- data/features/step_definations/list_item_steps.rb +24 -0
- data/features/step_definations/modal_dialog_steps.rb +38 -0
- data/features/step_definations/multi_elements_steps.rb +557 -0
- data/features/step_definations/nested_elements_steps.rb +219 -0
- data/features/step_definations/ordered_list_steps.rb +49 -0
- data/features/step_definations/page_level_actions_steps.rb +172 -0
- data/features/step_definations/page_traversal_steps.rb +4 -0
- data/features/step_definations/paragraph_steps.rb +19 -0
- data/features/step_definations/populate_page_with_steps.rb +3 -0
- data/features/step_definations/radio_button_group_steps.rb +32 -0
- data/features/step_definations/radio_button_steps.rb +31 -0
- data/features/step_definations/section_steps.rb +271 -0
- data/features/step_definations/select_list_steps.rb +91 -0
- data/features/step_definations/span_steps.rb +23 -0
- data/features/step_definations/table_cell_steps.rb +27 -0
- data/features/step_definations/table_row_steps.rb +23 -0
- data/features/step_definations/table_steps.rb +109 -0
- data/features/step_definations/text_area_steps.rb +39 -0
- data/features/step_definations/text_field_steps.rb +39 -0
- data/features/step_definations/unordered_list_steps.rb +27 -0
- data/features/step_definations/video_steps.rb +27 -0
- data/features/support/ajax_test_environment.rb +26 -0
- data/features/support/audio_video_page.rb +23 -0
- data/features/support/env.rb +5 -0
- data/features/support/hooks.rb +3 -0
- data/features/support/page.rb +372 -0
- data/features/support/persistent_browser.rb +58 -0
- data/features/support/targets/firefox14_osx.rb +5 -0
- data/features/support/targets/firefox14_windows7.rb +5 -0
- data/features/support/url_helper.rb +50 -0
- data/features/table.feature +127 -0
- data/features/table_cell.feature +42 -0
- data/features/table_row.feature +30 -0
- data/features/text_area.feature +44 -0
- data/features/text_field.feature +53 -0
- data/features/unordered_list.feature +46 -0
- data/features/video.feature +66 -0
- data/lib/druid/accessors.rb +1082 -0
- data/lib/druid/assist.rb +653 -0
- data/lib/druid/element_locators.rb +21 -0
- data/lib/druid/elements/area.rb +9 -0
- data/lib/druid/elements/audio.rb +9 -0
- data/lib/druid/elements/bold.rb +8 -0
- data/lib/druid/elements/button.rb +12 -0
- data/lib/druid/elements/canvas.rb +9 -0
- data/lib/druid/elements/check_box.rb +9 -0
- data/lib/druid/elements/div.rb +9 -0
- data/lib/druid/elements/element.rb +187 -0
- data/lib/druid/elements/file_field.rb +9 -0
- data/lib/druid/elements/form.rb +9 -0
- data/lib/druid/elements/heading.rb +14 -0
- data/lib/druid/elements/hidden_field.rb +9 -0
- data/lib/druid/elements/image.rb +9 -0
- data/lib/druid/elements/italic.rb +9 -0
- data/lib/druid/elements/label.rb +8 -0
- data/lib/druid/elements/link.rb +9 -0
- data/lib/druid/elements/list_item.rb +9 -0
- data/lib/druid/elements/media.rb +11 -0
- data/lib/druid/elements/option.rb +9 -0
- data/lib/druid/elements/ordered_list.rb +29 -0
- data/lib/druid/elements/paragraph.rb +9 -0
- data/lib/druid/elements/radio_button.rb +9 -0
- data/lib/druid/elements/select_list.rb +30 -0
- data/lib/druid/elements/span.rb +9 -0
- data/lib/druid/elements/table.rb +92 -0
- data/lib/druid/elements/table_cell.rb +11 -0
- data/lib/druid/elements/table_row.rb +50 -0
- data/lib/druid/elements/text_area.rb +10 -0
- data/lib/druid/elements/text_field.rb +11 -0
- data/lib/druid/elements/unordered_list.rb +32 -0
- data/lib/druid/elements/video.rb +8 -0
- data/lib/druid/elements.rb +55 -0
- data/lib/druid/javascript/angularjs.rb +12 -0
- data/lib/druid/javascript/jquery.rb +12 -0
- data/lib/druid/javascript/prototype.rb +12 -0
- data/lib/druid/javascript/yui.rb +19 -0
- data/lib/druid/javascript_framework_facade.rb +76 -0
- data/lib/druid/locator_generator.rb +181 -0
- data/lib/druid/nested_elements.rb +56 -0
- data/lib/druid/page_factory.rb +115 -0
- data/lib/druid/page_populator.rb +104 -0
- data/lib/druid/section_collection.rb +17 -0
- data/lib/druid/version.rb +3 -0
- data/lib/druid.rb +452 -0
- data/spec/druid/accessors_spec.rb +1209 -0
- data/spec/druid/druid_spec.rb +295 -0
- data/spec/druid/element_locators_spec.rb +750 -0
- data/spec/druid/elements/bold_spec.rb +12 -0
- data/spec/druid/elements/button_spec.rb +23 -0
- data/spec/druid/elements/check_box_spec.rb +14 -0
- data/spec/druid/elements/div_spec.rb +10 -0
- data/spec/druid/elements/element_spec.rb +250 -0
- data/spec/druid/elements/file_field_spec.rb +13 -0
- data/spec/druid/elements/form_spec.rb +18 -0
- data/spec/druid/elements/heading_spec.rb +30 -0
- data/spec/druid/elements/hidden_field_spec.rb +10 -0
- data/spec/druid/elements/image_spec.rb +23 -0
- data/spec/druid/elements/itatic_spec.rb +11 -0
- data/spec/druid/elements/label_spec.rb +10 -0
- data/spec/druid/elements/link_spec.rb +10 -0
- data/spec/druid/elements/list_item_spec.rb +10 -0
- data/spec/druid/elements/media_spec.rb +12 -0
- data/spec/druid/elements/option_spec.rb +21 -0
- data/spec/druid/elements/ordered_list_spec.rb +38 -0
- data/spec/druid/elements/page_factory_spec.rb +40 -0
- data/spec/druid/elements/paragraph_spec.rb +12 -0
- data/spec/druid/elements/radio_button_spec.rb +14 -0
- data/spec/druid/elements/select_list_spec.rb +51 -0
- data/spec/druid/elements/span_spec.rb +10 -0
- data/spec/druid/elements/table_cell_spec.rb +14 -0
- data/spec/druid/elements/table_row_spec.rb +34 -0
- data/spec/druid/elements/table_spec.rb +47 -0
- data/spec/druid/elements/text_area_spec.rb +13 -0
- data/spec/druid/elements/text_field_spec.rb +22 -0
- data/spec/druid/elements/unordered_list_spec.rb +39 -0
- data/spec/druid/javascript_framework_facade_spec.rb +59 -0
- data/spec/druid/nested_element_spec.rb +128 -0
- data/spec/druid/page_factory_spec.rb +235 -0
- data/spec/druid/page_populator_spec.rb +173 -0
- data/spec/druid/page_section_spec.rb +70 -0
- data/spec/spec_helper.rb +9 -0
- metadata +517 -0
data/lib/druid.rb
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
require 'watir'
|
|
2
|
+
require 'druid/accessors'
|
|
3
|
+
require 'druid/assist'
|
|
4
|
+
require 'druid/page_factory'
|
|
5
|
+
require 'druid/element_locators'
|
|
6
|
+
require 'druid/page_populator'
|
|
7
|
+
require 'druid/section_collection'
|
|
8
|
+
require 'druid/javascript_framework_facade'
|
|
9
|
+
|
|
10
|
+
# require 'watir/extensions/alerts'
|
|
11
|
+
#
|
|
12
|
+
# Module that when included adds functionality to a page object. This module
|
|
13
|
+
# will add numerous class and instance methods that you use to define and
|
|
14
|
+
# interact with web pages.
|
|
15
|
+
#
|
|
16
|
+
# If we have a login page with a username and password textfield and a login
|
|
17
|
+
# button we might define our page like the one below. We can then interact with
|
|
18
|
+
# the object using the generated methods.
|
|
19
|
+
#
|
|
20
|
+
# @example Login page example
|
|
21
|
+
# class LoginPage
|
|
22
|
+
# include Druid
|
|
23
|
+
#
|
|
24
|
+
# text_field(:username, :id => 'user')
|
|
25
|
+
# text_field(:password, :id => 'pass')
|
|
26
|
+
# button(:login, :value => 'Login')
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# ...
|
|
30
|
+
#
|
|
31
|
+
# browser = Watir::Browser.new :firefox
|
|
32
|
+
# login_page = LoginPage.new(browser)
|
|
33
|
+
# login_page.username = 'tim'
|
|
34
|
+
# login_page.password = 'sheng'
|
|
35
|
+
# login_page.login
|
|
36
|
+
#
|
|
37
|
+
# @see Druid::Accessors to see what class level methods are added to this module at runtime.
|
|
38
|
+
#
|
|
39
|
+
module Druid
|
|
40
|
+
include Assist
|
|
41
|
+
include ElementLocators
|
|
42
|
+
include PagePopulator
|
|
43
|
+
# extend Forwardable
|
|
44
|
+
|
|
45
|
+
def method_missing(method, *args, &block)
|
|
46
|
+
@root_element.send(method, *args, &block)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def respond_to_missing?(method, include_all = false)
|
|
50
|
+
@root_element && @root_element.respond_to?(method) || super
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Forward visibility checks to root so page sections can be tested for existence.
|
|
54
|
+
# def_delegators :root, :visible?, :exist?
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# @return [Watir::Browser] the drvier passed to the constructor
|
|
58
|
+
attr_reader :driver
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Construct a new druid. Prior to browser initialization it will call
|
|
62
|
+
# a method named initialize_accessors if it exists. Upon initialization of
|
|
63
|
+
# the page it will call a method named initialize_page if it exists
|
|
64
|
+
#
|
|
65
|
+
# @param [Watir::Browser, Watir:HTMLElement] the driver/element to use
|
|
66
|
+
# @param [bool] open the page if page_url is set
|
|
67
|
+
#
|
|
68
|
+
def initialize(root, visit=false)
|
|
69
|
+
initialize_accessors if respond_to?(:initialize_accessors)
|
|
70
|
+
initialize_driver root
|
|
71
|
+
goto if visit && respond_to?(:goto)
|
|
72
|
+
initialize_page if respond_to?(:initialize_page)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def initialize_driver root
|
|
76
|
+
@driver = root if root.is_a? Watir::HTMLElement or root.is_a? Watir::Browser
|
|
77
|
+
@root_element = Elements::Element.new root if root.is_a? Watir::HTMLElement
|
|
78
|
+
raise "expect Watir::Browser or Watir::HTMLElement" if not root.is_a? Watir::HTMLElement and not root.is_a? Watir::Browser
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @private
|
|
82
|
+
def self.included(cls)
|
|
83
|
+
cls.extend Druid::Accessors
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# navigate to the provided url
|
|
88
|
+
#
|
|
89
|
+
# @param [String] the full url to navigate to
|
|
90
|
+
#
|
|
91
|
+
def navigate_to url
|
|
92
|
+
driver.goto url
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Set the default timeout for page level Waits
|
|
97
|
+
#
|
|
98
|
+
def self.default_page_wait=(timeout)
|
|
99
|
+
@page_wait = timeout
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Return the default timeout for page level Waits
|
|
104
|
+
#
|
|
105
|
+
def self.default_page_wait
|
|
106
|
+
@page_wait ||= 30
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
# Sets the default timeout for element level Waits
|
|
111
|
+
#
|
|
112
|
+
def self.default_element_wait=(timeout)
|
|
113
|
+
@element_wait = timeout
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# Returns the default timeout for element level Waits
|
|
118
|
+
#
|
|
119
|
+
def self.default_element_wait
|
|
120
|
+
@element_wait ||= 5
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# Set the javascript framework to use when determining number of
|
|
125
|
+
# ajax requests. Valid frameworks are :jquery, :prototype, and :yui,
|
|
126
|
+
# and :angularjs
|
|
127
|
+
#
|
|
128
|
+
def self.javascript_framework=(framework)
|
|
129
|
+
Druid::JavascriptFrameworkFacade.framework = framework
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
# Add a new javascript framework to druid. The module passed
|
|
134
|
+
# in must adhere to the same prototype as the JQuery and Prototype
|
|
135
|
+
# modules.
|
|
136
|
+
#
|
|
137
|
+
# @param [Symbol] the name used to reference the framework in
|
|
138
|
+
# subsequent calls
|
|
139
|
+
# @param [Module] a module that has the necessary methods to perform
|
|
140
|
+
# the required actions.
|
|
141
|
+
#
|
|
142
|
+
def self.add_framework(key, framework)
|
|
143
|
+
Druid::JavascriptFrameworkFacade.add_framework(key, framework)
|
|
144
|
+
end
|
|
145
|
+
#
|
|
146
|
+
# get the current page url
|
|
147
|
+
#
|
|
148
|
+
def current_url
|
|
149
|
+
driver.url
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
#
|
|
153
|
+
# Returns the text of the current page
|
|
154
|
+
#
|
|
155
|
+
def text
|
|
156
|
+
driver.text
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
#
|
|
160
|
+
# Returns the html of the current page
|
|
161
|
+
#
|
|
162
|
+
def html
|
|
163
|
+
driver.html
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
#
|
|
167
|
+
# Returns the title of the current page
|
|
168
|
+
#
|
|
169
|
+
def title
|
|
170
|
+
driver.title
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
#
|
|
174
|
+
# Refresh current page
|
|
175
|
+
#
|
|
176
|
+
def refresh
|
|
177
|
+
driver.refresh
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
#
|
|
181
|
+
# Waits until readyState of document is complete
|
|
182
|
+
#
|
|
183
|
+
# @example
|
|
184
|
+
# @page.wait
|
|
185
|
+
#
|
|
186
|
+
# @param [Integer] timeout
|
|
187
|
+
#
|
|
188
|
+
def wait(timeout = 5)
|
|
189
|
+
driver.wait(timeout = 5)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
#
|
|
193
|
+
# Go back to the previous page
|
|
194
|
+
#
|
|
195
|
+
def back
|
|
196
|
+
driver.back
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
#
|
|
200
|
+
# Go forward to the next page
|
|
201
|
+
#
|
|
202
|
+
def forward
|
|
203
|
+
driver.forward
|
|
204
|
+
end
|
|
205
|
+
#
|
|
206
|
+
# Wait until the block returns true or times out
|
|
207
|
+
#
|
|
208
|
+
# @example
|
|
209
|
+
# @page.wait_until(5, 'Success not found on page') do
|
|
210
|
+
# @page.text.include? 'Success'
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
# @param [Numeric] the amount of time to wait for the block to return true
|
|
214
|
+
# @param [String] the message to include with the error if we exceed the timeout duration
|
|
215
|
+
# @param block the block to execute. It should return true when successful.
|
|
216
|
+
#
|
|
217
|
+
def wait_until(timeout = Druid.default_page_wait, message = nil, &block)
|
|
218
|
+
driver.wait_until(timeout: timeout, message: message, &block)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
#
|
|
222
|
+
# wait until there are no pending ajax requests. This requires you to set the javascript framework in advance.
|
|
223
|
+
#
|
|
224
|
+
# @param [Numeric] the amount of time to wait for the block to return true.
|
|
225
|
+
# @param [String] the message to include with the error if we exceed the timeout duration
|
|
226
|
+
#
|
|
227
|
+
def wait_for_ajax(timeout = Druid.default_page_wait, message = nil)
|
|
228
|
+
end_time = ::Time.now + timeout
|
|
229
|
+
until ::Time.now > end_time
|
|
230
|
+
return if driver.execute_script(Druid::JavascriptFrameworkFacade.pending_requests) == 0
|
|
231
|
+
sleep 1
|
|
232
|
+
end
|
|
233
|
+
message = "Timed out waiting for ajax requests to complete" unless message
|
|
234
|
+
raise message
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
#
|
|
238
|
+
# Override the normal alert popup so it does not occur.
|
|
239
|
+
#
|
|
240
|
+
# @example
|
|
241
|
+
# message = @page.alert do
|
|
242
|
+
# @page.button_that_causes_alert
|
|
243
|
+
# end
|
|
244
|
+
#
|
|
245
|
+
# @param block a block that has the call that will cause the alert to display
|
|
246
|
+
# @return [String] the message that was contained in the alert
|
|
247
|
+
#
|
|
248
|
+
def alert(&block)
|
|
249
|
+
# switch_to_frame(frame)
|
|
250
|
+
yield
|
|
251
|
+
value = nil
|
|
252
|
+
if driver.alert.exists?
|
|
253
|
+
value = driver.alert.text
|
|
254
|
+
driver.alert.ok
|
|
255
|
+
end
|
|
256
|
+
# switch_to_default_content(frame)
|
|
257
|
+
value
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
#
|
|
261
|
+
# Override the normal confirm popup so it does not occur
|
|
262
|
+
#
|
|
263
|
+
# @example
|
|
264
|
+
# message = @popup.confirm(true) do
|
|
265
|
+
# @page.button_that_causes_confirm
|
|
266
|
+
# end
|
|
267
|
+
#
|
|
268
|
+
# @param [boolean] what response you want to return back from the confirm popup
|
|
269
|
+
# @param block a block that has the call that will cause the confirm to display
|
|
270
|
+
# @return [String] the message that was contained in the confirm
|
|
271
|
+
#
|
|
272
|
+
def confirm(response, &block)
|
|
273
|
+
yield
|
|
274
|
+
value = nil
|
|
275
|
+
if driver.alert.exists?
|
|
276
|
+
value = driver.alert.text
|
|
277
|
+
response ? driver.alert.ok : driver.alert.close
|
|
278
|
+
end
|
|
279
|
+
value
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
#
|
|
283
|
+
# Override the normal prompt popup so it does not occur
|
|
284
|
+
#
|
|
285
|
+
# @example
|
|
286
|
+
# message = @popup.prompt("Some Value") do
|
|
287
|
+
# @page.button_that_causes_prompt
|
|
288
|
+
# end
|
|
289
|
+
#
|
|
290
|
+
# @param [String] the value will be setted in the prompt field
|
|
291
|
+
# @param block a block that has the call that will cause the prompt to display
|
|
292
|
+
# @return [String] the message that was contained in the prompt
|
|
293
|
+
#
|
|
294
|
+
def prompt(answer, &block)
|
|
295
|
+
yield
|
|
296
|
+
value = nil
|
|
297
|
+
if driver.alert.exists?
|
|
298
|
+
value = driver.alert.text
|
|
299
|
+
driver.alert.set answer
|
|
300
|
+
driver.alert.ok
|
|
301
|
+
end
|
|
302
|
+
value
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
#
|
|
306
|
+
# Execute javascript on the browser
|
|
307
|
+
#
|
|
308
|
+
def execute_script(script, *args)
|
|
309
|
+
args.map! { |e| e.kind_of?(Druid::Elements::Element) ? e.element : e }
|
|
310
|
+
driver.execute_script(script, *args)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
#
|
|
314
|
+
# Attach to a running window. You can locate the window using either
|
|
315
|
+
# the window's title or url or index, If it fails to connect to a window it will
|
|
316
|
+
# pause for 1 second and try again.
|
|
317
|
+
#
|
|
318
|
+
# @example
|
|
319
|
+
# @page.attach_to_window(:title => "other window's title")
|
|
320
|
+
#
|
|
321
|
+
# @param [Hash] either :title or :url or index of the other window. The url does not need to
|
|
322
|
+
# be the entire url - it can just be the page name like index.html
|
|
323
|
+
#
|
|
324
|
+
def attach_to_window(identifier, &block)
|
|
325
|
+
if identifier.keys.first == :url
|
|
326
|
+
win_id = {identifier.keys.first => /#{Regexp.escape(identifier.values.first)}/}
|
|
327
|
+
else
|
|
328
|
+
win_id = {identifier.keys.first => identifier.values.first}
|
|
329
|
+
end
|
|
330
|
+
begin
|
|
331
|
+
driver.window(win_id).use &block
|
|
332
|
+
rescue
|
|
333
|
+
sleep 1
|
|
334
|
+
driver.window(win_id).use &block
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
#
|
|
339
|
+
# Find the element that has focus on the page
|
|
340
|
+
#
|
|
341
|
+
def element_with_focus
|
|
342
|
+
element = driver.execute_script("return document.activeElement")
|
|
343
|
+
type = element.type.to_sym if element.tag_name.to_sym == :input
|
|
344
|
+
cls = Druid::Elements.element_class_for(element.tag_name, type)
|
|
345
|
+
cls.new(element)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
#
|
|
349
|
+
# Override the normal showModalDialog call is it opens a window instead of a dialog.
|
|
350
|
+
# You will need to attach to the new window in order to continue.
|
|
351
|
+
#
|
|
352
|
+
# @example
|
|
353
|
+
# @page.modal_dialog do
|
|
354
|
+
# @page.action_that_spawns_the_modal
|
|
355
|
+
# end
|
|
356
|
+
#
|
|
357
|
+
# @param block a block that contains the call that will cause the modal dialog.
|
|
358
|
+
#
|
|
359
|
+
def modal_dialog(&block)
|
|
360
|
+
script =
|
|
361
|
+
%Q{
|
|
362
|
+
window.showModalDialog = function(sURL, vArguments, sFeatures) {
|
|
363
|
+
window.dialogArguments = vArguments;
|
|
364
|
+
modalWin = window.open(sURL, 'modal', sFeatures);
|
|
365
|
+
return modalWin;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
driver.execute_script script
|
|
369
|
+
yield if block_given?
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
#
|
|
373
|
+
# Handle cookies
|
|
374
|
+
#
|
|
375
|
+
# @return [Watir::Cookies]
|
|
376
|
+
#
|
|
377
|
+
def cookies
|
|
378
|
+
driver.cookies
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
#
|
|
382
|
+
# Save the current screenshot to the provided path. File is saved as a png file.
|
|
383
|
+
|
|
384
|
+
def save_screenshot(file_name)
|
|
385
|
+
driver.screenshot.save(file_name)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
#
|
|
389
|
+
# Identify an element as existing within a frame. A frame parameter is
|
|
390
|
+
# passed to the block and must be passed to the other calls to Druid.
|
|
391
|
+
# You can nest calls to in_frame by passing the frame to the next level.
|
|
392
|
+
#
|
|
393
|
+
# @example
|
|
394
|
+
# @page.in_frame(:id => 'frame_id') do |frame|
|
|
395
|
+
# @page.text_field_element(:id=> 'fname', :frame => frame)
|
|
396
|
+
# end
|
|
397
|
+
#
|
|
398
|
+
# @param [Hash] identifier how we find the frame. The valid keys are:
|
|
399
|
+
# * :id
|
|
400
|
+
# * :index
|
|
401
|
+
# * :name
|
|
402
|
+
# @param block that contains the calls to elements that exist inside the frame.
|
|
403
|
+
#
|
|
404
|
+
def in_frame(identifier, frame=nil, &block)
|
|
405
|
+
frame = [] if frame.nil?
|
|
406
|
+
frame << {frame: identifier}
|
|
407
|
+
block.call(frame)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
#
|
|
411
|
+
# Identify an element as existing within an iframe. Aframe parameter is
|
|
412
|
+
# passed to the block and must be passed to the other calls to Druid.
|
|
413
|
+
# You can nest calls to in_iframe by passing the frame to the next level.
|
|
414
|
+
#
|
|
415
|
+
# @example
|
|
416
|
+
# @page.in_iframe(:id => 'frame_id') do |frame|
|
|
417
|
+
# @page.text_field_element(:id=> 'fname', :frame => frame)
|
|
418
|
+
# end
|
|
419
|
+
#
|
|
420
|
+
# @param [Hash] identifier how we find the frame. The valid keys are:
|
|
421
|
+
# * :id
|
|
422
|
+
# * :index
|
|
423
|
+
# * :name
|
|
424
|
+
# @param block that contains the calls to elements that exist inside the frame.
|
|
425
|
+
#
|
|
426
|
+
def in_iframe(identifier, frame=nil, &block)
|
|
427
|
+
frame = [] if frame.nil?
|
|
428
|
+
frame << {iframe: identifier}
|
|
429
|
+
block.call(frame)
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def switch_to_frame(frame_identifiers)
|
|
433
|
+
unless frame_identifiers.nil?
|
|
434
|
+
frame_identifiers.each do |frame|
|
|
435
|
+
frame_id = frame.values.first
|
|
436
|
+
value = frame_id.values.first
|
|
437
|
+
driver.wd.switch_to.frame(value)
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def call_block(&block)
|
|
443
|
+
block.arity == 1 ? block.call(self) : self.instance_eval(&block)
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
private
|
|
447
|
+
|
|
448
|
+
def root
|
|
449
|
+
@root_element || driver
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
end
|