selenium-webdriver 3.142.7 → 4.0.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +21 -43
- data/lib/selenium/webdriver.rb +2 -4
- data/lib/selenium/webdriver/chrome/bridge.rb +3 -21
- data/lib/selenium/webdriver/chrome/driver.rb +12 -39
- data/lib/selenium/webdriver/chrome/options.rb +3 -7
- data/lib/selenium/webdriver/chrome/profile.rb +2 -2
- data/lib/selenium/webdriver/chrome/service.rb +4 -9
- data/lib/selenium/webdriver/common.rb +7 -16
- data/lib/selenium/webdriver/common/action_builder.rb +97 -249
- data/lib/selenium/webdriver/common/driver.rb +2 -4
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +1 -1
- data/lib/selenium/webdriver/common/element.rb +3 -6
- data/lib/selenium/webdriver/common/error.rb +27 -203
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -5
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +13 -13
- data/lib/selenium/webdriver/common/manager.rb +1 -1
- data/lib/selenium/webdriver/common/options.rb +148 -24
- data/lib/selenium/webdriver/common/service.rb +16 -34
- data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
- data/lib/selenium/webdriver/common/w3c_options.rb +45 -0
- data/lib/selenium/webdriver/edge.rb +0 -1
- data/lib/selenium/webdriver/edge/driver.rb +14 -10
- data/lib/selenium/webdriver/edge/service.rb +6 -7
- data/lib/selenium/webdriver/firefox.rb +2 -6
- data/lib/selenium/webdriver/firefox/binary.rb +3 -80
- data/lib/selenium/webdriver/firefox/bridge.rb +47 -0
- data/lib/selenium/webdriver/firefox/driver.rb +44 -22
- data/lib/selenium/webdriver/firefox/marionette/driver.rb +1 -1
- data/lib/selenium/webdriver/firefox/options.rb +2 -2
- data/lib/selenium/webdriver/firefox/profile.rb +25 -14
- data/lib/selenium/webdriver/firefox/service.rb +4 -4
- data/lib/selenium/webdriver/ie/driver.rb +5 -18
- data/lib/selenium/webdriver/ie/options.rb +2 -2
- data/lib/selenium/webdriver/ie/service.rb +4 -4
- data/lib/selenium/webdriver/remote.rb +2 -6
- data/lib/selenium/webdriver/remote/bridge.rb +515 -69
- data/lib/selenium/webdriver/remote/capabilities.rb +77 -99
- data/lib/selenium/webdriver/remote/commands.rb +156 -0
- data/lib/selenium/webdriver/remote/driver.rb +12 -5
- data/lib/selenium/webdriver/remote/http/default.rb +0 -9
- data/lib/selenium/webdriver/remote/response.rb +16 -47
- data/lib/selenium/webdriver/safari.rb +1 -1
- data/lib/selenium/webdriver/safari/bridge.rb +3 -3
- data/lib/selenium/webdriver/safari/driver.rb +4 -1
- data/lib/selenium/webdriver/safari/service.rb +4 -4
- data/lib/selenium/webdriver/support/select.rb +1 -1
- data/lib/selenium/webdriver/version.rb +1 -1
- data/selenium-webdriver.gemspec +3 -3
- metadata +14 -5
@@ -20,29 +20,38 @@
|
|
20
20
|
module Selenium
|
21
21
|
module WebDriver
|
22
22
|
module Remote
|
23
|
+
|
23
24
|
#
|
24
25
|
# Specification of the desired and/or actual capabilities of the browser that the
|
25
26
|
# server is being asked to create.
|
26
27
|
#
|
28
|
+
|
27
29
|
class Capabilities
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
30
|
+
|
31
|
+
KNOWN = [
|
32
|
+
:browser_name,
|
33
|
+
:browser_version,
|
34
|
+
:platform_name,
|
35
|
+
:accept_insecure_certs,
|
36
|
+
:page_load_strategy,
|
37
|
+
:proxy,
|
38
|
+
:set_window_rect,
|
39
|
+
:timeouts,
|
40
|
+
:unhandled_prompt_behavior,
|
41
|
+
:strict_file_interactability,
|
42
|
+
|
43
|
+
# remote-specific
|
44
|
+
:remote_session_id,
|
45
|
+
|
46
|
+
# TODO: (AR) deprecate compatibility with OSS-capabilities
|
47
|
+
:implicit_timeout,
|
48
|
+
:page_load_timeout,
|
49
|
+
:script_timeout
|
50
|
+
].freeze
|
51
|
+
|
52
|
+
KNOWN.each do |key|
|
53
|
+
define_method key do
|
54
|
+
@capabilities.fetch(key)
|
46
55
|
end
|
47
56
|
|
48
57
|
next if key == :proxy
|
@@ -53,19 +62,13 @@ module Selenium
|
|
53
62
|
end
|
54
63
|
|
55
64
|
#
|
56
|
-
#
|
57
|
-
# It is true if not set explicitly.
|
65
|
+
# Backward compatibility
|
58
66
|
#
|
59
|
-
def javascript_enabled
|
60
|
-
javascript_enabled = @capabilities.fetch(:javascript_enabled)
|
61
|
-
javascript_enabled.nil? ? true : javascript_enabled
|
62
|
-
end
|
63
67
|
|
64
|
-
alias_method :
|
65
|
-
alias_method :
|
66
|
-
alias_method :
|
67
|
-
alias_method :
|
68
|
-
alias_method :rotatable?, :rotatable
|
68
|
+
alias_method :version, :browser_version
|
69
|
+
alias_method :version=, :browser_version=
|
70
|
+
alias_method :platform, :platform_name
|
71
|
+
alias_method :platform=, :platform_name=
|
69
72
|
|
70
73
|
#
|
71
74
|
# Convenience methods for the common choices.
|
@@ -74,16 +77,14 @@ module Selenium
|
|
74
77
|
class << self
|
75
78
|
def chrome(opts = {})
|
76
79
|
new({
|
77
|
-
browser_name: 'chrome'
|
78
|
-
javascript_enabled: true,
|
79
|
-
css_selectors_enabled: true
|
80
|
+
browser_name: 'chrome'
|
80
81
|
}.merge(opts))
|
81
82
|
end
|
82
83
|
|
83
84
|
def edge(opts = {})
|
84
85
|
new({
|
85
86
|
browser_name: 'MicrosoftEdge',
|
86
|
-
|
87
|
+
platform_name: :windows
|
87
88
|
}.merge(opts))
|
88
89
|
end
|
89
90
|
|
@@ -94,15 +95,15 @@ module Selenium
|
|
94
95
|
opts[:timeouts]['implicit'] = opts.delete(:implicit_timeout) if opts.key?(:implicit_timeout)
|
95
96
|
opts[:timeouts]['pageLoad'] = opts.delete(:page_load_timeout) if opts.key?(:page_load_timeout)
|
96
97
|
opts[:timeouts]['script'] = opts.delete(:script_timeout) if opts.key?(:script_timeout)
|
97
|
-
new({browser_name: 'firefox'
|
98
|
+
new({browser_name: 'firefox'}.merge(opts))
|
98
99
|
end
|
99
100
|
|
100
|
-
|
101
|
+
alias_method :ff, :firefox
|
102
|
+
|
103
|
+
def safari(opts = {})
|
101
104
|
new({
|
102
|
-
browser_name: '
|
103
|
-
|
104
|
-
takes_screenshot: true,
|
105
|
-
css_selectors_enabled: true
|
105
|
+
browser_name: 'safari',
|
106
|
+
platform_name: :mac
|
106
107
|
}.merge(opts))
|
107
108
|
end
|
108
109
|
|
@@ -112,44 +113,14 @@ module Selenium
|
|
112
113
|
}.merge(opts))
|
113
114
|
end
|
114
115
|
|
115
|
-
def htmlunitwithjs(opts = {})
|
116
|
-
new({
|
117
|
-
browser_name: 'htmlunit',
|
118
|
-
javascript_enabled: true
|
119
|
-
}.merge(opts))
|
120
|
-
end
|
121
|
-
|
122
116
|
def internet_explorer(opts = {})
|
123
117
|
new({
|
124
118
|
browser_name: 'internet explorer',
|
125
|
-
|
126
|
-
takes_screenshot: true,
|
127
|
-
css_selectors_enabled: true,
|
128
|
-
native_events: true
|
119
|
+
platform_name: :windows
|
129
120
|
}.merge(opts))
|
130
121
|
end
|
131
122
|
alias_method :ie, :internet_explorer
|
132
123
|
|
133
|
-
def phantomjs(opts = {})
|
134
|
-
WebDriver.logger.deprecate 'Selenium support for PhantomJS', 'headless Chrome/Firefox or HTMLUnit'
|
135
|
-
new({
|
136
|
-
browser_name: 'phantomjs',
|
137
|
-
javascript_enabled: true,
|
138
|
-
takes_screenshot: true,
|
139
|
-
css_selectors_enabled: true
|
140
|
-
}.merge(opts))
|
141
|
-
end
|
142
|
-
|
143
|
-
def safari(opts = {})
|
144
|
-
new({
|
145
|
-
browser_name: 'safari',
|
146
|
-
platform: :mac,
|
147
|
-
javascript_enabled: true,
|
148
|
-
takes_screenshot: true,
|
149
|
-
css_selectors_enabled: true
|
150
|
-
}.merge(opts))
|
151
|
-
end
|
152
|
-
|
153
124
|
#
|
154
125
|
# @api private
|
155
126
|
#
|
@@ -158,15 +129,26 @@ module Selenium
|
|
158
129
|
data = data.dup
|
159
130
|
|
160
131
|
caps = new
|
161
|
-
caps.browser_name
|
162
|
-
caps.
|
163
|
-
caps.
|
164
|
-
caps.
|
165
|
-
caps.
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
132
|
+
caps.browser_name = data.delete('browserName') if data.key?('browserName')
|
133
|
+
caps.browser_version = data.delete('browserVersion') if data.key?('browserVersion')
|
134
|
+
caps.platform_name = data.delete('platformName') if data.key?('platformName')
|
135
|
+
caps.accept_insecure_certs = data.delete('acceptInsecureCerts') if data.key?('acceptInsecureCerts')
|
136
|
+
caps.page_load_strategy = data.delete('pageLoadStrategy') if data.key?('pageLoadStrategy')
|
137
|
+
|
138
|
+
if data.key?('timeouts')
|
139
|
+
timeouts = data.delete('timeouts')
|
140
|
+
caps.implicit_timeout = timeouts['implicit'] if timeouts
|
141
|
+
caps.page_load_timeout = timeouts['pageLoad'] if timeouts
|
142
|
+
caps.script_timeout = timeouts['script'] if timeouts
|
143
|
+
end
|
144
|
+
|
145
|
+
if data.key?('proxy')
|
146
|
+
proxy = data.delete('proxy')
|
147
|
+
caps.proxy = Proxy.json_create(proxy) unless proxy.nil? || proxy.empty?
|
148
|
+
end
|
149
|
+
|
150
|
+
# Remote Server Specific
|
151
|
+
caps[:remote_session_id] = data.delete('webdriver.remote.sessionid') if data.key?('webdriver.remote.sessionid')
|
170
152
|
|
171
153
|
# any remaining pairs will be added as is, with no conversion
|
172
154
|
caps.merge!(data)
|
@@ -176,21 +158,19 @@ module Selenium
|
|
176
158
|
end
|
177
159
|
|
178
160
|
#
|
179
|
-
# @
|
180
|
-
# @option :
|
181
|
-
# @option :
|
182
|
-
# @option :
|
183
|
-
# @option :
|
184
|
-
# @option :
|
185
|
-
# @option :native_events [Boolean] does this driver use native events?
|
186
|
-
# @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
|
161
|
+
# @param [Hash] opts
|
162
|
+
# @option :browser_name [String] required browser name
|
163
|
+
# @option :browser_version [String] required browser version number
|
164
|
+
# @option :platform_name [Symbol] one of :any, :win, :mac, or :x
|
165
|
+
# @option :accept_insecure_certs [Boolean] does the driver accept insecure SSL certifications?
|
166
|
+
# @option :proxy [Selenium::WebDriver::Proxy, Hash] proxy configuration
|
187
167
|
#
|
188
168
|
# @api public
|
189
169
|
#
|
190
170
|
|
191
171
|
def initialize(opts = {})
|
192
|
-
@capabilities =
|
193
|
-
self.proxy
|
172
|
+
@capabilities = opts
|
173
|
+
self.proxy = opts.delete(:proxy)
|
194
174
|
end
|
195
175
|
|
196
176
|
#
|
@@ -230,24 +210,20 @@ module Selenium
|
|
230
210
|
# @api private
|
231
211
|
#
|
232
212
|
|
233
|
-
def as_json(*)
|
213
|
+
def as_json(*)
|
234
214
|
hash = {}
|
235
215
|
|
236
216
|
@capabilities.each do |key, value|
|
237
217
|
case key
|
238
218
|
when :platform
|
239
219
|
hash['platform'] = value.to_s.upcase
|
240
|
-
when :firefox_profile
|
241
|
-
if value
|
242
|
-
WebDriver.logger.deprecate(':firefox_profile capabilitiy', 'Selenium::WebDriver::Firefox::Options#profile')
|
243
|
-
hash['firefox_profile'] = value.as_json['zip']
|
244
|
-
end
|
245
220
|
when :proxy
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
221
|
+
if value
|
222
|
+
hash['proxy'] = value.as_json
|
223
|
+
hash['proxy']['proxyType'] &&= hash['proxy']['proxyType'].downcase
|
224
|
+
hash['proxy']['noProxy'] = hash['proxy']['noProxy'].split(', ') if hash['proxy']['noProxy'].is_a?(String)
|
250
225
|
end
|
226
|
+
when String
|
251
227
|
hash[key.to_s] = value
|
252
228
|
when Symbol
|
253
229
|
hash[camel_case(key.to_s)] = value
|
@@ -268,6 +244,7 @@ module Selenium
|
|
268
244
|
|
269
245
|
as_json == other.as_json
|
270
246
|
end
|
247
|
+
|
271
248
|
alias_method :eql?, :==
|
272
249
|
|
273
250
|
protected
|
@@ -279,6 +256,7 @@ module Selenium
|
|
279
256
|
def camel_case(str)
|
280
257
|
str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
|
281
258
|
end
|
259
|
+
|
282
260
|
end # Capabilities
|
283
261
|
end # Remote
|
284
262
|
end # WebDriver
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Licensed to the Software Freedom Conservancy (SFC) under one
|
4
|
+
# or more contributor license agreements. See the NOTICE file
|
5
|
+
# distributed with this work for additional information
|
6
|
+
# regarding copyright ownership. The SFC licenses this file
|
7
|
+
# to you under the Apache License, Version 2.0 (the
|
8
|
+
# "License"); you may not use this file except in compliance
|
9
|
+
# with the License. You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing,
|
14
|
+
# software distributed under the License is distributed on an
|
15
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
16
|
+
# KIND, either express or implied. See the License for the
|
17
|
+
# specific language governing permissions and limitations
|
18
|
+
# under the License.
|
19
|
+
|
20
|
+
module Selenium
|
21
|
+
module WebDriver
|
22
|
+
module Remote
|
23
|
+
|
24
|
+
#
|
25
|
+
# https://w3c.github.io/webdriver/#endpoints
|
26
|
+
# @api private
|
27
|
+
#
|
28
|
+
|
29
|
+
class Bridge
|
30
|
+
COMMANDS = {
|
31
|
+
status: [:get, 'status'],
|
32
|
+
|
33
|
+
#
|
34
|
+
# session handling
|
35
|
+
#
|
36
|
+
|
37
|
+
new_session: [:post, 'session'],
|
38
|
+
delete_session: [:delete, 'session/:session_id'],
|
39
|
+
|
40
|
+
#
|
41
|
+
# basic driver
|
42
|
+
#
|
43
|
+
|
44
|
+
get: [:post, 'session/:session_id/url'],
|
45
|
+
get_current_url: [:get, 'session/:session_id/url'],
|
46
|
+
back: [:post, 'session/:session_id/back'],
|
47
|
+
forward: [:post, 'session/:session_id/forward'],
|
48
|
+
refresh: [:post, 'session/:session_id/refresh'],
|
49
|
+
get_title: [:get, 'session/:session_id/title'],
|
50
|
+
|
51
|
+
#
|
52
|
+
# window and Frame handling
|
53
|
+
#
|
54
|
+
|
55
|
+
get_window_handle: [:get, 'session/:session_id/window'],
|
56
|
+
new_window: [:post, 'session/:session_id/window/new'],
|
57
|
+
close_window: [:delete, 'session/:session_id/window'],
|
58
|
+
switch_to_window: [:post, 'session/:session_id/window'],
|
59
|
+
get_window_handles: [:get, 'session/:session_id/window/handles'],
|
60
|
+
fullscreen_window: [:post, 'session/:session_id/window/fullscreen'],
|
61
|
+
minimize_window: [:post, 'session/:session_id/window/minimize'],
|
62
|
+
maximize_window: [:post, 'session/:session_id/window/maximize'],
|
63
|
+
set_window_size: [:post, 'session/:session_id/window/size'],
|
64
|
+
get_window_size: [:get, 'session/:session_id/window/size'],
|
65
|
+
set_window_position: [:post, 'session/:session_id/window/position'],
|
66
|
+
get_window_position: [:get, 'session/:session_id/window/position'],
|
67
|
+
set_window_rect: [:post, 'session/:session_id/window/rect'],
|
68
|
+
get_window_rect: [:get, 'session/:session_id/window/rect'],
|
69
|
+
switch_to_frame: [:post, 'session/:session_id/frame'],
|
70
|
+
switch_to_parent_frame: [:post, 'session/:session_id/frame/parent'],
|
71
|
+
|
72
|
+
#
|
73
|
+
# element
|
74
|
+
#
|
75
|
+
|
76
|
+
find_element: [:post, 'session/:session_id/element'],
|
77
|
+
find_elements: [:post, 'session/:session_id/elements'],
|
78
|
+
find_child_element: [:post, 'session/:session_id/element/:id/element'],
|
79
|
+
find_child_elements: [:post, 'session/:session_id/element/:id/elements'],
|
80
|
+
get_active_element: [:get, 'session/:session_id/element/active'],
|
81
|
+
is_element_selected: [:get, 'session/:session_id/element/:id/selected'],
|
82
|
+
get_element_attribute: [:get, 'session/:session_id/element/:id/attribute/:name'],
|
83
|
+
get_element_property: [:get, 'session/:session_id/element/:id/property/:name'],
|
84
|
+
get_element_css_value: [:get, 'session/:session_id/element/:id/css/:property_name'],
|
85
|
+
get_element_text: [:get, 'session/:session_id/element/:id/text'],
|
86
|
+
get_element_tag_name: [:get, 'session/:session_id/element/:id/name'],
|
87
|
+
get_element_rect: [:get, 'session/:session_id/element/:id/rect'],
|
88
|
+
is_element_enabled: [:get, 'session/:session_id/element/:id/enabled'],
|
89
|
+
|
90
|
+
#
|
91
|
+
# document handling
|
92
|
+
#
|
93
|
+
|
94
|
+
get_page_source: [:get, 'session/:session_id/source'],
|
95
|
+
execute_script: [:post, 'session/:session_id/execute/sync'],
|
96
|
+
execute_async_script: [:post, 'session/:session_id/execute/async'],
|
97
|
+
|
98
|
+
#
|
99
|
+
# cookies
|
100
|
+
#
|
101
|
+
|
102
|
+
get_all_cookies: [:get, 'session/:session_id/cookie'],
|
103
|
+
get_cookie: [:get, 'session/:session_id/cookie/:name'],
|
104
|
+
add_cookie: [:post, 'session/:session_id/cookie'],
|
105
|
+
delete_cookie: [:delete, 'session/:session_id/cookie/:name'],
|
106
|
+
delete_all_cookies: [:delete, 'session/:session_id/cookie'],
|
107
|
+
|
108
|
+
#
|
109
|
+
# timeouts
|
110
|
+
#
|
111
|
+
|
112
|
+
set_timeout: [:post, 'session/:session_id/timeouts'],
|
113
|
+
|
114
|
+
#
|
115
|
+
# actions
|
116
|
+
#
|
117
|
+
|
118
|
+
actions: [:post, 'session/:session_id/actions'],
|
119
|
+
release_actions: [:delete, 'session/:session_id/actions'],
|
120
|
+
|
121
|
+
#
|
122
|
+
# Element Operations
|
123
|
+
#
|
124
|
+
|
125
|
+
element_click: [:post, 'session/:session_id/element/:id/click'],
|
126
|
+
element_tap: [:post, 'session/:session_id/element/:id/tap'],
|
127
|
+
element_clear: [:post, 'session/:session_id/element/:id/clear'],
|
128
|
+
element_send_keys: [:post, 'session/:session_id/element/:id/value'],
|
129
|
+
|
130
|
+
#
|
131
|
+
# alerts
|
132
|
+
#
|
133
|
+
|
134
|
+
dismiss_alert: [:post, 'session/:session_id/alert/dismiss'],
|
135
|
+
accept_alert: [:post, 'session/:session_id/alert/accept'],
|
136
|
+
get_alert_text: [:get, 'session/:session_id/alert/text'],
|
137
|
+
send_alert_text: [:post, 'session/:session_id/alert/text'],
|
138
|
+
|
139
|
+
#
|
140
|
+
# screenshot
|
141
|
+
#
|
142
|
+
|
143
|
+
take_screenshot: [:get, 'session/:session_id/screenshot'],
|
144
|
+
take_element_screenshot: [:get, 'session/:session_id/element/:id/screenshot'],
|
145
|
+
|
146
|
+
#
|
147
|
+
# server extensions
|
148
|
+
#
|
149
|
+
|
150
|
+
upload_file: [:post, 'session/:session_id/se/file']
|
151
|
+
}.freeze
|
152
|
+
|
153
|
+
end # Bridge
|
154
|
+
end # Remote
|
155
|
+
end # WebDriver
|
156
|
+
end # Selenium
|
@@ -36,12 +36,19 @@ module Selenium
|
|
36
36
|
|
37
37
|
def initialize(opts = {})
|
38
38
|
listener = opts.delete(:listener)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
desired_capabilities = opts.delete(:desired_capabilities) { Capabilities.new }
|
40
|
+
|
41
|
+
if desired_capabilities.is_a?(Symbol)
|
42
|
+
unless Capabilities.respond_to?(desired_capabilities)
|
43
|
+
raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
|
44
|
+
end
|
45
|
+
|
46
|
+
desired_capabilities = Capabilities.__send__(desired_capabilities)
|
44
47
|
end
|
48
|
+
|
49
|
+
@bridge = Bridge.new(opts)
|
50
|
+
@bridge.create_session(desired_capabilities, opts.delete(:options))
|
51
|
+
|
45
52
|
super(@bridge, listener: listener)
|
46
53
|
end
|
47
54
|
|