browserstack-webdriver 0.0.1
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/CHANGES +791 -0
- data/README.md +31 -0
- data/build.desc +334 -0
- data/lib/selenium-client.rb +2 -0
- data/lib/selenium-webdriver.rb +1 -0
- data/lib/selenium/client.rb +37 -0
- data/lib/selenium/client/base.rb +132 -0
- data/lib/selenium/client/driver.rb +10 -0
- data/lib/selenium/client/errors.rb +9 -0
- data/lib/selenium/client/extensions.rb +118 -0
- data/lib/selenium/client/idiomatic.rb +488 -0
- data/lib/selenium/client/javascript_expression_builder.rb +116 -0
- data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
- data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
- data/lib/selenium/client/legacy_driver.rb +1720 -0
- data/lib/selenium/client/protocol.rb +104 -0
- data/lib/selenium/client/selenium_helper.rb +34 -0
- data/lib/selenium/rake/server_task.rb +157 -0
- data/lib/selenium/server.rb +248 -0
- data/lib/selenium/webdriver.rb +71 -0
- data/lib/selenium/webdriver/android.rb +9 -0
- data/lib/selenium/webdriver/android/bridge.rb +47 -0
- data/lib/selenium/webdriver/chrome.rb +26 -0
- data/lib/selenium/webdriver/chrome/bridge.rb +120 -0
- data/lib/selenium/webdriver/chrome/profile.rb +90 -0
- data/lib/selenium/webdriver/chrome/service.rb +75 -0
- data/lib/selenium/webdriver/common.rb +44 -0
- data/lib/selenium/webdriver/common/action_builder.rb +352 -0
- data/lib/selenium/webdriver/common/alert.rb +30 -0
- data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
- data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
- data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
- data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
- data/lib/selenium/webdriver/common/driver.rb +301 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_browser_connection.rb +17 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +25 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +13 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +22 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +19 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +22 -0
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +45 -0
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
- data/lib/selenium/webdriver/common/element.rb +293 -0
- data/lib/selenium/webdriver/common/error.rb +207 -0
- data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
- data/lib/selenium/webdriver/common/html5/local_storage.rb +42 -0
- data/lib/selenium/webdriver/common/html5/location.rb +0 -0
- data/lib/selenium/webdriver/common/html5/session_storage.rb +44 -0
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +42 -0
- data/lib/selenium/webdriver/common/json_helper.rb +34 -0
- data/lib/selenium/webdriver/common/keyboard.rb +55 -0
- data/lib/selenium/webdriver/common/keys.rb +109 -0
- data/lib/selenium/webdriver/common/log_entry.rb +29 -0
- data/lib/selenium/webdriver/common/logs.rb +23 -0
- data/lib/selenium/webdriver/common/mouse.rb +72 -0
- data/lib/selenium/webdriver/common/navigation.rb +43 -0
- data/lib/selenium/webdriver/common/options.rb +136 -0
- data/lib/selenium/webdriver/common/platform.rb +218 -0
- data/lib/selenium/webdriver/common/port_prober.rb +42 -0
- data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
- data/lib/selenium/webdriver/common/proxy.rb +149 -0
- data/lib/selenium/webdriver/common/search_context.rb +92 -0
- data/lib/selenium/webdriver/common/socket_poller.rb +105 -0
- data/lib/selenium/webdriver/common/target_locator.rb +81 -0
- data/lib/selenium/webdriver/common/timeouts.rb +38 -0
- data/lib/selenium/webdriver/common/touch_action_builder.rb +64 -0
- data/lib/selenium/webdriver/common/touch_screen.rb +105 -0
- data/lib/selenium/webdriver/common/wait.rb +63 -0
- data/lib/selenium/webdriver/common/window.rb +104 -0
- data/lib/selenium/webdriver/common/zipper.rb +82 -0
- data/lib/selenium/webdriver/firefox.rb +37 -0
- data/lib/selenium/webdriver/firefox/binary.rb +158 -0
- data/lib/selenium/webdriver/firefox/bridge.rb +70 -0
- data/lib/selenium/webdriver/firefox/extension.rb +52 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +106 -0
- data/lib/selenium/webdriver/firefox/profile.rb +263 -0
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
- data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
- data/lib/selenium/webdriver/firefox/util.rb +29 -0
- data/lib/selenium/webdriver/ie.rb +19 -0
- data/lib/selenium/webdriver/ie/bridge.rb +68 -0
- data/lib/selenium/webdriver/ie/server.rb +86 -0
- data/lib/selenium/webdriver/iphone.rb +9 -0
- data/lib/selenium/webdriver/iphone/bridge.rb +45 -0
- data/lib/selenium/webdriver/opera.rb +24 -0
- data/lib/selenium/webdriver/opera/bridge.rb +112 -0
- data/lib/selenium/webdriver/opera/service.rb +49 -0
- data/lib/selenium/webdriver/phantomjs.rb +22 -0
- data/lib/selenium/webdriver/phantomjs/bridge.rb +59 -0
- data/lib/selenium/webdriver/phantomjs/service.rb +90 -0
- data/lib/selenium/webdriver/remote.rb +22 -0
- data/lib/selenium/webdriver/remote/bridge.rb +644 -0
- data/lib/selenium/webdriver/remote/capabilities.rb +267 -0
- data/lib/selenium/webdriver/remote/commands.rb +193 -0
- data/lib/selenium/webdriver/remote/http/common.rb +74 -0
- data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
- data/lib/selenium/webdriver/remote/http/default.rb +139 -0
- data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
- data/lib/selenium/webdriver/remote/response.rb +97 -0
- data/lib/selenium/webdriver/remote/server_error.rb +17 -0
- data/lib/selenium/webdriver/safari.rb +46 -0
- data/lib/selenium/webdriver/safari/bridge.rb +110 -0
- data/lib/selenium/webdriver/safari/browser.rb +20 -0
- data/lib/selenium/webdriver/safari/extension.rb +120 -0
- data/lib/selenium/webdriver/safari/server.rb +145 -0
- data/lib/selenium/webdriver/support.rb +5 -0
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
- data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
- data/lib/selenium/webdriver/support/color.rb +110 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
- data/lib/selenium/webdriver/support/select.rb +293 -0
- data/ruby.iml +13 -0
- data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
- data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
- data/spec/integration/selenium/client/api/click_spec.rb +39 -0
- data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
- data/spec/integration/selenium/client/api/element_spec.rb +14 -0
- data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
- data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
- data/spec/integration/selenium/client/api/screenshot_spec.rb +31 -0
- data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
- data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
- data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
- data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
- data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
- data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
- data/spec/integration/selenium/client/api/webdriver_backed_spec.rb +21 -0
- data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
- data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
- data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
- data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
- data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
- data/spec/integration/selenium/client/spec_helper.rb +139 -0
- data/spec/integration/selenium/webdriver/app_cache_spec.rb +47 -0
- data/spec/integration/selenium/webdriver/browser_connection_spec.rb +20 -0
- data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
- data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +63 -0
- data/spec/integration/selenium/webdriver/driver_spec.rb +266 -0
- data/spec/integration/selenium/webdriver/element_spec.rb +191 -0
- data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
- data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
- data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
- data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
- data/spec/integration/selenium/webdriver/location_spec.rb +29 -0
- data/spec/integration/selenium/webdriver/mouse_spec.rb +57 -0
- data/spec/integration/selenium/webdriver/navigation_spec.rb +46 -0
- data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
- data/spec/integration/selenium/webdriver/options_spec.rb +77 -0
- data/spec/integration/selenium/webdriver/remote/driver_spec.rb +19 -0
- data/spec/integration/selenium/webdriver/remote/element_spec.rb +26 -0
- data/spec/integration/selenium/webdriver/spec_helper.rb +36 -0
- data/spec/integration/selenium/webdriver/spec_support.rb +12 -0
- data/spec/integration/selenium/webdriver/spec_support/guards.rb +110 -0
- data/spec/integration/selenium/webdriver/spec_support/helpers.rb +51 -0
- data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
- data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +239 -0
- data/spec/integration/selenium/webdriver/sql_database_spec.rb +59 -0
- data/spec/integration/selenium/webdriver/storage_spec.rb +96 -0
- data/spec/integration/selenium/webdriver/target_locator_spec.rb +186 -0
- data/spec/integration/selenium/webdriver/timeout_spec.rb +69 -0
- data/spec/integration/selenium/webdriver/touch_spec.rb +176 -0
- data/spec/integration/selenium/webdriver/window_spec.rb +70 -0
- data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
- data/spec/unit/selenium/client/base_spec.rb +239 -0
- data/spec/unit/selenium/client/extensions_spec.rb +174 -0
- data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
- data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
- data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
- data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
- data/spec/unit/selenium/client/protocol_spec.rb +124 -0
- data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
- data/spec/unit/selenium/client/spec_helper.rb +24 -0
- data/spec/unit/selenium/rake/task_spec.rb +79 -0
- data/spec/unit/selenium/server_spec.rb +150 -0
- data/spec/unit/selenium/webdriver/action_builder_spec.rb +97 -0
- data/spec/unit/selenium/webdriver/android/bridge_spec.rb +43 -0
- data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +137 -0
- data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
- data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
- data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
- data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +47 -0
- data/spec/unit/selenium/webdriver/ie/bridge_spec.rb +91 -0
- data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +42 -0
- data/spec/unit/selenium/webdriver/log_entry_spec.rb +11 -0
- data/spec/unit/selenium/webdriver/opera/bridge_spec.rb +44 -0
- data/spec/unit/selenium/webdriver/phantomjs/bridge_spec.rb +55 -0
- data/spec/unit/selenium/webdriver/proxy_spec.rb +106 -0
- data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
- data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +115 -0
- data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
- data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +124 -0
- data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
- data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
- data/spec/unit/selenium/webdriver/spec_helper.rb +27 -0
- data/spec/unit/selenium/webdriver/support/color_spec.rb +119 -0
- data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
- data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
- data/spec/unit/selenium/webdriver/wait_spec.rb +49 -0
- metadata +370 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
require 'selenium/webdriver/remote/capabilities'
|
|
4
|
+
require 'selenium/webdriver/remote/bridge'
|
|
5
|
+
require 'selenium/webdriver/remote/server_error'
|
|
6
|
+
require 'selenium/webdriver/remote/response'
|
|
7
|
+
require 'selenium/webdriver/remote/commands'
|
|
8
|
+
require 'selenium/webdriver/remote/http/common'
|
|
9
|
+
require 'selenium/webdriver/remote/http/default'
|
|
10
|
+
require 'selenium/webdriver/remote/http/curb'
|
|
11
|
+
|
|
12
|
+
module Selenium
|
|
13
|
+
module WebDriver
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
module Remote
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
@@ -0,0 +1,644 @@
|
|
|
1
|
+
module Selenium
|
|
2
|
+
module WebDriver
|
|
3
|
+
module Remote
|
|
4
|
+
|
|
5
|
+
COMMANDS = {}
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Low level bridge to the remote server, through which the rest of the API works.
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
class Bridge
|
|
14
|
+
include BridgeHelper
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# Defines a wrapper method for a command, which ultimately calls #execute.
|
|
18
|
+
#
|
|
19
|
+
# @param name [Symbol]
|
|
20
|
+
# name of the resulting method
|
|
21
|
+
# @param url [String]
|
|
22
|
+
# a URL template, which can include some arguments, much like the definitions on the server.
|
|
23
|
+
# the :session_id parameter is implicitly handled, but the remainder will become required method arguments.
|
|
24
|
+
# @param verb [Symbol]
|
|
25
|
+
# the appropriate http verb, such as :get, :post, or :delete
|
|
26
|
+
#
|
|
27
|
+
|
|
28
|
+
def self.command(name, verb, url)
|
|
29
|
+
COMMANDS[name] = [verb, url.freeze]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_accessor :context, :http, :file_detector
|
|
33
|
+
attr_reader :capabilities
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Initializes the bridge with the given server URL.
|
|
37
|
+
#
|
|
38
|
+
# @param url [String] url for the remote server
|
|
39
|
+
# @param http_client [Object] an HTTP client instance that implements the same protocol as Http::Default
|
|
40
|
+
# @param desired_capabilities [Capabilities] an instance of Remote::Capabilities describing the capabilities you want
|
|
41
|
+
#
|
|
42
|
+
|
|
43
|
+
def initialize(opts = {})
|
|
44
|
+
opts = opts.dup
|
|
45
|
+
|
|
46
|
+
http_client = opts.delete(:http_client) { Http::Curb.new }
|
|
47
|
+
desired_capabilities = opts.delete(:desired_capabilities) { Capabilities.firefox }
|
|
48
|
+
url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" }
|
|
49
|
+
|
|
50
|
+
unless opts.empty?
|
|
51
|
+
raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if desired_capabilities.kind_of?(Symbol)
|
|
55
|
+
unless Capabilities.respond_to?(desired_capabilities)
|
|
56
|
+
raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desired_capabilities = Capabilities.send(desired_capabilities)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
uri = url.kind_of?(URI) ? url : URI.parse(url)
|
|
63
|
+
uri.path += "/" unless uri.path =~ /\/$/
|
|
64
|
+
|
|
65
|
+
http_client.server_url = uri
|
|
66
|
+
|
|
67
|
+
@http = http_client
|
|
68
|
+
@capabilities = create_session(desired_capabilities)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def browser
|
|
72
|
+
@browser ||= (
|
|
73
|
+
name = @capabilities.browser_name
|
|
74
|
+
name ? name.gsub(" ", "_").to_sym : 'unknown'
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def driver_extensions
|
|
79
|
+
[
|
|
80
|
+
DriverExtensions::HasInputDevices,
|
|
81
|
+
DriverExtensions::UploadsFiles,
|
|
82
|
+
DriverExtensions::TakesScreenshot,
|
|
83
|
+
DriverExtensions::HasSessionId,
|
|
84
|
+
DriverExtensions::Rotatable,
|
|
85
|
+
DriverExtensions::HasTouchScreen,
|
|
86
|
+
DriverExtensions::HasRemoteStatus
|
|
87
|
+
]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# Returns the current session ID.
|
|
92
|
+
#
|
|
93
|
+
|
|
94
|
+
def session_id
|
|
95
|
+
@session_id || raise(Error::WebDriverError, "no current session exists")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def create_session(desired_capabilities)
|
|
99
|
+
resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities
|
|
100
|
+
@session_id = resp['sessionId'] or raise Error::WebDriverError, 'no sessionId in returned payload'
|
|
101
|
+
|
|
102
|
+
Capabilities.json_create resp['value']
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def status
|
|
106
|
+
execute :status
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def get(url)
|
|
110
|
+
execute :get, {}, :url => url
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def getCapabilities
|
|
114
|
+
Capabilities.json_create execute(:getCapabilities)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def setImplicitWaitTimeout(milliseconds)
|
|
118
|
+
execute :implicitlyWait, {}, :ms => milliseconds
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def setScriptTimeout(milliseconds)
|
|
122
|
+
execute :setScriptTimeout, {}, :ms => milliseconds
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def setTimeout(type, milliseconds)
|
|
126
|
+
execute :setTimeout, {}, :type => type, :ms => milliseconds
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# alerts
|
|
131
|
+
#
|
|
132
|
+
|
|
133
|
+
def getAlert
|
|
134
|
+
execute :getAlert
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def acceptAlert
|
|
138
|
+
execute :acceptAlert
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def dismissAlert
|
|
142
|
+
execute :dismissAlert
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def setAlertValue(keys)
|
|
146
|
+
execute :setAlertValue, {}, :text => keys.to_s
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def getAlertText
|
|
150
|
+
execute :getAlertText
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#
|
|
154
|
+
# navigation
|
|
155
|
+
#
|
|
156
|
+
|
|
157
|
+
def goBack
|
|
158
|
+
execute :goBack
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def goForward
|
|
162
|
+
execute :goForward
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def getCurrentUrl
|
|
166
|
+
execute :getCurrentUrl
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def getTitle
|
|
170
|
+
execute :getTitle
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def getPageSource
|
|
174
|
+
execute :getPageSource
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def getVisible
|
|
178
|
+
execute :getVisible
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def setVisible(bool)
|
|
182
|
+
execute :setVisible, {}, bool
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def switchToWindow(name)
|
|
186
|
+
execute :switchToWindow, {}, :name => name
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def switchToFrame(id)
|
|
190
|
+
execute :switchToFrame, {}, :id => id
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def switchToDefaultContent
|
|
194
|
+
execute :switchToFrame, {}, :id => nil
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
QUIT_ERRORS = [IOError]
|
|
198
|
+
|
|
199
|
+
def quit
|
|
200
|
+
execute :quit
|
|
201
|
+
http.close
|
|
202
|
+
rescue *QUIT_ERRORS
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def close
|
|
206
|
+
execute :close
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def refresh
|
|
210
|
+
execute :refresh
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
#
|
|
214
|
+
# window handling
|
|
215
|
+
#
|
|
216
|
+
|
|
217
|
+
def getWindowHandles
|
|
218
|
+
execute :getWindowHandles
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def getCurrentWindowHandle
|
|
222
|
+
execute :getCurrentWindowHandle
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def setWindowSize(width, height, handle = :current)
|
|
226
|
+
execute :setWindowSize, {:window_handle => handle},
|
|
227
|
+
:width => width,
|
|
228
|
+
:height => height
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def maximizeWindow(handle = :current)
|
|
232
|
+
execute :maximizeWindow, :window_handle => handle
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def getWindowSize(handle = :current)
|
|
236
|
+
data = execute :getWindowSize, :window_handle => handle
|
|
237
|
+
|
|
238
|
+
Dimension.new data['width'], data['height']
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def setWindowPosition(x, y, handle = :current)
|
|
242
|
+
execute :setWindowPosition, {:window_handle => handle},
|
|
243
|
+
:x => x, :y => y
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def getWindowPosition(handle = :current)
|
|
247
|
+
data = execute :getWindowPosition, :window_handle => handle
|
|
248
|
+
|
|
249
|
+
Point.new data['x'], data['y']
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def getScreenshot
|
|
253
|
+
execute :screenshot
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
#
|
|
257
|
+
# HTML 5
|
|
258
|
+
#
|
|
259
|
+
|
|
260
|
+
def getLocalStorageItem(key)
|
|
261
|
+
execute :getLocalStorageItem, :key => key
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def removeLocalStorageItem(key)
|
|
265
|
+
execute :removeLocalStorageItem, :key => key
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def getLocalStorageKeys
|
|
269
|
+
execute :getLocalStorageKeys
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def setLocalStorageItem(key, value)
|
|
273
|
+
execute :setLocalStorageItem, {}, :key => key, :value => value
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def clearLocalStorage
|
|
277
|
+
execute :clearLocalStorage
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def getLocalStorageSize
|
|
281
|
+
execute :getLocalStorageSize
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def getSessionStorageItem(key)
|
|
285
|
+
execute :getSessionStorageItem, :key => key
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def removeSessionStorageItem(key)
|
|
289
|
+
execute :removeSessionStorageItem, :key => key
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def getSessionStorageKeys
|
|
293
|
+
execute :getSessionStorageKeys
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def setSessionStorageItem(key, value)
|
|
297
|
+
execute :setSessionStorageItem, {}, :key => key, :value => value
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def clearSessionStorage
|
|
301
|
+
execute :clearSessionStorage
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def getSessionStorageSize
|
|
305
|
+
execute :getSessionStorageSize
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def getLocation
|
|
309
|
+
obj = execute(:getLocation) || {} # android returns null
|
|
310
|
+
Location.new obj['latitude'], obj['longitude'], obj['altitude']
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def setLocation(lat, lon, alt)
|
|
314
|
+
loc = {:latitude => lat, :longitude => lon, :altitude => alt}
|
|
315
|
+
execute :setLocation, {}, :location => loc
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def isBrowserOnline
|
|
319
|
+
execute :isBrowserOnline
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def setBrowserOnline(bool)
|
|
323
|
+
execute :setBrowserOnline, {}, :state => bool
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
#
|
|
327
|
+
# javascript execution
|
|
328
|
+
#
|
|
329
|
+
|
|
330
|
+
def executeScript(script, *args)
|
|
331
|
+
assert_javascript_enabled
|
|
332
|
+
|
|
333
|
+
result = execute :executeScript, {}, :script => script, :args => args
|
|
334
|
+
unwrap_script_result result
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def executeAsyncScript(script, *args)
|
|
338
|
+
assert_javascript_enabled
|
|
339
|
+
|
|
340
|
+
result = execute :executeAsyncScript, {}, :script => script, :args => args
|
|
341
|
+
unwrap_script_result result
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
#
|
|
345
|
+
# cookies
|
|
346
|
+
#
|
|
347
|
+
|
|
348
|
+
def addCookie(cookie)
|
|
349
|
+
execute :addCookie, {}, :cookie => cookie
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def deleteCookie(name)
|
|
353
|
+
execute :deleteCookie, :name => name
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def getAllCookies
|
|
357
|
+
execute :getCookies
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def deleteAllCookies
|
|
361
|
+
execute :deleteAllCookies
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
#
|
|
365
|
+
# actions
|
|
366
|
+
#
|
|
367
|
+
|
|
368
|
+
def clickElement(element)
|
|
369
|
+
execute :clickElement, :id => element
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def click
|
|
373
|
+
execute :click, {}, :button => 0
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def doubleClick
|
|
377
|
+
execute :doubleClick
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def contextClick
|
|
381
|
+
execute :click, {}, :button => 2
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def mouseDown
|
|
385
|
+
execute :mouseDown
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def mouseUp
|
|
389
|
+
execute :mouseUp
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def mouseMoveTo(element, x = nil, y = nil)
|
|
393
|
+
params = { :element => element }
|
|
394
|
+
|
|
395
|
+
if x && y
|
|
396
|
+
params.merge! :xoffset => x, :yoffset => y
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
execute :mouseMoveTo, {}, params
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def sendKeysToActiveElement(key)
|
|
403
|
+
execute :sendKeysToActiveElement, {}, :value => key
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def sendKeysToElement(element, keys)
|
|
407
|
+
if @file_detector && local_file = @file_detector.call(keys)
|
|
408
|
+
keys = upload(local_file)
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
execute :sendKeysToElement, {:id => element}, {:value => Array(keys)}
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def upload(local_file)
|
|
415
|
+
unless File.file?(local_file)
|
|
416
|
+
raise WebDriverError::Error, "you may only upload files: #{local_file.inspect}"
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
execute :uploadFile, {}, :file => Zipper.zip_file(local_file)
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def clearElement(element)
|
|
423
|
+
execute :clearElement, :id => element
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def submitElement(element)
|
|
428
|
+
execute :submitElement, :id => element
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
def dragElement(element, right_by, down_by)
|
|
432
|
+
execute :dragElement, {:id => element}, :x => right_by, :y => down_by
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def touchSingleTap(element)
|
|
436
|
+
execute :touchSingleTap, {}, :element => element
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def touchDoubleTap(element)
|
|
440
|
+
execute :touchDoubleTap, {}, :element => element
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def touchLongPress(element)
|
|
444
|
+
execute :touchLongPress, {}, :element => element
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def touchDown(x, y)
|
|
448
|
+
execute :touchDown, {}, :x => x, :y => y
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def touchUp(x, y)
|
|
452
|
+
execute :touchUp, {}, :x => x, :y => y
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def touchMove(x, y)
|
|
456
|
+
execute :touchMove, {}, :x => x, :y => y
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def touchScroll(element, x, y)
|
|
460
|
+
if element
|
|
461
|
+
execute :touchScroll, {}, :element => element,
|
|
462
|
+
:xoffset => x,
|
|
463
|
+
:yoffset => y
|
|
464
|
+
else
|
|
465
|
+
execute :touchScroll, {}, :xoffset => x, :yoffset => y
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def touchFlick(xspeed, yspeed)
|
|
470
|
+
execute :touchFlick, {}, :xspeed => xspeed, :yspeed => yspeed
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def touchElementFlick(element, right_by, down_by, speed)
|
|
474
|
+
execute :touchFlick, {}, :element => element,
|
|
475
|
+
:xoffset => right_by,
|
|
476
|
+
:yoffset => down_by,
|
|
477
|
+
:speed => speed
|
|
478
|
+
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def setScreenOrientation(orientation)
|
|
482
|
+
execute :setScreenOrientation, {}, :orientation => orientation
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def getScreenOrientation
|
|
486
|
+
execute :getScreenOrientation
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
#
|
|
490
|
+
# logs
|
|
491
|
+
#
|
|
492
|
+
|
|
493
|
+
def getAvailableLogTypes
|
|
494
|
+
types = execute :getAvailableLogTypes
|
|
495
|
+
Array(types).map { |e| e.to_sym }
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def getLog(type)
|
|
499
|
+
data = execute :getLog, {}, :type => type.to_s
|
|
500
|
+
|
|
501
|
+
Array(data).map do |l|
|
|
502
|
+
LogEntry.new l.fetch('level'), l.fetch('timestamp'), l.fetch('message')
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
#
|
|
507
|
+
# element properties
|
|
508
|
+
#
|
|
509
|
+
|
|
510
|
+
def getElementTagName(element)
|
|
511
|
+
execute :getElementTagName, :id => element
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
def getElementAttribute(element, name)
|
|
515
|
+
execute :getElementAttribute, :id => element, :name => name
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
def getElementValue(element)
|
|
519
|
+
execute :getElementValue, :id => element
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
def getElementText(element)
|
|
523
|
+
execute :getElementText, :id => element
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
def getElementLocation(element)
|
|
527
|
+
data = execute :getElementLocation, :id => element
|
|
528
|
+
|
|
529
|
+
Point.new data['x'], data['y']
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
def getElementLocationOnceScrolledIntoView(element)
|
|
533
|
+
data = execute :getElementLocationOnceScrolledIntoView, :id => element
|
|
534
|
+
|
|
535
|
+
Point.new data['x'], data['y']
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
def getElementSize(element)
|
|
539
|
+
data = execute :getElementSize, :id => element
|
|
540
|
+
|
|
541
|
+
Dimension.new data['width'], data['height']
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def isElementEnabled(element)
|
|
545
|
+
execute :isElementEnabled, :id => element
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
def isElementSelected(element)
|
|
549
|
+
execute :isElementSelected, :id => element
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
def isElementDisplayed(element)
|
|
553
|
+
execute :isElementDisplayed, :id => element
|
|
554
|
+
end
|
|
555
|
+
def getElementValueOfCssProperty(element, prop)
|
|
556
|
+
execute :getElementValueOfCssProperty, :id => element, :property_name => prop
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def elementEquals(element, other)
|
|
560
|
+
if element.ref == other.ref
|
|
561
|
+
true
|
|
562
|
+
else
|
|
563
|
+
execute :elementEquals, :id => element.ref, :other => other.ref
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
#
|
|
568
|
+
# finding elements
|
|
569
|
+
#
|
|
570
|
+
|
|
571
|
+
def getActiveElement
|
|
572
|
+
Element.new self, element_id_from(execute(:getActiveElement))
|
|
573
|
+
end
|
|
574
|
+
alias_method :switchToActiveElement, :getActiveElement
|
|
575
|
+
|
|
576
|
+
def find_element_by(how, what, parent = nil)
|
|
577
|
+
if parent
|
|
578
|
+
id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
|
|
579
|
+
else
|
|
580
|
+
id = execute :findElement, {}, {:using => how, :value => what}
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
Element.new self, element_id_from(id)
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def find_elements_by(how, what, parent = nil)
|
|
587
|
+
if parent
|
|
588
|
+
ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what}
|
|
589
|
+
else
|
|
590
|
+
ids = execute :findElements, {}, {:using => how, :value => what}
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
ids.map { |id| Element.new self, element_id_from(id) }
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
private
|
|
597
|
+
|
|
598
|
+
def assert_javascript_enabled
|
|
599
|
+
unless capabilities.javascript_enabled?
|
|
600
|
+
raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
#
|
|
605
|
+
# executes a command on the remote server.
|
|
606
|
+
#
|
|
607
|
+
#
|
|
608
|
+
# Returns the 'value' of the returned payload
|
|
609
|
+
#
|
|
610
|
+
|
|
611
|
+
def execute(*args)
|
|
612
|
+
raw_execute(*args)['value']
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
#
|
|
616
|
+
# executes a command on the remote server.
|
|
617
|
+
#
|
|
618
|
+
# @return [WebDriver::Remote::Response]
|
|
619
|
+
#
|
|
620
|
+
|
|
621
|
+
def raw_execute(command, opts = {}, command_hash = nil)
|
|
622
|
+
verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
|
|
623
|
+
path = path.dup
|
|
624
|
+
|
|
625
|
+
path[':session_id'] = @session_id if path.include?(":session_id")
|
|
626
|
+
|
|
627
|
+
begin
|
|
628
|
+
opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
|
|
629
|
+
rescue IndexError
|
|
630
|
+
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG
|
|
634
|
+
http.call verb, path, command_hash
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
def escaper
|
|
638
|
+
@escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
end # Bridge
|
|
642
|
+
end # Remote
|
|
643
|
+
end # WebDriver
|
|
644
|
+
end # Selenium
|