selenium-webdriver 4.8.6 → 4.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c69ba703c9453c083e2bbe503e91d8b97e7c2d01b2f3d9c951da889cba869ba
4
- data.tar.gz: 424f8fdd62f259292559cf5e89dcea5de3a6463b8b73efe6127a7dde780fae22
3
+ metadata.gz: 382f56851a268a1f44ed42a9a0ec85d5136540df32711606657bf8961a95b6b1
4
+ data.tar.gz: edbf74e77ed56b92fe01cfe6493b8db901ebc7cdb3df9b4d561f03cb5a91dcda
5
5
  SHA512:
6
- metadata.gz: ee7364197f821c41049983d4445f1e41a9d9200509f160af5df28bbb8e7e3195278990db0c2ab79f25d37f2d52f5cfba8c25cc15e3996e70007363904451e44f
7
- data.tar.gz: c8ca6b72468be025a71afe7142979fba69f8d3b1652e2dc68c5db6de44b8b9aa3607b4345317c9be446247d4ce8b174c47a71f16499128a5935612b78436c142
6
+ metadata.gz: 84260d58d81b2be75717e10d597bdeaf7c7b36bec5483d664fe19a6c5891967a176ef26d8806ea160a4f229b051d1ede4fa20d244e4b0c08f8409ccac8f640ca
7
+ data.tar.gz: 40af1b4e6fa0f6a85b608ce485336b0b7ba10ad35e7c8749c81c78808ba506d5a6294933b5771b3b5cb413f2b57b447af62dd236ce3e6ca4ed25f1949cc07bf6
data/CHANGES CHANGED
@@ -1,3 +1,25 @@
1
+ 4.9.1 (2023-05-08)
2
+ =========================
3
+ Ruby:
4
+ * Allow users to specify driver process output in Service class (#11964)
5
+ * Updated minimum required Ruby version to 3.0
6
+ * Selenium Logger defaults to :info and all debugging is now logged as :debug (#11967)
7
+ * Every logging entry can be ignored based on ID, not just warnings
8
+ * Logging entries can be filtered to allow or ignore specific IDs
9
+
10
+ BiDi:
11
+ * Fix bug with loading devtools (#11931) (thanks Boris Petrov!)
12
+ * Released selenium-devtools 0.113.0 (supports CDP v85, v111, v112, v113)
13
+
14
+ 4.9.0 (2023-04-21)
15
+ =========================
16
+ Ruby:
17
+ * Fix devtools version fallback (#11869)
18
+ * Fix bug in selenium manager escaping back slashes in Windows (#11884)
19
+
20
+ BiDi:
21
+ * Released selenium-devtools 0.112.0 (supports CDP v85, v110, v111, v112)
22
+
1
23
  4.8.6 (2023-03-29)
2
24
  =========================
3
25
  Ruby:
data/Gemfile CHANGED
@@ -4,3 +4,5 @@ source 'https://rubygems.org'
4
4
  Dir["#{__dir__}/*.gemspec"].each do |spec|
5
5
  gemspec name: File.basename(spec, '.gemspec')
6
6
  end
7
+
8
+ gem 'debug', '~> 1.7', require: false, platforms: %i[mri mingw x64_mingw]
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # selenium-webdriver
2
2
 
3
- This gem provides Ruby bindings for Selenium and supports MRI >= 2.6
3
+ This gem provides Ruby bindings for Selenium and supports MRI >= 3.0.
4
4
 
5
5
  ## Install
6
6
 
@@ -254,7 +254,7 @@ module Selenium
254
254
  args = ['-jar', @jar, @role, '--port', @port.to_s]
255
255
  server_command = ['java'] + properties + args + @additional_args
256
256
  cp = WebDriver::ChildProcess.build(*server_command)
257
- WebDriver.logger.debug("Executing Process #{server_command}")
257
+ WebDriver.logger.debug("Executing Process #{server_command}", id: :server)
258
258
 
259
259
  if @log.is_a?(String)
260
260
  cp.io = @log
@@ -250,14 +250,6 @@ module Selenium
250
250
  @devices << device
251
251
  device
252
252
  end
253
-
254
- def deprecate_method(device = nil, duration = nil, number = nil, method: :pause)
255
- return unless device || number || duration
256
-
257
- WebDriver.logger.deprecate "ActionBuilder##{method} with ordered parameters",
258
- ':device, :duration, :number keywords',
259
- id: method
260
- end
261
253
  end # ActionBuilder
262
254
  end # WebDriver
263
255
  end # Selenium
@@ -53,9 +53,9 @@ module Selenium
53
53
  options = {%i[out err] => io}
54
54
  options[:pgroup] = true unless Platform.windows? # NOTE: this is a bug only in Windows 7
55
55
 
56
- WebDriver.logger.debug("Starting process: #{@command} with #{options}")
56
+ WebDriver.logger.debug("Starting process: #{@command} with #{options}", id: :process)
57
57
  @pid = Process.spawn(*@command, options)
58
- WebDriver.logger.debug(" -> pid: #{@pid}")
58
+ WebDriver.logger.debug(" -> pid: #{@pid}", id: :process)
59
59
 
60
60
  Process.detach(@pid) if detach
61
61
  end
@@ -64,16 +64,16 @@ module Selenium
64
64
  return unless @pid
65
65
  return if exited?
66
66
 
67
- WebDriver.logger.debug("Sending TERM to process: #{@pid}")
67
+ WebDriver.logger.debug("Sending TERM to process: #{@pid}", id: :process)
68
68
  terminate(@pid)
69
69
  poll_for_exit(timeout)
70
70
 
71
- WebDriver.logger.debug(" -> stopped #{@pid}")
71
+ WebDriver.logger.debug(" -> stopped #{@pid}", id: :process)
72
72
  rescue TimeoutError, Errno::EINVAL
73
- WebDriver.logger.debug(" -> sending KILL to process: #{@pid}")
73
+ WebDriver.logger.debug(" -> sending KILL to process: #{@pid}", id: :process)
74
74
  kill(@pid)
75
75
  wait
76
- WebDriver.logger.debug(" -> killed #{@pid}")
76
+ WebDriver.logger.debug(" -> killed #{@pid}", id: :process)
77
77
  end
78
78
 
79
79
  def alive?
@@ -83,18 +83,18 @@ module Selenium
83
83
  def exited?
84
84
  return unless @pid
85
85
 
86
- WebDriver.logger.debug("Checking if #{@pid} is exited:")
86
+ WebDriver.logger.debug("Checking if #{@pid} is exited:", id: :process)
87
87
  _, @status = Process.waitpid2(@pid, Process::WNOHANG | Process::WUNTRACED) if @status.nil?
88
88
  return if @status.nil?
89
89
 
90
90
  exit_code = @status.exitstatus || @status.termsig
91
- WebDriver.logger.debug(" -> exit code is #{exit_code.inspect}")
91
+ WebDriver.logger.debug(" -> exit code is #{exit_code.inspect}", id: :process)
92
92
 
93
93
  !!exit_code
94
94
  end
95
95
 
96
96
  def poll_for_exit(timeout)
97
- WebDriver.logger.debug("Polling #{timeout} seconds for exit of #{@pid}")
97
+ WebDriver.logger.debug("Polling #{timeout} seconds for exit of #{@pid}", id: :process)
98
98
 
99
99
  end_time = Time.now + timeout
100
100
  sleep POLL_INTERVAL until exited? || Time.now > end_time
@@ -28,7 +28,8 @@ module Selenium
28
28
  path ||= begin
29
29
  SeleniumManager.driver_path(options)
30
30
  rescue StandardError => e
31
- WebDriver.logger.warn("Unable obtain driver using Selenium Manager\n #{e.message}")
31
+ WebDriver.logger.warn("Unable to obtain driver using Selenium Manager\n #{e.message}",
32
+ id: :selenium_manager)
32
33
  nil
33
34
  end
34
35
  msg = "Unable to locate the #{klass::EXECUTABLE} executable; for more information on how to install drivers, " \
@@ -38,22 +38,33 @@ module Selenium
38
38
 
39
39
  def_delegators :@logger,
40
40
  :close,
41
- :debug, :debug?,
42
- :info, :info?,
41
+ :debug?,
42
+ :info?,
43
43
  :warn?,
44
44
  :error, :error?,
45
45
  :fatal, :fatal?,
46
- :level, :level=
46
+ :level
47
47
 
48
48
  #
49
49
  # @param [String] progname Allow child projects to use Selenium's Logger pattern
50
50
  #
51
- def initialize(progname = 'Selenium', ignored: nil)
52
- @logger = create_logger(progname)
51
+ def initialize(progname = 'Selenium', default_level: nil, ignored: nil, allowed: nil)
52
+ default_level ||= $DEBUG || ENV.key?('DEBUG') ? :debug : :warn
53
+
54
+ @logger = create_logger(progname, level: default_level)
53
55
  @ignored = Array(ignored)
56
+ @allowed = Array(allowed)
54
57
  @first_warning = false
55
58
  end
56
59
 
60
+ def level=(level)
61
+ if level == :info && @logger.level == :info
62
+ info(':info is now the default log level, to see additional logging, set log level to :debug')
63
+ end
64
+
65
+ @logger.level = level
66
+ end
67
+
57
68
  #
58
69
  # Changes logger output to a new IO.
59
70
  #
@@ -81,34 +92,60 @@ module Selenium
81
92
  #
82
93
  # Will not log the provided ID.
83
94
  #
84
- # @param [Array, Symbol] id
95
+ # @param [Array, Symbol] ids
96
+ #
97
+ def ignore(*ids)
98
+ @ignored += Array(ids).flatten
99
+ end
100
+
101
+ #
102
+ # Will only log the provided ID.
103
+ #
104
+ # @param [Array, Symbol] ids
105
+ #
106
+ def allow(ids)
107
+ @allowed += Array(ids).flatten
108
+ end
109
+
110
+ #
111
+ # Used to supply information of interest for debugging a problem
112
+ # Overrides default #debug to skip ignored messages by provided id
113
+ #
114
+ # @param [String] message
115
+ # @param [Symbol, Array<Sybmol>] id
116
+ # @yield see #deprecate
85
117
  #
86
- def ignore(id)
87
- Array(id).each { |ignore| @ignored << ignore }
118
+ def debug(message, id: [], &block)
119
+ discard_or_log(:debug, message, id, &block)
88
120
  end
89
121
 
90
122
  #
91
- # Overrides default #warn to skip ignored messages by provided id
123
+ # Used to supply information of general interest
92
124
  #
93
125
  # @param [String] message
94
126
  # @param [Symbol, Array<Sybmol>] id
95
127
  # @yield see #deprecate
96
128
  #
97
- def warn(message, id: [])
129
+ def info(message, id: [], &block)
98
130
  unless @first_warning
99
131
  @first_warning = true
100
- warn("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
101
- "https://selenium.dev/documentation/webdriver/troubleshooting/logging#ruby\n"
132
+ info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
133
+ "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
102
134
  end
103
135
  end
104
136
 
105
- id = Array(id)
106
- return if (@ignored & id).any?
107
-
108
- msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
109
- msg += " #{yield}" if block_given?
137
+ discard_or_log(:info, message, id, &block)
138
+ end
110
139
 
111
- @logger.warn { msg }
140
+ #
141
+ # Used to supply information that suggests action be taken by user
142
+ #
143
+ # @param [String] message
144
+ # @param [Symbol, Array<Sybmol>] id
145
+ # @yield see #deprecate
146
+ #
147
+ def warn(message, id: [], &block)
148
+ discard_or_log(:warn, message, id, &block)
112
149
  end
113
150
 
114
151
  #
@@ -122,11 +159,11 @@ module Selenium
122
159
  #
123
160
  def deprecate(old, new = nil, id: [], reference: '', &block)
124
161
  id = Array(id)
125
- return if @ignored.include?(:deprecations) || (@ignored & id).any?
162
+ return if @ignored.include?(:deprecations)
126
163
 
127
- ids = id.empty? ? '' : "[#{id.map(&:inspect).join(', ')}] "
164
+ id << :deprecations if @allowed.include?(:deprecations)
128
165
 
129
- message = +"[DEPRECATION] #{ids}#{old} is deprecated"
166
+ message = +"[DEPRECATION] #{old} is deprecated"
130
167
  message << if new
131
168
  ". Use #{new} instead."
132
169
  else
@@ -134,15 +171,15 @@ module Selenium
134
171
  end
135
172
  message << " See explanation for this deprecation: #{reference}." unless reference.empty?
136
173
 
137
- warn message, &block
174
+ discard_or_log(:warn, message, id, &block)
138
175
  end
139
176
 
140
177
  private
141
178
 
142
- def create_logger(name)
179
+ def create_logger(name, level:)
143
180
  logger = ::Logger.new($stdout)
144
181
  logger.progname = name
145
- logger.level = default_level
182
+ logger.level = level
146
183
  logger.formatter = proc do |severity, time, progname, msg|
147
184
  "#{time.strftime('%F %T')} #{severity} #{progname} #{msg}\n"
148
185
  end
@@ -150,8 +187,15 @@ module Selenium
150
187
  logger
151
188
  end
152
189
 
153
- def default_level
154
- $DEBUG || ENV.key?('DEBUG') ? :debug : :warn
190
+ def discard_or_log(level, message, id)
191
+ id = Array(id)
192
+ return if (@ignored & id).any?
193
+ return if @allowed.any? && (@allowed & id).none?
194
+
195
+ msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
196
+ msg += " #{yield}" if block_given?
197
+
198
+ @logger.send(level) { msg }
155
199
  end
156
200
  end # Logger
157
201
  end # WebDriver
@@ -128,7 +128,7 @@ module Selenium
128
128
 
129
129
  unless options.empty?
130
130
  msg = 'These options are not w3c compliant and will result in failures in a future release'
131
- WebDriver.logger.warn("#{msg}: #{options}")
131
+ WebDriver.logger.warn("#{msg}: #{options}", id: :w3c_options)
132
132
  browser_options.merge!(options)
133
133
  end
134
134
 
@@ -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
 
@@ -33,8 +33,8 @@ module Selenium
33
33
  # @param [Options] options browser options.
34
34
  # @return [String] the path to the correct driver.
35
35
  def driver_path(options)
36
- message = 'applicable driver not found; attempting to install with Selenium Manager'
37
- WebDriver.logger.warn(message)
36
+ message = 'applicable driver not found; attempting to install with Selenium Manager (Beta)'
37
+ WebDriver.logger.info(message, id: :selenium_manager)
38
38
 
39
39
  unless options.is_a?(Options)
40
40
  raise ArgumentError, "SeleniumManager requires a WebDriver::Options instance, not #{options.inspect}"
@@ -47,12 +47,12 @@ module Selenium
47
47
  end
48
48
  if options.respond_to?(:binary) && !options.binary.nil?
49
49
  command << '--browser-path'
50
- command << options.binary
50
+ command << options.binary.gsub('\\', '\\\\\\')
51
51
  end
52
52
  command << '--debug' if WebDriver.logger.debug?
53
53
 
54
54
  location = run(*command)
55
- WebDriver.logger.debug("Driver found at #{location}")
55
+ WebDriver.logger.debug("Driver found at #{location}", id: :selenium_manager)
56
56
  Platform.assert_executable location
57
57
 
58
58
  location
@@ -76,13 +76,13 @@ module Selenium
76
76
  raise Error::WebDriverError, 'Unable to obtain Selenium Manager'
77
77
  end
78
78
 
79
- WebDriver.logger.debug("Selenium Manager found at #{location}")
79
+ WebDriver.logger.debug("Selenium Manager found at #{location}", id: :selenium_manager)
80
80
  location
81
81
  end
82
82
  end
83
83
 
84
84
  def run(*command)
85
- WebDriver.logger.debug("Executing Process #{command}")
85
+ WebDriver.logger.debug("Executing Process #{command}", id: :selenium_manager)
86
86
 
87
87
  begin
88
88
  stdout, stderr, status = Open3.capture3(*command)
@@ -97,7 +97,7 @@ module Selenium
97
97
  end
98
98
 
99
99
  json_output['logs'].each do |log|
100
- WebDriver.logger.send(log['level'].downcase, log['message'])
100
+ WebDriver.logger.send(log['level'].downcase, log['message'], id: :selenium_manager)
101
101
  end
102
102
 
103
103
  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,13 +66,21 @@ 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
+ @log = case log
77
+ when :stdout
78
+ $stdout
79
+ when :stderr
80
+ $stderr
81
+ else
82
+ log
83
+ end
76
84
 
77
85
  @args = args.is_a?(Hash) ? extract_service_args(args) : args
78
86
 
@@ -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
- @process.io = WebDriver.logger.io if WebDriver.logger.debug?
83
+ @io ||= WebDriver.logger.io if WebDriver.logger.debug?
84
+ @process.io = @io if @io
83
85
 
84
86
  @process
85
87
  end
@@ -70,7 +70,7 @@ module Selenium
70
70
  @server.close_on_exec = true
71
71
  true
72
72
  rescue SocketError, Errno::EADDRINUSE, Errno::EBADF => e
73
- WebDriver.logger.debug("#{self}: #{e.message}")
73
+ WebDriver.logger.debug("#{self}: #{e.message}", id: :driver_service)
74
74
  false
75
75
  end
76
76
 
@@ -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
@@ -134,7 +134,7 @@ module Selenium
134
134
  request_id: request.id,
135
135
  url: request.url,
136
136
  method: request.method,
137
- post_data: request.post_data,
137
+ post_data: (Base64.strict_encode64(request.post_data) if request.post_data),
138
138
  headers: request.headers.map do |k, v|
139
139
  {name: k, value: v}
140
140
  end
@@ -52,7 +52,17 @@ module Selenium
52
52
  end
53
53
 
54
54
  def method_missing(method, *_args)
55
- desired_class = "Selenium::DevTools::V#{Selenium::DevTools.version}::#{method.capitalize}"
55
+ namespace = "Selenium::DevTools::V#{Selenium::DevTools.version}"
56
+ methods_to_classes = "#{namespace}::METHODS_TO_CLASSES"
57
+
58
+ desired_class = if Object.const_defined?(methods_to_classes)
59
+ # selenium-devtools 0.113 and newer
60
+ "#{namespace}::#{Object.const_get(methods_to_classes)[method]}"
61
+ else
62
+ # selenium-devtools 0.112 and older
63
+ "#{namespace}::#{method.capitalize}"
64
+ end
65
+
56
66
  return unless Object.const_defined?(desired_class)
57
67
 
58
68
  self.class.class_eval do
@@ -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({extenstion: name}.inspect)
163
+ WebDriver.logger.debug({extension: name}.inspect, id: :firefox_profile)
164
164
  extension.write_to(destination)
165
165
  end
166
166
  end
@@ -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.info "Using script for :getAttribute of #{name}"
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.info 'Using script for :isDisplayed'
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.info("-> #{verb.to_s.upcase} #{path}")
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 = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])/.freeze
686
+ ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])/
686
687
  UNICODE_CODE_POINT = 30
687
688
 
688
689
  # Escapes invalid characters in CSS selector.
@@ -45,8 +45,10 @@ module Selenium
45
45
  end
46
46
 
47
47
  def devtools_version
48
- capabilities['se:cdpVersion']&.split('.')&.first ||
49
- raise(Error::WebDriverError, 'DevTools is not supported by the Remote Server')
48
+ cdp_version = capabilities['se:cdpVersion']&.split('.')&.first
49
+ raise Error::WebDriverError, 'DevTools is not supported by the Remote Server' unless cdp_version
50
+
51
+ Integer(cdp_version)
50
52
  end
51
53
 
52
54
  def process_options(options, capabilities)
@@ -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.info(" >>> #{url} | #{payload}")
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.info("<- #{body}")
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?
@@ -83,7 +83,7 @@ module Selenium
83
83
  c.max_redirects = MAX_REDIRECTS
84
84
  c.follow_location = true
85
85
  c.timeout = @timeout if @timeout
86
- c.verbose = WebDriver.logger.info?
86
+ c.verbose = WebDriver.logger.debug?
87
87
 
88
88
  c
89
89
  end
@@ -100,7 +100,7 @@ module Selenium
100
100
 
101
101
  request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
102
102
  else
103
- WebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}")
103
+ WebDriver.logger.debug(" <<< #{response.instance_variable_get(:@header).inspect}", id: :header)
104
104
  create_response response.code, response.body, response.content_type
105
105
  end
106
106
  end
@@ -23,27 +23,27 @@ module Selenium
23
23
  class Color
24
24
  RGB_PATTERN = /^\s*rgb\(\s*(\d{1,3})\s*,
25
25
  \s*(\d{1,3})\s*,
26
- \s*(\d{1,3})\s*\)\s*$/x.freeze
26
+ \s*(\d{1,3})\s*\)\s*$/x
27
27
  RGB_PCT_PATTERN = /^\s*rgb\(\s*(\d{1,3}|\d{1,2}\.\d+)%\s*,
28
28
  \s*(\d{1,3}|\d{1,2}\.\d+)%\s*,
29
- \s*(\d{1,3}|\d{1,2}\.\d+)%\s*\)\s*$/x.freeze
29
+ \s*(\d{1,3}|\d{1,2}\.\d+)%\s*\)\s*$/x
30
30
  RGBA_PATTERN = /^\s*rgba\(\s*(\d{1,3})\s*,
31
31
  \s*(\d{1,3})\s*,
32
32
  \s*(\d{1,3})\s*,
33
- \s*(0|1|0\.\d+)\s*\)\s*$/x.freeze
33
+ \s*(0|1|0\.\d+)\s*\)\s*$/x
34
34
  RGBA_PCT_PATTERN = /^\s*rgba\(\s*(\d{1,3}|\d{1,2}\.\d+)
35
35
  %\s*,\s*(\d{1,3}|\d{1,2}\.\d+)
36
36
  %\s*,\s*(\d{1,3}|\d{1,2}\.\d+)
37
- %\s*,\s*(0|1|0\.\d+)\s*\)\s*$/x.freeze
38
- HEX_PATTERN = /#(\h{2})(\h{2})(\h{2})/.freeze
39
- HEX3_PATTERN = /#(\h)(\h)(\h)/.freeze
37
+ %\s*,\s*(0|1|0\.\d+)\s*\)\s*$/x
38
+ HEX_PATTERN = /#(\h{2})(\h{2})(\h{2})/
39
+ HEX3_PATTERN = /#(\h)(\h)(\h)/
40
40
  HSL_PATTERN = /^\s*hsl\(\s*(\d{1,3})\s*,
41
41
  \s*(\d{1,3})%\s*,
42
- \s*(\d{1,3})%\s*\)\s*$/x.freeze
42
+ \s*(\d{1,3})%\s*\)\s*$/x
43
43
  HSLA_PATTERN = /^\s*hsla\(\s*(\d{1,3})\s*,
44
44
  \s*(\d{1,3})%\s*,
45
45
  \s*(\d{1,3})%\s*,
46
- \s*(0|1|0\.\d+)\s*\)\s*$/x.freeze
46
+ \s*(0|1|0\.\d+)\s*\)\s*$/x
47
47
 
48
48
  attr_reader :red, :green, :blue, :alpha
49
49
 
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- VERSION = '4.8.6'
22
+ VERSION = '4.9.1'
23
23
  end # WebDriver
24
24
  end # Selenium
@@ -95,7 +95,8 @@ module Selenium
95
95
  #
96
96
 
97
97
  def self.logger(**opts)
98
- @logger ||= WebDriver::Logger.new('Selenium', **opts)
98
+ level = $DEBUG || ENV.key?('DEBUG') ? :debug : :info
99
+ @logger ||= WebDriver::Logger.new('Selenium', default_level: level, **opts)
99
100
  end
100
101
  end # WebDriver
101
102
  end # Selenium
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  }
31
31
 
32
32
  s.required_rubygems_version = Gem::Requirement.new('> 1.3.1') if s.respond_to? :required_rubygems_version=
33
- s.required_ruby_version = Gem::Requirement.new('>= 2.7')
33
+ s.required_ruby_version = Gem::Requirement.new('>= 3.0')
34
34
 
35
35
  s.files = [
36
36
  'CHANGES',
@@ -53,7 +53,6 @@ Gem::Specification.new do |s|
53
53
  s.add_runtime_dependency 'rubyzip', ['>= 1.2.2', '< 3.0']
54
54
  s.add_runtime_dependency 'websocket', ['~> 1.0']
55
55
 
56
- s.add_development_dependency 'pry', ['~> 0.14']
57
56
  s.add_development_dependency 'rack', ['~> 2.0']
58
57
  s.add_development_dependency 'rspec', ['~> 3.0']
59
58
  s.add_development_dependency 'rubocop', ['~> 1.42']
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium-webdriver
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.8.6
4
+ version: 4.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Rodionov
8
8
  - Titus Fortner
9
9
  - Thomas Walpole
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-03-29 00:00:00.000000000 Z
13
+ date: 2023-05-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rexml
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.0'
69
- - !ruby/object:Gem::Dependency
70
- name: pry
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0.14'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.14'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: rack
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -389,7 +375,7 @@ metadata:
389
375
  github_repo: ssh://github.com/SeleniumHQ/selenium
390
376
  source_code_uri: https://github.com/SeleniumHQ/selenium/tree/trunk/rb
391
377
  rubygems_mfa_required: 'true'
392
- post_install_message:
378
+ post_install_message:
393
379
  rdoc_options: []
394
380
  require_paths:
395
381
  - lib
@@ -397,15 +383,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
397
383
  requirements:
398
384
  - - ">="
399
385
  - !ruby/object:Gem::Version
400
- version: '2.7'
386
+ version: '3.0'
401
387
  required_rubygems_version: !ruby/object:Gem::Requirement
402
388
  requirements:
403
389
  - - ">"
404
390
  - !ruby/object:Gem::Version
405
391
  version: 1.3.1
406
392
  requirements: []
407
- rubygems_version: 3.1.6
408
- signing_key:
393
+ rubygems_version: 3.2.33
394
+ signing_key:
409
395
  specification_version: 4
410
396
  summary: Selenium is a browser automation tool for automated testing of webapps and
411
397
  more