selenium-webdriver 4.27.0 → 4.32.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +61 -0
  3. data/Gemfile +3 -1
  4. data/LICENSE +1 -1
  5. data/NOTICE +1 -1
  6. data/bin/linux/selenium-manager +0 -0
  7. data/bin/macos/selenium-manager +0 -0
  8. data/bin/windows/selenium-manager.exe +0 -0
  9. data/lib/selenium/server.rb +4 -4
  10. data/lib/selenium/webdriver/atoms/findElements.js +50 -118
  11. data/lib/selenium/webdriver/atoms/getAttribute.js +1 -1
  12. data/lib/selenium/webdriver/atoms/isDisplayed.js +1 -1
  13. data/lib/selenium/webdriver/bidi/browsing_context.rb +15 -0
  14. data/lib/selenium/webdriver/bidi/log_inspector.rb +4 -4
  15. data/lib/selenium/webdriver/{common/html5/session_storage.rb → bidi/network/cookies.rb} +11 -34
  16. data/lib/selenium/webdriver/{common/html5/local_storage.rb → bidi/network/credentials.rb} +15 -31
  17. data/lib/selenium/webdriver/bidi/network/headers.rb +38 -0
  18. data/lib/selenium/webdriver/{common/html5/shared_web_storage.rb → bidi/network/intercepted_auth.rb} +10 -25
  19. data/lib/selenium/webdriver/{common/driver_extensions/has_web_storage.rb → bidi/network/intercepted_item.rb} +10 -11
  20. data/lib/selenium/webdriver/bidi/network/intercepted_request.rb +69 -0
  21. data/lib/selenium/webdriver/bidi/network/intercepted_response.rb +81 -0
  22. data/lib/selenium/webdriver/bidi/network/url_pattern.rb +65 -0
  23. data/lib/selenium/webdriver/bidi/network.rb +80 -11
  24. data/lib/selenium/webdriver/bidi/struct.rb +1 -1
  25. data/lib/selenium/webdriver/bidi.rb +6 -2
  26. data/lib/selenium/webdriver/chromium/driver.rb +0 -1
  27. data/lib/selenium/webdriver/common/driver.rb +3 -10
  28. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +4 -3
  29. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -2
  30. data/lib/selenium/webdriver/common/logger.rb +1 -1
  31. data/lib/selenium/webdriver/common/manager.rb +1 -1
  32. data/lib/selenium/webdriver/common/network.rb +66 -16
  33. data/lib/selenium/webdriver/common/options.rb +1 -1
  34. data/lib/selenium/webdriver/common/print_options.rb +93 -0
  35. data/lib/selenium/webdriver/common/script.rb +4 -4
  36. data/lib/selenium/webdriver/common/selenium_manager.rb +36 -17
  37. data/lib/selenium/webdriver/common/takes_screenshot.rb +1 -0
  38. data/lib/selenium/webdriver/common.rb +1 -4
  39. data/lib/selenium/webdriver/devtools.rb +7 -5
  40. data/lib/selenium/webdriver/firefox/driver.rb +0 -19
  41. data/lib/selenium/webdriver/firefox/options.rb +2 -2
  42. data/lib/selenium/webdriver/firefox/service.rb +9 -0
  43. data/lib/selenium/webdriver/ie/driver.rb +1 -1
  44. data/lib/selenium/webdriver/remote/bridge.rb +4 -64
  45. data/lib/selenium/webdriver/safari/driver.rb +1 -2
  46. data/lib/selenium/webdriver/support/guards.rb +4 -2
  47. data/lib/selenium/webdriver/version.rb +1 -1
  48. data/selenium-webdriver.gemspec +5 -4
  49. metadata +20 -20
@@ -94,6 +94,21 @@ module Selenium
94
94
  result = @bidi.send_cmd('browsingContext.create', type: type.to_s, referenceContext: context_id)
95
95
  result['context']
96
96
  end
97
+
98
+ def set_viewport(context_id: nil, width: nil, height: nil, device_pixel_ratio: nil)
99
+ context_id ||= @bridge.window_handle
100
+ params = {context: context_id, viewport: {width:, height:}, device_pixel_ratio:}
101
+ @bidi.send_cmd('browsingContext.setViewport', **params)
102
+ end
103
+
104
+ def handle_user_prompt(context_id, accept: true, text: nil)
105
+ @bidi.send_cmd('browsingContext.handleUserPrompt', context: context_id, accept: accept, text: text)
106
+ end
107
+
108
+ def activate(context_id: nil)
109
+ context_id ||= @bridge.window_handle
110
+ @bidi.send_cmd('browsingContext.activate', context: context_id)
111
+ end
97
112
  end
98
113
  end # BiDi
99
114
  end # WebDriver
@@ -79,7 +79,7 @@ module Selenium
79
79
  end
80
80
  end
81
81
 
82
- def on_log(filter_by = nil, &)
82
+ def on_log(filter_by = nil, &block)
83
83
  unless filter_by.nil?
84
84
  check_valid_filter(filter_by)
85
85
 
@@ -89,14 +89,14 @@ module Selenium
89
89
  return
90
90
  end
91
91
 
92
- on(:entry_added, &)
92
+ on(:entry_added, &block)
93
93
  end
94
94
 
95
95
  private
96
96
 
97
- def on(event, &)
97
+ def on(event, &block)
98
98
  event = EVENTS[event] if event.is_a?(Symbol)
99
- @bidi.add_callback("log.#{event}", &)
99
+ @bidi.add_callback("log.#{event}", &block)
100
100
  end
101
101
 
102
102
  def check_valid_filter(filter_by)
@@ -19,43 +19,20 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- module HTML5
23
- class SessionStorage
24
- include Enumerable
25
- include SharedWebStorage
26
-
27
- def [](key)
28
- @bridge.session_storage_item key
29
- end
30
-
31
- def []=(key, value)
32
- @bridge.session_storage_item key, value
33
- end
34
-
35
- def delete(key)
36
- @bridge.remove_session_storage_item key
37
- end
38
-
39
- def clear
40
- @bridge.clear_session_storage
41
- end
42
-
43
- def size
44
- @bridge.session_storage_size
45
- end
46
-
47
- def keys
48
- @bridge.session_storage_keys.reverse
22
+ class BiDi
23
+ class Cookies < Hash
24
+ def initialize(cookies = {})
25
+ super()
26
+ merge!(cookies)
49
27
  end
50
28
 
51
- #
52
- # @api private
53
- #
29
+ def as_json
30
+ self[:name] = self[:name].to_s
31
+ self[:value] = {type: 'string', value: self[:value].to_s}
54
32
 
55
- def initialize(bridge)
56
- @bridge = bridge
33
+ [compact]
57
34
  end
58
- end # SessionStorage
59
- end # HTML5
35
+ end
36
+ end # BiDi
60
37
  end # WebDriver
61
38
  end # Selenium
@@ -19,41 +19,25 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- module HTML5
23
- class LocalStorage
24
- include SharedWebStorage
22
+ class BiDi
23
+ class Credentials
24
+ attr_accessor :username, :password
25
25
 
26
- #
27
- # @api private
28
- #
29
- def initialize(bridge)
30
- @bridge = bridge
26
+ def initialize(username: nil, password: nil)
27
+ @username = username
28
+ @password = password
31
29
  end
32
30
 
33
- def [](key)
34
- @bridge.local_storage_item key
35
- end
36
-
37
- def []=(key, value)
38
- @bridge.local_storage_item key, value
39
- end
40
-
41
- def delete(key)
42
- @bridge.remove_local_storage_item key
43
- end
44
-
45
- def clear
46
- @bridge.clear_local_storage
47
- end
48
-
49
- def size
50
- @bridge.local_storage_size
51
- end
31
+ def as_json
32
+ return nil unless username && password
52
33
 
53
- def keys
54
- @bridge.local_storage_keys.reverse
34
+ {
35
+ type: 'password',
36
+ username: username,
37
+ password: password
38
+ }
55
39
  end
56
- end # LocalStorage
57
- end # HTML5
40
+ end
41
+ end # BiDi
58
42
  end # WebDriver
59
43
  end # Selenium
@@ -0,0 +1,38 @@
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 BiDi
23
+ class Headers < Hash
24
+ def as_json
25
+ map do |name, val|
26
+ {
27
+ name: name.to_s,
28
+ value: {
29
+ type: 'string',
30
+ value: val.to_s
31
+ }
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end # BiDi
37
+ end # WebDriver
38
+ end # Selenium
@@ -19,35 +19,20 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- module HTML5
23
- module SharedWebStorage
24
- include Enumerable
25
-
26
- def key?(key)
27
- keys.include? key
22
+ class BiDi
23
+ class InterceptedAuth < InterceptedItem
24
+ def authenticate(username, password)
25
+ network.continue_with_auth(id, username, password)
28
26
  end
29
- alias member? key?
30
- alias has_key? key?
31
-
32
- def fetch(key)
33
- return self[key] if key? key
34
- return yield(key) if block_given?
35
27
 
36
- raise KeyError, "missing key #{key.inspect}"
28
+ def skip
29
+ network.continue_without_auth(id)
37
30
  end
38
31
 
39
- def empty?
40
- to_a.empty?
41
- end
42
-
43
- def each
44
- return enum_for(:each) unless block_given?
45
-
46
- keys.each do |k|
47
- yield k, self[k]
48
- end
32
+ def cancel
33
+ network.cancel_auth(id)
49
34
  end
50
- end # SharedWebStorage
51
- end # HTML5
35
+ end
36
+ end # BiDi
52
37
  end # WebDriver
53
38
  end # Selenium
@@ -19,20 +19,19 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- #
23
- # @api private
24
- #
22
+ class BiDi
23
+ class InterceptedItem
24
+ attr_reader :network, :request
25
25
 
26
- module DriverExtensions
27
- module HasWebStorage
28
- def local_storage
29
- HTML5::LocalStorage.new @bridge
26
+ def initialize(network, request)
27
+ @network = network
28
+ @request = request
30
29
  end
31
30
 
32
- def session_storage
33
- HTML5::SessionStorage.new @bridge
31
+ def id
32
+ @id ||= @request['request']
34
33
  end
35
- end # HasWebStorage
36
- end # DriverExtensions
34
+ end
35
+ end # BiDi
37
36
  end # WebDriver
38
37
  end # Selenium
@@ -0,0 +1,69 @@
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
+ require_relative 'cookies'
21
+ require_relative 'headers'
22
+
23
+ module Selenium
24
+ module WebDriver
25
+ class BiDi
26
+ class InterceptedRequest < InterceptedItem
27
+ attr_accessor :method, :url
28
+ attr_reader :body
29
+
30
+ def initialize(network, request)
31
+ super
32
+ @method = nil
33
+ @url = nil
34
+ @body = nil
35
+ end
36
+
37
+ def continue
38
+ network.continue_request(
39
+ id: id,
40
+ body: body,
41
+ cookies: cookies.as_json,
42
+ headers: headers.as_json,
43
+ method: method,
44
+ url: url
45
+ )
46
+ end
47
+
48
+ def fail
49
+ network.fail_request(id)
50
+ end
51
+
52
+ def body=(value)
53
+ @body = {
54
+ type: 'string',
55
+ value: value.to_json
56
+ }
57
+ end
58
+
59
+ def headers
60
+ @headers ||= Headers.new
61
+ end
62
+
63
+ def cookies(cookies = {})
64
+ @cookies ||= Cookies.new(cookies)
65
+ end
66
+ end
67
+ end # BiDi
68
+ end # WebDriver
69
+ end # Selenium
@@ -0,0 +1,81 @@
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
+ require_relative 'credentials'
21
+ require_relative 'headers'
22
+ require_relative 'cookies'
23
+
24
+ module Selenium
25
+ module WebDriver
26
+ class BiDi
27
+ class InterceptedResponse < InterceptedItem
28
+ attr_accessor :reason, :status
29
+ attr_reader :body
30
+
31
+ def initialize(network, request)
32
+ super
33
+ @reason = nil
34
+ @status = nil
35
+ @body = nil
36
+ end
37
+
38
+ def continue
39
+ network.continue_response(
40
+ id: id,
41
+ cookies: cookies.as_json,
42
+ headers: headers.as_json,
43
+ credentials: credentials.as_json,
44
+ reason: reason,
45
+ status: status
46
+ )
47
+ end
48
+
49
+ def provide_response
50
+ network.provide_response(
51
+ id: id,
52
+ cookies: cookies.as_json,
53
+ headers: headers.as_json,
54
+ body: body,
55
+ reason: reason,
56
+ status: status
57
+ )
58
+ end
59
+
60
+ def credentials(username: nil, password: nil)
61
+ @credentials ||= Credentials.new(username: username, password: password)
62
+ end
63
+
64
+ def headers
65
+ @headers ||= Headers.new
66
+ end
67
+
68
+ def cookies(cookies = {})
69
+ @cookies ||= Cookies.new(cookies)
70
+ end
71
+
72
+ def body=(value)
73
+ @body = {
74
+ type: 'string',
75
+ value: value.to_json
76
+ }
77
+ end
78
+ end
79
+ end # BiDi
80
+ end # WebDriver
81
+ end # Selenium
@@ -0,0 +1,65 @@
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
+ require 'uri'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ class BiDi
25
+ module UrlPattern
26
+ module_function
27
+
28
+ def format_pattern(url_patterns, pattern_type)
29
+ case pattern_type
30
+ when :string
31
+ to_url_string_pattern(url_patterns)
32
+ when :url
33
+ to_url_pattern(url_patterns)
34
+ else
35
+ raise ArgumentError, "Unknown pattern type: #{pattern_type}"
36
+ end
37
+ end
38
+
39
+ def to_url_pattern(*url_patterns)
40
+ url_patterns.flatten.map do |url_pattern|
41
+ uri = URI.parse(url_pattern)
42
+
43
+ {
44
+ type: 'pattern',
45
+ protocol: uri.scheme || '',
46
+ hostname: uri.host || '',
47
+ port: uri.port.to_s || '',
48
+ pathname: uri.path || '',
49
+ search: uri.query || ''
50
+ }
51
+ end
52
+ end
53
+
54
+ def to_url_string_pattern(*url_patterns)
55
+ url_patterns.flatten.map do |url_pattern|
56
+ {
57
+ type: 'string',
58
+ pattern: url_pattern
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end # BiDi
64
+ end # WebDriver
65
+ end # Selenium
@@ -16,6 +16,7 @@
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
+ require_relative 'network/url_pattern'
19
20
 
20
21
  module Selenium
21
22
  module WebDriver
@@ -26,7 +27,7 @@ module Selenium
26
27
  response_started: 'network.responseStarted',
27
28
  response_completed: 'network.responseCompleted',
28
29
  auth_required: 'network.authRequired',
29
- FETCH_ERROR: 'network.fetchError'
30
+ fetch_error: 'network.fetchError'
30
31
  }.freeze
31
32
 
32
33
  PHASES = {
@@ -39,8 +40,12 @@ module Selenium
39
40
  @bidi = bidi
40
41
  end
41
42
 
42
- def add_intercept(phases: [], contexts: nil, url_patterns: nil)
43
- @bidi.send_cmd('network.addIntercept', phases: phases, contexts: contexts, urlPatterns: url_patterns)
43
+ def add_intercept(phases: [], contexts: nil, url_patterns: nil, pattern_type: :string)
44
+ url_patterns = url_patterns && pattern_type ? UrlPattern.format_pattern(url_patterns, pattern_type) : nil
45
+ @bidi.send_cmd('network.addIntercept',
46
+ phases: phases,
47
+ contexts: contexts,
48
+ urlPatterns: url_patterns)
44
49
  end
45
50
 
46
51
  def remove_intercept(intercept)
@@ -50,19 +55,83 @@ module Selenium
50
55
  def continue_with_auth(request_id, username, password)
51
56
  @bidi.send_cmd(
52
57
  'network.continueWithAuth',
53
- 'request' => request_id,
54
- 'action' => 'provideCredentials',
55
- 'credentials' => {
56
- 'type' => 'password',
57
- 'username' => username,
58
- 'password' => password
58
+ request: request_id,
59
+ action: 'provideCredentials',
60
+ credentials: {
61
+ type: 'password',
62
+ username: username,
63
+ password: password
59
64
  }
60
65
  )
61
66
  end
62
67
 
63
- def on(event, &)
68
+ def continue_without_auth(request_id)
69
+ @bidi.send_cmd(
70
+ 'network.continueWithAuth',
71
+ request: request_id,
72
+ action: 'default'
73
+ )
74
+ end
75
+
76
+ def cancel_auth(request_id)
77
+ @bidi.send_cmd(
78
+ 'network.continueWithAuth',
79
+ request: request_id,
80
+ action: 'cancel'
81
+ )
82
+ end
83
+
84
+ def continue_request(**args)
85
+ @bidi.send_cmd(
86
+ 'network.continueRequest',
87
+ request: args[:id],
88
+ body: args[:body],
89
+ cookies: args[:cookies],
90
+ headers: args[:headers],
91
+ method: args[:method],
92
+ url: args[:url]
93
+ )
94
+ end
95
+
96
+ def fail_request(request_id)
97
+ @bidi.send_cmd(
98
+ 'network.failRequest',
99
+ request: request_id
100
+ )
101
+ end
102
+
103
+ def continue_response(**args)
104
+ @bidi.send_cmd(
105
+ 'network.continueResponse',
106
+ request: args[:id],
107
+ cookies: args[:cookies],
108
+ credentials: args[:credentials],
109
+ headers: args[:headers],
110
+ reasonPhrase: args[:reason],
111
+ statusCode: args[:status]
112
+ )
113
+ end
114
+
115
+ def provide_response(**args)
116
+ @bidi.send_cmd(
117
+ 'network.provideResponse',
118
+ request: args[:id],
119
+ body: args[:body],
120
+ cookies: args[:cookies],
121
+ headers: args[:headers],
122
+ reasonPhrase: args[:reason],
123
+ statusCode: args[:status]
124
+ )
125
+ end
126
+
127
+ def set_cache_behavior(behavior, *contexts)
128
+ @bidi.send_cmd('network.setCacheBehavior', cacheBehavior: behavior, contexts: contexts)
129
+ end
130
+
131
+ def on(event, &block)
64
132
  event = EVENTS[event] if event.is_a?(Symbol)
65
- @bidi.add_callback(event, &)
133
+ @bidi.add_callback(event, &block)
134
+ @bidi.session.subscribe(event)
66
135
  end
67
136
  end # Network
68
137
  end # BiDi
@@ -23,7 +23,7 @@ module Selenium
23
23
  class Struct < ::Struct
24
24
  class << self
25
25
  def new(*args, &block)
26
- super(*args) do
26
+ super do
27
27
  define_method(:initialize) do |**kwargs|
28
28
  converted_kwargs = kwargs.transform_keys { |key| self.class.camel_to_snake(key.to_s).to_sym }
29
29
  super(*converted_kwargs.values_at(*self.class.members))
@@ -26,6 +26,10 @@ module Selenium
26
26
  autoload :BrowsingContext, 'selenium/webdriver/bidi/browsing_context'
27
27
  autoload :Struct, 'selenium/webdriver/bidi/struct'
28
28
  autoload :Network, 'selenium/webdriver/bidi/network'
29
+ autoload :InterceptedRequest, 'selenium/webdriver/bidi/network/intercepted_request'
30
+ autoload :InterceptedResponse, 'selenium/webdriver/bidi/network/intercepted_response'
31
+ autoload :InterceptedAuth, 'selenium/webdriver/bidi/network/intercepted_auth'
32
+ autoload :InterceptedItem, 'selenium/webdriver/bidi/network/intercepted_item'
29
33
 
30
34
  def initialize(url:)
31
35
  @ws = WebSocketConnection.new(url: url)
@@ -39,8 +43,8 @@ module Selenium
39
43
  @ws.callbacks
40
44
  end
41
45
 
42
- def add_callback(event, &)
43
- @ws.add_callback(event, &)
46
+ def add_callback(event, &block)
47
+ @ws.add_callback(event, &block)
44
48
  end
45
49
 
46
50
  def remove_callback(event, id)
@@ -32,7 +32,6 @@ module Selenium
32
32
  DriverExtensions::HasFedCmDialog,
33
33
  DriverExtensions::HasNetworkConditions,
34
34
  DriverExtensions::HasNetworkInterception,
35
- DriverExtensions::HasWebStorage,
36
35
  DriverExtensions::HasLaunching,
37
36
  DriverExtensions::HasPermissions,
38
37
  DriverExtensions::DownloadsFiles,
@@ -104,15 +104,8 @@ module Selenium
104
104
  # @see Script
105
105
  #
106
106
 
107
- def script(*args)
108
- if args.any?
109
- WebDriver.logger.deprecate('`Driver#script` as an alias for `#execute_script`',
110
- '`Driver#execute_script`',
111
- id: :driver_script)
112
- execute_script(*args)
113
- else
114
- @script ||= WebDriver::Script.new(bridge)
115
- end
107
+ def script
108
+ @script ||= WebDriver::Script.new(bridge)
116
109
  end
117
110
 
118
111
  #
@@ -188,7 +181,7 @@ module Selenium
188
181
  bridge.quit
189
182
  ensure
190
183
  @service_manager&.stop
191
- @devtools&.close
184
+ @devtools&.each_value(&:close)
192
185
  end
193
186
 
194
187
  #