selenium-webdriver 4.5.0 → 4.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +219 -1
  3. data/Gemfile +3 -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 +8 -22
  11. data/lib/selenium/webdriver/atoms/findElements.js +5 -5
  12. data/lib/selenium/webdriver/atoms/getAttribute.js +0 -0
  13. data/lib/selenium/webdriver/atoms/isDisplayed.js +2 -1
  14. data/lib/selenium/webdriver/atoms/mutationListener.js +0 -0
  15. data/lib/selenium/webdriver/atoms.rb +5 -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 +13 -0
  26. data/lib/selenium/webdriver/bidi.rb +3 -2
  27. data/lib/selenium/webdriver/chrome/driver.rb +9 -30
  28. data/lib/selenium/webdriver/chrome/features.rb +8 -71
  29. data/lib/selenium/webdriver/chrome/options.rb +3 -237
  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 -2
  33. data/lib/selenium/webdriver/chromium/driver.rb +60 -0
  34. data/lib/selenium/webdriver/chromium/features.rb +99 -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 +11 -58
  39. data/lib/selenium/webdriver/common/child_process.rb +124 -0
  40. data/lib/selenium/webdriver/common/driver.rb +19 -36
  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_bidi.rb +0 -2
  47. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +0 -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 +0 -2
  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_file_downloads.rb +65 -0
  53. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
  54. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +0 -1
  55. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
  56. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +0 -2
  57. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
  58. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +0 -2
  59. data/lib/selenium/webdriver/common/driver_finder.rb +45 -0
  60. data/lib/selenium/webdriver/common/element.rb +6 -6
  61. data/lib/selenium/webdriver/common/error.rb +27 -4
  62. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
  63. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +3 -3
  64. data/lib/selenium/webdriver/common/interactions/pointer_move.rb +2 -2
  65. data/lib/selenium/webdriver/common/interactions/scroll.rb +7 -5
  66. data/lib/selenium/webdriver/common/local_driver.rb +46 -0
  67. data/lib/selenium/webdriver/common/logger.rb +91 -26
  68. data/lib/selenium/webdriver/common/options.rb +15 -8
  69. data/lib/selenium/webdriver/common/platform.rb +8 -49
  70. data/lib/selenium/webdriver/common/port_prober.rb +1 -1
  71. data/lib/selenium/webdriver/common/profile_helper.rb +1 -1
  72. data/lib/selenium/webdriver/common/proxy.rb +2 -2
  73. data/lib/selenium/webdriver/common/selenium_manager.rb +140 -0
  74. data/lib/selenium/webdriver/common/service.rb +21 -30
  75. data/lib/selenium/webdriver/common/service_manager.rb +6 -12
  76. data/lib/selenium/webdriver/common/shadow_root.rb +1 -2
  77. data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
  78. data/lib/selenium/webdriver/common/socket_poller.rb +1 -1
  79. data/lib/selenium/webdriver/common/takes_screenshot.rb +2 -3
  80. data/lib/selenium/webdriver/common/target_locator.rb +2 -3
  81. data/lib/selenium/webdriver/common/timeouts.rb +2 -2
  82. data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +8 -6
  83. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +0 -1
  84. data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +16 -16
  85. data/lib/selenium/webdriver/common/websocket_connection.rb +12 -4
  86. data/lib/selenium/webdriver/common.rb +5 -2
  87. data/lib/selenium/webdriver/devtools/console_event.rb +0 -2
  88. data/lib/selenium/webdriver/devtools/exception_event.rb +0 -2
  89. data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -2
  90. data/lib/selenium/webdriver/devtools/network_interceptor.rb +4 -7
  91. data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
  92. data/lib/selenium/webdriver/devtools/request.rb +0 -2
  93. data/lib/selenium/webdriver/devtools/response.rb +0 -2
  94. data/lib/selenium/webdriver/devtools.rb +11 -2
  95. data/lib/selenium/webdriver/edge/driver.rb +9 -3
  96. data/lib/selenium/webdriver/edge/features.rb +7 -4
  97. data/lib/selenium/webdriver/edge/options.rb +17 -5
  98. data/lib/selenium/webdriver/edge/profile.rb +2 -2
  99. data/lib/selenium/webdriver/edge/service.rb +8 -7
  100. data/lib/selenium/webdriver/edge.rb +0 -2
  101. data/lib/selenium/webdriver/firefox/driver.rb +8 -2
  102. data/lib/selenium/webdriver/firefox/features.rb +5 -2
  103. data/lib/selenium/webdriver/firefox/options.rb +2 -14
  104. data/lib/selenium/webdriver/firefox/profile.rb +10 -8
  105. data/lib/selenium/webdriver/firefox/service.rb +0 -18
  106. data/lib/selenium/webdriver/ie/driver.rb +7 -1
  107. data/lib/selenium/webdriver/{common/driver_extensions/has_network_connection.rb → ie/features.rb} +8 -11
  108. data/lib/selenium/webdriver/ie/options.rb +4 -3
  109. data/lib/selenium/webdriver/ie/service.rb +0 -22
  110. data/lib/selenium/webdriver/ie.rb +4 -3
  111. data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +0 -8
  112. data/lib/selenium/webdriver/remote/bridge.rb +13 -37
  113. data/lib/selenium/webdriver/remote/capabilities.rb +3 -53
  114. data/lib/selenium/webdriver/remote/driver.rb +35 -13
  115. data/lib/selenium/webdriver/remote/features.rb +75 -0
  116. data/lib/selenium/webdriver/remote/http/common.rb +3 -3
  117. data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
  118. data/lib/selenium/webdriver/remote/http/default.rb +2 -2
  119. data/lib/selenium/webdriver/remote/response.rb +0 -1
  120. data/lib/selenium/webdriver/remote/server_error.rb +1 -1
  121. data/lib/selenium/webdriver/remote.rb +1 -1
  122. data/lib/selenium/webdriver/safari/driver.rb +7 -1
  123. data/lib/selenium/webdriver/safari/features.rb +5 -3
  124. data/lib/selenium/webdriver/safari/options.rb +5 -1
  125. data/lib/selenium/webdriver/safari/service.rb +10 -4
  126. data/lib/selenium/webdriver/safari.rb +1 -1
  127. data/lib/selenium/webdriver/support/color.rb +17 -17
  128. data/lib/selenium/webdriver/support/event_firing_bridge.rb +2 -2
  129. data/lib/selenium/webdriver/support/guards/guard.rb +6 -5
  130. data/lib/selenium/webdriver/support/guards/guard_condition.rb +0 -2
  131. data/lib/selenium/webdriver/support/guards.rb +1 -1
  132. data/lib/selenium/webdriver/support/relative_locator.rb +0 -1
  133. data/lib/selenium/webdriver/support/select.rb +2 -5
  134. data/lib/selenium/webdriver/version.rb +1 -1
  135. data/lib/selenium/webdriver.rb +5 -4
  136. data/selenium-webdriver.gemspec +10 -11
  137. metadata +43 -84
  138. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
  139. data/lib/selenium/webdriver/support/cdp_client_generator.rb +0 -108
@@ -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
@@ -127,14 +127,6 @@ module Selenium
127
127
  bridge.action(**opts)
128
128
  end
129
129
 
130
- def mouse
131
- bridge.mouse
132
- end
133
-
134
- def keyboard
135
- bridge.keyboard
136
- end
137
-
138
130
  #
139
131
  # Opens the specified URL in the browser.
140
132
  #
@@ -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
  #
@@ -263,19 +259,19 @@ module Selenium
263
259
  # driver.first(id: 'foo')
264
260
  #
265
261
 
266
- alias_method :first, :find_element
262
+ alias first find_element
267
263
 
268
264
  #
269
265
  # driver.all(class: 'bar') #=> [#<WebDriver::Element:0x1011c3b88, ...]
270
266
  #
271
267
 
272
- alias_method :all, :find_elements
268
+ alias all find_elements
273
269
 
274
270
  #
275
271
  # driver.script('function() { ... };')
276
272
  #
277
273
 
278
- alias_method :script, :execute_script
274
+ alias script execute_script
279
275
 
280
276
  # Get the first element matching the given selector. If given a
281
277
  # String or Symbol, it will be used as the id of the element.
@@ -316,30 +312,15 @@ module Selenium
316
312
 
317
313
  attr_reader :bridge
318
314
 
319
- def create_bridge(capabilities: nil, options: nil, url: nil, service: nil, http_client: nil)
320
- Remote::Bridge.new(http_client: http_client,
321
- url: url || service_url(service)).tap do |bridge|
322
- generated_caps = options ? options.as_json : generate_capabilities(capabilities)
323
- bridge.create_session(generated_caps)
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)
324
318
  end
325
319
  end
326
320
 
327
- def generate_capabilities(capabilities)
328
- Array(capabilities).map { |cap|
329
- if cap.is_a? Symbol
330
- cap = Remote::Capabilities.send(cap)
331
- elsif !cap.respond_to? :as_json
332
- msg = ":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not"
333
- raise ArgumentError, msg
334
- end
335
- cap.as_json
336
- }.inject(:merge) || Remote::Capabilities.send(browser || :new)
337
- end
338
-
339
321
  def service_url(service)
340
- service ||= Service.send(browser)
341
- @service = service.launch
342
- @service.uri
322
+ @service_manager = service.launch
323
+ @service_manager.uri
343
324
  end
344
325
 
345
326
  def screenshot
@@ -349,11 +330,13 @@ module Selenium
349
330
  def add_extensions(browser)
350
331
  extensions = case browser
351
332
  when :chrome, :msedge
352
- Chrome::Driver::EXTENSIONS
333
+ Chromium::Driver::EXTENSIONS
353
334
  when :firefox
354
335
  Firefox::Driver::EXTENSIONS
355
336
  when :safari, :safari_technology_preview
356
337
  Safari::Driver::EXTENSIONS
338
+ when :ie, :internet_explorer
339
+ IE::Driver::EXTENSIONS
357
340
  else
358
341
  []
359
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
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasBiDi
24
-
25
24
  #
26
25
  # Retrieves WebDriver BiDi connection.
27
26
  #
@@ -31,7 +30,6 @@ module Selenium
31
30
  def bidi
32
31
  @bidi ||= Selenium::WebDriver::BiDi.new(url: capabilities[:web_socket_url])
33
32
  end
34
-
35
33
  end # HasBiDi
36
34
  end # DriverExtensions
37
35
  end # WebDriver
@@ -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
  #
@@ -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,7 +21,6 @@ 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
@@ -37,7 +36,6 @@ module Selenium
37
36
  def context
38
37
  @bridge.context
39
38
  end
40
-
41
39
  end # HasContext
42
40
  end # DriverExtensions
43
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
@@ -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
+ module Selenium
21
+ module WebDriver
22
+ module DriverExtensions
23
+ module HasFileDownloads
24
+ def downloadable_files
25
+ verify_enabled
26
+
27
+ @bridge.downloadable_files['names']
28
+ end
29
+
30
+ def download_file(file_name, target_directory)
31
+ verify_enabled
32
+
33
+ response = @bridge.download_file(file_name)
34
+ contents = response['contents']
35
+
36
+ File.open("#{file_name}.zip", 'wb') { |f| f << Base64.decode64(contents) }
37
+ target_directory += '/' unless target_directory.end_with?('/')
38
+ FileUtils.mkdir_p(target_directory)
39
+
40
+ begin
41
+ Zip::File.open("#{file_name}.zip") do |zip|
42
+ zip.each { |entry| zip.extract(entry, "#{target_directory}#{file_name}") }
43
+ end
44
+ ensure
45
+ FileUtils.rm_f("#{file_name}.zip")
46
+ end
47
+ end
48
+
49
+ def delete_downloadable_files
50
+ verify_enabled
51
+
52
+ @bridge.delete_downloadable_files
53
+ end
54
+
55
+ private
56
+
57
+ def verify_enabled
58
+ return if capabilities['se:downloadsEnabled']
59
+
60
+ raise Error::WebDriverError, 'You must enable downloads in order to work with downloadable files.'
61
+ end
62
+ end # HasFileDownloads
63
+ end # DriverExtensions
64
+ end # WebDriver
65
+ end # Selenium
@@ -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
@@ -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
  #
@@ -61,7 +60,6 @@ module Selenium
61
60
  def delete_network_conditions
62
61
  @bridge.delete_network_conditions
63
62
  end
64
-
65
63
  end # HasNetworkConditions
66
64
  end # DriverExtensions
67
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
@@ -64,7 +63,6 @@ module Selenium
64
63
  @interceptor ||= DevTools::NetworkInterceptor.new(devtools)
65
64
  @interceptor.intercept(&block)
66
65
  end
67
-
68
66
  end # HasNetworkInterception
69
67
  end # DriverExtensions
70
68
  end # WebDriver
@@ -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
@@ -21,7 +21,6 @@ module Selenium
21
21
  module WebDriver
22
22
  module DriverExtensions
23
23
  module HasPinnedScripts
24
-
25
24
  #
26
25
  # Returns the list of all pinned scripts.
27
26
  #
@@ -70,7 +69,6 @@ module Selenium
70
69
  devtools.page.remove_script_to_evaluate_on_new_document(identifier: script.devtools_identifier)
71
70
  pinned_scripts.delete(script)
72
71
  end
73
-
74
72
  end # HasPinnedScripts
75
73
  end # DriverExtensions
76
74
  end # WebDriver
@@ -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 DriverFinder
23
+ def self.path(options, klass)
24
+ path = klass.driver_path
25
+ path = path.call if path.is_a?(Proc)
26
+
27
+ path ||= begin
28
+ SeleniumManager.driver_path(options) unless options.is_a?(Remote::Capabilities)
29
+ rescue StandardError => e
30
+ raise Error::NoSuchDriverError, "Unable to obtain #{klass::EXECUTABLE} using Selenium Manager; #{e.message}"
31
+ end
32
+
33
+ begin
34
+ Platform.assert_executable(path)
35
+ rescue TypeError
36
+ raise Error::NoSuchDriverError, "Unable to locate or obtain #{klass::EXECUTABLE}"
37
+ rescue Error::WebDriverError => e
38
+ raise Error::NoSuchDriverError, "#{klass::EXECUTABLE} located, but: #{e.message}"
39
+ end
40
+
41
+ path
42
+ end
43
+ end
44
+ end
45
+ end
@@ -43,7 +43,7 @@ module Selenium
43
43
  def ==(other)
44
44
  other.is_a?(self.class) && ref == other.ref
45
45
  end
46
- alias_method :eql?, :==
46
+ alias eql? ==
47
47
 
48
48
  def hash
49
49
  [@id, @bridge].hash
@@ -207,7 +207,7 @@ module Selenium
207
207
  def send_keys(*args)
208
208
  bridge.send_keys_to_element @id, Keys.encode(args)
209
209
  end
210
- alias_method :send_key, :send_keys
210
+ alias send_key send_keys
211
211
 
212
212
  #
213
213
  # If this element is a text entry element, this will clear the value. Has no effect on other
@@ -275,7 +275,7 @@ module Selenium
275
275
  def css_value(prop)
276
276
  bridge.element_value_of_css_property @id, prop
277
277
  end
278
- alias_method :style, :css_value
278
+ alias style css_value
279
279
 
280
280
  #
281
281
  # Get the location of this element.
@@ -333,18 +333,18 @@ module Selenium
333
333
  # element.first(id: 'foo')
334
334
  #
335
335
 
336
- alias_method :first, :find_element
336
+ alias first find_element
337
337
 
338
338
  #
339
339
  # element.all(class: 'bar')
340
340
  #
341
341
 
342
- alias_method :all, :find_elements
342
+ alias all find_elements
343
343
 
344
344
  #
345
345
  # element['class'] or element[:class] #=> "someclass"
346
346
  #
347
- alias_method :[], :attribute
347
+ alias [] attribute
348
348
 
349
349
  #
350
350
  # @api private
@@ -20,7 +20,6 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Error
23
-
24
23
  #
25
24
  # Returns exception from its string representation.
26
25
  # @param [String, nil] error
@@ -35,13 +34,20 @@ module Selenium
35
34
  WebDriverError
36
35
  end
37
36
 
37
+ SUPPORT_MSG = 'For documentation on this error, please visit:'
38
+ ERROR_URL = 'https://www.selenium.dev/documentation/webdriver/troubleshooting/errors'
39
+
38
40
  class WebDriverError < StandardError; end
39
41
 
40
42
  #
41
43
  # An element could not be located on the page using the given search parameters.
42
44
  #
43
45
 
44
- class NoSuchElementError < WebDriverError; end
46
+ class NoSuchElementError < WebDriverError
47
+ def initialize(msg = '')
48
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#no-such-element-exception")
49
+ end
50
+ end
45
51
 
46
52
  #
47
53
  # A command to switch to a frame could not be satisfied because the frame could not be found.
@@ -59,7 +65,11 @@ module Selenium
59
65
  # A command failed because the referenced element is no longer attached to the DOM.
60
66
  #
61
67
 
62
- class StaleElementReferenceError < WebDriverError; end
68
+ class StaleElementReferenceError < WebDriverError
69
+ def initialize(msg = '')
70
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#stale-element-reference-exception")
71
+ end
72
+ end
63
73
 
64
74
  #
65
75
  # A command failed because the referenced shadow root is no longer attached to the DOM.
@@ -133,7 +143,11 @@ module Selenium
133
143
  # Argument was an invalid selector.
134
144
  #
135
145
 
136
- class InvalidSelectorError < WebDriverError; end
146
+ class InvalidSelectorError < WebDriverError
147
+ def initialize(msg = '')
148
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#invalid-selector-exception")
149
+ end
150
+ end
137
151
 
138
152
  #
139
153
  # A new session could not be created.
@@ -214,6 +228,15 @@ module Selenium
214
228
 
215
229
  class UnsupportedOperationError < WebDriverError; end
216
230
 
231
+ #
232
+ # Indicates that driver was not specified and could not be located.
233
+ #
234
+
235
+ class NoSuchDriverError < WebDriverError
236
+ def initialize(msg = '')
237
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}/driver_location")
238
+ end
239
+ end
217
240
  end # Error
218
241
  end # WebDriver
219
242
  end # Selenium
@@ -26,8 +26,8 @@ module Selenium
26
26
  def key?(key)
27
27
  keys.include? key
28
28
  end
29
- alias_method :member?, :key?
30
- alias_method :has_key?, :key?
29
+ alias member? key?
30
+ alias has_key? key?
31
31
 
32
32
  def fetch(key)
33
33
  return self[key] if key? key
@@ -95,9 +95,9 @@ module Selenium
95
95
  # @return [ActionBuilder] A self reference.
96
96
  #
97
97
 
98
- def move_to(element, right_by = nil, down_by = nil, device: nil, duration: default_move_duration, **opts)
99
- pointer = pointer_input(device)
100
- pointer.create_pointer_move(duration: duration,
98
+ def move_to(element, right_by = nil, down_by = nil, **opts)
99
+ pointer = pointer_input(opts.delete(:device))
100
+ pointer.create_pointer_move(duration: opts.delete(:duration) || default_move_duration,
101
101
  x: right_by || 0,
102
102
  y: down_by || 0,
103
103
  origin: element,
@@ -33,12 +33,12 @@ module Selenium
33
33
  POINTER = :pointer
34
34
  ORIGINS = [VIEWPORT, POINTER].freeze
35
35
 
36
- def initialize(source, duration, x, y, element: nil, origin: nil, **opts)
36
+ def initialize(source, duration, x, y, **opts)
37
37
  super(source)
38
38
  @duration = duration * 1000
39
39
  @x_offset = x
40
40
  @y_offset = y
41
- @origin = element || origin || :viewport
41
+ @origin = opts.delete(:element) || opts.delete(:origin) || :viewport
42
42
  @type = :pointerMove
43
43
  @opts = opts
44
44
  end