selenium-webdriver 4.2.1 → 4.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +252 -0
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/NOTICE +1 -1
- data/README.md +2 -2
- data/bin/linux/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/server.rb +22 -30
- data/lib/selenium/webdriver/atoms/findElements.js +3 -4
- data/lib/selenium/webdriver/atoms/getAttribute.js +0 -0
- data/lib/selenium/webdriver/atoms/isDisplayed.js +0 -0
- data/lib/selenium/webdriver/atoms/mutationListener.js +0 -0
- data/lib/selenium/webdriver/atoms.rb +5 -3
- data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
- data/lib/selenium/webdriver/{common/driver_extensions/has_network_connection.rb → bidi/browsing_context_info.rb} +10 -12
- data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
- data/lib/selenium/webdriver/{common/driver_extensions/has_location.rb → bidi/log/filter_by.rb} +14 -11
- data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
- data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
- data/lib/selenium/webdriver/bidi/session.rb +13 -0
- data/lib/selenium/webdriver/bidi.rb +3 -2
- data/lib/selenium/webdriver/chrome/driver.rb +9 -29
- data/lib/selenium/webdriver/chrome/features.rb +8 -71
- data/lib/selenium/webdriver/chrome/options.rb +3 -223
- data/lib/selenium/webdriver/chrome/profile.rb +3 -83
- data/lib/selenium/webdriver/chrome/service.rb +4 -19
- data/lib/selenium/webdriver/chrome.rb +0 -16
- data/lib/selenium/webdriver/chromium/driver.rb +60 -0
- data/lib/selenium/webdriver/chromium/features.rb +99 -0
- data/lib/selenium/webdriver/chromium/options.rb +243 -0
- data/lib/selenium/webdriver/chromium/profile.rb +113 -0
- data/lib/selenium/webdriver/chromium.rb +29 -0
- data/lib/selenium/webdriver/common/action_builder.rb +11 -58
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +29 -79
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb +65 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -69
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +0 -2
- data/lib/selenium/webdriver/common/driver_finder.rb +45 -0
- data/lib/selenium/webdriver/common/element.rb +7 -7
- data/lib/selenium/webdriver/common/error.rb +27 -4
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +19 -36
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/scroll.rb +7 -5
- data/lib/selenium/webdriver/common/local_driver.rb +46 -0
- data/lib/selenium/webdriver/common/logger.rb +90 -25
- data/lib/selenium/webdriver/common/manager.rb +0 -27
- data/lib/selenium/webdriver/common/options.rb +17 -17
- data/lib/selenium/webdriver/common/platform.rb +4 -50
- data/lib/selenium/webdriver/common/port_prober.rb +1 -1
- data/lib/selenium/webdriver/common/profile_helper.rb +1 -1
- data/lib/selenium/webdriver/common/proxy.rb +2 -2
- data/lib/selenium/webdriver/common/selenium_manager.rb +134 -0
- data/lib/selenium/webdriver/common/service.rb +21 -30
- data/lib/selenium/webdriver/common/service_manager.rb +6 -12
- data/lib/selenium/webdriver/common/shadow_root.rb +1 -2
- data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
- data/lib/selenium/webdriver/common/socket_poller.rb +1 -1
- data/lib/selenium/webdriver/common/takes_screenshot.rb +2 -3
- data/lib/selenium/webdriver/common/target_locator.rb +2 -3
- data/lib/selenium/webdriver/common/timeouts.rb +2 -2
- data/lib/selenium/webdriver/common/virtual_authenticator/credential.rb +85 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +72 -0
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +62 -0
- data/lib/selenium/webdriver/common/websocket_connection.rb +22 -7
- data/lib/selenium/webdriver/common/window.rb +6 -6
- data/lib/selenium/webdriver/common/zipper.rb +1 -1
- data/lib/selenium/webdriver/common.rb +8 -3
- data/lib/selenium/webdriver/devtools/console_event.rb +0 -2
- data/lib/selenium/webdriver/devtools/exception_event.rb +0 -2
- data/lib/selenium/webdriver/devtools/mutation_event.rb +0 -2
- data/lib/selenium/webdriver/devtools/network_interceptor.rb +173 -0
- data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
- data/lib/selenium/webdriver/devtools/request.rb +0 -2
- data/lib/selenium/webdriver/devtools/response.rb +0 -2
- data/lib/selenium/webdriver/devtools.rb +12 -2
- data/lib/selenium/webdriver/edge/driver.rb +9 -3
- data/lib/selenium/webdriver/edge/features.rb +7 -4
- data/lib/selenium/webdriver/edge/options.rb +17 -5
- data/lib/selenium/webdriver/edge/profile.rb +2 -2
- data/lib/selenium/webdriver/edge/service.rb +8 -7
- data/lib/selenium/webdriver/edge.rb +0 -2
- data/lib/selenium/webdriver/firefox/driver.rb +8 -2
- data/lib/selenium/webdriver/firefox/features.rb +10 -3
- data/lib/selenium/webdriver/firefox/options.rb +4 -15
- data/lib/selenium/webdriver/firefox/profile.rb +7 -7
- data/lib/selenium/webdriver/firefox/service.rb +0 -18
- data/lib/selenium/webdriver/firefox.rb +0 -14
- data/lib/selenium/webdriver/ie/driver.rb +7 -1
- data/lib/selenium/webdriver/{common/driver_extensions/has_remote_status.rb → ie/features.rb} +10 -7
- data/lib/selenium/webdriver/ie/options.rb +4 -3
- data/lib/selenium/webdriver/ie/service.rb +0 -22
- data/lib/selenium/webdriver/ie.rb +4 -17
- data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +10 -4
- data/lib/selenium/webdriver/remote/bridge.rb +48 -39
- data/lib/selenium/webdriver/remote/capabilities.rb +3 -53
- data/lib/selenium/webdriver/remote/driver.rb +35 -14
- data/lib/selenium/webdriver/remote/features.rb +75 -0
- data/lib/selenium/webdriver/remote/http/common.rb +3 -3
- data/lib/selenium/webdriver/remote/http/curb.rb +1 -3
- data/lib/selenium/webdriver/remote/http/default.rb +2 -2
- data/lib/selenium/webdriver/remote/response.rb +0 -1
- data/lib/selenium/webdriver/remote/server_error.rb +1 -1
- data/lib/selenium/webdriver/remote.rb +1 -1
- data/lib/selenium/webdriver/safari/driver.rb +7 -1
- data/lib/selenium/webdriver/safari/features.rb +5 -3
- data/lib/selenium/webdriver/safari/options.rb +5 -1
- data/lib/selenium/webdriver/safari/service.rb +10 -4
- data/lib/selenium/webdriver/safari.rb +1 -15
- data/lib/selenium/webdriver/support/color.rb +17 -17
- data/lib/selenium/webdriver/support/guards/guard.rb +6 -5
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +0 -2
- data/lib/selenium/webdriver/support/guards.rb +1 -1
- data/lib/selenium/webdriver/support/relative_locator.rb +0 -1
- data/lib/selenium/webdriver/support/select.rb +3 -1
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +5 -4
- data/selenium-webdriver.gemspec +10 -11
- metadata +51 -90
- data/lib/selenium/webdriver/remote/http/persistent.rb +0 -65
- data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
- 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
|
-
@
|
|
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
|
-
|
|
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
|
-
|
|
262
|
+
alias first find_element
|
|
258
263
|
|
|
259
264
|
#
|
|
260
265
|
# driver.all(class: 'bar') #=> [#<WebDriver::Element:0x1011c3b88, ...]
|
|
261
266
|
#
|
|
262
267
|
|
|
263
|
-
|
|
268
|
+
alias all find_elements
|
|
264
269
|
|
|
265
270
|
#
|
|
266
271
|
# driver.script('function() { ... };')
|
|
267
272
|
#
|
|
268
273
|
|
|
269
|
-
|
|
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(
|
|
311
|
-
|
|
312
|
-
|
|
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
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
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
|
|
@@ -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 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
|
|
@@ -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
|
|
@@ -61,74 +60,8 @@ module Selenium
|
|
|
61
60
|
#
|
|
62
61
|
|
|
63
62
|
def intercept(&block)
|
|
64
|
-
|
|
65
|
-
|
|
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
|
|
@@ -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
|
-
|
|
46
|
+
alias eql? ==
|
|
47
47
|
|
|
48
48
|
def hash
|
|
49
49
|
[@id, @bridge].hash
|
|
@@ -101,7 +101,7 @@ module Selenium
|
|
|
101
101
|
# if it exists. If it does not, then the value of the attribute with the given name is returned.
|
|
102
102
|
# If neither exists, null is returned.
|
|
103
103
|
#
|
|
104
|
-
# The "style" attribute is converted as best can be to a text representation with a trailing
|
|
104
|
+
# The "style" attribute is converted as best can be to a text representation with a trailing semicolon.
|
|
105
105
|
#
|
|
106
106
|
# The following are deemed to be "boolean" attributes, and will return either "true" or "false":
|
|
107
107
|
#
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
336
|
+
alias first find_element
|
|
337
337
|
|
|
338
338
|
#
|
|
339
339
|
# element.all(class: 'bar')
|
|
340
340
|
#
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
alias all find_elements
|
|
343
343
|
|
|
344
344
|
#
|
|
345
345
|
# element['class'] or element[:class] #=> "someclass"
|
|
346
346
|
#
|
|
347
|
-
|
|
347
|
+
alias [] attribute
|
|
348
348
|
|
|
349
349
|
#
|
|
350
350
|
# @api private
|