selenium-webdriver 4.0.0.rc3 → 4.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +338 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +1 -1
  5. data/NOTICE +1 -1
  6. data/README.md +2 -2
  7. data/bin/linux/selenium-manager +0 -0
  8. data/bin/macos/selenium-manager +0 -0
  9. data/bin/windows/selenium-manager.exe +0 -0
  10. data/lib/selenium/server.rb +90 -79
  11. data/lib/selenium/webdriver/atoms/findElements.js +5 -6
  12. data/lib/selenium/webdriver/atoms/getAttribute.js +0 -0
  13. data/lib/selenium/webdriver/atoms/isDisplayed.js +0 -0
  14. data/lib/selenium/webdriver/atoms/mutationListener.js +0 -0
  15. data/lib/selenium/webdriver/atoms.rb +2 -3
  16. data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
  17. data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
  18. data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
  19. data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
  20. data/lib/selenium/webdriver/{common/driver_extensions/has_location.rb → bidi/log/filter_by.rb} +14 -11
  21. data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
  22. data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
  23. data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
  24. data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
  25. data/lib/selenium/webdriver/bidi/session.rb +51 -0
  26. data/lib/selenium/webdriver/bidi.rb +56 -0
  27. data/lib/selenium/webdriver/chrome/driver.rb +9 -29
  28. data/lib/selenium/webdriver/chrome/features.rb +6 -68
  29. data/lib/selenium/webdriver/chrome/options.rb +3 -223
  30. data/lib/selenium/webdriver/chrome/profile.rb +3 -83
  31. data/lib/selenium/webdriver/chrome/service.rb +4 -19
  32. data/lib/selenium/webdriver/chrome.rb +0 -16
  33. data/lib/selenium/webdriver/chromium/driver.rb +60 -0
  34. data/lib/selenium/webdriver/chromium/features.rb +103 -0
  35. data/lib/selenium/webdriver/chromium/options.rb +243 -0
  36. data/lib/selenium/webdriver/chromium/profile.rb +113 -0
  37. data/lib/selenium/webdriver/chromium.rb +29 -0
  38. data/lib/selenium/webdriver/common/action_builder.rb +62 -22
  39. data/lib/selenium/webdriver/common/child_process.rb +124 -0
  40. data/lib/selenium/webdriver/common/driver.rb +31 -81
  41. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
  42. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
  43. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
  44. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
  45. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
  46. data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_bidi.rb} +10 -5
  47. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -1
  48. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
  49. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -4
  50. data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
  51. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
  52. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
  53. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -2
  54. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +9 -2
  55. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -69
  56. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
  57. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +1 -3
  58. data/lib/selenium/webdriver/common/driver_finder.rb +45 -0
  59. data/lib/selenium/webdriver/common/element.rb +8 -8
  60. data/lib/selenium/webdriver/common/error.rb +28 -5
  61. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
  62. data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
  63. data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -25
  64. data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
  65. data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -1
  66. data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
  67. data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
  68. data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
  69. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +59 -70
  70. data/lib/selenium/webdriver/common/{driver_extensions/has_network_connection.rb → interactions/pointer_cancel.rb} +19 -11
  71. data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
  72. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
  73. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
  74. data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
  75. data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
  76. data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
  77. data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
  78. data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
  79. data/lib/selenium/webdriver/common/interactions/wheel_input.rb +42 -0
  80. data/lib/selenium/webdriver/common/keys.rb +1 -0
  81. data/lib/selenium/webdriver/common/local_driver.rb +46 -0
  82. data/lib/selenium/webdriver/common/logger.rb +90 -25
  83. data/lib/selenium/webdriver/common/manager.rb +0 -27
  84. data/lib/selenium/webdriver/common/options.rb +14 -20
  85. data/lib/selenium/webdriver/common/platform.rb +5 -51
  86. data/lib/selenium/webdriver/common/port_prober.rb +1 -1
  87. data/lib/selenium/webdriver/common/profile_helper.rb +2 -8
  88. data/lib/selenium/webdriver/common/proxy.rb +2 -2
  89. data/lib/selenium/webdriver/common/search_context.rb +0 -6
  90. data/lib/selenium/webdriver/common/selenium_manager.rb +134 -0
  91. data/lib/selenium/webdriver/common/service.rb +21 -30
  92. data/lib/selenium/webdriver/common/service_manager.rb +8 -15
  93. data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
  94. data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
  95. data/lib/selenium/webdriver/common/socket_poller.rb +31 -20
  96. data/lib/selenium/webdriver/common/takes_screenshot.rb +2 -3
  97. data/lib/selenium/webdriver/common/target_locator.rb +2 -3
  98. data/lib/selenium/webdriver/common/timeouts.rb +2 -2
  99. data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
  100. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
  101. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
  102. data/lib/selenium/webdriver/common/websocket_connection.rb +164 -0
  103. data/lib/selenium/webdriver/common/window.rb +6 -6
  104. data/lib/selenium/webdriver/common/zipper.rb +4 -10
  105. data/lib/selenium/webdriver/common.rb +21 -5
  106. data/lib/selenium/webdriver/devtools/console_event.rb +0 -2
  107. data/lib/selenium/webdriver/devtools/exception_event.rb +0 -2
  108. data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -2
  109. data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
  110. data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
  111. data/lib/selenium/webdriver/devtools/request.rb +1 -3
  112. data/lib/selenium/webdriver/devtools/response.rb +1 -3
  113. data/lib/selenium/webdriver/devtools.rb +17 -103
  114. data/lib/selenium/webdriver/edge/driver.rb +9 -3
  115. data/lib/selenium/webdriver/edge/features.rb +4 -4
  116. data/lib/selenium/webdriver/edge/options.rb +17 -5
  117. data/lib/selenium/webdriver/edge/profile.rb +2 -2
  118. data/lib/selenium/webdriver/edge/service.rb +8 -7
  119. data/lib/selenium/webdriver/edge.rb +0 -2
  120. data/lib/selenium/webdriver/firefox/driver.rb +9 -2
  121. data/lib/selenium/webdriver/firefox/features.rb +6 -6
  122. data/lib/selenium/webdriver/firefox/options.rb +9 -14
  123. data/lib/selenium/webdriver/firefox/profile.rb +8 -12
  124. data/lib/selenium/webdriver/firefox/service.rb +0 -18
  125. data/lib/selenium/webdriver/firefox/util.rb +46 -0
  126. data/lib/selenium/webdriver/firefox.rb +1 -14
  127. data/lib/selenium/webdriver/ie/driver.rb +7 -1
  128. data/lib/selenium/webdriver/ie/options.rb +2 -1
  129. data/lib/selenium/webdriver/ie/service.rb +0 -22
  130. data/lib/selenium/webdriver/ie.rb +0 -14
  131. data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +15 -8
  132. data/lib/selenium/webdriver/remote/bridge.rb +70 -37
  133. data/lib/selenium/webdriver/remote/capabilities.rb +3 -53
  134. data/lib/selenium/webdriver/remote/driver.rb +31 -14
  135. data/lib/selenium/webdriver/remote/http/common.rb +3 -3
  136. data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
  137. data/lib/selenium/webdriver/remote/http/default.rb +8 -14
  138. data/lib/selenium/webdriver/remote/response.rb +2 -3
  139. data/lib/selenium/webdriver/remote/server_error.rb +1 -1
  140. data/lib/selenium/webdriver/remote.rb +5 -5
  141. data/lib/selenium/webdriver/safari/driver.rb +7 -1
  142. data/lib/selenium/webdriver/safari/features.rb +0 -2
  143. data/lib/selenium/webdriver/safari/options.rb +5 -1
  144. data/lib/selenium/webdriver/safari/service.rb +10 -4
  145. data/lib/selenium/webdriver/safari.rb +1 -15
  146. data/lib/selenium/webdriver/support/color.rb +22 -22
  147. data/lib/selenium/webdriver/support/guards/guard.rb +0 -2
  148. data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -3
  149. data/lib/selenium/webdriver/support/guards.rb +1 -1
  150. data/lib/selenium/webdriver/support/relative_locator.rb +0 -1
  151. data/lib/selenium/webdriver/support/select.rb +4 -2
  152. data/lib/selenium/webdriver/version.rb +1 -1
  153. data/lib/selenium/webdriver.rb +7 -5
  154. data/selenium-webdriver.gemspec +15 -13
  155. metadata +79 -65
  156. data/lib/selenium/webdriver/remote/http/persistent.rb +0 -65
  157. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
  158. data/lib/selenium/webdriver/support/cdp_client_generator.rb +0 -108
@@ -0,0 +1,124 @@
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
+ #
23
+ # @api private
24
+ #
25
+
26
+ class ChildProcess
27
+ TimeoutError = Class.new(StandardError)
28
+
29
+ SIGTERM = 'TERM'
30
+ SIGKILL = 'KILL'
31
+
32
+ POLL_INTERVAL = 0.1
33
+
34
+ attr_accessor :detach
35
+ attr_writer :io
36
+
37
+ def self.build(*command)
38
+ new(*command)
39
+ end
40
+
41
+ def initialize(*command)
42
+ @command = command
43
+ @detach = false
44
+ @pid = nil
45
+ @status = nil
46
+ end
47
+
48
+ def io
49
+ @io ||= Platform.null_device
50
+ end
51
+
52
+ def start
53
+ options = {%i[out err] => io}
54
+ options[:pgroup] = true unless Platform.windows? # NOTE: this is a bug only in Windows 7
55
+
56
+ WebDriver.logger.debug("Starting process: #{@command} with #{options}", id: :process)
57
+ @pid = Process.spawn(*@command, options)
58
+ WebDriver.logger.debug(" -> pid: #{@pid}", id: :process)
59
+
60
+ Process.detach(@pid) if detach
61
+ end
62
+
63
+ def stop(timeout = 3)
64
+ return unless @pid
65
+ return if exited?
66
+
67
+ WebDriver.logger.debug("Sending TERM to process: #{@pid}", id: :process)
68
+ terminate(@pid)
69
+ poll_for_exit(timeout)
70
+
71
+ WebDriver.logger.debug(" -> stopped #{@pid}", id: :process)
72
+ rescue TimeoutError, Errno::EINVAL
73
+ WebDriver.logger.debug(" -> sending KILL to process: #{@pid}", id: :process)
74
+ kill(@pid)
75
+ wait
76
+ WebDriver.logger.debug(" -> killed #{@pid}", id: :process)
77
+ end
78
+
79
+ def alive?
80
+ @pid && !exited?
81
+ end
82
+
83
+ def exited?
84
+ return false unless @pid
85
+
86
+ WebDriver.logger.debug("Checking if #{@pid} is exited:", id: :process)
87
+ _, @status = Process.waitpid2(@pid, Process::WNOHANG | Process::WUNTRACED) if @status.nil?
88
+ return false if @status.nil?
89
+
90
+ exit_code = @status.exitstatus || @status.termsig
91
+ WebDriver.logger.debug(" -> exit code is #{exit_code.inspect}", id: :process)
92
+
93
+ !!exit_code
94
+ end
95
+
96
+ def poll_for_exit(timeout)
97
+ WebDriver.logger.debug("Polling #{timeout} seconds for exit of #{@pid}", id: :process)
98
+
99
+ end_time = Time.now + timeout
100
+ sleep POLL_INTERVAL until exited? || Time.now > end_time
101
+
102
+ raise TimeoutError, " -> #{@pid} still alive after #{timeout} seconds" unless exited?
103
+ end
104
+
105
+ def wait
106
+ return if exited?
107
+
108
+ _, @status = Process.waitpid2(@pid)
109
+ end
110
+
111
+ private
112
+
113
+ def terminate(pid)
114
+ Process.kill(SIGTERM, pid)
115
+ end
116
+
117
+ def kill(pid)
118
+ Process.kill(SIGKILL, pid)
119
+ rescue Errno::ECHILD, Errno::ESRCH
120
+ # already dead
121
+ end
122
+ end # ChildProcess
123
+ end # WebDriver
124
+ end # Selenium
@@ -51,7 +51,7 @@ module Selenium
51
51
  Safari::Driver.new(**opts)
52
52
  when :firefox, :ff
53
53
  Firefox::Driver.new(**opts)
54
- when :edge
54
+ when :edge, :microsoftedge, :msedge
55
55
  Edge::Driver.new(**opts)
56
56
  when :remote
57
57
  Remote::Driver.new(**opts)
@@ -69,8 +69,8 @@ module Selenium
69
69
  #
70
70
 
71
71
  def initialize(bridge: nil, listener: nil, **opts)
72
- @service = nil
73
72
  @devtools = nil
73
+ @bidi = nil
74
74
  bridge ||= create_bridge(**opts)
75
75
  add_extensions(bridge.browser)
76
76
  @bridge = listener ? Support::EventFiringBridge.new(bridge, listener) : bridge
@@ -123,16 +123,8 @@ module Selenium
123
123
  # @see ActionBuilder
124
124
  #
125
125
 
126
- def action
127
- bridge.action
128
- end
129
-
130
- def mouse
131
- bridge.mouse
132
- end
133
-
134
- def keyboard
135
- bridge.keyboard
126
+ def action(**opts)
127
+ bridge.action(**opts)
136
128
  end
137
129
 
138
130
  #
@@ -180,8 +172,9 @@ module Selenium
180
172
  def quit
181
173
  bridge.quit
182
174
  ensure
183
- @service&.stop
175
+ @service_manager&.stop
184
176
  @devtools&.close
177
+ @bidi&.close
185
178
  end
186
179
 
187
180
  #
@@ -189,7 +182,10 @@ module Selenium
189
182
  #
190
183
 
191
184
  def close
192
- bridge.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? }
193
189
  end
194
190
 
195
191
  #
@@ -248,25 +244,34 @@ module Selenium
248
244
  bridge.execute_async_script(script, *args)
249
245
  end
250
246
 
247
+ #
248
+ # @return [VirtualAuthenticator]
249
+ # @see VirtualAuthenticator
250
+ #
251
+
252
+ def add_virtual_authenticator(options)
253
+ bridge.add_virtual_authenticator(options)
254
+ end
255
+
251
256
  #-------------------------------- sugar --------------------------------
252
257
 
253
258
  #
254
259
  # driver.first(id: 'foo')
255
260
  #
256
261
 
257
- alias_method :first, :find_element
262
+ alias first find_element
258
263
 
259
264
  #
260
265
  # driver.all(class: 'bar') #=> [#<WebDriver::Element:0x1011c3b88, ...]
261
266
  #
262
267
 
263
- alias_method :all, :find_elements
268
+ alias all find_elements
264
269
 
265
270
  #
266
271
  # driver.script('function() { ... };')
267
272
  #
268
273
 
269
- alias_method :script, :execute_script
274
+ alias script execute_script
270
275
 
271
276
  # Get the first element matching the given selector. If given a
272
277
  # String or Symbol, it will be used as the id of the element.
@@ -307,72 +312,15 @@ module Selenium
307
312
 
308
313
  attr_reader :bridge
309
314
 
310
- def create_bridge(**opts)
311
- opts[:url] ||= service_url(opts)
312
- caps = opts.delete(:capabilities)
313
- # NOTE: This is deprecated
314
- cap_array = caps.is_a?(Hash) ? [caps] : Array(caps)
315
-
316
- desired_capabilities = opts.delete(:desired_capabilities)
317
- if desired_capabilities
318
- WebDriver.logger.deprecate(':desired_capabilities as a parameter for driver initialization',
319
- ':capabilities with an Array value of capabilities/options if necessary',
320
- id: :desired_capabilities)
321
- desired_capabilities = Remote::Capabilities.new(desired_capabilities) if desired_capabilities.is_a?(Hash)
322
- cap_array << desired_capabilities
323
- end
324
-
325
- options = opts.delete(:options)
326
- if options
327
- WebDriver.logger.deprecate(':options as a parameter for driver initialization',
328
- ':capabilities with an Array of value capabilities/options if necessary',
329
- id: :browser_options)
330
- cap_array << options
315
+ def create_bridge(caps:, url:, http_client: nil)
316
+ Remote::Bridge.new(http_client: http_client, url: url).tap do |bridge|
317
+ bridge.create_session(caps)
331
318
  end
332
-
333
- capabilities = generate_capabilities(cap_array)
334
-
335
- bridge_opts = {http_client: opts.delete(:http_client), url: opts.delete(:url)}
336
- raise ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
337
-
338
- bridge = Remote::Bridge.new(**bridge_opts)
339
-
340
- bridge.create_session(capabilities)
341
- bridge
342
319
  end
343
320
 
344
- def generate_capabilities(cap_array)
345
- cap_array.map { |cap|
346
- if cap.is_a? Symbol
347
- cap = Remote::Capabilities.send(cap)
348
- elsif cap.is_a? Hash
349
- new_message = 'Capabilities instance initialized with the Hash, or build values with Options class'
350
- WebDriver.logger.deprecate("passing a Hash value to :capabilities",
351
- new_message,
352
- id: :capabilities_hash)
353
- cap = Remote::Capabilities.new(cap)
354
- elsif !cap.respond_to? :as_json
355
- msg = ":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not"
356
- raise ArgumentError, msg
357
- end
358
- cap&.as_json
359
- }.inject(:merge) || Remote::Capabilities.send(browser || :new)
360
- end
361
-
362
- def service_url(opts)
363
- service_config = opts.delete(:service)
364
- %i[driver_opts driver_path port].each do |key|
365
- next unless opts.key? key
366
-
367
- WebDriver.logger.deprecate(":#{key}", ':service with an instance of Selenium::WebDriver::Service',
368
- id: "service_#{key}".to_sym)
369
- end
370
- service_config ||= Service.send(browser,
371
- args: opts.delete(:driver_opts),
372
- path: opts.delete(:driver_path),
373
- port: opts.delete(:port))
374
- @service = service_config.launch
375
- @service.uri
321
+ def service_url(service)
322
+ @service_manager = service.launch
323
+ @service_manager.uri
376
324
  end
377
325
 
378
326
  def screenshot
@@ -382,11 +330,13 @@ module Selenium
382
330
  def add_extensions(browser)
383
331
  extensions = case browser
384
332
  when :chrome, :msedge
385
- Chrome::Driver::EXTENSIONS
333
+ Chromium::Driver::EXTENSIONS
386
334
  when :firefox
387
335
  Firefox::Driver::EXTENSIONS
388
336
  when :safari, :safari_technology_preview
389
337
  Safari::Driver::EXTENSIONS
338
+ when :ie, :internet_explorer
339
+ IE::Driver::EXTENSIONS
390
340
  else
391
341
  []
392
342
  end
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module DownloadsFiles
24
-
25
24
  #
26
25
  # Sets download path for Chromium.
27
26
  #
@@ -38,7 +37,6 @@ module Selenium
38
37
  }
39
38
  @bridge.send_command(params)
40
39
  end
41
-
42
40
  end # DownloadsFiles
43
41
  end # DriverExtensions
44
42
  end # WebDriver
@@ -36,7 +36,6 @@ module Selenium
36
36
  def full_screenshot
37
37
  @bridge.full_screenshot
38
38
  end
39
-
40
39
  end # FullPageScreenshot
41
40
  end # DriverExtensions
42
41
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasAddons
24
-
25
24
  #
26
25
  # Installs addon.
27
26
  #
@@ -43,7 +42,6 @@ module Selenium
43
42
  def uninstall_addon(id)
44
43
  @bridge.uninstall_addon(id)
45
44
  end
46
-
47
45
  end # HasAddons
48
46
  end # DriverExtensions
49
47
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasApplePermissions
24
-
25
24
  #
26
25
  # Returns permissions.
27
26
  #
@@ -44,7 +43,6 @@ module Selenium
44
43
  def permissions=(permissions)
45
44
  @bridge.permissions = permissions
46
45
  end
47
-
48
46
  end # HasPermissions
49
47
  end # DriverExtensions
50
48
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasAuthentication
24
-
25
24
  #
26
25
  # Registers basic authentication handler which is automatically
27
26
  # used whenever browser gets an authentication required response.
@@ -82,7 +81,6 @@ module Selenium
82
81
  )
83
82
  end
84
83
  end
85
-
86
84
  end # HasAuthentication
87
85
  end # DriverExtensions
88
86
  end # WebDriver
@@ -20,12 +20,17 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
- module HasRemoteStatus
24
- def remote_status
25
- WebDriver.logger.deprecate('#remote_status', '#status')
26
- @bridge.status
23
+ module HasBiDi
24
+ #
25
+ # Retrieves WebDriver BiDi connection.
26
+ #
27
+ # @return [BiDi]
28
+ #
29
+
30
+ def bidi
31
+ @bidi ||= Selenium::WebDriver::BiDi.new(url: capabilities[:web_socket_url])
27
32
  end
28
- end # HasRemoteStatus
33
+ end # HasBiDi
29
34
  end # DriverExtensions
30
35
  end # WebDriver
31
36
  end # Selenium
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasCasting
24
-
25
24
  #
26
25
  # What devices ("sinks") are available to be cast to.
27
26
  #
@@ -52,6 +51,16 @@ module Selenium
52
51
  @bridge.start_cast_tab_mirroring(name)
53
52
  end
54
53
 
54
+ #
55
+ # Starts a tab mirroring session on a specific receiver target.
56
+ #
57
+ # @param [String] name the sink to use as the target
58
+ #
59
+
60
+ def start_cast_desktop_mirroring(name)
61
+ @bridge.start_cast_desktop_mirroring(name)
62
+ end
63
+
55
64
  #
56
65
  # Gets error messages when there is any issue in a Cast session.
57
66
  #
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasCDP
24
-
25
24
  #
26
25
  # Returns network conditions.
27
26
  #
@@ -31,7 +30,6 @@ module Selenium
31
30
  def execute_cdp(cmd, **params)
32
31
  @bridge.send_command(cmd: cmd, params: params)
33
32
  end
34
-
35
33
  end # HasCDP
36
34
  end # DriverExtensions
37
35
  end # WebDriver
@@ -21,14 +21,12 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasContext
24
-
25
24
  #
26
25
  # Sets the context that Selenium commands are running in using
27
26
  # a `with` statement. The state of the context on the server is
28
27
  # saved before entering the block, and restored upon exiting it.
29
28
  #
30
- # @param [String] name which permission to set
31
- # @param [String] value what to set the permission to
29
+ # @param [String] value which context gets set (either 'chrome' or 'content')
32
30
  #
33
31
 
34
32
  def context=(value)
@@ -38,7 +36,6 @@ module Selenium
38
36
  def context
39
37
  @bridge.context
40
38
  end
41
-
42
39
  end # HasContext
43
40
  end # DriverExtensions
44
41
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasDebugger
24
-
25
24
  #
26
25
  # Attaches debugger to session.
27
26
  #
@@ -35,7 +34,6 @@ module Selenium
35
34
  def attach_debugger
36
35
  @bridge.attach_debugger
37
36
  end
38
-
39
37
  end # HasDebugger
40
38
  end # DriverExtensions
41
39
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasDevTools
24
-
25
24
  #
26
25
  # Retrieves connection to DevTools.
27
26
  #
@@ -36,7 +35,6 @@ module Selenium
36
35
  Selenium::WebDriver::DevTools.new(url: devtools_url)
37
36
  end
38
37
  end
39
-
40
38
  end # HasDevTools
41
39
  end # DriverExtensions
42
40
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasLaunching
24
-
25
24
  #
26
25
  # Launches Chromium app specified by id.
27
26
  #
@@ -31,7 +30,6 @@ module Selenium
31
30
  def launch_app(id)
32
31
  @bridge.launch_app(id)
33
32
  end
34
-
35
33
  end # HasLaunching
36
34
  end # DriverExtensions
37
35
  end # WebDriver
@@ -114,7 +114,7 @@ module Selenium
114
114
  execute_script(mutation_listener)
115
115
  devtools.page.add_script_to_evaluate_on_new_document(source: mutation_listener)
116
116
 
117
- devtools.runtime.on(:binding_called, &method(:log_mutation_event))
117
+ devtools.runtime.on(:binding_called) { |event| log_mutation_event(event) }
118
118
  end
119
119
 
120
120
  def log_mutation_event(params)
@@ -137,7 +137,6 @@ module Selenium
137
137
  def mutation_listener
138
138
  @mutation_listener ||= read_atom(:mutationListener)
139
139
  end
140
-
141
140
  end # HasLogEvents
142
141
  end # DriverExtensions
143
142
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasNetworkConditions
24
-
25
24
  #
26
25
  # Returns network conditions.
27
26
  #
@@ -38,10 +37,19 @@ module Selenium
38
37
  # @param [Hash] conditions
39
38
  # @option conditions [Integer] :latency
40
39
  # @option conditions [Integer] :throughput
40
+ # @option conditions [Integer] :upload_throughput
41
+ # @option conditions [Integer] :download_throughput
41
42
  # @option conditions [Boolean] :offline
42
43
  #
43
44
 
44
45
  def network_conditions=(conditions)
46
+ conditions[:latency] ||= 0
47
+ unless conditions.key?(:throughput)
48
+ conditions[:download_throughput] ||= -1
49
+ conditions[:upload_throughput] ||= -1
50
+ end
51
+ conditions[:offline] = false unless conditions.key?(:offline)
52
+
45
53
  @bridge.network_conditions = conditions
46
54
  end
47
55
 
@@ -52,7 +60,6 @@ module Selenium
52
60
  def delete_network_conditions
53
61
  @bridge.delete_network_conditions
54
62
  end
55
-
56
63
  end # HasNetworkConditions
57
64
  end # DriverExtensions
58
65
  end # WebDriver
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasNetworkInterception
24
-
25
24
  #
26
25
  # Intercepts requests coming from browser allowing
27
26
  # to either pass them through like proxy or provide
@@ -61,74 +60,8 @@ module Selenium
61
60
  #
62
61
 
63
62
  def intercept(&block)
64
- devtools.network.set_cache_disabled(cache_disabled: true)
65
- devtools.fetch.on(:request_paused) do |params|
66
- id = params['requestId']
67
- if params.key?('responseStatusCode') || params.key?('responseErrorReason')
68
- intercept_response(id, params, &pending_response_requests.delete(id))
69
- else
70
- intercept_request(id, params, &block)
71
- end
72
- end
73
- devtools.fetch.enable(patterns: [{requestStage: 'Request'}, {requestStage: 'Response'}])
74
- end
75
-
76
- private
77
-
78
- def pending_response_requests
79
- @pending_response_requests ||= {}
80
- end
81
-
82
- def intercept_request(id, params, &block)
83
- original = DevTools::Request.from(id, params)
84
- mutable = DevTools::Request.from(id, params)
85
-
86
- block.call(mutable) do |&continue| # rubocop:disable Performance/RedundantBlockCall
87
- pending_response_requests[id] = continue
88
-
89
- if original == mutable
90
- devtools.fetch.continue_request(request_id: id)
91
- else
92
- devtools.fetch.continue_request(
93
- request_id: id,
94
- url: mutable.url,
95
- method: mutable.method,
96
- post_data: mutable.post_data,
97
- headers: mutable.headers.map do |k, v|
98
- {name: k, value: v}
99
- end
100
- )
101
- end
102
- end
103
- end
104
-
105
- def intercept_response(id, params)
106
- return devtools.fetch.continue_request(request_id: id) unless block_given?
107
-
108
- body = fetch_response_body(id)
109
- original = DevTools::Response.from(id, body, params)
110
- mutable = DevTools::Response.from(id, body, params)
111
- yield mutable
112
-
113
- if original == mutable
114
- devtools.fetch.continue_request(request_id: id)
115
- else
116
- devtools.fetch.fulfill_request(
117
- request_id: id,
118
- body: (Base64.strict_encode64(mutable.body) if mutable.body),
119
- response_code: mutable.code,
120
- response_headers: mutable.headers.map do |k, v|
121
- {name: k, value: v}
122
- end
123
- )
124
- end
125
- end
126
-
127
- def fetch_response_body(id)
128
- devtools.fetch.get_response_body(request_id: id).dig('result', 'body')
129
- rescue Error::WebDriverError
130
- # CDP fails to get body on certain responses (301) and raises:
131
- # Can only get response body on requests captured after headers received.
63
+ @interceptor ||= DevTools::NetworkInterceptor.new(devtools)
64
+ @interceptor.intercept(&block)
132
65
  end
133
66
  end # HasNetworkInterception
134
67
  end # DriverExtensions
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasPermissions
24
-
25
24
  #
26
25
  # Set one permission.
27
26
  #
@@ -44,7 +43,6 @@ module Selenium
44
43
  @bridge.set_permission(key, value)
45
44
  end
46
45
  end
47
-
48
46
  end # HasPermissions
49
47
  end # DriverExtensions
50
48
  end # WebDriver