selenium-webdriver 4.45.0 → 4.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +36 -0
- data/bin/linux/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/selenium-manager-THIRD-PARTY-NOTICES.txt +5971 -0
- data/bin/selenium-manager.cdx.json +11629 -0
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/webdriver/{common/driver_extensions/has_bidi.rb → bidi/error.rb} +21 -13
- data/lib/selenium/webdriver/bidi/protocol/bluetooth.rb +495 -0
- data/lib/selenium/webdriver/bidi/protocol/browser.rb +250 -0
- data/lib/selenium/webdriver/bidi/protocol/browsing_context.rb +798 -0
- data/lib/selenium/webdriver/bidi/protocol/domain.rb +46 -0
- data/lib/selenium/webdriver/bidi/protocol/emulation.rb +448 -0
- data/lib/selenium/webdriver/bidi/protocol/error_code.rb +66 -0
- data/lib/selenium/webdriver/bidi/protocol/input.rb +354 -0
- data/lib/selenium/webdriver/bidi/protocol/log.rb +115 -0
- data/lib/selenium/webdriver/bidi/protocol/network.rb +720 -0
- data/lib/selenium/webdriver/bidi/protocol/permissions.rb +75 -0
- data/lib/selenium/webdriver/bidi/protocol/script.rb +1052 -0
- data/lib/selenium/webdriver/bidi/protocol/session.rb +286 -0
- data/lib/selenium/webdriver/bidi/protocol/speculation.rb +58 -0
- data/lib/selenium/webdriver/bidi/protocol/storage.rb +183 -0
- data/lib/selenium/webdriver/bidi/protocol/user_agent_client_hints.rb +88 -0
- data/lib/selenium/webdriver/bidi/protocol/web_extension.rb +132 -0
- data/lib/selenium/webdriver/bidi/protocol.rb +42 -0
- data/lib/selenium/webdriver/bidi/serialization/record.rb +402 -0
- data/lib/selenium/webdriver/bidi/serialization/union.rb +156 -0
- data/lib/selenium/webdriver/bidi/serialization.rb +90 -0
- data/lib/selenium/webdriver/bidi/support/bidi_generate.rb +1420 -0
- data/lib/selenium/webdriver/bidi/support/check_generated.rb +63 -0
- data/lib/selenium/webdriver/bidi/transport.rb +57 -0
- data/lib/selenium/webdriver/bidi.rb +3 -0
- data/lib/selenium/webdriver/chrome/driver.rb +3 -3
- data/lib/selenium/webdriver/chrome/service.rb +4 -1
- data/lib/selenium/webdriver/chromium/driver.rb +0 -1
- data/lib/selenium/webdriver/chromium/options.rb +20 -0
- data/lib/selenium/webdriver/common/client_config.rb +97 -0
- data/lib/selenium/webdriver/common/driver.rb +13 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +0 -7
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +0 -7
- data/lib/selenium/webdriver/common/driver_finder.rb +4 -3
- data/lib/selenium/webdriver/common/local_driver.rb +15 -4
- data/lib/selenium/webdriver/common/options.rb +21 -1
- data/lib/selenium/webdriver/common/proxy.rb +1 -9
- data/lib/selenium/webdriver/common/selenium_manager.rb +2 -1
- data/lib/selenium/webdriver/common/takes_screenshot.rb +1 -1
- data/lib/selenium/webdriver/common.rb +1 -1
- data/lib/selenium/webdriver/edge/driver.rb +3 -3
- data/lib/selenium/webdriver/edge/service.rb +4 -1
- data/lib/selenium/webdriver/firefox/driver.rb +3 -6
- data/lib/selenium/webdriver/firefox/options.rb +19 -0
- data/lib/selenium/webdriver/firefox/profile.rb +13 -6
- data/lib/selenium/webdriver/ie/driver.rb +3 -3
- data/lib/selenium/webdriver/remote/bidi_bridge.rb +41 -9
- data/lib/selenium/webdriver/remote/bridge.rb +8 -10
- data/lib/selenium/webdriver/remote/driver.rb +14 -4
- data/lib/selenium/webdriver/remote/http/common.rb +25 -12
- data/lib/selenium/webdriver/remote/http/default.rb +56 -39
- data/lib/selenium/webdriver/safari/driver.rb +3 -3
- data/lib/selenium/webdriver/safari/options.rb +16 -1
- data/lib/selenium/webdriver/support/guards/guard.rb +20 -3
- data/lib/selenium/webdriver/support/guards.rb +9 -3
- data/lib/selenium/webdriver/version.rb +1 -1
- metadata +29 -3
|
@@ -40,7 +40,6 @@ module Selenium
|
|
|
40
40
|
LOCK_FILES = %w[.parentlock parent.lock lock].freeze
|
|
41
41
|
|
|
42
42
|
attr_reader :name, :log_file
|
|
43
|
-
attr_writer :secure_ssl, :load_no_focus_lib
|
|
44
43
|
|
|
45
44
|
class << self
|
|
46
45
|
def ini
|
|
@@ -110,19 +109,28 @@ module Selenium
|
|
|
110
109
|
end
|
|
111
110
|
|
|
112
111
|
def port=(port)
|
|
112
|
+
WebDriver.logger.deprecate('Firefox::Profile#port=', 'the Service class', id: :firefox_profile)
|
|
113
113
|
self[WEBDRIVER_PREFS[:port]] = port
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
def secure_ssl=(value)
|
|
117
|
+
WebDriver.logger.deprecate('Firefox::Profile#secure_ssl=', id: :firefox_profile)
|
|
118
|
+
@secure_ssl = value
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def load_no_focus_lib=(value)
|
|
122
|
+
WebDriver.logger.deprecate('Firefox::Profile#load_no_focus_lib=', id: :firefox_profile)
|
|
123
|
+
@load_no_focus_lib = value
|
|
124
|
+
end
|
|
125
|
+
|
|
116
126
|
def log_file=(file)
|
|
117
127
|
@log_file = file
|
|
118
128
|
self[WEBDRIVER_PREFS[:log_file]] = file
|
|
119
129
|
end
|
|
120
130
|
|
|
121
|
-
#
|
|
122
|
-
# Add the extension (directory, .zip or .xpi) at the given path to the profile.
|
|
123
|
-
#
|
|
124
|
-
|
|
125
131
|
def add_extension(path, name = extension_name_for(path))
|
|
132
|
+
WebDriver.logger.deprecate('Firefox::Profile#add_extension', 'Driver#install_addon',
|
|
133
|
+
id: :firefox_profile)
|
|
126
134
|
@extensions[name] = Extension.new(path)
|
|
127
135
|
end
|
|
128
136
|
|
|
@@ -133,7 +141,6 @@ module Selenium
|
|
|
133
141
|
when :manual
|
|
134
142
|
self['network.proxy.type'] = 1
|
|
135
143
|
|
|
136
|
-
set_manual_proxy_preference 'ftp', proxy.ftp
|
|
137
144
|
set_manual_proxy_preference 'http', proxy.http
|
|
138
145
|
set_manual_proxy_preference 'ssl', proxy.ssl
|
|
139
146
|
set_manual_proxy_preference 'socks', proxy.socks
|
|
@@ -31,9 +31,9 @@ module Selenium
|
|
|
31
31
|
|
|
32
32
|
include LocalDriver
|
|
33
33
|
|
|
34
|
-
def initialize(options: nil, service: nil, url: nil, **)
|
|
35
|
-
initialize_local_driver(options, service, url) do |caps,
|
|
36
|
-
super(caps: caps,
|
|
34
|
+
def initialize(options: nil, service: nil, url: nil, http_client: nil, client_config: nil, **)
|
|
35
|
+
initialize_local_driver(options, service, url, http_client, client_config) do |caps, client|
|
|
36
|
+
super(caps: caps, http_client: client, **)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -17,36 +17,56 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
+
require 'selenium/webdriver/bidi'
|
|
21
|
+
require 'selenium/webdriver/bidi/protocol'
|
|
22
|
+
|
|
20
23
|
module Selenium
|
|
21
24
|
module WebDriver
|
|
22
25
|
module Remote
|
|
23
26
|
class BiDiBridge < Bridge
|
|
24
|
-
attr_reader :bidi
|
|
27
|
+
attr_reader :bidi, :connection
|
|
28
|
+
|
|
29
|
+
READINESS_STATE = {
|
|
30
|
+
'none' => :none,
|
|
31
|
+
'eager' => :interactive,
|
|
32
|
+
'normal' => :complete
|
|
33
|
+
}.freeze
|
|
25
34
|
|
|
26
35
|
def create_session(capabilities)
|
|
27
36
|
super
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
|
|
38
|
+
begin
|
|
39
|
+
@bidi = Selenium::WebDriver::BiDi.new(url: validated_socket_url)
|
|
40
|
+
# Reuse the BiDi object's socket as the connection until the bridge owns it directly.
|
|
41
|
+
@connection = @bidi.ws
|
|
42
|
+
rescue StandardError
|
|
43
|
+
quit
|
|
44
|
+
raise
|
|
45
|
+
end
|
|
30
46
|
end
|
|
31
47
|
|
|
32
48
|
def get(url)
|
|
33
|
-
browsing_context.navigate(url)
|
|
49
|
+
browsing_context.navigate(context: window_handle, url: url, wait: readiness_state)
|
|
50
|
+
nil
|
|
34
51
|
end
|
|
35
52
|
|
|
36
53
|
def go_back
|
|
37
|
-
browsing_context.traverse_history(-1)
|
|
54
|
+
browsing_context.traverse_history(context: window_handle, delta: -1)
|
|
55
|
+
nil
|
|
38
56
|
end
|
|
39
57
|
|
|
40
58
|
def go_forward
|
|
41
|
-
browsing_context.traverse_history(1)
|
|
59
|
+
browsing_context.traverse_history(context: window_handle, delta: 1)
|
|
60
|
+
nil
|
|
42
61
|
end
|
|
43
62
|
|
|
44
63
|
def refresh
|
|
45
|
-
browsing_context.reload
|
|
64
|
+
browsing_context.reload(context: window_handle, wait: readiness_state)
|
|
65
|
+
nil
|
|
46
66
|
end
|
|
47
67
|
|
|
48
68
|
def quit
|
|
49
|
-
bidi
|
|
69
|
+
bidi&.close
|
|
50
70
|
rescue *QUIT_ERRORS
|
|
51
71
|
nil
|
|
52
72
|
ensure
|
|
@@ -59,8 +79,20 @@ module Selenium
|
|
|
59
79
|
|
|
60
80
|
private
|
|
61
81
|
|
|
82
|
+
def validated_socket_url
|
|
83
|
+
url = @capabilities[:web_socket_url]
|
|
84
|
+
return url if url.is_a?(String) && url.start_with?('ws://', 'wss://')
|
|
85
|
+
|
|
86
|
+
raise Error::WebDriverError,
|
|
87
|
+
"BiDi was enabled, but the remote end did not return a valid webSocketUrl: #{url.inspect}."
|
|
88
|
+
end
|
|
89
|
+
|
|
62
90
|
def browsing_context
|
|
63
|
-
@browsing_context ||=
|
|
91
|
+
@browsing_context ||= BiDi::Protocol::BrowsingContext.new(connection)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def readiness_state
|
|
95
|
+
READINESS_STATE.fetch(capabilities[:page_load_strategy] || 'normal')
|
|
64
96
|
end
|
|
65
97
|
end # BiDiBridge
|
|
66
98
|
end # Remote
|
|
@@ -51,20 +51,13 @@ module Selenium
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
#
|
|
54
|
-
#
|
|
55
|
-
# @param [String, URI] url url for the remote server
|
|
56
|
-
# @param [Object] http_client an HTTP client instance that implements the same protocol as Http::Default
|
|
54
|
+
# @param [Object] http_client a configured HTTP client implementing the same protocol as Http::Default
|
|
57
55
|
# @api private
|
|
58
56
|
#
|
|
59
57
|
|
|
60
|
-
def initialize(
|
|
61
|
-
|
|
62
|
-
uri.path += '/' unless uri.path.end_with?('/')
|
|
63
|
-
|
|
64
|
-
@http = http_client || Http::Default.new
|
|
65
|
-
@http.server_url = uri
|
|
58
|
+
def initialize(http_client:)
|
|
59
|
+
@http = http_client
|
|
66
60
|
@file_detector = nil
|
|
67
|
-
|
|
68
61
|
@locator_converter = self.class.locator_converter
|
|
69
62
|
end
|
|
70
63
|
|
|
@@ -605,6 +598,11 @@ module Selenium
|
|
|
605
598
|
raise(WebDriver::Error::WebDriverError, msg)
|
|
606
599
|
end
|
|
607
600
|
|
|
601
|
+
def connection
|
|
602
|
+
msg = 'BiDi must be enabled by setting #web_socket_url to true in options class'
|
|
603
|
+
raise(WebDriver::Error::WebDriverError, msg)
|
|
604
|
+
end
|
|
605
|
+
|
|
608
606
|
def command_list
|
|
609
607
|
COMMANDS
|
|
610
608
|
end
|
|
@@ -31,12 +31,16 @@ module Selenium
|
|
|
31
31
|
include DriverExtensions::HasFileDownloads
|
|
32
32
|
include DriverExtensions::HasSessionEvents
|
|
33
33
|
|
|
34
|
-
def initialize(capabilities: nil, options: nil, service: nil, url: nil,
|
|
35
|
-
|
|
34
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, http_client: nil, client_config: nil,
|
|
35
|
+
**)
|
|
36
|
+
assert_arguments(service, url, http_client, client_config)
|
|
36
37
|
|
|
37
|
-
url ||= "http://#{Platform.localhost}:4444/wd/hub"
|
|
38
38
|
caps = process_options(options, capabilities)
|
|
39
|
-
|
|
39
|
+
http_client ||= Remote::Http::Default.new(client_config: client_config)
|
|
40
|
+
server_url = url || client_config&.server_url || "http://#{Platform.localhost}:4444/wd/hub"
|
|
41
|
+
http_client.server_url = server_url
|
|
42
|
+
caps['se:remoteUrl'] = server_url.to_s.chomp('/')
|
|
43
|
+
super(caps: caps, http_client: http_client, **)
|
|
40
44
|
@bridge.file_detector = ->((filename, *)) { File.exist?(filename) && filename.to_s }
|
|
41
45
|
command_list = @bridge.command_list
|
|
42
46
|
@bridge.extend(WebDriver::Remote::Features)
|
|
@@ -45,6 +49,12 @@ module Selenium
|
|
|
45
49
|
|
|
46
50
|
private
|
|
47
51
|
|
|
52
|
+
def assert_arguments(service, url, http_client, client_config)
|
|
53
|
+
raise ArgumentError, "Can not set :service object on #{self.class}" if service
|
|
54
|
+
raise ArgumentError, 'Cannot use both :http_client and :client_config' if http_client && client_config
|
|
55
|
+
raise ArgumentError, 'Cannot use both :url and a ClientConfig#server_url' if url && client_config&.server_url
|
|
56
|
+
end
|
|
57
|
+
|
|
48
58
|
def devtools_url
|
|
49
59
|
capabilities['se:cdp']
|
|
50
60
|
end
|
|
@@ -31,15 +31,32 @@ module Selenium
|
|
|
31
31
|
BINARY_ENCODINGS = [Encoding::BINARY, Encoding::ASCII_8BIT].freeze
|
|
32
32
|
|
|
33
33
|
class << self
|
|
34
|
-
attr_accessor :extra_headers
|
|
35
|
-
attr_writer :user_agent
|
|
36
|
-
|
|
37
34
|
def user_agent
|
|
38
|
-
|
|
35
|
+
ClientConfig.default_user_agent
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def user_agent=(value)
|
|
39
|
+
ClientConfig.default_user_agent = value
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def extra_headers
|
|
43
|
+
ClientConfig.default_extra_headers
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def extra_headers=(value)
|
|
47
|
+
ClientConfig.default_extra_headers = value
|
|
39
48
|
end
|
|
40
49
|
end
|
|
41
50
|
|
|
42
|
-
|
|
51
|
+
attr_reader :client_config
|
|
52
|
+
|
|
53
|
+
def initialize(client_config: nil)
|
|
54
|
+
@client_config = client_config || ClientConfig.new
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def server_url=(url)
|
|
58
|
+
client_config.server_url = url
|
|
59
|
+
end
|
|
43
60
|
|
|
44
61
|
def quit_errors
|
|
45
62
|
[IOError]
|
|
@@ -76,17 +93,13 @@ module Selenium
|
|
|
76
93
|
def common_headers
|
|
77
94
|
@common_headers ||= begin
|
|
78
95
|
headers = DEFAULT_HEADERS.dup
|
|
79
|
-
headers['User-Agent'] =
|
|
80
|
-
headers
|
|
81
|
-
|
|
82
|
-
headers
|
|
96
|
+
headers['User-Agent'] = client_config.user_agent
|
|
97
|
+
headers.merge(client_config.extra_headers || {})
|
|
83
98
|
end
|
|
84
99
|
end
|
|
85
100
|
|
|
86
101
|
def server_url
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
raise Error::WebDriverError, 'server_url not set'
|
|
102
|
+
client_config.server_url || raise(Error::WebDriverError, 'server_url not set')
|
|
90
103
|
end
|
|
91
104
|
|
|
92
105
|
def request(*)
|
|
@@ -24,19 +24,41 @@ module Selenium
|
|
|
24
24
|
module Http
|
|
25
25
|
# @api private
|
|
26
26
|
class Default < Common
|
|
27
|
-
attr_writer :proxy
|
|
28
|
-
|
|
29
|
-
attr_accessor :open_timeout, :read_timeout
|
|
30
|
-
|
|
31
27
|
# Initializes object.
|
|
32
28
|
# Warning: Setting {#open_timeout} to non-nil values will cause a separate thread to spawn.
|
|
33
29
|
# Debuggers that freeze the process will not be able to evaluate any operations if that happens.
|
|
30
|
+
# @param [ClientConfig] client_config - Configuration used to build the HTTP client.
|
|
34
31
|
# @param [Numeric] open_timeout - Open timeout to apply to HTTP client.
|
|
35
32
|
# @param [Numeric] read_timeout - Read timeout (seconds) to apply to HTTP client.
|
|
36
|
-
def initialize(open_timeout: nil, read_timeout: nil)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
def initialize(client_config: nil, open_timeout: nil, read_timeout: nil)
|
|
34
|
+
if client_config && (open_timeout || read_timeout)
|
|
35
|
+
raise ArgumentError, 'Cannot use both :client_config and :open_timeout/:read_timeout'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
client_config ||= ClientConfig.new
|
|
39
|
+
client_config.open_timeout = open_timeout if open_timeout
|
|
40
|
+
client_config.read_timeout = read_timeout if read_timeout
|
|
41
|
+
super(client_config: client_config)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def open_timeout
|
|
45
|
+
client_config.open_timeout
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def read_timeout
|
|
49
|
+
client_config.read_timeout
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def open_timeout=(value)
|
|
53
|
+
client_config.open_timeout = value
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def read_timeout=(value)
|
|
57
|
+
client_config.read_timeout = value
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def proxy=(value)
|
|
61
|
+
client_config.proxy = value
|
|
40
62
|
end
|
|
41
63
|
|
|
42
64
|
def close
|
|
@@ -94,16 +116,20 @@ module Selenium
|
|
|
94
116
|
end
|
|
95
117
|
|
|
96
118
|
if response.is_a? Net::HTTPRedirection
|
|
97
|
-
|
|
98
|
-
raise Error::WebDriverError, 'too many redirects' if redirects >= MAX_REDIRECTS
|
|
99
|
-
|
|
100
|
-
request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
|
|
119
|
+
follow_redirect(response, redirects)
|
|
101
120
|
else
|
|
102
121
|
WebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}", id: :header)
|
|
103
122
|
create_response response.code, response.body, response.content_type
|
|
104
123
|
end
|
|
105
124
|
end
|
|
106
125
|
|
|
126
|
+
def follow_redirect(response, redirects)
|
|
127
|
+
WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}", id: :redirect)
|
|
128
|
+
raise Error::WebDriverError, 'too many redirects' if redirects >= client_config.max_redirects
|
|
129
|
+
|
|
130
|
+
request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
|
|
131
|
+
end
|
|
132
|
+
|
|
107
133
|
def new_request_for(verb, url, headers, payload)
|
|
108
134
|
req = Net::HTTP.const_get(verb.to_s.capitalize).new(url.path, headers)
|
|
109
135
|
|
|
@@ -120,52 +146,43 @@ module Selenium
|
|
|
120
146
|
|
|
121
147
|
def new_http_client
|
|
122
148
|
if use_proxy?
|
|
123
|
-
url =
|
|
149
|
+
url = proxy.http
|
|
124
150
|
unless proxy.respond_to?(:http) && url
|
|
125
151
|
raise Error::WebDriverError,
|
|
126
|
-
"expected HTTP proxy, got #{
|
|
152
|
+
"expected HTTP proxy, got #{proxy.inspect}"
|
|
127
153
|
end
|
|
128
154
|
|
|
129
|
-
|
|
155
|
+
proxy_uri = URI.parse(url)
|
|
130
156
|
|
|
131
|
-
Net::HTTP.new(server_url.host, server_url.port,
|
|
157
|
+
Net::HTTP.new(server_url.host, server_url.port,
|
|
158
|
+
proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
|
|
132
159
|
else
|
|
133
160
|
Net::HTTP.new server_url.host, server_url.port
|
|
134
161
|
end
|
|
135
162
|
end
|
|
136
163
|
|
|
137
164
|
def proxy
|
|
138
|
-
|
|
139
|
-
proxy = ENV.fetch('http_proxy', nil) || ENV.fetch('HTTP_PROXY', nil)
|
|
140
|
-
no_proxy = ENV.fetch('no_proxy', nil) || ENV.fetch('NO_PROXY', nil)
|
|
141
|
-
|
|
142
|
-
if proxy
|
|
143
|
-
proxy = "http://#{proxy}" unless proxy.start_with?('http://')
|
|
144
|
-
Proxy.new(http: proxy, no_proxy: no_proxy)
|
|
145
|
-
end
|
|
146
|
-
end
|
|
165
|
+
client_config.proxy
|
|
147
166
|
end
|
|
148
167
|
|
|
149
168
|
def use_proxy?
|
|
150
169
|
return false if proxy.nil?
|
|
170
|
+
return true unless proxy.no_proxy
|
|
151
171
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
host == '*' ||
|
|
155
|
-
host == server_url.host || (
|
|
156
|
-
begin
|
|
157
|
-
IPAddr.new(host).include?(server_url.host)
|
|
158
|
-
rescue ArgumentError
|
|
159
|
-
false
|
|
160
|
-
end
|
|
161
|
-
)
|
|
162
|
-
end
|
|
172
|
+
!proxy_ignored?
|
|
173
|
+
end
|
|
163
174
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
175
|
+
def proxy_ignored?
|
|
176
|
+
proxy.no_proxy.split(',').map(&:strip).reject(&:empty?).any? do |host|
|
|
177
|
+
host == '*' || host == server_url.host || ip_match?(host)
|
|
167
178
|
end
|
|
168
179
|
end
|
|
180
|
+
|
|
181
|
+
def ip_match?(host)
|
|
182
|
+
IPAddr.new(host).include?(server_url.host)
|
|
183
|
+
rescue ArgumentError
|
|
184
|
+
false
|
|
185
|
+
end
|
|
169
186
|
end # Default
|
|
170
187
|
end # Http
|
|
171
188
|
end # Remote
|
|
@@ -31,9 +31,9 @@ module Selenium
|
|
|
31
31
|
|
|
32
32
|
include LocalDriver
|
|
33
33
|
|
|
34
|
-
def initialize(options: nil, service: nil, url: nil, **)
|
|
35
|
-
initialize_local_driver(options, service, url) do |caps,
|
|
36
|
-
super(caps: caps,
|
|
34
|
+
def initialize(options: nil, service: nil, url: nil, http_client: nil, client_config: nil, **)
|
|
35
|
+
initialize_local_driver(options, service, url, http_client, client_config) do |caps, client|
|
|
36
|
+
super(caps: caps, http_client: client, **)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -25,7 +25,8 @@ module Selenium
|
|
|
25
25
|
|
|
26
26
|
# @see https://developer.apple.com/documentation/webkit/about_webdriver_for_safari
|
|
27
27
|
CAPABILITIES = {automatic_inspection: 'safari:automaticInspection',
|
|
28
|
-
automatic_profiling: 'safari:automaticProfiling'
|
|
28
|
+
automatic_profiling: 'safari:automaticProfiling',
|
|
29
|
+
experimental_web_socket_url: 'safari:experimentalWebSocketUrl'}.freeze
|
|
29
30
|
BROWSER = 'safari'
|
|
30
31
|
TECHNOLOGY_PREVIEW = 'Safari Technology Preview'
|
|
31
32
|
|
|
@@ -43,6 +44,20 @@ module Selenium
|
|
|
43
44
|
def browser_name
|
|
44
45
|
@options[:browser_name] = Safari.technology_preview? ? TECHNOLOGY_PREVIEW : BROWSER
|
|
45
46
|
end
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# Enables WebDriver BiDi for Safari, which also requires the experimental capability, and
|
|
50
|
+
# warns that Safari's BiDi support is experimental.
|
|
51
|
+
#
|
|
52
|
+
# @return [Boolean]
|
|
53
|
+
#
|
|
54
|
+
|
|
55
|
+
def enable_bidi!
|
|
56
|
+
super
|
|
57
|
+
WebDriver.logger.warn("Safari's WebDriver BiDi support is experimental and may be incomplete",
|
|
58
|
+
id: :safari_bidi)
|
|
59
|
+
@options[:experimental_web_socket_url] = true
|
|
60
|
+
end
|
|
46
61
|
end # Options
|
|
47
62
|
end # Safari
|
|
48
63
|
end # WebDriver
|
|
@@ -30,7 +30,7 @@ module Selenium
|
|
|
30
30
|
attr_reader :guarded, :type, :messages, :reason, :tracker
|
|
31
31
|
|
|
32
32
|
def initialize(guarded, type, guards = nil)
|
|
33
|
-
@guarded = guarded
|
|
33
|
+
@guarded = guarded.dup
|
|
34
34
|
@tracker = guards&.bug_tracker || ''
|
|
35
35
|
@messages = guards&.messages || {}
|
|
36
36
|
@messages[:unknown] = 'TODO: Investigate why this is failing and file a bug report'
|
|
@@ -47,7 +47,7 @@ module Selenium
|
|
|
47
47
|
when Symbol
|
|
48
48
|
messages[reason]
|
|
49
49
|
else
|
|
50
|
-
"
|
|
50
|
+
"#{type.to_s.tr('_', ' ')} #{guarded};"
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
case type
|
|
@@ -57,8 +57,10 @@ module Selenium
|
|
|
57
57
|
"Test skipped because it is unreliable in this configuration; #{details}"
|
|
58
58
|
when :skip_unless, :exclusive
|
|
59
59
|
"Test does not apply to this configuration; #{details}"
|
|
60
|
-
|
|
60
|
+
when :pending_if, :pending_unless, :except, :only
|
|
61
61
|
"Test guarded; #{details}"
|
|
62
|
+
else
|
|
63
|
+
raise ArgumentError, "unknown guard type: #{type}"
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
|
|
@@ -81,6 +83,21 @@ module Selenium
|
|
|
81
83
|
def exclusive?
|
|
82
84
|
@type == :skip_unless || @type == :exclusive
|
|
83
85
|
end
|
|
86
|
+
|
|
87
|
+
# A pending guard that only applies when the failure matches an expected exception.
|
|
88
|
+
def exception?
|
|
89
|
+
(except? || only?) && !@guarded[:exception].nil?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Whether the exception is the guard's `exception:` class and matches its optional `message:`
|
|
93
|
+
# (Regexp pattern or exact String), following RSpec's `raise_error` semantics.
|
|
94
|
+
def matches_exception?(exception)
|
|
95
|
+
spec = @guarded[:exception]
|
|
96
|
+
return false unless spec && exception.is_a?(spec[:class])
|
|
97
|
+
|
|
98
|
+
message = spec[:message]
|
|
99
|
+
message.nil? || (message.is_a?(Regexp) ? message.match?(exception.message) : message == exception.message)
|
|
100
|
+
end
|
|
84
101
|
end # Guard
|
|
85
102
|
end # Guards
|
|
86
103
|
end # Support
|
|
@@ -41,7 +41,7 @@ module Selenium
|
|
|
41
41
|
def add_condition(name, condition = false, &block)
|
|
42
42
|
condition = false if condition.nil?
|
|
43
43
|
@guard_conditions << GuardCondition.new(name, condition, &block)
|
|
44
|
-
WebDriver.logger.debug "Running with Guard '#{name}' set to: #{condition}"
|
|
44
|
+
WebDriver.logger.debug "Running with Guard '#{name}' set to: #{condition}", id: :guard
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def add_message(name, message)
|
|
@@ -52,12 +52,18 @@ module Selenium
|
|
|
52
52
|
if !skipping_guard.nil?
|
|
53
53
|
[:skip, skipping_guard.message]
|
|
54
54
|
elsif !pending_guard.nil? && ENV.fetch('SKIP_PENDING', nil)
|
|
55
|
-
[:skip, pending_guard.message]
|
|
56
|
-
elsif !pending_guard.nil?
|
|
55
|
+
[:skip, "(skipped by SKIP_PENDING) #{pending_guard.message}"]
|
|
56
|
+
elsif !pending_guard.nil? && !pending_guard.exception?
|
|
57
57
|
[:pending, pending_guard.message]
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
# The deferred `exception:` pending guard, evaluated against the failure after the run, else nil.
|
|
62
|
+
def pending_exception_guard
|
|
63
|
+
guard = pending_guard
|
|
64
|
+
guard if disposition.nil? && guard&.exception?
|
|
65
|
+
end
|
|
66
|
+
|
|
61
67
|
def satisfied?(guard)
|
|
62
68
|
@guard_conditions.all? { |condition| condition.satisfied?(guard) }
|
|
63
69
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: selenium-webdriver
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.47.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Rodionov
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2026-
|
|
13
|
+
date: 2026-08-10 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: base64
|
|
@@ -273,6 +273,8 @@ files:
|
|
|
273
273
|
- README.md
|
|
274
274
|
- bin/linux/selenium-manager
|
|
275
275
|
- bin/macos/selenium-manager
|
|
276
|
+
- bin/selenium-manager-THIRD-PARTY-NOTICES.txt
|
|
277
|
+
- bin/selenium-manager.cdx.json
|
|
276
278
|
- bin/windows/selenium-manager.exe
|
|
277
279
|
- lib/selenium-webdriver.rb
|
|
278
280
|
- lib/selenium/server.rb
|
|
@@ -285,6 +287,7 @@ files:
|
|
|
285
287
|
- lib/selenium/webdriver/bidi.rb
|
|
286
288
|
- lib/selenium/webdriver/bidi/browser.rb
|
|
287
289
|
- lib/selenium/webdriver/bidi/browsing_context.rb
|
|
290
|
+
- lib/selenium/webdriver/bidi/error.rb
|
|
288
291
|
- lib/selenium/webdriver/bidi/log_handler.rb
|
|
289
292
|
- lib/selenium/webdriver/bidi/network.rb
|
|
290
293
|
- lib/selenium/webdriver/bidi/network/cookies.rb
|
|
@@ -295,8 +298,31 @@ files:
|
|
|
295
298
|
- lib/selenium/webdriver/bidi/network/intercepted_request.rb
|
|
296
299
|
- lib/selenium/webdriver/bidi/network/intercepted_response.rb
|
|
297
300
|
- lib/selenium/webdriver/bidi/network/url_pattern.rb
|
|
301
|
+
- lib/selenium/webdriver/bidi/protocol.rb
|
|
302
|
+
- lib/selenium/webdriver/bidi/protocol/bluetooth.rb
|
|
303
|
+
- lib/selenium/webdriver/bidi/protocol/browser.rb
|
|
304
|
+
- lib/selenium/webdriver/bidi/protocol/browsing_context.rb
|
|
305
|
+
- lib/selenium/webdriver/bidi/protocol/domain.rb
|
|
306
|
+
- lib/selenium/webdriver/bidi/protocol/emulation.rb
|
|
307
|
+
- lib/selenium/webdriver/bidi/protocol/error_code.rb
|
|
308
|
+
- lib/selenium/webdriver/bidi/protocol/input.rb
|
|
309
|
+
- lib/selenium/webdriver/bidi/protocol/log.rb
|
|
310
|
+
- lib/selenium/webdriver/bidi/protocol/network.rb
|
|
311
|
+
- lib/selenium/webdriver/bidi/protocol/permissions.rb
|
|
312
|
+
- lib/selenium/webdriver/bidi/protocol/script.rb
|
|
313
|
+
- lib/selenium/webdriver/bidi/protocol/session.rb
|
|
314
|
+
- lib/selenium/webdriver/bidi/protocol/speculation.rb
|
|
315
|
+
- lib/selenium/webdriver/bidi/protocol/storage.rb
|
|
316
|
+
- lib/selenium/webdriver/bidi/protocol/user_agent_client_hints.rb
|
|
317
|
+
- lib/selenium/webdriver/bidi/protocol/web_extension.rb
|
|
318
|
+
- lib/selenium/webdriver/bidi/serialization.rb
|
|
319
|
+
- lib/selenium/webdriver/bidi/serialization/record.rb
|
|
320
|
+
- lib/selenium/webdriver/bidi/serialization/union.rb
|
|
298
321
|
- lib/selenium/webdriver/bidi/session.rb
|
|
299
322
|
- lib/selenium/webdriver/bidi/struct.rb
|
|
323
|
+
- lib/selenium/webdriver/bidi/support/bidi_generate.rb
|
|
324
|
+
- lib/selenium/webdriver/bidi/support/check_generated.rb
|
|
325
|
+
- lib/selenium/webdriver/bidi/transport.rb
|
|
300
326
|
- lib/selenium/webdriver/chrome.rb
|
|
301
327
|
- lib/selenium/webdriver/chrome/driver.rb
|
|
302
328
|
- lib/selenium/webdriver/chrome/features.rb
|
|
@@ -312,13 +338,13 @@ files:
|
|
|
312
338
|
- lib/selenium/webdriver/common/action_builder.rb
|
|
313
339
|
- lib/selenium/webdriver/common/alert.rb
|
|
314
340
|
- lib/selenium/webdriver/common/child_process.rb
|
|
341
|
+
- lib/selenium/webdriver/common/client_config.rb
|
|
315
342
|
- lib/selenium/webdriver/common/driver.rb
|
|
316
343
|
- lib/selenium/webdriver/common/driver_extensions/downloads_files.rb
|
|
317
344
|
- lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb
|
|
318
345
|
- lib/selenium/webdriver/common/driver_extensions/has_addons.rb
|
|
319
346
|
- lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb
|
|
320
347
|
- lib/selenium/webdriver/common/driver_extensions/has_authentication.rb
|
|
321
|
-
- lib/selenium/webdriver/common/driver_extensions/has_bidi.rb
|
|
322
348
|
- lib/selenium/webdriver/common/driver_extensions/has_casting.rb
|
|
323
349
|
- lib/selenium/webdriver/common/driver_extensions/has_cdp.rb
|
|
324
350
|
- lib/selenium/webdriver/common/driver_extensions/has_context.rb
|