selenium-webdriver 4.8.1 → 4.8.2

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: 9777fa00d3b0216e227ce5194d19da4268b8c7805b27d57782fa33f27d13e66c
4
- data.tar.gz: 0c5fa5ecf085aa83a0d2ba6ef690c98a637ee6667656a0e2edb129a2850307a9
3
+ metadata.gz: 89df774609a456df7ab08ce405cfc1fdbb5576d78551bbdecdb3bc31b09d83eb
4
+ data.tar.gz: 0655f0bc97e7e78787cc8d3ca4d511504f90dcbebcf9112c2b577e809cb0f19a
5
5
  SHA512:
6
- metadata.gz: d10526d84df80cd437990f38cb9b4445b19c67141115ba53ae5b300d668f5e8ef87f11b8efa70b231535bc817d2d276e21e83c70564fed3165a6627a08a17abe
7
- data.tar.gz: 9175b92a1ca431f2ffde1d1005c2a6e712c7a2c0808c58581f51a440d33e3307fd1693ae8fd098571ddd68d8bc06d5257e9ec3467b071758a25db9aab990232e
6
+ metadata.gz: f4388f9c9f129e642cbb7b01e5ba29b7fb232e21396e66c4e91720e746dfd3b8d515aadd7f2b5e51d79daa8cef4c60d14c01f2e017262d427cb4ef320bcbc896
7
+ data.tar.gz: a5a2870b6e2000eb5734025821361546b0e81f06915f94fd290fa58fb0fe0e20b0ce3ac2ae3a1b1d5e0f8a29b4ad3e0798dd0820a033b347cd167825658f57fa
data/CHANGES CHANGED
@@ -1,3 +1,12 @@
1
+ 4.8.2 (2023-03-24)
2
+ =========================
3
+ Ruby:
4
+ * Ruby driver finder (#11523)
5
+ * Using json output with Selenium Manager
6
+
7
+ BiDi:
8
+ * Released selenium-devtools 0.111.0 (supports CDP v85, v109, v110, v111)
9
+
1
10
  4.8.1 (2023-02-17)
2
11
  =========================
3
12
  Ruby:
Binary file
Binary file
Binary file
@@ -28,11 +28,10 @@ module Selenium
28
28
  #
29
29
 
30
30
  class Driver < Chromium::Driver
31
- def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
32
- raise ArgumentError, "Can't initialize #{self.class} with :url" if url
31
+ include LocalDriver
33
32
 
34
- caps = process_options(options, capabilities)
35
- url = service_url(service || Service.chrome)
33
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
34
+ caps, url = initialize_local_driver(capabilities, options, service, url)
36
35
  super(caps: caps, url: url, **opts)
37
36
  end
38
37
 
@@ -45,16 +44,6 @@ module Selenium
45
44
  def devtools_address
46
45
  "http://#{capabilities['goog:chromeOptions']['debuggerAddress']}"
47
46
  end
48
-
49
- def process_options(options, capabilities)
50
- if options && !options.is_a?(Options)
51
- raise ArgumentError, ":options must be an instance of #{Options}"
52
- elsif options.nil? && capabilities.nil?
53
- options = Options.new
54
- end
55
-
56
- super(options, capabilities)
57
- end
58
47
  end # Driver
59
48
  end # Chrome
60
49
  end # WebDriver
@@ -25,11 +25,6 @@ module Selenium
25
25
  class Service < Chromium::Service
26
26
  DEFAULT_PORT = 9515
27
27
  EXECUTABLE = 'chromedriver'
28
- MISSING_TEXT = <<~ERROR
29
- Unable to find chromedriver. Please download the server from
30
- https://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH.
31
- More info at https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/?language=ruby.
32
- ERROR
33
28
  SHUTDOWN_SUPPORTED = true
34
29
  end # Service
35
30
  end # Chrome
@@ -318,24 +318,6 @@ module Selenium
318
318
  end
319
319
  end
320
320
 
321
- def process_options(options, capabilities)
322
- if options && capabilities
323
- msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options"
324
- raise ArgumentError, msg
325
- end
326
-
327
- options ? options.as_json : deprecate_capabilities(capabilities)
328
- end
329
-
330
- def deprecate_capabilities(capabilities)
331
- unless is_a?(Remote::Driver)
332
- WebDriver.logger.deprecate("The :capabilities parameter for #{self.class}",
333
- ":options argument with an instance of #{self.class}",
334
- id: :capabilities)
335
- end
336
- generate_capabilities(capabilities)
337
- end
338
-
339
321
  def generate_capabilities(capabilities)
340
322
  Array(capabilities).map { |cap|
341
323
  if cap.is_a? Symbol
@@ -0,0 +1,43 @@
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
+ class DriverFinder
23
+ def self.path(options, klass)
24
+ path = klass.driver_path
25
+ path = path.call if path.is_a?(Proc)
26
+ path ||= Platform.find_binary(klass::EXECUTABLE)
27
+
28
+ path ||= begin
29
+ SeleniumManager.driver_path(options)
30
+ rescue Error::WebDriverError => e
31
+ WebDriver.logger.debug("Unable obtain driver using Selenium Manager\n #{e.message}")
32
+ nil
33
+ end
34
+ msg = "Unable to locate the #{klass::EXECUTABLE} executable; for more information on how to install drivers, " \
35
+ 'see https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/'
36
+ raise Error::WebDriverError, msg unless path
37
+
38
+ Platform.assert_executable path
39
+ path
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,54 @@
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 LocalDriver
23
+ def initialize_local_driver(capabilities, options, service, url)
24
+ raise ArgumentError, "Can't initialize #{self.class} with :url" if url
25
+
26
+ service ||= Service.send(browser)
27
+ caps = process_options(options, capabilities, service)
28
+ url = service_url(service)
29
+
30
+ [caps, url]
31
+ end
32
+
33
+ def process_options(options, capabilities, service)
34
+ default_options = Options.send(browser)
35
+
36
+ if options && capabilities
37
+ msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options"
38
+ raise ArgumentError, msg
39
+ elsif options && !options.is_a?(default_options.class)
40
+ raise ArgumentError, ":options must be an instance of #{default_options.class}"
41
+ elsif capabilities
42
+ WebDriver.logger.deprecate("The :capabilities parameter for #{self.class}",
43
+ ":options argument with an instance of #{self.class}",
44
+ id: :capabilities)
45
+ generate_capabilities(capabilities)
46
+ else
47
+ options ||= default_options
48
+ service.executable_path ||= WebDriver::DriverFinder.path(options, service.class)
49
+ options.as_json
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -30,15 +30,28 @@ module Selenium
30
30
  BIN_PATH = '../../../../../bin'
31
31
 
32
32
  class << self
33
- # @param [String] driver_name which driver to use.
33
+ # @param [Options] options browser options.
34
34
  # @return [String] the path to the correct driver.
35
- def driver_path(driver_name)
36
- unless %w[chromedriver geckodriver msedgedriver IEDriverServer].include?(driver_name)
37
- msg = "Unable to locate driver with name: #{driver_name}"
38
- raise Error::WebDriverError, msg
35
+ def driver_path(options)
36
+ message = "driver for #{options.browser_name} not found; attempting to install with Selenium Manager"
37
+ WebDriver.logger.warn(message)
38
+
39
+ unless options.is_a?(Options)
40
+ raise ArgumentError, "SeleniumManager requires a WebDriver::Options instance, not a #{options.inspect}"
41
+ end
42
+
43
+ command = [binary, '--browser', options.browser_name, '--output', 'json']
44
+ if options.browser_version
45
+ command << '--browser-version'
46
+ command << options.browser_version
39
47
  end
48
+ if options.respond_to?(:binary) && !options.binary.nil?
49
+ command << '--browser-path'
50
+ command << "\"#{options.binary.gsub('\ ', ' ').gsub(' ', '\ ')}\""
51
+ end
52
+ command << '--debug' if WebDriver.logger.debug?
40
53
 
41
- location = run("#{binary} --driver #{driver_name}")
54
+ location = run(command.join(' '))
42
55
  WebDriver.logger.debug("Driver found at #{location}")
43
56
  Platform.assert_executable location
44
57
 
@@ -73,15 +86,21 @@ module Selenium
73
86
 
74
87
  begin
75
88
  stdout, stderr, status = Open3.capture3(command)
89
+ json_output = stdout.empty? ? nil : JSON.parse(stdout)
90
+ result = json_output&.dig('result', 'message')
76
91
  rescue StandardError => e
77
92
  raise Error::WebDriverError, "Unsuccessful command executed: #{command}", e.message
78
93
  end
79
94
 
80
95
  if status.exitstatus.positive?
81
- raise Error::WebDriverError, "Unsuccessful command executed: #{command}\n#{stdout}#{stderr}"
96
+ raise Error::WebDriverError, "Unsuccessful command executed: #{command}\n#{result}#{stderr}"
97
+ end
98
+
99
+ json_output['logs'].each do |log|
100
+ WebDriver.logger.send(log['level'].downcase, log['message'])
82
101
  end
83
102
 
84
- stdout.gsub("INFO\t", '').strip
103
+ result
85
104
  end
86
105
  end
87
106
  end # SeleniumManager
@@ -67,11 +67,10 @@ module Selenium
67
67
  #
68
68
 
69
69
  def initialize(path: nil, port: nil, args: nil)
70
- path ||= self.class.driver_path
71
70
  port ||= self.class::DEFAULT_PORT
72
71
  args ||= []
73
72
 
74
- @executable_path = binary_path(path)
73
+ @executable_path = path
75
74
  @host = Platform.localhost
76
75
  @port = Integer(port)
77
76
 
@@ -96,24 +95,6 @@ module Selenium
96
95
  id: :driver_opts)
97
96
  driver_opts.key?(:args) ? driver_opts.delete(:args) : []
98
97
  end
99
-
100
- private
101
-
102
- def binary_path(path = nil)
103
- path = path.call if path.is_a?(Proc)
104
- path ||= Platform.find_binary(self.class::EXECUTABLE)
105
-
106
- begin
107
- path ||= SeleniumManager.driver_path(self.class::EXECUTABLE)
108
- rescue Error::WebDriverError => e
109
- WebDriver.logger.debug("Unable obtain driver using Selenium Manager\n #{e.message}")
110
- end
111
-
112
- raise Error::WebDriverError, self.class::MISSING_TEXT unless path
113
-
114
- Platform.assert_executable path
115
- path
116
- end
117
98
  end # Service
118
99
  end # WebDriver
119
100
  end # Selenium
@@ -64,7 +64,7 @@ module Selenium
64
64
 
65
65
  stop_server
66
66
  @process.poll_for_exit STOP_TIMEOUT
67
- rescue ChildProcess::TimeoutError
67
+ rescue ChildProcess::TimeoutError, Errno::ECONNREFUSED
68
68
  nil # noop
69
69
  ensure
70
70
  stop_process
@@ -18,6 +18,8 @@
18
18
  # under the License.
19
19
 
20
20
  require 'selenium/webdriver/common/error'
21
+ require 'selenium/webdriver/common/local_driver'
22
+ require 'selenium/webdriver/common/driver_finder'
21
23
  require 'selenium/webdriver/common/platform'
22
24
  require 'selenium/webdriver/common/proxy'
23
25
  require 'selenium/webdriver/common/log_entry'
@@ -28,11 +28,10 @@ module Selenium
28
28
  #
29
29
 
30
30
  class Driver < Chromium::Driver
31
- def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
32
- raise ArgumentError, "Can't initialize #{self.class} with :url" if url
31
+ include LocalDriver
33
32
 
34
- caps = process_options(options, capabilities)
35
- url = service_url(service || Service.edge)
33
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
34
+ caps, url = initialize_local_driver(capabilities, options, service, url)
36
35
  super(caps: caps, url: url, **opts)
37
36
  end
38
37
 
@@ -45,16 +44,6 @@ module Selenium
45
44
  def devtools_address
46
45
  "http://#{capabilities['ms:edgeOptions']['debuggerAddress']}"
47
46
  end
48
-
49
- def process_options(options, capabilities)
50
- if options && !options.is_a?(Options)
51
- raise ArgumentError, ":options must be an instance of #{Options}"
52
- elsif options.nil? && capabilities.nil?
53
- options = Options.new
54
- end
55
-
56
- super(options, capabilities)
57
- end
58
47
  end # Driver
59
48
  end # Edge
60
49
  end # WebDriver
@@ -25,10 +25,6 @@ module Selenium
25
25
  class Service < Chromium::Service
26
26
  DEFAULT_PORT = 9515
27
27
  EXECUTABLE = 'msedgedriver'
28
- MISSING_TEXT = <<~ERROR
29
- Unable to find msedgedriver. Please download the server from
30
- https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ and place it somewhere on your PATH.
31
- ERROR
32
28
  SHUTDOWN_SUPPORTED = true
33
29
  end # Service
34
30
  end # Edge
@@ -36,11 +36,10 @@ module Selenium
36
36
  DriverExtensions::HasWebStorage,
37
37
  DriverExtensions::PrintsPage].freeze
38
38
 
39
- def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
40
- raise ArgumentError, "Can't initialize #{self.class} with :url" if url
39
+ include LocalDriver
41
40
 
42
- caps = process_options(options, capabilities)
43
- url = service_url(service || Service.firefox)
41
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
42
+ caps, url = initialize_local_driver(capabilities, options, service, url)
44
43
  super(caps: caps, url: url, **opts)
45
44
  end
46
45
 
@@ -64,16 +63,6 @@ module Selenium
64
63
  def devtools_version
65
64
  Firefox::DEVTOOLS_VERSION
66
65
  end
67
-
68
- def process_options(options, capabilities)
69
- if options && !options.is_a?(Options)
70
- raise ArgumentError, ":options must be an instance of #{Options}"
71
- elsif options.nil? && capabilities.nil?
72
- options = Options.new
73
- end
74
-
75
- super(options, capabilities)
76
- end
77
66
  end # Driver
78
67
  end # Firefox
79
68
  end # WebDriver
@@ -23,11 +23,6 @@ module Selenium
23
23
  class Service < WebDriver::Service
24
24
  DEFAULT_PORT = 4444
25
25
  EXECUTABLE = 'geckodriver'
26
- MISSING_TEXT = <<~ERROR
27
- Unable to find Mozilla geckodriver. Please download the server from
28
- https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH.
29
- More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
30
- ERROR
31
26
  SHUTDOWN_SUPPORTED = false
32
27
 
33
28
  private
@@ -29,29 +29,16 @@ module Selenium
29
29
  class Driver < WebDriver::Driver
30
30
  EXTENSIONS = [DriverExtensions::HasWebStorage].freeze
31
31
 
32
- def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
33
- raise ArgumentError, "Can't initialize #{self.class} with :url" if url
32
+ include LocalDriver
34
33
 
35
- caps = process_options(options, capabilities)
36
- url = service_url(service || Service.ie)
34
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
35
+ caps, url = initialize_local_driver(capabilities, options, service, url)
37
36
  super(caps: caps, url: url, **opts)
38
37
  end
39
38
 
40
39
  def browser
41
40
  :internet_explorer
42
41
  end
43
-
44
- private
45
-
46
- def process_options(options, capabilities)
47
- if options && !options.is_a?(Options)
48
- raise ArgumentError, ":options must be an instance of #{Options}"
49
- elsif options.nil? && capabilities.nil?
50
- options = Options.new
51
- end
52
-
53
- super(options, capabilities)
54
- end
55
42
  end # Driver
56
43
  end # IE
57
44
  end # WebDriver
@@ -23,11 +23,6 @@ module Selenium
23
23
  class Service < WebDriver::Service
24
24
  DEFAULT_PORT = 5555
25
25
  EXECUTABLE = 'IEDriverServer'
26
- MISSING_TEXT = <<~ERROR
27
- Unable to find IEDriverServer. Please download the server from
28
- https://www.selenium.dev/downloads/ and place it somewhere on your PATH.
29
- More info at https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver.
30
- ERROR
31
26
  SHUTDOWN_SUPPORTED = true
32
27
 
33
28
  private
@@ -50,9 +50,13 @@ module Selenium
50
50
  end
51
51
 
52
52
  def process_options(options, capabilities)
53
- raise ArgumentError, "#{self.class} needs :options to be set" if options.nil? && capabilities.nil?
54
-
55
- super(options, capabilities)
53
+ if options && capabilities
54
+ msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options"
55
+ raise ArgumentError, msg
56
+ elsif options.nil? && capabilities.nil?
57
+ raise ArgumentError, "#{self.class} needs :options to be set"
58
+ end
59
+ options ? options.as_json : generate_capabilities(capabilities)
56
60
  end
57
61
  end # Driver
58
62
  end # Remote
@@ -30,29 +30,16 @@ module Selenium
30
30
  DriverExtensions::HasApplePermissions,
31
31
  DriverExtensions::HasWebStorage].freeze
32
32
 
33
- def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
34
- raise ArgumentError, "Can't initialize #{self.class} with :url" if url
33
+ include LocalDriver
35
34
 
36
- caps = process_options(options, capabilities)
37
- url = service_url(service || Service.safari)
35
+ def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
36
+ caps, url = initialize_local_driver(capabilities, options, service, url)
38
37
  super(caps: caps, url: url, **opts)
39
38
  end
40
39
 
41
40
  def browser
42
41
  :safari
43
42
  end
44
-
45
- private
46
-
47
- def process_options(options, capabilities)
48
- if options && !options.is_a?(Options)
49
- raise ArgumentError, ":options must be an instance of #{Options}"
50
- elsif options.nil? && capabilities.nil?
51
- options = Options.new
52
- end
53
-
54
- super(options, capabilities)
55
- end
56
43
  end # Driver
57
44
  end # Safari
58
45
  end # WebDriver
@@ -23,10 +23,6 @@ module Selenium
23
23
  class Service < WebDriver::Service
24
24
  DEFAULT_PORT = 7050
25
25
  EXECUTABLE = 'safaridriver'
26
- MISSING_TEXT = <<~ERROR
27
- Unable to find Apple's safaridriver which comes with Safari 10.
28
- More info at https://webkit.org/blog/6900/webdriver-support-in-safari-10/
29
- ERROR
30
26
  SHUTDOWN_SUPPORTED = false
31
27
  end # Service
32
28
  end # Safari
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- VERSION = '4.8.1'
22
+ VERSION = '4.8.2'
23
23
  end # WebDriver
24
24
  end # Selenium
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.8.1
4
+ version: 4.8.2
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: 2023-02-17 00:00:00.000000000 Z
13
+ date: 2023-03-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rexml
@@ -272,6 +272,7 @@ files:
272
272
  - lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb
273
273
  - lib/selenium/webdriver/common/driver_extensions/prints_page.rb
274
274
  - lib/selenium/webdriver/common/driver_extensions/uploads_files.rb
275
+ - lib/selenium/webdriver/common/driver_finder.rb
275
276
  - lib/selenium/webdriver/common/element.rb
276
277
  - lib/selenium/webdriver/common/error.rb
277
278
  - lib/selenium/webdriver/common/file_reaper.rb
@@ -297,6 +298,7 @@ files:
297
298
  - lib/selenium/webdriver/common/interactions/wheel_actions.rb
298
299
  - lib/selenium/webdriver/common/interactions/wheel_input.rb
299
300
  - lib/selenium/webdriver/common/keys.rb
301
+ - lib/selenium/webdriver/common/local_driver.rb
300
302
  - lib/selenium/webdriver/common/log_entry.rb
301
303
  - lib/selenium/webdriver/common/logger.rb
302
304
  - lib/selenium/webdriver/common/logs.rb