selenium-webdriver 4.21.1 → 4.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +22 -0
  3. data/README.md +1 -1
  4. data/bin/linux/selenium-manager +0 -0
  5. data/bin/macos/selenium-manager +0 -0
  6. data/bin/windows/selenium-manager.exe +0 -0
  7. data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +1 -1
  8. data/lib/selenium/webdriver/bidi/log_handler.rb +63 -0
  9. data/lib/selenium/webdriver/bidi/log_inspector.rb +5 -1
  10. data/lib/selenium/webdriver/bidi/session.rb +7 -7
  11. data/lib/selenium/webdriver/bidi/struct.rb +44 -0
  12. data/lib/selenium/webdriver/bidi.rb +10 -0
  13. data/lib/selenium/webdriver/chromium/driver.rb +1 -0
  14. data/lib/selenium/webdriver/common/child_process.rb +8 -2
  15. data/lib/selenium/webdriver/common/driver.rb +20 -14
  16. data/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb +1 -1
  17. data/lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb +55 -0
  18. data/lib/selenium/webdriver/common/error.rb +21 -21
  19. data/lib/selenium/webdriver/common/fedcm/account.rb +50 -0
  20. data/lib/selenium/webdriver/common/fedcm/dialog.rb +74 -0
  21. data/lib/selenium/webdriver/common/fedcm.rb +27 -0
  22. data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +1 -1
  23. data/lib/selenium/webdriver/common/interactions/wheel_input.rb +1 -1
  24. data/lib/selenium/webdriver/common/logger.rb +1 -1
  25. data/lib/selenium/webdriver/common/script.rb +45 -0
  26. data/lib/selenium/webdriver/common/websocket_connection.rb +12 -0
  27. data/lib/selenium/webdriver/common.rb +4 -0
  28. data/lib/selenium/webdriver/firefox/options.rb +3 -0
  29. data/lib/selenium/webdriver/ie/options.rb +3 -2
  30. data/lib/selenium/webdriver/remote/bidi_bridge.rb +44 -0
  31. data/lib/selenium/webdriver/remote/bridge/commands.rb +13 -1
  32. data/lib/selenium/webdriver/remote/bridge.rb +45 -0
  33. data/lib/selenium/webdriver/remote/response.rb +8 -33
  34. data/lib/selenium/webdriver/remote/server_error.rb +1 -1
  35. data/lib/selenium/webdriver/remote.rb +1 -0
  36. data/lib/selenium/webdriver/support/guards/guard.rb +8 -9
  37. data/lib/selenium/webdriver/version.rb +1 -1
  38. data/selenium-webdriver.gemspec +6 -4
  39. metadata +38 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b167c7575b53791dfd989aae9c4ba8375661ff7c43fe343c4f4234673f8f6ba0
4
- data.tar.gz: cc520cbd925b221a24e38547b15101bbf68812989affaf7435534f96099f7bc4
3
+ metadata.gz: 6eff1b0194347648ce4b4e5f2e5871f2fdfdeb85fa00edb762db57f480aeb3e0
4
+ data.tar.gz: d2d6c02c0357e5b52f0e843a704a554c0bf853d5b16c76bf6ed909614c0d62f1
5
5
  SHA512:
6
- metadata.gz: 7313dfdf491d92732485821260da007ad0b63bd5570e9c5623c7fc6dfdba0b14fdddd6293d62c7e30b31610ca986a7c17291174091e1d3ffb7d3dee81caaeffe
7
- data.tar.gz: 63a335b0a954e00c75cee80f9c2129360e1542b9d1d7528b461d51b5840935457a88a3528114f29f146949cf273581143dc1eaa8aefd6b479a3c81e0d3d0cc1f
6
+ metadata.gz: 4d7fa72ea30b744c7fd5eb6ddaa7c61b889a1dc5f0d21ef36d6e03fa7ad983e94c0ac071e7a6f0c6942e6d3d43722923d1b8d33ac1b83c43597ea5f153ebc275
7
+ data.tar.gz: 1288baedcdaea282540c55457eff420891b3fabe8b791a62a22b71a0fdd4c6da6e16b1f3a9d83056d684ea8a2efe1f674a40f206ef8ad9b659fcded049dd9695
data/CHANGES CHANGED
@@ -1,3 +1,25 @@
1
+ 4.23.0 (2024-07-18)
2
+ =========================
3
+ * Add FedCM support to the ruby selenium client (#13796)
4
+ * Add URLs constant to update error messages (#14174)
5
+ * Update selenium manager types (#14189)
6
+ * Add backtrace locations and cause to errors (#14170)
7
+ * Add CDP for Chrome 127 and remove 124
8
+
9
+ 4.22.0 (2024-06-20)
10
+ =========================
11
+
12
+ * Force UTF-8 encoding on logger (see #6937)
13
+ * Don't crash when ChildProcess is already killed (see #14032)
14
+ * Manage bidi instance on the bridge not the driver (#14071)
15
+ * Implement High Level Logging API with BiDi (#14073)
16
+ * Fix bug with message deletion in Guard class
17
+ * Change output for Guard class
18
+ * Implement toggle for BiDi and Classic implementations (#14092)
19
+ * Add preference to enable CDP in Firefox by default (#14091)
20
+ * Add support for the w3c silent option for the ruby library (#14152)
21
+ * Add CDP for Chrome 126 and remove 123
22
+
1
23
  4.21.1 (2024-05-16)
2
24
  =========================
3
25
 
data/README.md CHANGED
@@ -15,7 +15,7 @@ This gem provides Ruby bindings for Selenium and supports MRI >= 3.0.
15
15
 
16
16
  ## License
17
17
 
18
- Copyright 2009-2023 Software Freedom Conservancy
18
+ Copyright 2009-2024 Software Freedom Conservancy
19
19
 
20
20
  Licensed to the Software Freedom Conservancy (SFC) under one
21
21
  or more contributor license agreements. See the NOTICE file
Binary file
Binary file
Binary file
@@ -24,7 +24,7 @@ module Selenium
24
24
  attr_accessor :type
25
25
 
26
26
  def initialize(level:, text:, timestamp:, type:, stack_trace:)
27
- super(level: level, text: text, timestamp: timestamp, type: type, stack_trace: stack_trace)
27
+ super
28
28
  @type = 'javascript'
29
29
  end
30
30
  end # JavascriptLogEntry
@@ -0,0 +1,63 @@
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 LogHandler
24
+ ConsoleLogEntry = BiDi::Struct.new(:level, :text, :timestamp, :method, :args, :type)
25
+ JavaScriptLogEntry = BiDi::Struct.new(:level, :text, :timestamp, :stack_trace, :type)
26
+
27
+ def initialize(bidi)
28
+ @bidi = bidi
29
+ @log_entry_subscribed = false
30
+ end
31
+
32
+ # @return [int] id of the handler
33
+ def add_message_handler(type)
34
+ subscribe_log_entry unless @log_entry_subscribed
35
+ @bidi.add_callback('log.entryAdded') do |params|
36
+ if params['type'] == type
37
+ log_entry_klass = type == 'console' ? ConsoleLogEntry : JavaScriptLogEntry
38
+ yield(log_entry_klass.new(**params))
39
+ end
40
+ end
41
+ end
42
+
43
+ # @param [int] id of the handler previously added
44
+ def remove_message_handler(id)
45
+ @bidi.remove_callback('log.entryAdded', id)
46
+ unsubscribe_log_entry if @log_entry_subscribed && @bidi.callbacks['log.entryAdded'].empty?
47
+ end
48
+
49
+ private
50
+
51
+ def subscribe_log_entry
52
+ @bidi.session.subscribe('log.entryAdded')
53
+ @log_entry_subscribed = true
54
+ end
55
+
56
+ def unsubscribe_log_entry
57
+ @bidi.session.unsubscribe('log.entryAdded')
58
+ @log_entry_subscribed = false
59
+ end
60
+ end # LogHandler
61
+ end # Bidi
62
+ end # WebDriver
63
+ end # Selenium
@@ -41,6 +41,10 @@ module Selenium
41
41
  }.freeze
42
42
 
43
43
  def initialize(driver, browsing_context_ids = nil)
44
+ WebDriver.logger.deprecate('LogInspector class',
45
+ 'Script class with driver.script',
46
+ id: :log_inspector)
47
+
44
48
  unless driver.capabilities.web_socket_url
45
49
  raise Error::WebDriverError,
46
50
  'WebDriver instance must support BiDi protocol'
@@ -92,7 +96,7 @@ module Selenium
92
96
 
93
97
  def on(event, &block)
94
98
  event = EVENTS[event] if event.is_a?(Symbol)
95
- @bidi.callbacks["log.#{event}"] << block
99
+ @bidi.add_callback("log.#{event}", &block)
96
100
  end
97
101
 
98
102
  def check_valid_filter(filter_by)
@@ -29,21 +29,21 @@ module Selenium
29
29
 
30
30
  def status
31
31
  status = @bidi.send_cmd('session.status')
32
- Status.new(status['ready'], status['message'])
32
+ Status.new(**status)
33
33
  end
34
34
 
35
35
  def subscribe(events, browsing_contexts = nil)
36
- events_list = Array(events)
37
- browsing_contexts_list = browsing_contexts.nil? ? nil : Array(browsing_contexts)
36
+ opts = {events: Array(events)}
37
+ opts[:browsing_contexts] = Array(browsing_contexts) if browsing_contexts
38
38
 
39
- @bidi.send_cmd('session.subscribe', events: events_list, contexts: browsing_contexts_list)
39
+ @bidi.send_cmd('session.subscribe', **opts)
40
40
  end
41
41
 
42
42
  def unsubscribe(events, browsing_contexts = nil)
43
- events_list = Array(events)
44
- browsing_contexts_list = browsing_contexts.nil? ? nil : Array(browsing_contexts)
43
+ opts = {events: Array(events)}
44
+ opts[:browsing_contexts] = Array(browsing_contexts) if browsing_contexts
45
45
 
46
- @bidi.send_cmd('session.unsubscribe', events: events_list, contexts: browsing_contexts_list)
46
+ @bidi.send_cmd('session.unsubscribe', **opts)
47
47
  end
48
48
  end # Session
49
49
  end # BiDi
@@ -0,0 +1,44 @@
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 Struct < ::Struct
24
+ class << self
25
+ def new(*args, &block)
26
+ super(*args) do
27
+ define_method(:initialize) do |**kwargs|
28
+ converted_kwargs = kwargs.transform_keys { |key| self.class.camel_to_snake(key.to_s).to_sym }
29
+ super(*converted_kwargs.values_at(*self.class.members))
30
+ end
31
+ class_eval(&block) if block
32
+ end
33
+ end
34
+
35
+ def camel_to_snake(camel_str)
36
+ camel_str.gsub(/([A-Z])/, '_\1').downcase
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ # BiDi
43
+ end # WebDriver
44
+ end # Selenium
@@ -22,7 +22,9 @@ module Selenium
22
22
  class BiDi
23
23
  autoload :Session, 'selenium/webdriver/bidi/session'
24
24
  autoload :LogInspector, 'selenium/webdriver/bidi/log_inspector'
25
+ autoload :LogHandler, 'selenium/webdriver/bidi/log_handler'
25
26
  autoload :BrowsingContext, 'selenium/webdriver/bidi/browsing_context'
27
+ autoload :Struct, 'selenium/webdriver/bidi/struct'
26
28
 
27
29
  def initialize(url:)
28
30
  @ws = WebSocketConnection.new(url: url)
@@ -36,6 +38,14 @@ module Selenium
36
38
  @ws.callbacks
37
39
  end
38
40
 
41
+ def add_callback(event, &block)
42
+ @ws.add_callback(event, &block)
43
+ end
44
+
45
+ def remove_callback(event, id)
46
+ @ws.remove_callback(event, id)
47
+ end
48
+
39
49
  def session
40
50
  @session ||= Session.new(self)
41
51
  end
@@ -29,6 +29,7 @@ module Selenium
29
29
  EXTENSIONS = [DriverExtensions::HasCDP,
30
30
  DriverExtensions::HasBiDi,
31
31
  DriverExtensions::HasCasting,
32
+ DriverExtensions::HasFedCmDialog,
32
33
  DriverExtensions::HasNetworkConditions,
33
34
  DriverExtensions::HasNetworkInterception,
34
35
  DriverExtensions::HasWebStorage,
@@ -84,7 +84,7 @@ module Selenium
84
84
  return false unless @pid
85
85
 
86
86
  WebDriver.logger.debug("Checking if #{@pid} is exited:", id: :process)
87
- _, @status = Process.waitpid2(@pid, Process::WNOHANG | Process::WUNTRACED) if @status.nil?
87
+ _, @status = waitpid2(@pid, Process::WNOHANG | Process::WUNTRACED) if @status.nil?
88
88
  return false if @status.nil?
89
89
 
90
90
  exit_code = @status.exitstatus || @status.termsig
@@ -105,7 +105,7 @@ module Selenium
105
105
  def wait
106
106
  return if exited?
107
107
 
108
- _, @status = Process.waitpid2(@pid)
108
+ _, @status = waitpid2(@pid)
109
109
  end
110
110
 
111
111
  private
@@ -119,6 +119,12 @@ module Selenium
119
119
  rescue Errno::ECHILD, Errno::ESRCH
120
120
  # already dead
121
121
  end
122
+
123
+ def waitpid2(pid, flags = 0)
124
+ Process.waitpid2(pid, flags)
125
+ rescue Errno::ECHILD
126
+ # already dead
127
+ end
122
128
  end # ChildProcess
123
129
  end # WebDriver
124
130
  end # Selenium
@@ -70,10 +70,9 @@ module Selenium
70
70
 
71
71
  def initialize(bridge: nil, listener: nil, **opts)
72
72
  @devtools = nil
73
- @bidi = nil
74
73
  bridge ||= create_bridge(**opts)
75
- add_extensions(bridge.browser)
76
74
  @bridge = listener ? Support::EventFiringBridge.new(bridge, listener) : bridge
75
+ add_extensions(@bridge.browser)
77
76
  end
78
77
 
79
78
  def inspect
@@ -100,6 +99,22 @@ module Selenium
100
99
  @navigate ||= WebDriver::Navigation.new(bridge)
101
100
  end
102
101
 
102
+ #
103
+ # @return [Script]
104
+ # @see Script
105
+ #
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
116
+ end
117
+
103
118
  #
104
119
  # @return [TargetLocator]
105
120
  # @see TargetLocator
@@ -174,7 +189,6 @@ module Selenium
174
189
  ensure
175
190
  @service_manager&.stop
176
191
  @devtools&.close
177
- @bidi&.close
178
192
  end
179
193
 
180
194
  #
@@ -182,10 +196,7 @@ module Selenium
182
196
  #
183
197
 
184
198
  def close
185
- # If no top-level browsing contexts are open after calling close,
186
- # it indicates that the WebDriver session is closed.
187
- # If the WebDriver session is closed, the BiDi session also needs to be closed.
188
- bridge.close.tap { |handles| @bidi&.close if handles&.empty? }
199
+ bridge&.close
189
200
  end
190
201
 
191
202
  #
@@ -267,12 +278,6 @@ module Selenium
267
278
 
268
279
  alias all find_elements
269
280
 
270
- #
271
- # driver.script('function() { ... };')
272
- #
273
-
274
- alias script execute_script
275
-
276
281
  # Get the first element matching the given selector. If given a
277
282
  # String or Symbol, it will be used as the id of the element.
278
283
  #
@@ -313,7 +318,8 @@ module Selenium
313
318
  attr_reader :bridge
314
319
 
315
320
  def create_bridge(caps:, url:, http_client: nil)
316
- Remote::Bridge.new(http_client: http_client, url: url).tap do |bridge|
321
+ klass = caps['webSocketUrl'] ? Remote::BiDiBridge : Remote::Bridge
322
+ klass.new(http_client: http_client, url: url).tap do |bridge|
317
323
  bridge.create_session(caps)
318
324
  end
319
325
  end
@@ -28,7 +28,7 @@ module Selenium
28
28
  #
29
29
 
30
30
  def bidi
31
- @bidi ||= Selenium::WebDriver::BiDi.new(url: capabilities[:web_socket_url])
31
+ @bridge.bidi
32
32
  end
33
33
  end # HasBiDi
34
34
  end # DriverExtensions
@@ -0,0 +1,55 @@
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 DriverExtensions
23
+ module HasFedCmDialog
24
+ # Disables the promise rejection delay for FedCm.
25
+ #
26
+ # FedCm by default delays promise resolution in failure cases for privacy reasons.
27
+ # This method allows turning it off to let tests run faster where this is not relevant.
28
+ def enable_fedcm_delay=(enable)
29
+ @bridge.fedcm_delay(enable)
30
+ end
31
+
32
+ # Resets the FedCm dialog cooldown.
33
+ #
34
+ # If a user agent triggers a cooldown when the account chooser is dismissed,
35
+ # this method resets that cooldown so that the dialog can be triggered again immediately.
36
+ def reset_fedcm_cooldown
37
+ @bridge.reset_fedcm_cooldown
38
+ end
39
+
40
+ def fedcm_dialog
41
+ @fedcm_dialog ||= FedCM::Dialog.new(@bridge)
42
+ end
43
+
44
+ def wait_for_fedcm_dialog(timeout: 5, interval: 0.2, message: nil, ignore: nil)
45
+ wait = Wait.new(timeout: timeout, interval: interval, message: message, ignore: ignore)
46
+ wait.until do
47
+ fedcm_dialog if fedcm_dialog.type
48
+ rescue Error::NoSuchAlertError
49
+ nil
50
+ end
51
+ end
52
+ end # HasFedCmDialog
53
+ end # DriverExtensions
54
+ end # WebDriver
55
+ end # Selenium
@@ -37,17 +37,29 @@ module Selenium
37
37
  SUPPORT_MSG = 'For documentation on this error, please visit:'
38
38
  ERROR_URL = 'https://www.selenium.dev/documentation/webdriver/troubleshooting/errors'
39
39
 
40
- class WebDriverError < StandardError; end
40
+ URLS = {
41
+ NoSuchElementError: "#{ERROR_URL}#no-such-element-exception",
42
+ StaleElementReferenceError: "#{ERROR_URL}#stale-element-reference-exception",
43
+ InvalidSelectorError: "#{ERROR_URL}#invalid-selector-exception",
44
+ NoSuchDriverError: "#{ERROR_URL}/driver_location"
45
+ }.freeze
46
+
47
+ class WebDriverError < StandardError
48
+ def initialize(msg = '')
49
+ # Remove this conditional when all the error pages have been documented
50
+ super(URLS[class_name] ? "#{msg}; #{SUPPORT_MSG} #{URLS[class_name]}" : msg)
51
+ end
52
+
53
+ def class_name
54
+ self.class.name&.split('::')&.last&.to_sym
55
+ end
56
+ end
41
57
 
42
58
  #
43
59
  # An element could not be located on the page using the given search parameters.
44
60
  #
45
61
 
46
- class NoSuchElementError < WebDriverError
47
- def initialize(msg = '')
48
- super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#no-such-element-exception")
49
- end
50
- end
62
+ class NoSuchElementError < WebDriverError; end
51
63
 
52
64
  #
53
65
  # A command to switch to a frame could not be satisfied because the frame could not be found.
@@ -65,11 +77,7 @@ module Selenium
65
77
  # A command failed because the referenced element is no longer attached to the DOM.
66
78
  #
67
79
 
68
- class StaleElementReferenceError < WebDriverError
69
- def initialize(msg = '')
70
- super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#stale-element-reference-exception")
71
- end
72
- end
80
+ class StaleElementReferenceError < WebDriverError; end
73
81
 
74
82
  #
75
83
  # A command failed because the referenced shadow root is no longer attached to the DOM.
@@ -143,11 +151,7 @@ module Selenium
143
151
  # Argument was an invalid selector.
144
152
  #
145
153
 
146
- class InvalidSelectorError < WebDriverError
147
- def initialize(msg = '')
148
- super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#invalid-selector-exception")
149
- end
150
- end
154
+ class InvalidSelectorError < WebDriverError; end
151
155
 
152
156
  #
153
157
  # A new session could not be created.
@@ -232,11 +236,7 @@ module Selenium
232
236
  # Indicates that driver was not specified and could not be located.
233
237
  #
234
238
 
235
- class NoSuchDriverError < WebDriverError
236
- def initialize(msg = '')
237
- super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}/driver_location")
238
- end
239
- end
239
+ class NoSuchDriverError < WebDriverError; end
240
240
  end # Error
241
241
  end # WebDriver
242
242
  end # Selenium
@@ -0,0 +1,50 @@
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 FedCM
23
+ # Represents an account displayed in a FedCm account list.
24
+ # See: https://fedidcg.github.io/FedCM/#dictdef-identityprovideraccount
25
+ # https://fedidcg.github.io/FedCM/#webdriver-accountlist
26
+ class Account
27
+ LOGIN_STATE_SIGNIN = 'SignIn'
28
+ LOGIN_STATE_SIGNUP = 'SignUp'
29
+
30
+ attr_reader :account_id, :email, :name, :given_name, :picture_url,
31
+ :idp_config_url, :login_state, :terms_of_service_url, :privacy_policy_url
32
+
33
+ # Initializes a new account with the provided attributes.
34
+ #
35
+ # @param [Hash]
36
+ def initialize(**args)
37
+ @account_id = args['accountId']
38
+ @email = args['email']
39
+ @name = args['name']
40
+ @given_name = args['givenName']
41
+ @picture_url = args['pictureUrl']
42
+ @idp_config_url = args['idpConfigUrl']
43
+ @login_state = args['loginState']
44
+ @terms_of_service_url = args['termsOfServiceUrl']
45
+ @privacy_policy_url = args['privacyPolicyUrl']
46
+ end
47
+ end # Account
48
+ end # FedCM
49
+ end # WebDriver
50
+ end # Selenium
@@ -0,0 +1,74 @@
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 FedCM
23
+ class Dialog
24
+ def initialize(bridge)
25
+ @bridge = bridge
26
+ end
27
+
28
+ DIALOG_TYPE_ACCOUNT_LIST = 'AccountChooser'
29
+ DIALOG_TYPE_AUTO_REAUTH = 'AutoReauthn'
30
+
31
+ # Closes the dialog as if the user had clicked X.
32
+ def click
33
+ @bridge.click_fedcm_dialog_button
34
+ end
35
+
36
+ # Closes the dialog as if the user had clicked X.
37
+ def cancel
38
+ @bridge.cancel_fedcm_dialog
39
+ end
40
+
41
+ # Selects an account as if the user had clicked on it.
42
+ #
43
+ # @param [Integer] index The index of the account to select from the list returned by get_accounts.
44
+ def select_account(index)
45
+ @bridge.select_fedcm_account index
46
+ end
47
+
48
+ # Returns the type of the open dialog.
49
+ #
50
+ # One of DIALOG_TYPE_ACCOUNT_LIST and DIALOG_TYPE_AUTO_REAUTH.
51
+ def type
52
+ @bridge.fedcm_dialog_type
53
+ end
54
+
55
+ # Returns the title of the dialog.
56
+ def title
57
+ @bridge.fedcm_title
58
+ end
59
+
60
+ # Returns the subtitle of the dialog or nil if none.
61
+ def subtitle
62
+ @bridge.fedcm_subtitle
63
+ end
64
+
65
+ # Returns the accounts shown in the account chooser.
66
+ #
67
+ # If this is an auto reauth dialog, returns the single account that is being signed in.
68
+ def accounts
69
+ @bridge.fedcm_account_list.map { |account| Account.new(**account) }
70
+ end
71
+ end # Dialog
72
+ end # FedCM
73
+ end # WebDriver
74
+ end # Selenium
@@ -0,0 +1,27 @@
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 FedCM
23
+ autoload :Account, 'fedcm/account'
24
+ autoload :Dialog, 'fedcm/dialog'
25
+ end # FedCM
26
+ end # WebDriver
27
+ end # Selenium
@@ -28,7 +28,7 @@ module Selenium
28
28
 
29
29
  class PointerCancel < Interaction
30
30
  def initialize(source)
31
- super(source)
31
+ super
32
32
  @type = :pointerCancel
33
33
  end
34
34
 
@@ -28,7 +28,7 @@ module Selenium
28
28
 
29
29
  class WheelInput < InputDevice
30
30
  def initialize(name = nil)
31
- super(name)
31
+ super
32
32
  @type = Interactions::WHEEL
33
33
  end
34
34
 
@@ -185,7 +185,7 @@ module Selenium
185
185
  logger.progname = name
186
186
  logger.level = level
187
187
  logger.formatter = proc do |severity, time, progname, msg|
188
- "#{time.strftime('%F %T')} #{severity} #{progname} #{msg}\n"
188
+ "#{time.strftime('%F %T')} #{severity} #{progname} #{msg}\n".force_encoding('UTF-8')
189
189
  end
190
190
 
191
191
  logger
@@ -0,0 +1,45 @@
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 Script
23
+ def initialize(bridge)
24
+ @log_handler = BiDi::LogHandler.new(bridge.bidi)
25
+ end
26
+
27
+ # @return [int] id of the handler
28
+ def add_console_message_handler(&block)
29
+ @log_handler.add_message_handler('console', &block)
30
+ end
31
+
32
+ # @return [int] id of the handler
33
+ def add_javascript_error_handler(&block)
34
+ @log_handler.add_message_handler('javascript', &block)
35
+ end
36
+
37
+ # @param [int] id of the handler previously added
38
+ def remove_console_message_handler(id)
39
+ @log_handler.remove_message_handler(id)
40
+ end
41
+
42
+ alias remove_javascript_error_handler remove_console_message_handler
43
+ end # Script
44
+ end # WebDriver
45
+ end # Selenium
@@ -52,6 +52,18 @@ module Selenium
52
52
  @callbacks ||= Hash.new { |callbacks, event| callbacks[event] = [] }
53
53
  end
54
54
 
55
+ def add_callback(event, &block)
56
+ callbacks[event] << block
57
+ block.object_id
58
+ end
59
+
60
+ def remove_callback(event, id)
61
+ return if callbacks[event].reject! { |callback| callback.object_id == id }
62
+
63
+ ids = callbacks[event]&.map(&:object_id)
64
+ raise Error::WebDriverError, "Callback with ID #{id} does not exist for event #{event}: #{ids}"
65
+ end
66
+
55
67
  def send_cmd(**payload)
56
68
  id = next_id
57
69
  data = payload.merge(id: id)
@@ -89,6 +89,7 @@ require 'selenium/webdriver/common/driver_extensions/has_pinned_scripts'
89
89
  require 'selenium/webdriver/common/driver_extensions/has_cdp'
90
90
  require 'selenium/webdriver/common/driver_extensions/has_casting'
91
91
  require 'selenium/webdriver/common/driver_extensions/has_launching'
92
+ require 'selenium/webdriver/common/driver_extensions/has_fedcm_dialog'
92
93
  require 'selenium/webdriver/common/keys'
93
94
  require 'selenium/webdriver/common/profile_helper'
94
95
  require 'selenium/webdriver/common/options'
@@ -98,3 +99,6 @@ require 'selenium/webdriver/common/element'
98
99
  require 'selenium/webdriver/common/shadow_root'
99
100
  require 'selenium/webdriver/common/websocket_connection'
100
101
  require 'selenium/webdriver/common/child_process'
102
+ require 'selenium/webdriver/common/script'
103
+ require 'selenium/webdriver/common/fedcm/account'
104
+ require 'selenium/webdriver/common/fedcm/dialog'
@@ -64,6 +64,9 @@ module Selenium
64
64
 
65
65
  @options[:args] ||= []
66
66
  @options[:prefs] ||= {}
67
+ # Firefox 129 onwards the CDP protocol will not be enabled by default. Setting this preference will enable it.
68
+ # https://fxdx.dev/deprecating-cdp-support-in-firefox-embracing-the-future-with-webdriver-bidi/.
69
+ @options[:prefs]['remote.active-protocols'] = 3
67
70
  @options[:env] ||= {}
68
71
  @options[:log] ||= {level: log_level} if log_level
69
72
 
@@ -42,7 +42,8 @@ module Selenium
42
42
  use_legacy_file_upload_dialog_handling: 'ie.useLegacyFileUploadDialogHandling',
43
43
  attach_to_edge_chrome: 'ie.edgechromium',
44
44
  edge_executable_path: 'ie.edgepath',
45
- ignore_process_match: 'ie.ignoreprocessmatch'
45
+ ignore_process_match: 'ie.ignoreprocessmatch',
46
+ silent: 'silent'
46
47
  }.freeze
47
48
  BROWSER = 'internet explorer'
48
49
 
@@ -81,7 +82,7 @@ module Selenium
81
82
 
82
83
  def initialize(**opts)
83
84
  @args = (opts.delete(:args) || []).to_set
84
- super(**opts)
85
+ super
85
86
 
86
87
  @options[:native_events] = true if @options[:native_events].nil?
87
88
  end
@@ -0,0 +1,44 @@
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 Remote
23
+ class BiDiBridge < Bridge
24
+ attr_reader :bidi
25
+
26
+ def create_session(capabilities)
27
+ super
28
+ socket_url = @capabilities[:web_socket_url]
29
+ @bidi = Selenium::WebDriver::BiDi.new(url: socket_url)
30
+ end
31
+
32
+ def quit
33
+ super
34
+ ensure
35
+ bidi.close
36
+ end
37
+
38
+ def close
39
+ execute(:close_window).tap { |handles| bidi.close if handles.empty? }
40
+ end
41
+ end # BiDiBridge
42
+ end # Remote
43
+ end # WebDriver
44
+ end # Selenium
@@ -155,8 +155,20 @@ module Selenium
155
155
  remove_credential: [:delete,
156
156
  'session/:session_id/webauthn/authenticator/:authenticatorId/credentials/:credentialId'],
157
157
  remove_all_credentials: [:delete, 'session/:session_id/webauthn/authenticator/:authenticatorId/credentials'],
158
- set_user_verified: [:post, 'session/:session_id/webauthn/authenticator/:authenticatorId/uv']
158
+ set_user_verified: [:post, 'session/:session_id/webauthn/authenticator/:authenticatorId/uv'],
159
159
 
160
+ #
161
+ # federated-credential management
162
+ #
163
+
164
+ get_fedcm_title: [:get, 'session/:session_id/fedcm/gettitle'],
165
+ get_fedcm_dialog_type: [:get, 'session/:session_id/fedcm/getdialogtype'],
166
+ get_fedcm_account_list: [:get, 'session/:session_id/fedcm/accountlist'],
167
+ click_fedcm_dialog_button: [:post, 'session/:session_id/fedcm/clickdialogbutton'],
168
+ cancel_fedcm_dialog: [:post, 'session/:session_id/fedcm/canceldialog'],
169
+ select_fedcm_account: [:post, 'session/:session_id/fedcm/selectaccount'],
170
+ set_fedcm_delay: [:post, 'session/:session_id/fedcm/setdelayenabled'],
171
+ reset_fedcm_cooldown: [:post, 'session/:session_id/fedcm/resetcooldown']
160
172
  }.freeze
161
173
  end # Bridge
162
174
  end # Remote
@@ -602,6 +602,51 @@ module Selenium
602
602
  execute :set_user_verified, {authenticatorId: authenticator_id}, {isUserVerified: verified}
603
603
  end
604
604
 
605
+ #
606
+ # federated-credential management
607
+ #
608
+
609
+ def cancel_fedcm_dialog
610
+ execute :cancel_fedcm_dialog
611
+ end
612
+
613
+ def select_fedcm_account(index)
614
+ execute :select_fedcm_account, {}, {accountIndex: index}
615
+ end
616
+
617
+ def fedcm_dialog_type
618
+ execute :get_fedcm_dialog_type
619
+ end
620
+
621
+ def fedcm_title
622
+ execute(:get_fedcm_title).fetch('title')
623
+ end
624
+
625
+ def fedcm_subtitle
626
+ execute(:get_fedcm_title).fetch('subtitle', nil)
627
+ end
628
+
629
+ def fedcm_account_list
630
+ execute :get_fedcm_account_list
631
+ end
632
+
633
+ def fedcm_delay(enabled)
634
+ execute :set_fedcm_delay, {}, {enabled: enabled}
635
+ end
636
+
637
+ def reset_fedcm_cooldown
638
+ execute :reset_fedcm_cooldown
639
+ end
640
+
641
+ def click_fedcm_dialog_button
642
+ execute :click_fedcm_dialog_button, {}, {dialogButton: 'ConfirmIdpLoginContinue'}
643
+ end
644
+
645
+ def bidi
646
+ msg = 'BiDi must be enabled by setting #web_socket_url to true in options class'
647
+ raise(WebDriver::Error::WebDriverError, msg)
648
+ end
649
+
605
650
  def command_list
606
651
  COMMANDS
607
652
  end
@@ -28,7 +28,7 @@ module Selenium
28
28
  attr_reader :code, :payload
29
29
 
30
30
  def initialize(code, payload = nil)
31
- @code = code
31
+ @code = code
32
32
  @payload = payload || {}
33
33
 
34
34
  assert_ok
@@ -37,11 +37,8 @@ module Selenium
37
37
  def error
38
38
  error, message, backtrace = process_error
39
39
  klass = Error.for_error(error) || return
40
-
41
40
  ex = klass.new(message)
42
- ex.set_backtrace(caller)
43
- add_backtrace ex, backtrace
44
-
41
+ add_cause(ex, error, backtrace)
45
42
  ex
46
43
  end
47
44
 
@@ -59,34 +56,12 @@ module Selenium
59
56
  raise Error::ServerError, self
60
57
  end
61
58
 
62
- def add_backtrace(ex, server_trace)
63
- return unless server_trace
64
-
65
- backtrace = case server_trace
66
- when Array
67
- backtrace_from_remote(server_trace)
68
- when String
69
- server_trace.split("\n")
70
- end
71
-
72
- ex.set_backtrace(backtrace + ex.backtrace)
73
- end
74
-
75
- def backtrace_from_remote(server_trace)
76
- server_trace.filter_map do |frame|
77
- next unless frame.is_a?(Hash)
78
-
79
- file = frame['fileName']
80
- line = frame['lineNumber']
81
- meth = frame['methodName']
82
-
83
- class_name = frame['className']
84
- file = "#{class_name}(#{file})" if class_name
85
-
86
- meth = 'unknown' if meth.nil? || meth.empty?
87
-
88
- "[remote server] #{file}:#{line}:in `#{meth}'"
89
- end
59
+ def add_cause(ex, error, backtrace)
60
+ cause = Error::WebDriverError.new
61
+ cause.set_backtrace(backtrace)
62
+ raise ex, cause: cause
63
+ rescue Error.for_error(error)
64
+ ex
90
65
  end
91
66
 
92
67
  def process_error
@@ -23,7 +23,7 @@ module Selenium
23
23
  class ServerError < StandardError
24
24
  def initialize(response)
25
25
  if response.is_a? String
26
- super(response)
26
+ super
27
27
  else
28
28
  super("status code #{response.code}; payload #{response.payload}")
29
29
  end
@@ -25,6 +25,7 @@ module Selenium
25
25
  module Remote
26
26
  autoload :Features, 'selenium/webdriver/remote/features'
27
27
  autoload :Bridge, 'selenium/webdriver/remote/bridge'
28
+ autoload :BiDiBridge, 'selenium/webdriver/remote/bidi_bridge'
28
29
  autoload :Driver, 'selenium/webdriver/remote/driver'
29
30
  autoload :Response, 'selenium/webdriver/remote/response'
30
31
  autoload :Capabilities, 'selenium/webdriver/remote/capabilities'
@@ -27,7 +27,7 @@ module Selenium
27
27
  #
28
28
 
29
29
  class Guard
30
- attr_reader :guarded, :type, :messages, :reason
30
+ attr_reader :guarded, :type, :messages, :reason, :tracker
31
31
 
32
32
  def initialize(guarded, type, guards = nil)
33
33
  @guarded = guarded
@@ -36,22 +36,21 @@ module Selenium
36
36
  @messages[:unknown] = 'TODO: Investigate why this is failing and file a bug report'
37
37
  @type = type
38
38
 
39
- @reason = @guarded.delete(:reason)
39
+ @reason = @guarded[:reason] || 'No reason given'
40
+ @guarded[:reason] = @reason
40
41
  end
41
42
 
42
43
  def message
43
- details = case @reason
44
+ details = case reason
44
45
  when Integer
45
- "Bug Filed: #{@tracker}/#{@reason}"
46
+ "Bug Filed: #{tracker}/#{reason}"
46
47
  when Symbol
47
- @messages[@reason]
48
- when String
49
- @reason
48
+ messages[reason]
50
49
  else
51
- 'no reason given'
50
+ "Guarded by #{guarded};"
52
51
  end
53
52
 
54
- case @type
53
+ case type
55
54
  when :exclude
56
55
  "Test skipped because it breaks test run; #{details}"
57
56
  when :flaky
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- VERSION = '4.21.1'
22
+ VERSION = '4.23.0'
23
23
  end # WebDriver
24
24
  end # Selenium
@@ -47,10 +47,11 @@ Gem::Specification.new do |s|
47
47
  s.bindir = 'bin'
48
48
  s.require_paths = ['lib']
49
49
 
50
- s.add_runtime_dependency 'base64', ['~> 0.2']
51
- s.add_runtime_dependency 'rexml', ['~> 3.2', '>= 3.2.5']
52
- s.add_runtime_dependency 'rubyzip', ['>= 1.2.2', '< 3.0']
53
- s.add_runtime_dependency 'websocket', ['~> 1.0']
50
+ s.add_dependency 'base64', ['~> 0.2']
51
+ s.add_dependency 'logger', ['~> 1.4']
52
+ s.add_dependency 'rexml', ['~> 3.2', '>= 3.2.5']
53
+ s.add_dependency 'rubyzip', ['>= 1.2.2', '< 3.0']
54
+ s.add_dependency 'websocket', ['~> 1.0']
54
55
 
55
56
  s.add_development_dependency 'git', ['~> 1.19']
56
57
  s.add_development_dependency 'rack', ['~> 2.0']
@@ -58,6 +59,7 @@ Gem::Specification.new do |s|
58
59
  s.add_development_dependency 'rspec', ['~> 3.0']
59
60
  s.add_development_dependency 'rubocop', ['~> 1.60', '>=1.60.2']
60
61
  s.add_development_dependency 'rubocop-performance', ['~> 1.15']
62
+ s.add_development_dependency 'rubocop-rake', ['~> 0.6.0']
61
63
  s.add_development_dependency 'rubocop-rspec', ['~> 2.16']
62
64
  s.add_development_dependency 'webmock', ['~> 3.5']
63
65
  s.add_development_dependency 'webrick', ['~> 1.7']
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.21.1
4
+ version: 4.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Rodionov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-05-16 00:00:00.000000000 Z
13
+ date: 2024-07-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: base64
@@ -26,6 +26,20 @@ dependencies:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: '0.2'
29
+ - !ruby/object:Gem::Dependency
30
+ name: logger
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '1.4'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '1.4'
29
43
  - !ruby/object:Gem::Dependency
30
44
  name: rexml
31
45
  requirement: !ruby/object:Gem::Requirement
@@ -170,6 +184,20 @@ dependencies:
170
184
  - - "~>"
171
185
  - !ruby/object:Gem::Version
172
186
  version: '1.15'
187
+ - !ruby/object:Gem::Dependency
188
+ name: rubocop-rake
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: 0.6.0
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: 0.6.0
173
201
  - !ruby/object:Gem::Dependency
174
202
  name: rubocop-rspec
175
203
  requirement: !ruby/object:Gem::Requirement
@@ -268,9 +296,11 @@ files:
268
296
  - lib/selenium/webdriver/bidi/log/filter_by.rb
269
297
  - lib/selenium/webdriver/bidi/log/generic_log_entry.rb
270
298
  - lib/selenium/webdriver/bidi/log/javascript_log_entry.rb
299
+ - lib/selenium/webdriver/bidi/log_handler.rb
271
300
  - lib/selenium/webdriver/bidi/log_inspector.rb
272
301
  - lib/selenium/webdriver/bidi/navigate_result.rb
273
302
  - lib/selenium/webdriver/bidi/session.rb
303
+ - lib/selenium/webdriver/bidi/struct.rb
274
304
  - lib/selenium/webdriver/chrome.rb
275
305
  - lib/selenium/webdriver/chrome/driver.rb
276
306
  - lib/selenium/webdriver/chrome/features.rb
@@ -298,6 +328,7 @@ files:
298
328
  - lib/selenium/webdriver/common/driver_extensions/has_context.rb
299
329
  - lib/selenium/webdriver/common/driver_extensions/has_debugger.rb
300
330
  - lib/selenium/webdriver/common/driver_extensions/has_devtools.rb
331
+ - lib/selenium/webdriver/common/driver_extensions/has_fedcm_dialog.rb
301
332
  - lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb
302
333
  - lib/selenium/webdriver/common/driver_extensions/has_launching.rb
303
334
  - lib/selenium/webdriver/common/driver_extensions/has_log_events.rb
@@ -313,6 +344,9 @@ files:
313
344
  - lib/selenium/webdriver/common/driver_finder.rb
314
345
  - lib/selenium/webdriver/common/element.rb
315
346
  - lib/selenium/webdriver/common/error.rb
347
+ - lib/selenium/webdriver/common/fedcm.rb
348
+ - lib/selenium/webdriver/common/fedcm/account.rb
349
+ - lib/selenium/webdriver/common/fedcm/dialog.rb
316
350
  - lib/selenium/webdriver/common/file_reaper.rb
317
351
  - lib/selenium/webdriver/common/html5/local_storage.rb
318
352
  - lib/selenium/webdriver/common/html5/session_storage.rb
@@ -347,6 +381,7 @@ files:
347
381
  - lib/selenium/webdriver/common/port_prober.rb
348
382
  - lib/selenium/webdriver/common/profile_helper.rb
349
383
  - lib/selenium/webdriver/common/proxy.rb
384
+ - lib/selenium/webdriver/common/script.rb
350
385
  - lib/selenium/webdriver/common/search_context.rb
351
386
  - lib/selenium/webdriver/common/selenium_manager.rb
352
387
  - lib/selenium/webdriver/common/service.rb
@@ -393,6 +428,7 @@ files:
393
428
  - lib/selenium/webdriver/ie/options.rb
394
429
  - lib/selenium/webdriver/ie/service.rb
395
430
  - lib/selenium/webdriver/remote.rb
431
+ - lib/selenium/webdriver/remote/bidi_bridge.rb
396
432
  - lib/selenium/webdriver/remote/bridge.rb
397
433
  - lib/selenium/webdriver/remote/bridge/commands.rb
398
434
  - lib/selenium/webdriver/remote/bridge/locator_converter.rb