bbc-selenium-webdriver 1.17.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.
- data/CHANGES +473 -0
- data/README +31 -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 +118 -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 +223 -0
- data/lib/selenium/webdriver.rb +64 -0
- data/lib/selenium/webdriver/android.rb +9 -0
- data/lib/selenium/webdriver/android/bridge.rb +51 -0
- data/lib/selenium/webdriver/chrome.rb +26 -0
- data/lib/selenium/webdriver/chrome/bridge.rb +106 -0
- data/lib/selenium/webdriver/chrome/profile.rb +83 -0
- data/lib/selenium/webdriver/chrome/service.rb +74 -0
- data/lib/selenium/webdriver/common.rb +30 -0
- data/lib/selenium/webdriver/common/action_builder.rb +352 -0
- data/lib/selenium/webdriver/common/alert.rb +26 -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_input_devices.rb +39 -0
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +44 -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 +262 -0
- data/lib/selenium/webdriver/common/error.rb +212 -0
- data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
- data/lib/selenium/webdriver/common/keyboard.rb +52 -0
- data/lib/selenium/webdriver/common/keys.rb +109 -0
- data/lib/selenium/webdriver/common/mouse.rb +65 -0
- data/lib/selenium/webdriver/common/navigation.rb +43 -0
- data/lib/selenium/webdriver/common/options.rb +128 -0
- data/lib/selenium/webdriver/common/platform.rb +166 -0
- data/lib/selenium/webdriver/common/port_prober.rb +25 -0
- data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
- data/lib/selenium/webdriver/common/proxy.rb +120 -0
- data/lib/selenium/webdriver/common/search_context.rb +92 -0
- data/lib/selenium/webdriver/common/socket_poller.rb +100 -0
- data/lib/selenium/webdriver/common/target_locator.rb +81 -0
- data/lib/selenium/webdriver/common/timeouts.rb +29 -0
- data/lib/selenium/webdriver/common/wait.rb +60 -0
- data/lib/selenium/webdriver/common/window.rb +96 -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 +161 -0
- data/lib/selenium/webdriver/firefox/bridge.rb +58 -0
- data/lib/selenium/webdriver/firefox/extension.rb +52 -0
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +104 -0
- data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/profile.rb +315 -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 +60 -0
- data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
- data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
- data/lib/selenium/webdriver/ie/server.rb +64 -0
- data/lib/selenium/webdriver/iphone.rb +9 -0
- data/lib/selenium/webdriver/iphone/bridge.rb +50 -0
- data/lib/selenium/webdriver/opera.rb +24 -0
- data/lib/selenium/webdriver/opera/bridge.rb +113 -0
- data/lib/selenium/webdriver/opera/service.rb +49 -0
- data/lib/selenium/webdriver/remote.rb +21 -0
- data/lib/selenium/webdriver/remote/bridge.rb +473 -0
- data/lib/selenium/webdriver/remote/capabilities.rb +241 -0
- data/lib/selenium/webdriver/remote/commands.rb +181 -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 +102 -0
- data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
- data/lib/selenium/webdriver/remote/response.rb +99 -0
- data/lib/selenium/webdriver/remote/server_error.rb +17 -0
- data/lib/selenium/webdriver/support.rb +4 -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/event_firing_bridge.rb +112 -0
- data/lib/selenium/webdriver/support/select.rb +293 -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 +29 -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/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 +125 -0
- data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
- data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +42 -0
- data/spec/integration/selenium/webdriver/driver_spec.rb +253 -0
- data/spec/integration/selenium/webdriver/element_spec.rb +185 -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/mouse_spec.rb +55 -0
- data/spec/integration/selenium/webdriver/navigation_spec.rb +44 -0
- data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
- data/spec/integration/selenium/webdriver/options_spec.rb +49 -0
- data/spec/integration/selenium/webdriver/remote/element_spec.rb +24 -0
- data/spec/integration/selenium/webdriver/spec_helper.rb +44 -0
- data/spec/integration/selenium/webdriver/spec_support.rb +13 -0
- data/spec/integration/selenium/webdriver/spec_support/guards.rb +86 -0
- data/spec/integration/selenium/webdriver/spec_support/helpers.rb +46 -0
- data/spec/integration/selenium/webdriver/spec_support/jruby_test_environment.rb +29 -0
- data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
- data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +199 -0
- data/spec/integration/selenium/webdriver/target_locator_spec.rb +170 -0
- data/spec/integration/selenium/webdriver/timeout_spec.rb +56 -0
- data/spec/integration/selenium/webdriver/window_spec.rb +56 -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 +131 -0
- data/spec/unit/selenium/webdriver/action_builder_spec.rb +90 -0
- data/spec/unit/selenium/webdriver/android/bridge_spec.rb +31 -0
- data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +94 -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 +17 -0
- data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +30 -0
- data/spec/unit/selenium/webdriver/proxy_spec.rb +87 -0
- data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
- data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +111 -0
- data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
- data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +46 -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 +6 -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 +40 -0
- metadata +215 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Selenium
|
|
2
|
+
module WebDriver
|
|
3
|
+
module Opera
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# @api private
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
class Service
|
|
10
|
+
MISSING_TEXT = 'Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver.'
|
|
11
|
+
|
|
12
|
+
def self.selenium_server_jar
|
|
13
|
+
@selenium_server_jar ||= (
|
|
14
|
+
ENV['SELENIUM_SERVER_JAR'] or raise Error::WebDriverError, MISSING_TEXT
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.selenium_server_jar=(path)
|
|
19
|
+
Platform.assert_file path
|
|
20
|
+
@selenium_server_jar = path
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.default_service(opts = {})
|
|
24
|
+
new selenium_server_jar, opts
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(jar, opts = {})
|
|
28
|
+
opts.merge! :background => true, :port => PortProber.random
|
|
29
|
+
opts.merge! :log => !!$DEBUG if $DEBUG
|
|
30
|
+
@server = Selenium::Server.new File.expand_path(jar), opts
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def uri
|
|
34
|
+
@server.webdriver_url
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def start
|
|
38
|
+
@server.start
|
|
39
|
+
Platform.exit_hook { stop } # make sure we don't leave the server running
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def stop
|
|
43
|
+
@server.stop
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
|
|
11
|
+
module Selenium
|
|
12
|
+
module WebDriver
|
|
13
|
+
|
|
14
|
+
# @api private
|
|
15
|
+
module Remote
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
@@ -0,0 +1,473 @@
|
|
|
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::Default.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 ||= @capabilities.browser_name.gsub(" ", "_").to_sym
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def driver_extensions
|
|
76
|
+
[
|
|
77
|
+
DriverExtensions::HasInputDevices,
|
|
78
|
+
DriverExtensions::UploadsFiles,
|
|
79
|
+
DriverExtensions::TakesScreenshot,
|
|
80
|
+
DriverExtensions::Rotatable
|
|
81
|
+
]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Returns the current session ID.
|
|
86
|
+
#
|
|
87
|
+
|
|
88
|
+
def session_id
|
|
89
|
+
@session_id || raise(Error::WebDriverError, "no current session exists")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def create_session(desired_capabilities)
|
|
93
|
+
resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities
|
|
94
|
+
@session_id = resp['sessionId'] or raise Error::WebDriverError, 'no sessionId in returned payload'
|
|
95
|
+
|
|
96
|
+
Capabilities.json_create resp['value']
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def get(url)
|
|
100
|
+
execute :get, {}, :url => url
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def getCapabilities
|
|
104
|
+
Capabilities.json_create execute(:getCapabilities)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def setImplicitWaitTimeout(milliseconds)
|
|
108
|
+
execute :setImplicitWaitTimeout, {}, :ms => milliseconds
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def setScriptTimeout(milliseconds)
|
|
112
|
+
execute :setScriptTimeout, {}, :ms => milliseconds
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# alerts
|
|
117
|
+
#
|
|
118
|
+
|
|
119
|
+
def getAlert
|
|
120
|
+
execute :getAlert
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def acceptAlert
|
|
124
|
+
execute :acceptAlert
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def dismissAlert
|
|
128
|
+
execute :dismissAlert
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def setAlertValue(keys)
|
|
132
|
+
execute :setAlertValue, {}, :text => keys.to_s
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def getAlertText
|
|
136
|
+
execute :getAlertText
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
#
|
|
140
|
+
# navigation
|
|
141
|
+
#
|
|
142
|
+
|
|
143
|
+
def goBack
|
|
144
|
+
execute :goBack
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def goForward
|
|
148
|
+
execute :goForward
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def getCurrentUrl
|
|
152
|
+
execute :getCurrentUrl
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def getTitle
|
|
156
|
+
execute :getTitle
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def getPageSource
|
|
160
|
+
execute :getPageSource
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def getVisible
|
|
164
|
+
execute :getVisible
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def setVisible(bool)
|
|
168
|
+
execute :setVisible, {}, bool
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def switchToWindow(name)
|
|
172
|
+
execute :switchToWindow, {}, :name => name
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def switchToFrame(id)
|
|
176
|
+
execute :switchToFrame, {}, :id => id
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def switchToDefaultContent
|
|
180
|
+
execute :switchToFrame, {}, :id => nil
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
QUIT_ERRORS = [IOError]
|
|
184
|
+
|
|
185
|
+
def quit
|
|
186
|
+
execute :quit
|
|
187
|
+
http.close
|
|
188
|
+
rescue *QUIT_ERRORS
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def close
|
|
192
|
+
execute :close
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def refresh
|
|
196
|
+
execute :refresh
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def getWindowHandles
|
|
200
|
+
execute :getWindowHandles
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def getCurrentWindowHandle
|
|
204
|
+
execute :getCurrentWindowHandle
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def setWindowSize(width, height, handle = :current)
|
|
208
|
+
execute :setWindowSize, {:window_handle => handle},
|
|
209
|
+
:width => width,
|
|
210
|
+
:height => height
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def getWindowSize(handle = :current)
|
|
214
|
+
data = execute :getWindowSize, :window_handle => handle
|
|
215
|
+
|
|
216
|
+
Dimension.new data['width'], data['height']
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def setWindowPosition(x, y, handle = :current)
|
|
220
|
+
execute :setWindowPosition, {:window_handle => handle},
|
|
221
|
+
:x => x, :y => y
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def getWindowPosition(handle = :current)
|
|
225
|
+
data = execute :getWindowPosition, :window_handle => handle
|
|
226
|
+
|
|
227
|
+
Point.new data['x'], data['y']
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def getScreenshot
|
|
231
|
+
execute :screenshot
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def executeScript(script, *args)
|
|
235
|
+
assert_javascript_enabled
|
|
236
|
+
|
|
237
|
+
result = execute :executeScript, {}, :script => script, :args => args
|
|
238
|
+
unwrap_script_result result
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def executeAsyncScript(script, *args)
|
|
242
|
+
assert_javascript_enabled
|
|
243
|
+
|
|
244
|
+
result = execute :executeAsyncScript, {}, :script => script, :args => args
|
|
245
|
+
unwrap_script_result result
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def addCookie(cookie)
|
|
249
|
+
execute :addCookie, {}, :cookie => cookie
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def deleteCookie(name)
|
|
253
|
+
execute :deleteCookieNamed, :name => name
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def getAllCookies
|
|
257
|
+
execute :getAllCookies
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def deleteAllCookies
|
|
261
|
+
execute :deleteAllCookies
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def clickElement(element)
|
|
265
|
+
execute :clickElement, :id => element
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def click
|
|
269
|
+
execute :click, {}, :button => 0
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def doubleClick
|
|
273
|
+
execute :doubleClick
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def contextClick
|
|
277
|
+
execute :click, {}, :button => 2
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def mouseDown
|
|
281
|
+
execute :mouseDown
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def mouseUp
|
|
285
|
+
execute :mouseUp
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def mouseMoveTo(element, x = nil, y = nil)
|
|
289
|
+
params = { :element => element }
|
|
290
|
+
|
|
291
|
+
if x && y
|
|
292
|
+
params.merge! :xoffset => x, :yoffset => y
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
execute :mouseMoveTo, {}, params
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def sendKeysToActiveElement(key)
|
|
299
|
+
execute :sendKeysToActiveElement, {}, :value => key
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def getElementTagName(element)
|
|
303
|
+
execute :getElementTagName, :id => element
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def getElementAttribute(element, name)
|
|
307
|
+
execute :getElementAttribute, :id => element, :name => name
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def getElementValue(element)
|
|
311
|
+
execute :getElementValue, :id => element
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def getElementText(element)
|
|
315
|
+
execute :getElementText, :id => element
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def getElementLocation(element)
|
|
319
|
+
data = execute :getElementLocation, :id => element
|
|
320
|
+
|
|
321
|
+
Point.new data['x'], data['y']
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def getElementLocationOnceScrolledIntoView(element)
|
|
325
|
+
data = execute :getElementLocationOnceScrolledIntoView, :id => element
|
|
326
|
+
|
|
327
|
+
Point.new data['x'], data['y']
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def getElementSize(element)
|
|
331
|
+
data = execute :getElementSize, :id => element
|
|
332
|
+
|
|
333
|
+
Dimension.new data['width'], data['height']
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def sendKeysToElement(element, keys)
|
|
337
|
+
if @file_detector && local_file = @file_detector.call(keys)
|
|
338
|
+
keys = upload(local_file)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
execute :sendKeysToElement, {:id => element}, {:value => Array(keys)}
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def upload(local_file)
|
|
345
|
+
unless File.file?(local_file)
|
|
346
|
+
raise WebDriverError::Error, "you may only upload files: #{local_file.inspect}"
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
execute :uploadFile, {}, :file => Zipper.zip_file(local_file)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def clearElement(element)
|
|
353
|
+
execute :clearElement, :id => element
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def isElementEnabled(element)
|
|
357
|
+
execute :isElementEnabled, :id => element
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def isElementSelected(element)
|
|
361
|
+
execute :isElementSelected, :id => element
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def isElementDisplayed(element)
|
|
365
|
+
execute :isElementDisplayed, :id => element
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def submitElement(element)
|
|
369
|
+
execute :submitElement, :id => element
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def setElementSelected(element)
|
|
373
|
+
execute :setElementSelected, :id => element
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def getElementValueOfCssProperty(element, prop)
|
|
377
|
+
execute :getElementValueOfCssProperty, :id => element, :property_name => prop
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def getActiveElement
|
|
381
|
+
Element.new self, element_id_from(execute(:getActiveElement))
|
|
382
|
+
end
|
|
383
|
+
alias_method :switchToActiveElement, :getActiveElement
|
|
384
|
+
|
|
385
|
+
def dragElement(element, right_by, down_by)
|
|
386
|
+
execute :dragElement, {:id => element}, :x => right_by, :y => down_by
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def elementEquals(element, other)
|
|
390
|
+
if element.ref == other.ref
|
|
391
|
+
true
|
|
392
|
+
else
|
|
393
|
+
execute :elementEquals, :id => element.ref, :other => other.ref
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def find_element_by(how, what, parent = nil)
|
|
398
|
+
if parent
|
|
399
|
+
id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
|
|
400
|
+
else
|
|
401
|
+
id = execute :findElement, {}, {:using => how, :value => what}
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
Element.new self, element_id_from(id)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def find_elements_by(how, what, parent = nil)
|
|
408
|
+
if parent
|
|
409
|
+
ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what}
|
|
410
|
+
else
|
|
411
|
+
ids = execute :findElements, {}, {:using => how, :value => what}
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
ids.map { |id| Element.new self, element_id_from(id) }
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def setScreenOrientation(orientation)
|
|
418
|
+
execute :setScreenOrientation, {}, :orientation => orientation
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
def getScreenOrientation
|
|
422
|
+
execute :getScreenOrientation
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
private
|
|
426
|
+
|
|
427
|
+
def assert_javascript_enabled
|
|
428
|
+
unless capabilities.javascript_enabled?
|
|
429
|
+
raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
#
|
|
434
|
+
# executes a command on the remote server via the REST / JSON API.
|
|
435
|
+
#
|
|
436
|
+
#
|
|
437
|
+
# Returns the 'value' of the returned payload
|
|
438
|
+
#
|
|
439
|
+
|
|
440
|
+
def execute(*args)
|
|
441
|
+
raw_execute(*args)['value']
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
#
|
|
445
|
+
# executes a command on the remote server via the REST / JSON API.
|
|
446
|
+
#
|
|
447
|
+
# @return [WebDriver::Remote::Response]
|
|
448
|
+
#
|
|
449
|
+
|
|
450
|
+
def raw_execute(command, opts = {}, command_hash = nil)
|
|
451
|
+
verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
|
|
452
|
+
path = path.dup
|
|
453
|
+
|
|
454
|
+
path[':session_id'] = @session_id if path.include?(":session_id")
|
|
455
|
+
|
|
456
|
+
begin
|
|
457
|
+
opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
|
|
458
|
+
rescue IndexError
|
|
459
|
+
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG
|
|
463
|
+
http.call verb, path, command_hash
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
def escaper
|
|
467
|
+
@escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
end # Bridge
|
|
471
|
+
end # Remote
|
|
472
|
+
end # WebDriver
|
|
473
|
+
end # Selenium
|