selenium-webdriver 2.53.4 → 3.0.0.beta1
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 +24 -18
- data/README.md +2 -3
- data/lib/selenium/server.rb +64 -68
- data/lib/selenium/webdriver.rb +5 -9
- data/lib/selenium/webdriver/chrome.rb +18 -3
- data/lib/selenium/webdriver/chrome/bridge.rb +13 -16
- data/lib/selenium/webdriver/chrome/profile.rb +7 -9
- data/lib/selenium/webdriver/chrome/service.rb +8 -84
- data/lib/selenium/webdriver/common.rb +1 -2
- data/lib/selenium/webdriver/common/action_builder.rb +28 -38
- data/lib/selenium/webdriver/common/alert.rb +7 -10
- data/lib/selenium/webdriver/common/bridge_helper.rb +10 -15
- data/lib/selenium/webdriver/common/driver.rb +19 -28
- data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +0 -3
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +4 -6
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +4 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +0 -3
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +3 -6
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +2 -5
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +2 -5
- data/lib/selenium/webdriver/common/element.rb +27 -29
- data/lib/selenium/webdriver/common/error.rb +17 -20
- data/lib/selenium/webdriver/common/file_reaper.rb +3 -9
- data/lib/selenium/webdriver/common/html5/local_storage.rb +6 -8
- data/lib/selenium/webdriver/common/html5/session_storage.rb +6 -8
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +6 -15
- data/lib/selenium/webdriver/common/keyboard.rb +7 -12
- data/lib/selenium/webdriver/common/keys.rb +67 -69
- data/lib/selenium/webdriver/common/log_entry.rb +3 -4
- data/lib/selenium/webdriver/common/logs.rb +2 -4
- data/lib/selenium/webdriver/common/mouse.rb +9 -12
- data/lib/selenium/webdriver/common/navigation.rb +2 -4
- data/lib/selenium/webdriver/common/options.rb +16 -19
- data/lib/selenium/webdriver/common/platform.rb +61 -90
- data/lib/selenium/webdriver/common/port_prober.rb +1 -2
- data/lib/selenium/webdriver/common/profile_helper.rb +5 -8
- data/lib/selenium/webdriver/common/proxy.rb +58 -70
- data/lib/selenium/webdriver/common/search_context.rb +15 -19
- data/lib/selenium/webdriver/common/service.rb +127 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +5 -11
- data/lib/selenium/webdriver/common/socket_poller.rb +4 -9
- data/lib/selenium/webdriver/common/target_locator.rb +11 -13
- data/lib/selenium/webdriver/common/timeouts.rb +4 -6
- data/lib/selenium/webdriver/common/touch_action_builder.rb +2 -4
- data/lib/selenium/webdriver/common/touch_screen.rb +15 -18
- data/lib/selenium/webdriver/common/w3c_error.rb +3 -6
- data/lib/selenium/webdriver/common/wait.rb +6 -11
- data/lib/selenium/webdriver/common/window.rb +12 -15
- data/lib/selenium/webdriver/common/zipper.rb +6 -8
- data/lib/selenium/webdriver/edge.rb +18 -3
- data/lib/selenium/webdriver/edge/bridge.rb +11 -16
- data/lib/selenium/webdriver/edge/legacy_support.rb +38 -39
- data/lib/selenium/webdriver/edge/service.rb +8 -82
- data/lib/selenium/webdriver/firefox.rb +25 -6
- data/lib/selenium/webdriver/firefox/binary.rb +37 -53
- data/lib/selenium/webdriver/firefox/bridge.rb +3 -6
- data/lib/selenium/webdriver/firefox/extension.rb +4 -6
- data/lib/selenium/webdriver/firefox/extension/prefs.json +1 -10
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +8 -11
- data/lib/selenium/webdriver/firefox/profile.rb +40 -42
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +8 -15
- data/lib/selenium/webdriver/firefox/service.rb +23 -79
- data/lib/selenium/webdriver/firefox/util.rb +0 -2
- data/lib/selenium/webdriver/firefox/w3c_bridge.rb +2 -4
- data/lib/selenium/webdriver/ie.rb +16 -7
- data/lib/selenium/webdriver/ie/bridge.rb +16 -23
- data/lib/selenium/webdriver/{iphone.rb → ie/service.rb} +26 -4
- data/lib/selenium/webdriver/phantomjs.rb +8 -3
- data/lib/selenium/webdriver/phantomjs/bridge.rb +9 -11
- data/lib/selenium/webdriver/phantomjs/service.rb +17 -81
- data/lib/selenium/webdriver/remote.rb +0 -2
- data/lib/selenium/webdriver/remote/bridge.rb +193 -191
- data/lib/selenium/webdriver/remote/capabilities.rb +60 -90
- data/lib/selenium/webdriver/remote/commands.rb +197 -192
- data/lib/selenium/webdriver/remote/http/common.rb +15 -13
- data/lib/selenium/webdriver/remote/http/curb.rb +5 -9
- data/lib/selenium/webdriver/remote/http/default.rb +32 -37
- data/lib/selenium/webdriver/remote/http/persistent.rb +4 -6
- data/lib/selenium/webdriver/remote/response.rb +13 -21
- data/lib/selenium/webdriver/remote/server_error.rb +1 -3
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +200 -195
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +38 -46
- data/lib/selenium/webdriver/remote/w3c_commands.rb +116 -113
- data/lib/selenium/webdriver/safari.rb +23 -7
- data/lib/selenium/{client/javascript_frameworks/jquery.rb → webdriver/safari/apple_bridge.rb} +28 -9
- data/lib/selenium/webdriver/safari/browser.rb +0 -2
- data/lib/selenium/webdriver/safari/{bridge.rb → legacy_bridge.rb} +12 -9
- data/lib/selenium/webdriver/safari/options.rb +3 -4
- data/lib/selenium/webdriver/safari/resources/client.js +56 -7255
- data/lib/selenium/webdriver/safari/server.rb +18 -24
- data/lib/selenium/{client/javascript_frameworks/prototype.rb → webdriver/safari/service.rb} +27 -9
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +17 -2
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -3
- data/lib/selenium/webdriver/support/color.rb +55 -38
- data/lib/selenium/webdriver/{android.rb → support/escaper.rb} +19 -4
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +36 -38
- data/lib/selenium/webdriver/support/select.rb +33 -84
- data/selenium-webdriver.gemspec +23 -23
- metadata +19 -30
- data/lib/selenium-client.rb +0 -21
- data/lib/selenium/client.rb +0 -57
- data/lib/selenium/client/base.rb +0 -151
- data/lib/selenium/client/driver.rb +0 -29
- data/lib/selenium/client/errors.rb +0 -28
- data/lib/selenium/client/extensions.rb +0 -132
- data/lib/selenium/client/idiomatic.rb +0 -507
- data/lib/selenium/client/javascript_expression_builder.rb +0 -135
- data/lib/selenium/client/legacy_driver.rb +0 -1722
- data/lib/selenium/client/protocol.rb +0 -123
- data/lib/selenium/client/selenium_helper.rb +0 -49
- data/lib/selenium/rake/server_task.rb +0 -176
- data/lib/selenium/webdriver/android/bridge.rb +0 -68
- data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -28
- data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -61
- data/lib/selenium/webdriver/common/html5/location.rb +0 -19
- data/lib/selenium/webdriver/ie/server.rb +0 -133
- data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
|
@@ -20,83 +20,20 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module PhantomJS
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# @api private
|
|
26
25
|
#
|
|
27
26
|
|
|
28
|
-
class Service
|
|
29
|
-
|
|
30
|
-
SOCKET_LOCK_TIMEOUT = 45
|
|
31
|
-
STOP_TIMEOUT = 5
|
|
32
|
-
DEFAULT_PORT = 8910
|
|
33
|
-
MISSING_TEXT = "Unable to find phantomjs executable."
|
|
34
|
-
|
|
35
|
-
def self.executable_path
|
|
36
|
-
@executable_path ||= (
|
|
37
|
-
path = PhantomJS.path
|
|
38
|
-
path or raise Error::WebDriverError, MISSING_TEXT
|
|
39
|
-
Platform.assert_executable path
|
|
40
|
-
|
|
41
|
-
path
|
|
42
|
-
)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def self.default_service(port = nil)
|
|
46
|
-
new executable_path, DEFAULT_PORT
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def initialize(executable_path, port)
|
|
50
|
-
@host = Platform.localhost
|
|
51
|
-
@executable = executable_path
|
|
52
|
-
@port = Integer(port)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def start(args = [])
|
|
56
|
-
if @process && @process.alive?
|
|
57
|
-
raise "already started: #{uri.inspect} #{@executable.inspect}"
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
Platform.exit_hook { stop } # make sure we don't leave the server running
|
|
61
|
-
|
|
62
|
-
socket_lock.locked do
|
|
63
|
-
find_free_port
|
|
64
|
-
start_process(args)
|
|
65
|
-
connect_until_stable
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def stop
|
|
70
|
-
return if @process.nil? || @process.exited?
|
|
71
|
-
|
|
72
|
-
Net::HTTP.start(@host, @port) do |http|
|
|
73
|
-
http.open_timeout = STOP_TIMEOUT / 2
|
|
74
|
-
http.read_timeout = STOP_TIMEOUT / 2
|
|
75
|
-
|
|
76
|
-
http.get("/shutdown")
|
|
77
|
-
end
|
|
78
|
-
ensure
|
|
79
|
-
stop_process
|
|
80
|
-
if Platform.jruby? && !$DEBUG
|
|
81
|
-
@process.io.close rescue nil
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def find_free_port
|
|
86
|
-
@port = PortProber.above @port
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def uri
|
|
90
|
-
URI.parse "http://#{@host}:#{@port}"
|
|
91
|
-
end
|
|
27
|
+
class Service < WebDriver::Service
|
|
28
|
+
DEFAULT_PORT = 8910
|
|
92
29
|
|
|
93
30
|
private
|
|
94
31
|
|
|
95
|
-
def start_process
|
|
96
|
-
server_command = [@
|
|
32
|
+
def start_process
|
|
33
|
+
server_command = [@executable_path, "--webdriver=#{@port}", *@extra_args]
|
|
97
34
|
@process = ChildProcess.build(*server_command.compact)
|
|
98
35
|
|
|
99
|
-
if $DEBUG
|
|
36
|
+
if $DEBUG
|
|
100
37
|
@process.io.inherit!
|
|
101
38
|
elsif Platform.jruby?
|
|
102
39
|
# apparently we need to read the output for phantomjs to work on jruby
|
|
@@ -107,24 +44,23 @@ module Selenium
|
|
|
107
44
|
end
|
|
108
45
|
|
|
109
46
|
def stop_process
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
socket_poller = SocketPoller.new @host, @port, START_TIMEOUT
|
|
117
|
-
|
|
118
|
-
unless socket_poller.connected?
|
|
119
|
-
raise Error::WebDriverError, "unable to connect to phantomjs @ #{uri} after #{START_TIMEOUT} seconds"
|
|
47
|
+
super
|
|
48
|
+
return unless Platform.jruby? && !$DEBUG
|
|
49
|
+
begin
|
|
50
|
+
@process.io.close
|
|
51
|
+
rescue
|
|
52
|
+
nil
|
|
120
53
|
end
|
|
121
54
|
end
|
|
122
55
|
|
|
123
|
-
def
|
|
124
|
-
|
|
56
|
+
def stop_server
|
|
57
|
+
connect_to_server { |http| http.get('/shutdown') }
|
|
125
58
|
end
|
|
126
59
|
|
|
60
|
+
def cannot_connect_error_text
|
|
61
|
+
"unable to connect to phantomjs @ #{uri} after #{START_TIMEOUT} seconds"
|
|
62
|
+
end
|
|
127
63
|
end # Service
|
|
128
64
|
end # PhantomJS
|
|
129
65
|
end # WebDriver
|
|
130
|
-
end #
|
|
66
|
+
end # Selenium
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Remote
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Low level bridge to the remote server, through which the rest of the API works.
|
|
26
25
|
#
|
|
@@ -30,6 +29,7 @@ module Selenium
|
|
|
30
29
|
class Bridge
|
|
31
30
|
include BridgeHelper
|
|
32
31
|
|
|
32
|
+
# TODO: constant shouldn't be modified in class
|
|
33
33
|
COMMANDS = {}
|
|
34
34
|
|
|
35
35
|
#
|
|
@@ -62,15 +62,15 @@ module Selenium
|
|
|
62
62
|
def initialize(opts = {})
|
|
63
63
|
opts = opts.dup
|
|
64
64
|
|
|
65
|
-
http_client
|
|
65
|
+
http_client = opts.delete(:http_client) { Http::Default.new }
|
|
66
66
|
desired_capabilities = opts.delete(:desired_capabilities) { Capabilities.firefox }
|
|
67
|
-
url
|
|
67
|
+
url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" }
|
|
68
68
|
|
|
69
69
|
unless opts.empty?
|
|
70
70
|
raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
if desired_capabilities.
|
|
73
|
+
if desired_capabilities.is_a?(Symbol)
|
|
74
74
|
unless Capabilities.respond_to?(desired_capabilities)
|
|
75
75
|
raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
|
|
76
76
|
end
|
|
@@ -78,13 +78,13 @@ module Selenium
|
|
|
78
78
|
desired_capabilities = Capabilities.send(desired_capabilities)
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
uri = url.
|
|
82
|
-
uri.path +=
|
|
81
|
+
uri = url.is_a?(URI) ? url : URI.parse(url)
|
|
82
|
+
uri.path += '/' unless uri.path =~ %r{\/$}
|
|
83
83
|
|
|
84
84
|
http_client.server_url = uri
|
|
85
85
|
|
|
86
|
-
@http
|
|
87
|
-
@capabilities
|
|
86
|
+
@http = http_client
|
|
87
|
+
@capabilities = create_session(desired_capabilities)
|
|
88
88
|
|
|
89
89
|
@file_detector = nil
|
|
90
90
|
end
|
|
@@ -92,7 +92,7 @@ module Selenium
|
|
|
92
92
|
def browser
|
|
93
93
|
@browser ||= (
|
|
94
94
|
name = @capabilities.browser_name
|
|
95
|
-
name ? name.
|
|
95
|
+
name ? name.tr(' ', '_').to_sym : 'unknown'
|
|
96
96
|
)
|
|
97
97
|
end
|
|
98
98
|
|
|
@@ -116,14 +116,15 @@ module Selenium
|
|
|
116
116
|
#
|
|
117
117
|
|
|
118
118
|
def session_id
|
|
119
|
-
@session_id || raise(Error::WebDriverError,
|
|
119
|
+
@session_id || raise(Error::WebDriverError, 'no current session exists')
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
def create_session(desired_capabilities)
|
|
123
|
-
resp = raw_execute :newSession, {}, :
|
|
124
|
-
@session_id = resp['sessionId']
|
|
123
|
+
resp = raw_execute :newSession, {}, {desiredCapabilities: desired_capabilities}
|
|
124
|
+
@session_id = resp['sessionId']
|
|
125
|
+
return Capabilities.json_create resp['value'] if @session_id
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
raise Error::WebDriverError, 'no sessionId in returned payload'
|
|
127
128
|
end
|
|
128
129
|
|
|
129
130
|
def status
|
|
@@ -131,46 +132,46 @@ module Selenium
|
|
|
131
132
|
end
|
|
132
133
|
|
|
133
134
|
def get(url)
|
|
134
|
-
execute :get, {}, :
|
|
135
|
+
execute :get, {}, {url: url}
|
|
135
136
|
end
|
|
136
137
|
|
|
137
|
-
def
|
|
138
|
+
def session_capabilities
|
|
138
139
|
Capabilities.json_create execute(:getCapabilities)
|
|
139
140
|
end
|
|
140
141
|
|
|
141
|
-
def
|
|
142
|
-
execute :implicitlyWait, {}, :
|
|
142
|
+
def implicit_wait_timeout=(milliseconds)
|
|
143
|
+
execute :implicitlyWait, {}, {ms: milliseconds}
|
|
143
144
|
end
|
|
144
145
|
|
|
145
|
-
def
|
|
146
|
-
execute :setScriptTimeout, {}, :
|
|
146
|
+
def script_timeout=(milliseconds)
|
|
147
|
+
execute :setScriptTimeout, {}, {ms: milliseconds}
|
|
147
148
|
end
|
|
148
149
|
|
|
149
|
-
def
|
|
150
|
-
execute :setTimeout, {}, :
|
|
150
|
+
def timeout(type, milliseconds)
|
|
151
|
+
execute :setTimeout, {}, {type: type, ms: milliseconds}
|
|
151
152
|
end
|
|
152
153
|
|
|
153
154
|
#
|
|
154
155
|
# alerts
|
|
155
156
|
#
|
|
156
157
|
|
|
157
|
-
def
|
|
158
|
+
def accept_alert
|
|
158
159
|
execute :acceptAlert
|
|
159
160
|
end
|
|
160
161
|
|
|
161
|
-
def
|
|
162
|
+
def dismiss_alert
|
|
162
163
|
execute :dismissAlert
|
|
163
164
|
end
|
|
164
165
|
|
|
165
|
-
def
|
|
166
|
-
execute :setAlertValue, {}, :
|
|
166
|
+
def alert=(keys)
|
|
167
|
+
execute :setAlertValue, {}, {text: keys.to_s}
|
|
167
168
|
end
|
|
168
169
|
|
|
169
|
-
def
|
|
170
|
+
def alert_text
|
|
170
171
|
execute :getAlertText
|
|
171
172
|
end
|
|
172
|
-
|
|
173
|
-
def
|
|
173
|
+
|
|
174
|
+
def authentication(credentials)
|
|
174
175
|
execute :setAuthentication, {}, credentials
|
|
175
176
|
end
|
|
176
177
|
|
|
@@ -178,43 +179,43 @@ module Selenium
|
|
|
178
179
|
# navigation
|
|
179
180
|
#
|
|
180
181
|
|
|
181
|
-
def
|
|
182
|
+
def go_back
|
|
182
183
|
execute :goBack
|
|
183
184
|
end
|
|
184
185
|
|
|
185
|
-
def
|
|
186
|
+
def go_forward
|
|
186
187
|
execute :goForward
|
|
187
188
|
end
|
|
188
189
|
|
|
189
|
-
def
|
|
190
|
+
def url
|
|
190
191
|
execute :getCurrentUrl
|
|
191
192
|
end
|
|
192
193
|
|
|
193
|
-
def
|
|
194
|
+
def title
|
|
194
195
|
execute :getTitle
|
|
195
196
|
end
|
|
196
197
|
|
|
197
|
-
def
|
|
198
|
+
def page_source
|
|
198
199
|
execute :getPageSource
|
|
199
200
|
end
|
|
200
201
|
|
|
201
|
-
def
|
|
202
|
-
execute :switchToWindow, {}, :
|
|
202
|
+
def switch_to_window(name)
|
|
203
|
+
execute :switchToWindow, {}, {name: name}
|
|
203
204
|
end
|
|
204
205
|
|
|
205
|
-
def
|
|
206
|
-
execute :switchToFrame, {}, :
|
|
206
|
+
def switch_to_frame(id)
|
|
207
|
+
execute :switchToFrame, {}, {id: id}
|
|
207
208
|
end
|
|
208
209
|
|
|
209
|
-
def
|
|
210
|
+
def switch_to_parent_frame
|
|
210
211
|
execute :switchToParentFrame
|
|
211
212
|
end
|
|
212
213
|
|
|
213
|
-
def
|
|
214
|
-
|
|
214
|
+
def switch_to_default_content
|
|
215
|
+
switch_to_frame(nil)
|
|
215
216
|
end
|
|
216
217
|
|
|
217
|
-
QUIT_ERRORS = [IOError]
|
|
218
|
+
QUIT_ERRORS = [IOError].freeze
|
|
218
219
|
|
|
219
220
|
def quit
|
|
220
221
|
execute :quit
|
|
@@ -234,42 +235,42 @@ module Selenium
|
|
|
234
235
|
# window handling
|
|
235
236
|
#
|
|
236
237
|
|
|
237
|
-
def
|
|
238
|
+
def window_handles
|
|
238
239
|
execute :getWindowHandles
|
|
239
240
|
end
|
|
240
241
|
|
|
241
|
-
def
|
|
242
|
+
def window_handle
|
|
242
243
|
execute :getCurrentWindowHandle
|
|
243
244
|
end
|
|
244
245
|
|
|
245
|
-
def
|
|
246
|
-
execute :setWindowSize, {:
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
def resize_window(width, height, handle = :current)
|
|
247
|
+
execute :setWindowSize, {window_handle: handle},
|
|
248
|
+
{width: width,
|
|
249
|
+
height: height}
|
|
249
250
|
end
|
|
250
251
|
|
|
251
|
-
def
|
|
252
|
-
execute :maximizeWindow, :
|
|
252
|
+
def maximize_window(handle = :current)
|
|
253
|
+
execute :maximizeWindow, window_handle: handle
|
|
253
254
|
end
|
|
254
255
|
|
|
255
|
-
def
|
|
256
|
-
data = execute :getWindowSize, :
|
|
256
|
+
def window_size(handle = :current)
|
|
257
|
+
data = execute :getWindowSize, window_handle: handle
|
|
257
258
|
|
|
258
259
|
Dimension.new data['width'], data['height']
|
|
259
260
|
end
|
|
260
261
|
|
|
261
|
-
def
|
|
262
|
-
execute :setWindowPosition, {:
|
|
263
|
-
|
|
262
|
+
def reposition_window(x, y, handle = :current)
|
|
263
|
+
execute :setWindowPosition, {window_handle: handle},
|
|
264
|
+
{x: x, y: y}
|
|
264
265
|
end
|
|
265
266
|
|
|
266
|
-
def
|
|
267
|
-
data = execute :getWindowPosition, :
|
|
267
|
+
def window_position(handle = :current)
|
|
268
|
+
data = execute :getWindowPosition, window_handle: handle
|
|
268
269
|
|
|
269
270
|
Point.new data['x'], data['y']
|
|
270
271
|
end
|
|
271
272
|
|
|
272
|
-
def
|
|
273
|
+
def screenshot
|
|
273
274
|
execute :screenshot
|
|
274
275
|
end
|
|
275
276
|
|
|
@@ -277,87 +278,87 @@ module Selenium
|
|
|
277
278
|
# HTML 5
|
|
278
279
|
#
|
|
279
280
|
|
|
280
|
-
def
|
|
281
|
-
|
|
281
|
+
def local_storage_item(key, value = nil)
|
|
282
|
+
if value
|
|
283
|
+
execute :setLocalStorageItem, {}, {key: key, value: value}
|
|
284
|
+
else
|
|
285
|
+
execute :getLocalStorageItem, key: key
|
|
286
|
+
end
|
|
282
287
|
end
|
|
283
288
|
|
|
284
|
-
def
|
|
285
|
-
execute :removeLocalStorageItem, :
|
|
289
|
+
def remove_local_storage_item(key)
|
|
290
|
+
execute :removeLocalStorageItem, key: key
|
|
286
291
|
end
|
|
287
292
|
|
|
288
|
-
def
|
|
293
|
+
def local_storage_keys
|
|
289
294
|
execute :getLocalStorageKeys
|
|
290
295
|
end
|
|
291
296
|
|
|
292
|
-
def
|
|
293
|
-
execute :setLocalStorageItem, {}, :key => key, :value => value
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
def clearLocalStorage
|
|
297
|
+
def clear_local_storage
|
|
297
298
|
execute :clearLocalStorage
|
|
298
299
|
end
|
|
299
300
|
|
|
300
|
-
def
|
|
301
|
+
def local_storage_size
|
|
301
302
|
execute :getLocalStorageSize
|
|
302
303
|
end
|
|
303
304
|
|
|
304
|
-
def
|
|
305
|
-
|
|
305
|
+
def session_storage_item(key, value = nil)
|
|
306
|
+
if value
|
|
307
|
+
execute :setSessionStorageItem, {}, {key: key, value: value}
|
|
308
|
+
else
|
|
309
|
+
execute :getSessionStorageItem, key: key
|
|
310
|
+
end
|
|
306
311
|
end
|
|
307
312
|
|
|
308
|
-
def
|
|
309
|
-
execute :removeSessionStorageItem, :
|
|
313
|
+
def remove_session_storage_item(key)
|
|
314
|
+
execute :removeSessionStorageItem, key: key
|
|
310
315
|
end
|
|
311
316
|
|
|
312
|
-
def
|
|
317
|
+
def session_storage_keys
|
|
313
318
|
execute :getSessionStorageKeys
|
|
314
319
|
end
|
|
315
320
|
|
|
316
|
-
def
|
|
317
|
-
execute :setSessionStorageItem, {}, :key => key, :value => value
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
def clearSessionStorage
|
|
321
|
+
def clear_session_storage
|
|
321
322
|
execute :clearSessionStorage
|
|
322
323
|
end
|
|
323
324
|
|
|
324
|
-
def
|
|
325
|
+
def session_storage_size
|
|
325
326
|
execute :getSessionStorageSize
|
|
326
327
|
end
|
|
327
328
|
|
|
328
|
-
def
|
|
329
|
-
obj = execute(:getLocation) || {}
|
|
329
|
+
def location
|
|
330
|
+
obj = execute(:getLocation) || {}
|
|
330
331
|
Location.new obj['latitude'], obj['longitude'], obj['altitude']
|
|
331
332
|
end
|
|
332
333
|
|
|
333
|
-
def
|
|
334
|
-
loc = {:
|
|
335
|
-
execute :setLocation, {}, :
|
|
334
|
+
def set_location(lat, lon, alt)
|
|
335
|
+
loc = {latitude: lat, longitude: lon, altitude: alt}
|
|
336
|
+
execute :setLocation, {}, {location: loc}
|
|
336
337
|
end
|
|
337
338
|
|
|
338
|
-
def
|
|
339
|
+
def network_connection
|
|
339
340
|
execute :getNetworkConnection
|
|
340
341
|
end
|
|
341
342
|
|
|
342
|
-
def
|
|
343
|
-
execute :setNetworkConnection, {}, :
|
|
343
|
+
def network_connection=(type)
|
|
344
|
+
execute :setNetworkConnection, {}, {parameters: {type: type}}
|
|
344
345
|
end
|
|
345
346
|
|
|
346
347
|
#
|
|
347
348
|
# javascript execution
|
|
348
349
|
#
|
|
349
350
|
|
|
350
|
-
def
|
|
351
|
+
def execute_script(script, *args)
|
|
351
352
|
assert_javascript_enabled
|
|
352
353
|
|
|
353
|
-
result = execute :executeScript, {}, :
|
|
354
|
+
result = execute :executeScript, {}, {script: script, args: args}
|
|
354
355
|
unwrap_script_result result
|
|
355
356
|
end
|
|
356
357
|
|
|
357
|
-
def
|
|
358
|
+
def execute_async_script(script, *args)
|
|
358
359
|
assert_javascript_enabled
|
|
359
360
|
|
|
360
|
-
result = execute :executeAsyncScript, {}, :
|
|
361
|
+
result = execute :executeAsyncScript, {}, {script: script, args: args}
|
|
361
362
|
unwrap_script_result result
|
|
362
363
|
end
|
|
363
364
|
|
|
@@ -365,19 +366,19 @@ module Selenium
|
|
|
365
366
|
# cookies
|
|
366
367
|
#
|
|
367
368
|
|
|
368
|
-
def
|
|
369
|
-
execute :addCookie, {}, :
|
|
369
|
+
def add_cookie(cookie)
|
|
370
|
+
execute :addCookie, {}, {cookie: cookie}
|
|
370
371
|
end
|
|
371
372
|
|
|
372
|
-
def
|
|
373
|
-
execute :deleteCookie, :
|
|
373
|
+
def delete_cookie(name)
|
|
374
|
+
execute :deleteCookie, name: name
|
|
374
375
|
end
|
|
375
376
|
|
|
376
|
-
def
|
|
377
|
+
def cookies
|
|
377
378
|
execute :getCookies
|
|
378
379
|
end
|
|
379
380
|
|
|
380
|
-
def
|
|
381
|
+
def delete_all_cookies
|
|
381
382
|
execute :deleteAllCookies
|
|
382
383
|
end
|
|
383
384
|
|
|
@@ -385,50 +386,52 @@ module Selenium
|
|
|
385
386
|
# actions
|
|
386
387
|
#
|
|
387
388
|
|
|
388
|
-
def
|
|
389
|
-
execute :clickElement, :
|
|
389
|
+
def click_element(element)
|
|
390
|
+
execute :clickElement, id: element
|
|
390
391
|
end
|
|
391
392
|
|
|
392
393
|
def click
|
|
393
|
-
execute :click, {}, :
|
|
394
|
+
execute :click, {}, {button: 0}
|
|
394
395
|
end
|
|
395
396
|
|
|
396
|
-
def
|
|
397
|
+
def double_click
|
|
397
398
|
execute :doubleClick
|
|
398
399
|
end
|
|
399
400
|
|
|
400
|
-
def
|
|
401
|
-
execute :click, {}, :
|
|
401
|
+
def context_click
|
|
402
|
+
execute :click, {}, {button: 2}
|
|
402
403
|
end
|
|
403
404
|
|
|
404
|
-
def
|
|
405
|
+
def mouse_down
|
|
405
406
|
execute :mouseDown
|
|
406
407
|
end
|
|
407
408
|
|
|
408
|
-
def
|
|
409
|
+
def mouse_up
|
|
409
410
|
execute :mouseUp
|
|
410
411
|
end
|
|
411
412
|
|
|
412
|
-
def
|
|
413
|
-
params = {
|
|
413
|
+
def mouse_move_to(element, x = nil, y = nil)
|
|
414
|
+
params = {element: element}
|
|
414
415
|
|
|
415
416
|
if x && y
|
|
416
|
-
params
|
|
417
|
+
params[:xoffset] = x
|
|
418
|
+
params[:yoffset] = y
|
|
417
419
|
end
|
|
418
420
|
|
|
419
421
|
execute :mouseMoveTo, {}, params
|
|
420
422
|
end
|
|
421
423
|
|
|
422
|
-
def
|
|
423
|
-
execute :sendKeysToActiveElement, {}, :
|
|
424
|
+
def send_keys_to_active_element(key)
|
|
425
|
+
execute :sendKeysToActiveElement, {}, {value: key}
|
|
424
426
|
end
|
|
425
427
|
|
|
426
|
-
def
|
|
427
|
-
if @file_detector
|
|
428
|
-
|
|
428
|
+
def send_keys_to_element(element, keys)
|
|
429
|
+
if @file_detector
|
|
430
|
+
local_file = @file_detector.call(keys)
|
|
431
|
+
keys = upload(local_file) if local_file
|
|
429
432
|
end
|
|
430
433
|
|
|
431
|
-
execute :sendKeysToElement, {:
|
|
434
|
+
execute :sendKeysToElement, {id: element}, {value: Array(keys)}
|
|
432
435
|
end
|
|
433
436
|
|
|
434
437
|
def upload(local_file)
|
|
@@ -436,72 +439,71 @@ module Selenium
|
|
|
436
439
|
raise Error::WebDriverError, "you may only upload files: #{local_file.inspect}"
|
|
437
440
|
end
|
|
438
441
|
|
|
439
|
-
execute :uploadFile, {}, :
|
|
442
|
+
execute :uploadFile, {}, {file: Zipper.zip_file(local_file)}
|
|
440
443
|
end
|
|
441
444
|
|
|
442
|
-
def
|
|
443
|
-
execute :clearElement, :
|
|
445
|
+
def clear_element(element)
|
|
446
|
+
execute :clearElement, id: element
|
|
444
447
|
end
|
|
445
448
|
|
|
446
|
-
def
|
|
447
|
-
execute :submitElement, :
|
|
449
|
+
def submit_element(element)
|
|
450
|
+
execute :submitElement, id: element
|
|
448
451
|
end
|
|
449
452
|
|
|
450
|
-
def
|
|
451
|
-
execute :dragElement, {:
|
|
453
|
+
def drag_element(element, right_by, down_by)
|
|
454
|
+
execute :dragElement, {id: element}, {x: right_by, y: down_by}
|
|
452
455
|
end
|
|
453
456
|
|
|
454
|
-
def
|
|
455
|
-
execute :touchSingleTap, {}, :
|
|
457
|
+
def touch_single_tap(element)
|
|
458
|
+
execute :touchSingleTap, {}, {element: element}
|
|
456
459
|
end
|
|
457
460
|
|
|
458
|
-
def
|
|
459
|
-
execute :touchDoubleTap, {}, :
|
|
461
|
+
def touch_double_tap(element)
|
|
462
|
+
execute :touchDoubleTap, {}, {element: element}
|
|
460
463
|
end
|
|
461
464
|
|
|
462
|
-
def
|
|
463
|
-
execute :touchLongPress, {}, :
|
|
465
|
+
def touch_long_press(element)
|
|
466
|
+
execute :touchLongPress, {}, {element: element}
|
|
464
467
|
end
|
|
465
468
|
|
|
466
|
-
def
|
|
467
|
-
execute :touchDown, {}, :
|
|
469
|
+
def touch_down(x, y)
|
|
470
|
+
execute :touchDown, {}, {x: x, y: y}
|
|
468
471
|
end
|
|
469
472
|
|
|
470
|
-
def
|
|
471
|
-
execute :touchUp, {}, :
|
|
473
|
+
def touch_up(x, y)
|
|
474
|
+
execute :touchUp, {}, {x: x, y: y}
|
|
472
475
|
end
|
|
473
476
|
|
|
474
|
-
def
|
|
475
|
-
execute :touchMove, {}, :
|
|
477
|
+
def touch_move(x, y)
|
|
478
|
+
execute :touchMove, {}, {x: x, y: y}
|
|
476
479
|
end
|
|
477
480
|
|
|
478
|
-
def
|
|
481
|
+
def touch_scroll(element, x, y)
|
|
479
482
|
if element
|
|
480
|
-
execute :touchScroll, {}, :
|
|
481
|
-
|
|
482
|
-
|
|
483
|
+
execute :touchScroll, {}, {element: element,
|
|
484
|
+
xoffset: x,
|
|
485
|
+
yoffset: y}
|
|
483
486
|
else
|
|
484
|
-
execute :touchScroll, {}, :
|
|
487
|
+
execute :touchScroll, {}, {xoffset: x, yoffset: y}
|
|
485
488
|
end
|
|
486
489
|
end
|
|
487
490
|
|
|
488
|
-
def
|
|
489
|
-
execute :touchFlick, {}, :
|
|
491
|
+
def touch_flick(xspeed, yspeed)
|
|
492
|
+
execute :touchFlick, {}, {xspeed: xspeed, yspeed: yspeed}
|
|
490
493
|
end
|
|
491
494
|
|
|
492
|
-
def
|
|
493
|
-
execute :touchFlick, {}, :
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
495
|
+
def touch_element_flick(element, right_by, down_by, speed)
|
|
496
|
+
execute :touchFlick, {}, {element: element,
|
|
497
|
+
xoffset: right_by,
|
|
498
|
+
yoffset: down_by,
|
|
499
|
+
speed: speed}
|
|
498
500
|
end
|
|
499
501
|
|
|
500
|
-
def
|
|
501
|
-
execute :setScreenOrientation, {}, :
|
|
502
|
+
def screen_orientation=(orientation)
|
|
503
|
+
execute :setScreenOrientation, {}, {orientation: orientation}
|
|
502
504
|
end
|
|
503
505
|
|
|
504
|
-
def
|
|
506
|
+
def screen_orientation
|
|
505
507
|
execute :getScreenOrientation
|
|
506
508
|
end
|
|
507
509
|
|
|
@@ -509,13 +511,13 @@ module Selenium
|
|
|
509
511
|
# logs
|
|
510
512
|
#
|
|
511
513
|
|
|
512
|
-
def
|
|
514
|
+
def available_log_types
|
|
513
515
|
types = execute :getAvailableLogTypes
|
|
514
|
-
Array(types).map
|
|
516
|
+
Array(types).map(&:to_sym)
|
|
515
517
|
end
|
|
516
518
|
|
|
517
|
-
def
|
|
518
|
-
data = execute :getLog, {}, :
|
|
519
|
+
def log(type)
|
|
520
|
+
data = execute :getLog, {}, {type: type.to_s}
|
|
519
521
|
|
|
520
522
|
Array(data).map do |l|
|
|
521
523
|
begin
|
|
@@ -530,81 +532,82 @@ module Selenium
|
|
|
530
532
|
# element properties
|
|
531
533
|
#
|
|
532
534
|
|
|
533
|
-
def
|
|
534
|
-
execute :getElementTagName, :
|
|
535
|
+
def element_tag_name(element)
|
|
536
|
+
execute :getElementTagName, id: element
|
|
535
537
|
end
|
|
536
538
|
|
|
537
|
-
def
|
|
538
|
-
execute :getElementAttribute, :
|
|
539
|
+
def element_attribute(element, name)
|
|
540
|
+
execute :getElementAttribute, id: element, name: name
|
|
539
541
|
end
|
|
540
542
|
|
|
541
|
-
def
|
|
542
|
-
execute :getElementValue, :
|
|
543
|
+
def element_value(element)
|
|
544
|
+
execute :getElementValue, id: element
|
|
543
545
|
end
|
|
544
546
|
|
|
545
|
-
def
|
|
546
|
-
execute :getElementText, :
|
|
547
|
+
def element_text(element)
|
|
548
|
+
execute :getElementText, id: element
|
|
547
549
|
end
|
|
548
550
|
|
|
549
|
-
def
|
|
550
|
-
data = execute :getElementLocation, :
|
|
551
|
+
def element_location(element)
|
|
552
|
+
data = execute :getElementLocation, id: element
|
|
551
553
|
|
|
552
554
|
Point.new data['x'], data['y']
|
|
553
555
|
end
|
|
554
556
|
|
|
555
|
-
def
|
|
556
|
-
data = execute :getElementLocationOnceScrolledIntoView, :
|
|
557
|
+
def element_location_once_scrolled_into_view(element)
|
|
558
|
+
data = execute :getElementLocationOnceScrolledIntoView, id: element
|
|
557
559
|
|
|
558
560
|
Point.new data['x'], data['y']
|
|
559
561
|
end
|
|
560
562
|
|
|
561
|
-
def
|
|
562
|
-
data = execute :getElementSize, :
|
|
563
|
+
def element_size(element)
|
|
564
|
+
data = execute :getElementSize, id: element
|
|
563
565
|
|
|
564
566
|
Dimension.new data['width'], data['height']
|
|
565
567
|
end
|
|
566
568
|
|
|
567
|
-
def
|
|
568
|
-
execute :isElementEnabled, :
|
|
569
|
+
def element_enabled?(element)
|
|
570
|
+
execute :isElementEnabled, id: element
|
|
569
571
|
end
|
|
570
572
|
|
|
571
|
-
def
|
|
572
|
-
execute :isElementSelected, :
|
|
573
|
+
def element_selected?(element)
|
|
574
|
+
execute :isElementSelected, id: element
|
|
573
575
|
end
|
|
574
576
|
|
|
575
|
-
def
|
|
576
|
-
execute :isElementDisplayed, :
|
|
577
|
+
def element_displayed?(element)
|
|
578
|
+
execute :isElementDisplayed, id: element
|
|
577
579
|
end
|
|
578
580
|
|
|
579
|
-
def
|
|
580
|
-
execute :getElementValueOfCssProperty, :
|
|
581
|
+
def element_value_of_css_property(element, prop)
|
|
582
|
+
execute :getElementValueOfCssProperty, id: element, property_name: prop
|
|
581
583
|
end
|
|
582
584
|
|
|
583
585
|
#
|
|
584
586
|
# finding elements
|
|
585
587
|
#
|
|
586
588
|
|
|
587
|
-
def
|
|
589
|
+
def active_element
|
|
588
590
|
Element.new self, element_id_from(execute(:getActiveElement))
|
|
589
591
|
end
|
|
590
|
-
|
|
592
|
+
|
|
593
|
+
alias_method :switch_to_active_element, :active_element
|
|
591
594
|
|
|
592
595
|
def find_element_by(how, what, parent = nil)
|
|
593
|
-
if parent
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
596
|
+
id = if parent
|
|
597
|
+
execute :findChildElement, {id: parent}, {using: how, value: what}
|
|
598
|
+
else
|
|
599
|
+
execute :findElement, {}, {using: how, value: what}
|
|
600
|
+
end
|
|
598
601
|
|
|
599
602
|
Element.new self, element_id_from(id)
|
|
600
603
|
end
|
|
601
604
|
|
|
602
605
|
def find_elements_by(how, what, parent = nil)
|
|
603
|
-
if parent
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
606
|
+
ids = if parent
|
|
607
|
+
execute :findChildElements, {id: parent}, {using: how, value: what}
|
|
608
|
+
else
|
|
609
|
+
execute :findElements, {}, {using: how, value: what}
|
|
610
|
+
end
|
|
608
611
|
|
|
609
612
|
ids.map { |id| Element.new self, element_id_from(id) }
|
|
610
613
|
end
|
|
@@ -613,7 +616,7 @@ module Selenium
|
|
|
613
616
|
|
|
614
617
|
def assert_javascript_enabled
|
|
615
618
|
return if capabilities.javascript_enabled?
|
|
616
|
-
raise Error::UnsupportedOperationError,
|
|
619
|
+
raise Error::UnsupportedOperationError, 'underlying webdriver instance does not support javascript'
|
|
617
620
|
end
|
|
618
621
|
|
|
619
622
|
#
|
|
@@ -635,9 +638,9 @@ module Selenium
|
|
|
635
638
|
|
|
636
639
|
def raw_execute(command, opts = {}, command_hash = nil)
|
|
637
640
|
verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
|
|
638
|
-
path
|
|
641
|
+
path = path.dup
|
|
639
642
|
|
|
640
|
-
path[':session_id'] = @session_id if path.include?(
|
|
643
|
+
path[':session_id'] = @session_id if path.include?(':session_id')
|
|
641
644
|
|
|
642
645
|
begin
|
|
643
646
|
opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }
|
|
@@ -652,7 +655,6 @@ module Selenium
|
|
|
652
655
|
def escaper
|
|
653
656
|
@escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
|
|
654
657
|
end
|
|
655
|
-
|
|
656
658
|
end # Bridge
|
|
657
659
|
end # Remote
|
|
658
660
|
end # WebDriver
|