selenium-webdriver 4.9.0 → 4.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +40 -0
- data/Gemfile +2 -0
- data/README.md +2 -2
- data/bin/linux/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/server.rb +4 -16
- data/lib/selenium/webdriver/atoms/findElements.js +3 -4
- data/lib/selenium/webdriver/chrome/service.rb +1 -3
- data/lib/selenium/webdriver/chromium/options.rb +0 -18
- data/lib/selenium/webdriver/chromium.rb +0 -1
- data/lib/selenium/webdriver/common/action_builder.rb +0 -8
- data/lib/selenium/webdriver/common/child_process.rb +11 -11
- data/lib/selenium/webdriver/common/driver_finder.rb +10 -8
- data/lib/selenium/webdriver/common/error.rb +28 -3
- data/lib/selenium/webdriver/common/logger.rb +87 -30
- data/lib/selenium/webdriver/common/options.rb +3 -22
- data/lib/selenium/webdriver/common/platform.rb +0 -49
- data/lib/selenium/webdriver/common/port_prober.rb +1 -1
- data/lib/selenium/webdriver/common/proxy.rb +1 -1
- data/lib/selenium/webdriver/common/selenium_manager.rb +50 -27
- data/lib/selenium/webdriver/common/service.rb +11 -13
- data/lib/selenium/webdriver/common/service_manager.rb +4 -2
- data/lib/selenium/webdriver/common/socket_lock.rb +1 -1
- data/lib/selenium/webdriver/common/socket_poller.rb +1 -1
- data/lib/selenium/webdriver/common/websocket_connection.rb +3 -3
- data/lib/selenium/webdriver/devtools.rb +1 -1
- data/lib/selenium/webdriver/edge/options.rb +14 -0
- data/lib/selenium/webdriver/edge/service.rb +1 -3
- data/lib/selenium/webdriver/firefox/options.rb +0 -15
- data/lib/selenium/webdriver/firefox/profile.rb +1 -1
- data/lib/selenium/webdriver/firefox/service.rb +0 -12
- data/lib/selenium/webdriver/ie/options.rb +2 -1
- data/lib/selenium/webdriver/ie/service.rb +0 -16
- data/lib/selenium/webdriver/remote/bridge.rb +6 -5
- data/lib/selenium/webdriver/remote/capabilities.rb +0 -72
- data/lib/selenium/webdriver/remote/http/common.rb +3 -3
- data/lib/selenium/webdriver/remote/http/curb.rb +1 -1
- data/lib/selenium/webdriver/remote/http/default.rb +2 -3
- data/lib/selenium/webdriver/remote/server_error.rb +1 -1
- data/lib/selenium/webdriver/safari/service.rb +10 -0
- data/lib/selenium/webdriver/support/color.rb +8 -8
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +2 -1
- data/selenium-webdriver.gemspec +2 -2
- metadata +13 -14
- data/lib/selenium/webdriver/chromium/service.rb +0 -42
@@ -62,18 +62,6 @@ module Selenium
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
def bitsize
|
66
|
-
@bitsize ||= if defined?(FFI::Platform::ADDRESS_SIZE)
|
67
|
-
FFI::Platform::ADDRESS_SIZE
|
68
|
-
elsif defined?(FFI)
|
69
|
-
FFI.type_size(:pointer) == 4 ? 32 : 64
|
70
|
-
elsif jruby?
|
71
|
-
Integer(ENV_JAVA['sun.arch.data.model'])
|
72
|
-
else
|
73
|
-
1.size == 4 ? 32 : 64
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
65
|
def jruby?
|
78
66
|
engine == :jruby
|
79
67
|
end
|
@@ -158,43 +146,6 @@ module Selenium
|
|
158
146
|
at_exit { yield if Process.pid == pid }
|
159
147
|
end
|
160
148
|
|
161
|
-
def find_binary(*binary_names)
|
162
|
-
paths = ENV['PATH'].split(File::PATH_SEPARATOR)
|
163
|
-
|
164
|
-
if windows?
|
165
|
-
binary_names.map! { |n| "#{n}.exe" }
|
166
|
-
binary_names.dup.each { |n| binary_names << n.gsub('exe', 'bat') }
|
167
|
-
end
|
168
|
-
|
169
|
-
binary_names.each do |binary_name|
|
170
|
-
paths.each do |path|
|
171
|
-
full_path = File.join(path, binary_name)
|
172
|
-
full_path = unix_path(full_path) if windows?
|
173
|
-
exe = Dir.glob(full_path).find { |f| File.executable?(f) }
|
174
|
-
return exe if exe
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
nil
|
179
|
-
end
|
180
|
-
|
181
|
-
def find_in_program_files(*binary_names)
|
182
|
-
paths = [
|
183
|
-
ENV.fetch('PROGRAMFILES', '\\Program Files'),
|
184
|
-
ENV.fetch('ProgramFiles(x86)', '\\Program Files (x86)'),
|
185
|
-
ENV.fetch('ProgramW6432', '\\Program Files')
|
186
|
-
]
|
187
|
-
|
188
|
-
paths.each do |root|
|
189
|
-
binary_names.each do |name|
|
190
|
-
exe = File.join(root, name)
|
191
|
-
return exe if File.executable?(exe)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
nil
|
196
|
-
end
|
197
|
-
|
198
149
|
def localhost
|
199
150
|
info = Socket.getaddrinfo 'localhost', 80, Socket::AF_INET, Socket::SOCK_STREAM
|
200
151
|
|
@@ -34,7 +34,7 @@ module Selenium
|
|
34
34
|
Platform.interfaces.each do |host|
|
35
35
|
TCPServer.new(host, port).close
|
36
36
|
rescue *IGNORED_ERRORS => e
|
37
|
-
WebDriver.logger.debug("port prober could not bind to #{host}:#{port} (#{e.message})")
|
37
|
+
WebDriver.logger.debug("port prober could not bind to #{host}:#{port} (#{e.message})", id: :driver_service)
|
38
38
|
# ignored - some machines appear unable to bind to some of their interfaces
|
39
39
|
end
|
40
40
|
|
@@ -27,20 +27,36 @@ module Selenium
|
|
27
27
|
# @api private
|
28
28
|
#
|
29
29
|
class SeleniumManager
|
30
|
-
BIN_PATH = '../../../../../bin'
|
31
|
-
|
32
30
|
class << self
|
31
|
+
attr_writer :bin_path
|
32
|
+
|
33
|
+
def bin_path
|
34
|
+
@bin_path ||= '../../../../../bin'
|
35
|
+
end
|
36
|
+
|
33
37
|
# @param [Options] options browser options.
|
34
38
|
# @return [String] the path to the correct driver.
|
35
39
|
def driver_path(options)
|
36
|
-
|
37
|
-
|
40
|
+
command = generate_command(binary, options)
|
41
|
+
|
42
|
+
output = run(*command)
|
43
|
+
|
44
|
+
browser_path = output['browser_path']
|
45
|
+
driver_path = output['driver_path']
|
46
|
+
Platform.assert_executable driver_path
|
38
47
|
|
39
|
-
|
40
|
-
|
48
|
+
if options.respond_to? :binary
|
49
|
+
options.binary = browser_path
|
50
|
+
options.browser_version = nil
|
41
51
|
end
|
42
52
|
|
43
|
-
|
53
|
+
driver_path
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def generate_command(binary, options)
|
59
|
+
command = [binary, '--browser', options.browser_name]
|
44
60
|
if options.browser_version
|
45
61
|
command << '--browser-version'
|
46
62
|
command << options.browser_version
|
@@ -49,21 +65,17 @@ module Selenium
|
|
49
65
|
command << '--browser-path'
|
50
66
|
command << options.binary.gsub('\\', '\\\\\\')
|
51
67
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
location
|
68
|
+
if options.proxy
|
69
|
+
command << '--proxy'
|
70
|
+
(command << options.proxy.ssl) || options.proxy.http
|
71
|
+
end
|
72
|
+
command
|
59
73
|
end
|
60
74
|
|
61
|
-
private
|
62
|
-
|
63
75
|
# @return [String] the path to the correct selenium manager
|
64
76
|
def binary
|
65
77
|
@binary ||= begin
|
66
|
-
path = File.expand_path(
|
78
|
+
path = File.expand_path(bin_path, __FILE__)
|
67
79
|
path << if Platform.windows?
|
68
80
|
'/windows/selenium-manager.exe'
|
69
81
|
elsif Platform.mac?
|
@@ -72,32 +84,43 @@ module Selenium
|
|
72
84
|
'/linux/selenium-manager'
|
73
85
|
end
|
74
86
|
location = File.expand_path(path, __FILE__)
|
75
|
-
|
76
|
-
|
87
|
+
|
88
|
+
begin
|
89
|
+
Platform.assert_file(location)
|
90
|
+
Platform.assert_executable(location)
|
91
|
+
rescue TypeError
|
92
|
+
raise Error::WebDriverError,
|
93
|
+
"Unable to locate or obtain Selenium Manager binary; #{location} is not a valid file object"
|
94
|
+
rescue Error::WebDriverError => e
|
95
|
+
raise Error::WebDriverError, "Selenium Manager binary located, but #{e.message}"
|
77
96
|
end
|
78
97
|
|
79
|
-
WebDriver.logger.debug("Selenium Manager found at #{location}")
|
98
|
+
WebDriver.logger.debug("Selenium Manager binary found at #{location}", id: :selenium_manager)
|
80
99
|
location
|
81
100
|
end
|
82
101
|
end
|
83
102
|
|
84
103
|
def run(*command)
|
85
|
-
|
104
|
+
command += %w[--output json]
|
105
|
+
command << '--debug' if WebDriver.logger.debug?
|
106
|
+
|
107
|
+
WebDriver.logger.debug("Executing Process #{command}", id: :selenium_manager)
|
86
108
|
|
87
109
|
begin
|
88
110
|
stdout, stderr, status = Open3.capture3(*command)
|
89
111
|
json_output = stdout.empty? ? nil : JSON.parse(stdout)
|
90
|
-
result = json_output
|
112
|
+
result = json_output['result']
|
91
113
|
rescue StandardError => e
|
92
|
-
raise Error::WebDriverError, "Unsuccessful command executed: #{command}
|
114
|
+
raise Error::WebDriverError, "Unsuccessful command executed: #{command}; #{e.message}"
|
93
115
|
end
|
94
116
|
|
95
|
-
|
96
|
-
|
117
|
+
(json_output&.fetch('logs') || []).each do |log|
|
118
|
+
level = log['level'].casecmp('info').zero? ? 'debug' : log['level'].downcase
|
119
|
+
WebDriver.logger.send(level, log['message'], id: :selenium_manager)
|
97
120
|
end
|
98
121
|
|
99
|
-
|
100
|
-
|
122
|
+
if status.exitstatus.positive?
|
123
|
+
raise Error::WebDriverError, "Unsuccessful command executed: #{command}\n#{result}#{stderr}"
|
101
124
|
end
|
102
125
|
|
103
126
|
result
|
@@ -57,7 +57,7 @@ module Selenium
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
attr_accessor :host, :executable_path, :port, :args
|
60
|
+
attr_accessor :host, :executable_path, :port, :log, :args
|
61
61
|
alias extra_args args
|
62
62
|
|
63
63
|
#
|
@@ -66,15 +66,22 @@ module Selenium
|
|
66
66
|
# @api private
|
67
67
|
#
|
68
68
|
|
69
|
-
def initialize(path: nil, port: nil, args: nil)
|
69
|
+
def initialize(path: nil, port: nil, log: nil, args: nil)
|
70
70
|
port ||= self.class::DEFAULT_PORT
|
71
71
|
args ||= []
|
72
72
|
|
73
73
|
@executable_path = path
|
74
74
|
@host = Platform.localhost
|
75
75
|
@port = Integer(port)
|
76
|
-
|
77
|
-
|
76
|
+
@log = case log
|
77
|
+
when :stdout
|
78
|
+
$stdout
|
79
|
+
when :stderr
|
80
|
+
$stderr
|
81
|
+
else
|
82
|
+
log
|
83
|
+
end
|
84
|
+
@args = args
|
78
85
|
|
79
86
|
raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
|
80
87
|
end
|
@@ -86,15 +93,6 @@ module Selenium
|
|
86
93
|
def shutdown_supported
|
87
94
|
self.class::SHUTDOWN_SUPPORTED
|
88
95
|
end
|
89
|
-
|
90
|
-
protected
|
91
|
-
|
92
|
-
def extract_service_args(driver_opts)
|
93
|
-
WebDriver.logger.deprecate('initializing Service class with :args using Hash',
|
94
|
-
':args parameter with an Array of String values',
|
95
|
-
id: :driver_opts)
|
96
|
-
driver_opts.key?(:args) ? driver_opts.delete(:args) : []
|
97
|
-
end
|
98
96
|
end # Service
|
99
97
|
end # WebDriver
|
100
98
|
end # Selenium
|
@@ -41,6 +41,7 @@ module Selenium
|
|
41
41
|
@host = Platform.localhost
|
42
42
|
@port = config.port
|
43
43
|
@extra_args = config.args
|
44
|
+
@io = config.log
|
44
45
|
@shutdown_supported = config.shutdown_supported
|
45
46
|
|
46
47
|
raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
|
@@ -77,9 +78,10 @@ module Selenium
|
|
77
78
|
private
|
78
79
|
|
79
80
|
def build_process(*command)
|
80
|
-
WebDriver.logger.debug("Executing Process #{command}")
|
81
|
+
WebDriver.logger.debug("Executing Process #{command}", id: :driver_service)
|
81
82
|
@process = ChildProcess.build(*command)
|
82
|
-
@
|
83
|
+
@io ||= WebDriver.logger.io if WebDriver.logger.debug?
|
84
|
+
@process.io = @io if @io
|
83
85
|
|
84
86
|
@process
|
85
87
|
end
|
@@ -93,7 +93,7 @@ module Selenium
|
|
93
93
|
true
|
94
94
|
rescue *NOT_CONNECTED_ERRORS
|
95
95
|
sock&.close
|
96
|
-
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}")
|
96
|
+
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}", id: :driver_service)
|
97
97
|
false
|
98
98
|
end
|
99
99
|
end
|
@@ -55,7 +55,7 @@ module Selenium
|
|
55
55
|
def send_cmd(**payload)
|
56
56
|
id = next_id
|
57
57
|
data = payload.merge(id: id)
|
58
|
-
WebDriver.logger.debug "WebSocket -> #{data}"[...MAX_LOG_MESSAGE_SIZE]
|
58
|
+
WebDriver.logger.debug "WebSocket -> #{data}"[...MAX_LOG_MESSAGE_SIZE], id: :bidi
|
59
59
|
data = JSON.generate(data)
|
60
60
|
out_frame = WebSocket::Frame::Outgoing::Client.new(version: ws.version, data: data, type: 'text')
|
61
61
|
socket.write(out_frame.to_s)
|
@@ -112,7 +112,7 @@ module Selenium
|
|
112
112
|
|
113
113
|
message = JSON.parse(message)
|
114
114
|
messages[message['id']] = message
|
115
|
-
WebDriver.logger.debug "WebSocket <- #{message}"[...MAX_LOG_MESSAGE_SIZE]
|
115
|
+
WebDriver.logger.debug "WebSocket <- #{message}"[...MAX_LOG_MESSAGE_SIZE], id: :bidi
|
116
116
|
|
117
117
|
message
|
118
118
|
end
|
@@ -129,7 +129,7 @@ module Selenium
|
|
129
129
|
Thread.current.report_on_exception = true
|
130
130
|
|
131
131
|
yield params
|
132
|
-
rescue *CONNECTION_ERRORS
|
132
|
+
rescue Error::WebDriverError, *CONNECTION_ERRORS
|
133
133
|
Thread.stop
|
134
134
|
end
|
135
135
|
end
|
@@ -60,7 +60,7 @@ module Selenium
|
|
60
60
|
"#{namespace}::#{Object.const_get(methods_to_classes)[method]}"
|
61
61
|
else
|
62
62
|
# selenium-devtools 0.112 and older
|
63
|
-
"#{namespace}::#{method.capitalize}
|
63
|
+
"#{namespace}::#{method.capitalize}"
|
64
64
|
end
|
65
65
|
|
66
66
|
return unless Object.const_defined?(desired_class)
|
@@ -26,6 +26,20 @@ module Selenium
|
|
26
26
|
KEY = 'ms:edgeOptions'
|
27
27
|
BROWSER = 'MicrosoftEdge'
|
28
28
|
|
29
|
+
#
|
30
|
+
# Changes the browser name enable webview2
|
31
|
+
# see: https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/webdriver
|
32
|
+
# Automation of WebView2 apps with Microsoft Edge WebDriver
|
33
|
+
#
|
34
|
+
# @example Enable webview2
|
35
|
+
# options = Selenium::WebDriver::Edge::Options.new
|
36
|
+
# options.webview2!
|
37
|
+
#
|
38
|
+
|
39
|
+
def webview2!
|
40
|
+
@options[:browser_name] = 'webview2'
|
41
|
+
end
|
42
|
+
|
29
43
|
private
|
30
44
|
|
31
45
|
def enable_logging(browser_options)
|
@@ -17,12 +17,10 @@
|
|
17
17
|
# specific language governing permissions and limitations
|
18
18
|
# under the License.
|
19
19
|
|
20
|
-
require 'selenium/webdriver/chromium/service'
|
21
|
-
|
22
20
|
module Selenium
|
23
21
|
module WebDriver
|
24
22
|
module Edge
|
25
|
-
class Service <
|
23
|
+
class Service < WebDriver::Service
|
26
24
|
DEFAULT_PORT = 9515
|
27
25
|
EXECUTABLE = 'msedgedriver'
|
28
26
|
SHUTDOWN_SUPPORTED = true
|
@@ -99,21 +99,6 @@ module Selenium
|
|
99
99
|
@options[:prefs][name] = value
|
100
100
|
end
|
101
101
|
|
102
|
-
#
|
103
|
-
# Run Firefox in headless mode.
|
104
|
-
#
|
105
|
-
# @example Enable headless mode
|
106
|
-
# options = Selenium::WebDriver::Firefox::Options.new
|
107
|
-
# options.headless!
|
108
|
-
#
|
109
|
-
|
110
|
-
def headless!
|
111
|
-
WebDriver.logger.deprecate('`Options#headless!`',
|
112
|
-
"`Options#add_argument('-headless')`",
|
113
|
-
id: :headless)
|
114
|
-
add_argument '-headless'
|
115
|
-
end
|
116
|
-
|
117
102
|
#
|
118
103
|
# Sets Firefox profile.
|
119
104
|
#
|
@@ -160,7 +160,7 @@ module Selenium
|
|
160
160
|
destination = File.join(directory, 'extensions')
|
161
161
|
|
162
162
|
@extensions.each do |name, extension|
|
163
|
-
WebDriver.logger.debug({
|
163
|
+
WebDriver.logger.debug({extension: name}.inspect, id: :firefox_profile)
|
164
164
|
extension.write_to(destination)
|
165
165
|
end
|
166
166
|
end
|
@@ -24,18 +24,6 @@ module Selenium
|
|
24
24
|
DEFAULT_PORT = 4444
|
25
25
|
EXECUTABLE = 'geckodriver'
|
26
26
|
SHUTDOWN_SUPPORTED = false
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def extract_service_args(driver_opts)
|
31
|
-
driver_args = super
|
32
|
-
driver_opts = driver_opts.dup
|
33
|
-
driver_args << "--binary=#{driver_opts[:binary]}" if driver_opts.key?(:binary)
|
34
|
-
driver_args << "--log=#{driver_opts[:log]}" if driver_opts.key?(:log)
|
35
|
-
driver_args << "--marionette-port=#{driver_opts[:marionette_port]}" if driver_opts.key?(:marionette_port)
|
36
|
-
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
37
|
-
driver_args
|
38
|
-
end
|
39
27
|
end # Service
|
40
28
|
end # Firefox
|
41
29
|
end # WebDriver
|
@@ -41,7 +41,8 @@ module Selenium
|
|
41
41
|
use_per_process_proxy: 'ie.usePerProcessProxy',
|
42
42
|
use_legacy_file_upload_dialog_handling: 'ie.useLegacyFileUploadDialogHandling',
|
43
43
|
attach_to_edge_chrome: 'ie.edgechromium',
|
44
|
-
edge_executable_path: 'ie.edgepath'
|
44
|
+
edge_executable_path: 'ie.edgepath',
|
45
|
+
ignore_process_match: 'ie.ignoreprocessmatch'
|
45
46
|
}.freeze
|
46
47
|
BROWSER = 'internet explorer'
|
47
48
|
|
@@ -24,22 +24,6 @@ module Selenium
|
|
24
24
|
DEFAULT_PORT = 5555
|
25
25
|
EXECUTABLE = 'IEDriverServer'
|
26
26
|
SHUTDOWN_SUPPORTED = true
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def extract_service_args(driver_opts)
|
31
|
-
driver_args = super
|
32
|
-
driver_opts = driver_opts.dup
|
33
|
-
driver_args << "--log-level=#{driver_opts[:log_level].to_s.upcase}" if driver_opts.key?(:log_level)
|
34
|
-
driver_args << "--log-file=#{driver_opts[:log_file]}" if driver_opts.key?(:log_file)
|
35
|
-
if driver_opts.key?(:implementation)
|
36
|
-
driver_args << "--implementation=#{driver_opts[:implementation].to_s.upcase}"
|
37
|
-
end
|
38
|
-
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
39
|
-
driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
|
40
|
-
driver_args << '--silent' if driver_opts[:silent] == true
|
41
|
-
driver_args
|
42
|
-
end
|
43
27
|
end # Server
|
44
28
|
end # IE
|
45
29
|
end # WebDriver
|
@@ -407,7 +407,8 @@ module Selenium
|
|
407
407
|
|
408
408
|
def upload(local_file)
|
409
409
|
unless File.file?(local_file)
|
410
|
-
WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!"
|
410
|
+
WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!",
|
411
|
+
id: :file_detector)
|
411
412
|
raise Error::WebDriverError, "You are trying to work with something that isn't a file."
|
412
413
|
end
|
413
414
|
|
@@ -443,7 +444,7 @@ module Selenium
|
|
443
444
|
end
|
444
445
|
|
445
446
|
def element_attribute(element, name)
|
446
|
-
WebDriver.logger.
|
447
|
+
WebDriver.logger.debug "Using script for :getAttribute of #{name}", id: :script
|
447
448
|
execute_atom :getAttribute, element, name
|
448
449
|
end
|
449
450
|
|
@@ -503,7 +504,7 @@ module Selenium
|
|
503
504
|
end
|
504
505
|
|
505
506
|
def element_displayed?(element)
|
506
|
-
WebDriver.logger.
|
507
|
+
WebDriver.logger.debug 'Using script for :isDisplayed', id: :script
|
507
508
|
execute_atom :isDisplayed, element
|
508
509
|
end
|
509
510
|
|
@@ -615,7 +616,7 @@ module Selenium
|
|
615
616
|
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
616
617
|
end
|
617
618
|
|
618
|
-
WebDriver.logger.
|
619
|
+
WebDriver.logger.debug("-> #{verb.to_s.upcase} #{path}", id: :command)
|
619
620
|
http.call(verb, path, command_hash)['value']
|
620
621
|
end
|
621
622
|
|
@@ -682,7 +683,7 @@ module Selenium
|
|
682
683
|
[how, what]
|
683
684
|
end
|
684
685
|
|
685
|
-
ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])
|
686
|
+
ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])/
|
686
687
|
UNICODE_CODE_POINT = 30
|
687
688
|
|
688
689
|
# Escapes invalid characters in CSS selector.
|
@@ -53,83 +53,11 @@ module Selenium
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
#
|
57
|
-
# Backward compatibility
|
58
|
-
#
|
59
|
-
|
60
|
-
def version
|
61
|
-
WebDriver.logger.deprecate('`Capabilities#version`', '`Capabilities#browser_version`', id: :jwp_caps)
|
62
|
-
browser_version
|
63
|
-
end
|
64
|
-
|
65
|
-
def version=(value)
|
66
|
-
WebDriver.logger.deprecate('`Capabilities#version=`', '`Capabilities#browser_version=`', id: :jwp_caps)
|
67
|
-
self.browser_version = value
|
68
|
-
end
|
69
|
-
|
70
|
-
def platform
|
71
|
-
WebDriver.logger.deprecate('`Capabilities#platform`', '`Capabilities#platform_name`', id: :jwp_caps)
|
72
|
-
platform_name
|
73
|
-
end
|
74
|
-
|
75
|
-
def platform=(value)
|
76
|
-
WebDriver.logger.deprecate('`Capabilities#platform=`', '`Capabilities#platform_name=`', id: :jwp_caps)
|
77
|
-
self.platform_name = value
|
78
|
-
end
|
79
|
-
|
80
56
|
#
|
81
57
|
# Convenience methods for the common choices.
|
82
58
|
#
|
83
59
|
|
84
60
|
class << self
|
85
|
-
def chrome(opts = {})
|
86
|
-
WebDriver.logger.deprecate('Remote::Capabilities.chrome', 'Options.chrome', id: :caps_browsers)
|
87
|
-
new({
|
88
|
-
browser_name: 'chrome'
|
89
|
-
}.merge(opts))
|
90
|
-
end
|
91
|
-
|
92
|
-
def edge(opts = {})
|
93
|
-
WebDriver.logger.deprecate('Remote::Capabilities.edge', 'Options.edge', id: :caps_browsers)
|
94
|
-
new({
|
95
|
-
browser_name: 'MicrosoftEdge'
|
96
|
-
}.merge(opts))
|
97
|
-
end
|
98
|
-
alias microsoftedge edge
|
99
|
-
|
100
|
-
def firefox(opts = {})
|
101
|
-
WebDriver.logger.deprecate('Remote::Capabilities.firefox', 'Options.firefox', id: :caps_browsers)
|
102
|
-
new({
|
103
|
-
browser_name: 'firefox'
|
104
|
-
}.merge(opts))
|
105
|
-
end
|
106
|
-
alias ff firefox
|
107
|
-
|
108
|
-
def safari(opts = {})
|
109
|
-
WebDriver.logger.deprecate('Remote::Capabilities.safari', 'Options.safari', id: :caps_browsers)
|
110
|
-
new({
|
111
|
-
browser_name: Selenium::WebDriver::Safari.technology_preview? ? 'Safari Technology Preview' : 'safari'
|
112
|
-
}.merge(opts))
|
113
|
-
end
|
114
|
-
|
115
|
-
def htmlunit(opts = {})
|
116
|
-
WebDriver.logger.deprecate('Remote::Capabilities.htmlunit',
|
117
|
-
'as argument in constructor',
|
118
|
-
id: :caps_browsers)
|
119
|
-
new({
|
120
|
-
browser_name: 'htmlunit'
|
121
|
-
}.merge(opts))
|
122
|
-
end
|
123
|
-
|
124
|
-
def internet_explorer(opts = {})
|
125
|
-
WebDriver.logger.deprecate('Remote::Capabilities.ie', 'Options.ie', id: :caps_browsers)
|
126
|
-
new({
|
127
|
-
browser_name: 'internet explorer',
|
128
|
-
platform_name: :windows
|
129
|
-
}.merge(opts))
|
130
|
-
end
|
131
|
-
alias ie internet_explorer
|
132
|
-
|
133
61
|
def always_match(capabilities)
|
134
62
|
new(always_match: capabilities)
|
135
63
|
end
|
@@ -49,8 +49,8 @@ module Selenium
|
|
49
49
|
payload = JSON.generate(command_hash)
|
50
50
|
headers['Content-Length'] = payload.bytesize.to_s if %i[post put].include?(verb)
|
51
51
|
|
52
|
-
WebDriver.logger.
|
53
|
-
WebDriver.logger.debug(" > #{headers.inspect}")
|
52
|
+
WebDriver.logger.debug(" >>> #{url} | #{payload}", id: :command)
|
53
|
+
WebDriver.logger.debug(" > #{headers.inspect}", id: :header)
|
54
54
|
elsif verb == :post
|
55
55
|
payload = '{}'
|
56
56
|
headers['Content-Length'] = '2'
|
@@ -75,7 +75,7 @@ module Selenium
|
|
75
75
|
code = code.to_i
|
76
76
|
body = body.to_s.strip
|
77
77
|
content_type = content_type.to_s
|
78
|
-
WebDriver.logger.
|
78
|
+
WebDriver.logger.debug("<- #{body}", id: :command)
|
79
79
|
|
80
80
|
if content_type.include? CONTENT_TYPE
|
81
81
|
raise Error::WebDriverError, "empty body: #{content_type.inspect} (#{code})\n#{body}" if body.empty?
|
@@ -16,8 +16,6 @@
|
|
16
16
|
# KIND, either express or implied. See the License for the
|
17
17
|
# specific language governing permissions and limitations
|
18
18
|
# under the License.
|
19
|
-
|
20
|
-
require 'net/https'
|
21
19
|
require 'ipaddr'
|
22
20
|
|
23
21
|
module Selenium
|
@@ -96,11 +94,12 @@ module Selenium
|
|
96
94
|
end
|
97
95
|
|
98
96
|
if response.is_a? Net::HTTPRedirection
|
97
|
+
WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")
|
99
98
|
raise Error::WebDriverError, 'too many redirects' if redirects >= MAX_REDIRECTS
|
100
99
|
|
101
100
|
request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
|
102
101
|
else
|
103
|
-
WebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}")
|
102
|
+
WebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}", id: :header)
|
104
103
|
create_response response.code, response.body, response.content_type
|
105
104
|
end
|
106
105
|
end
|