selenium-webdriver 4.1.0 → 4.9.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 +221 -1
- data/LICENSE +1 -1
- data/NOTICE +1 -1
- 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 +35 -26
- data/lib/selenium/webdriver/atoms/findElements.js +0 -0
- 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 +2 -3
- data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
- data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
- 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/bidi/log/filter_by.rb +40 -0
- 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 +51 -0
- data/lib/selenium/webdriver/bidi.rb +56 -0
- data/lib/selenium/webdriver/chrome/driver.rb +9 -29
- data/lib/selenium/webdriver/chrome/features.rb +6 -68
- 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 +3 -23
- data/lib/selenium/webdriver/chrome.rb +0 -14
- data/lib/selenium/webdriver/chromium/driver.rb +61 -0
- data/lib/selenium/webdriver/chromium/features.rb +103 -0
- data/lib/selenium/webdriver/chromium/options.rb +261 -0
- data/lib/selenium/webdriver/chromium/profile.rb +113 -0
- data/lib/selenium/webdriver/chromium/service.rb +42 -0
- data/lib/selenium/webdriver/chromium.rb +32 -0
- data/lib/selenium/webdriver/common/action_builder.rb +72 -22
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +36 -74
- 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_remote_status.rb → has_bidi.rb} +10 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -4
- 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_launching.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +1 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -2
- 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 +1 -3
- data/lib/selenium/webdriver/common/driver_finder.rb +43 -0
- data/lib/selenium/webdriver/common/element.rb +8 -8
- data/lib/selenium/webdriver/common/error.rb +1 -3
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
- data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -25
- data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -1
- data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
- data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
- data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +59 -70
- data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
- data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
- data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
- data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
- data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
- data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
- data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
- data/lib/selenium/webdriver/common/interactions/wheel_input.rb +42 -0
- data/lib/selenium/webdriver/common/keys.rb +1 -0
- data/lib/selenium/webdriver/common/local_driver.rb +55 -0
- data/lib/selenium/webdriver/common/logger.rb +10 -2
- data/lib/selenium/webdriver/common/manager.rb +0 -27
- data/lib/selenium/webdriver/common/options.rb +32 -17
- data/lib/selenium/webdriver/common/platform.rb +8 -5
- data/lib/selenium/webdriver/common/profile_helper.rb +1 -1
- data/lib/selenium/webdriver/common/proxy.rb +1 -1
- data/lib/selenium/webdriver/common/search_context.rb +0 -6
- data/lib/selenium/webdriver/common/selenium_manager.rb +108 -0
- data/lib/selenium/webdriver/common/service.rb +11 -22
- data/lib/selenium/webdriver/common/service_manager.rb +5 -14
- data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
- data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
- 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 +164 -0
- data/lib/selenium/webdriver/common/window.rb +6 -6
- data/lib/selenium/webdriver/common/zipper.rb +1 -1
- data/lib/selenium/webdriver/common.rb +21 -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 +1 -3
- data/lib/selenium/webdriver/devtools/response.rb +1 -3
- data/lib/selenium/webdriver/devtools.rb +17 -114
- data/lib/selenium/webdriver/edge/driver.rb +9 -3
- data/lib/selenium/webdriver/edge/features.rb +4 -4
- data/lib/selenium/webdriver/edge/options.rb +3 -5
- data/lib/selenium/webdriver/edge/profile.rb +2 -2
- data/lib/selenium/webdriver/edge/service.rb +2 -6
- data/lib/selenium/webdriver/firefox/driver.rb +9 -2
- data/lib/selenium/webdriver/firefox/features.rb +6 -6
- data/lib/selenium/webdriver/firefox/options.rb +9 -3
- data/lib/selenium/webdriver/firefox/profile.rb +7 -11
- data/lib/selenium/webdriver/firefox/service.rb +0 -6
- data/lib/selenium/webdriver/firefox/util.rb +46 -0
- data/lib/selenium/webdriver/firefox.rb +1 -14
- data/lib/selenium/webdriver/ie/driver.rb +7 -1
- data/lib/selenium/webdriver/ie/service.rb +1 -7
- data/lib/selenium/webdriver/ie.rb +0 -14
- data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +15 -8
- data/lib/selenium/webdriver/remote/bridge.rb +59 -30
- data/lib/selenium/webdriver/remote/capabilities.rb +34 -12
- data/lib/selenium/webdriver/remote/driver.rb +19 -14
- data/lib/selenium/webdriver/remote/http/curb.rb +0 -2
- data/lib/selenium/webdriver/remote/http/default.rb +7 -12
- data/lib/selenium/webdriver/remote/response.rb +2 -3
- data/lib/selenium/webdriver/remote.rb +0 -1
- data/lib/selenium/webdriver/safari/driver.rb +7 -1
- data/lib/selenium/webdriver/safari/features.rb +0 -2
- data/lib/selenium/webdriver/safari/options.rb +5 -1
- data/lib/selenium/webdriver/safari/service.rb +0 -4
- data/lib/selenium/webdriver/safari.rb +1 -15
- data/lib/selenium/webdriver/support/color.rb +20 -20
- data/lib/selenium/webdriver/support/guards/guard.rb +0 -2
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -3
- 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 +4 -4
- data/selenium-webdriver.gemspec +13 -11
- metadata +70 -59
- 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
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Firefox
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Driver implementation for Firefox using GeckoDriver.
|
|
26
25
|
# @api private
|
|
@@ -30,12 +29,20 @@ module Selenium
|
|
|
30
29
|
EXTENSIONS = [DriverExtensions::HasAddons,
|
|
31
30
|
DriverExtensions::FullPageScreenshot,
|
|
32
31
|
DriverExtensions::HasContext,
|
|
32
|
+
DriverExtensions::HasBiDi,
|
|
33
33
|
DriverExtensions::HasDevTools,
|
|
34
34
|
DriverExtensions::HasLogEvents,
|
|
35
35
|
DriverExtensions::HasNetworkInterception,
|
|
36
36
|
DriverExtensions::HasWebStorage,
|
|
37
37
|
DriverExtensions::PrintsPage].freeze
|
|
38
38
|
|
|
39
|
+
include LocalDriver
|
|
40
|
+
|
|
41
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
42
|
+
caps, url = initialize_local_driver(capabilities, options, service, url)
|
|
43
|
+
super(caps: caps, url: url, **opts)
|
|
44
|
+
end
|
|
45
|
+
|
|
39
46
|
def browser
|
|
40
47
|
:firefox
|
|
41
48
|
end
|
|
@@ -44,7 +51,7 @@ module Selenium
|
|
|
44
51
|
|
|
45
52
|
def devtools_url
|
|
46
53
|
if capabilities['moz:debuggerAddress'].nil?
|
|
47
|
-
raise(Error::WebDriverError,
|
|
54
|
+
raise(Error::WebDriverError, 'DevTools is not supported by this version of Firefox; use v85 or higher')
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
uri = URI("http://#{capabilities['moz:debuggerAddress']}")
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Firefox
|
|
23
23
|
module Features
|
|
24
|
-
|
|
25
24
|
FIREFOX_COMMANDS = {
|
|
26
25
|
get_context: [:get, 'session/:session_id/moz/context'],
|
|
27
26
|
set_context: [:post, 'session/:session_id/moz/context'],
|
|
@@ -35,12 +34,13 @@ module Selenium
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def install_addon(path, temporary)
|
|
38
|
-
if
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
addon = if File.directory?(path)
|
|
38
|
+
Zipper.zip(path)
|
|
39
|
+
else
|
|
40
|
+
File.open(path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
|
|
41
|
+
end
|
|
42
42
|
|
|
43
|
-
payload = {
|
|
43
|
+
payload = {addon: addon}
|
|
44
44
|
payload[:temporary] = temporary unless temporary.nil?
|
|
45
45
|
execute :install_addon, {}, payload
|
|
46
46
|
end
|
|
@@ -25,11 +25,12 @@ module Selenium
|
|
|
25
25
|
|
|
26
26
|
KEY = 'moz:firefoxOptions'
|
|
27
27
|
|
|
28
|
-
# see: https://
|
|
28
|
+
# see: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions
|
|
29
29
|
CAPABILITIES = {binary: 'binary',
|
|
30
30
|
args: 'args',
|
|
31
31
|
log: 'log',
|
|
32
32
|
prefs: 'prefs',
|
|
33
|
+
env: 'env',
|
|
33
34
|
android_package: 'androidPackage',
|
|
34
35
|
android_activity: 'androidActivity',
|
|
35
36
|
android_device_serial: 'androidDeviceSerial',
|
|
@@ -56,12 +57,14 @@ module Selenium
|
|
|
56
57
|
#
|
|
57
58
|
|
|
58
59
|
def initialize(log_level: nil, **opts)
|
|
59
|
-
@debugger_address = opts.delete(:debugger_address)
|
|
60
|
+
@debugger_address = opts.delete(:debugger_address) { true }
|
|
61
|
+
opts[:accept_insecure_certs] = true unless opts.key?(:accept_insecure_certs)
|
|
60
62
|
|
|
61
63
|
super(**opts)
|
|
62
64
|
|
|
63
65
|
@options[:args] ||= []
|
|
64
66
|
@options[:prefs] ||= {}
|
|
67
|
+
@options[:env] ||= {}
|
|
65
68
|
@options[:log] ||= {level: log_level} if log_level
|
|
66
69
|
|
|
67
70
|
process_profile(@options.delete(:profile))
|
|
@@ -105,6 +108,9 @@ module Selenium
|
|
|
105
108
|
#
|
|
106
109
|
|
|
107
110
|
def headless!
|
|
111
|
+
WebDriver.logger.deprecate('`Options#headless!`',
|
|
112
|
+
"`Options#add_argument('-headless')`",
|
|
113
|
+
id: :headless)
|
|
108
114
|
add_argument '-headless'
|
|
109
115
|
end
|
|
110
116
|
|
|
@@ -175,7 +181,7 @@ module Selenium
|
|
|
175
181
|
end
|
|
176
182
|
|
|
177
183
|
def camelize?(key)
|
|
178
|
-
key !=
|
|
184
|
+
key != 'prefs'
|
|
179
185
|
end
|
|
180
186
|
end # Options
|
|
181
187
|
end # Firefox
|
|
@@ -26,11 +26,11 @@ module Selenium
|
|
|
26
26
|
VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
|
|
27
27
|
|
|
28
28
|
DEFAULT_PREFERENCES = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
'browser.newtabpage.enabled' => false,
|
|
30
|
+
'browser.startup.homepage' => 'about:blank',
|
|
31
|
+
'browser.usedOnWindows10.introURL' => 'about:blank',
|
|
32
|
+
'network.captive-portal-service.enabled' => false,
|
|
33
|
+
'security.csp.enable' => false
|
|
34
34
|
}.freeze
|
|
35
35
|
|
|
36
36
|
attr_reader :name, :log_file
|
|
@@ -96,7 +96,7 @@ module Selenium
|
|
|
96
96
|
raise TypeError, "expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}"
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
if value.is_a?(String) && stringified?(value)
|
|
99
|
+
if value.is_a?(String) && Util.stringified?(value)
|
|
100
100
|
raise ArgumentError, "preference values must be plain strings: #{key.inspect} => #{value.inspect}"
|
|
101
101
|
end
|
|
102
102
|
|
|
@@ -143,7 +143,7 @@ module Selenium
|
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
alias as_json encoded
|
|
147
147
|
|
|
148
148
|
private
|
|
149
149
|
|
|
@@ -221,10 +221,6 @@ module Selenium
|
|
|
221
221
|
end
|
|
222
222
|
end
|
|
223
223
|
end
|
|
224
|
-
|
|
225
|
-
def stringified?(str)
|
|
226
|
-
/^".*"$/.match?(str)
|
|
227
|
-
end
|
|
228
224
|
end # Profile
|
|
229
225
|
end # Firefox
|
|
230
226
|
end # WebDriver
|
|
@@ -23,16 +23,10 @@ module Selenium
|
|
|
23
23
|
class Service < WebDriver::Service
|
|
24
24
|
DEFAULT_PORT = 4444
|
|
25
25
|
EXECUTABLE = 'geckodriver'
|
|
26
|
-
MISSING_TEXT = <<~ERROR
|
|
27
|
-
Unable to find Mozilla geckodriver. Please download the server from
|
|
28
|
-
https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH.
|
|
29
|
-
More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
|
|
30
|
-
ERROR
|
|
31
26
|
SHUTDOWN_SUPPORTED = false
|
|
32
27
|
|
|
33
28
|
private
|
|
34
29
|
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
30
|
def extract_service_args(driver_opts)
|
|
37
31
|
driver_args = super
|
|
38
32
|
driver_opts = driver_opts.dup
|
|
@@ -0,0 +1,46 @@
|
|
|
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 Firefox
|
|
23
|
+
# @api private
|
|
24
|
+
module Util
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
def app_data_path
|
|
28
|
+
case Platform.os
|
|
29
|
+
when :windows
|
|
30
|
+
"#{ENV.fetch('APPDATA')}\\Mozilla\\Firefox"
|
|
31
|
+
when :macosx
|
|
32
|
+
"#{Platform.home}/Library/Application Support/Firefox"
|
|
33
|
+
when :unix, :linux
|
|
34
|
+
"#{Platform.home}/.mozilla/firefox"
|
|
35
|
+
else
|
|
36
|
+
raise "Unknown os: #{Platform.os}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def stringified?(str)
|
|
41
|
+
str =~ /^".*"$/
|
|
42
|
+
end
|
|
43
|
+
end # Util
|
|
44
|
+
end # Firefox
|
|
45
|
+
end # WebDriver
|
|
46
|
+
end # Selenium
|
|
@@ -24,6 +24,7 @@ require 'rexml/document'
|
|
|
24
24
|
module Selenium
|
|
25
25
|
module WebDriver
|
|
26
26
|
module Firefox
|
|
27
|
+
autoload :Util, 'selenium/webdriver/firefox/util'
|
|
27
28
|
autoload :Extension, 'selenium/webdriver/firefox/extension'
|
|
28
29
|
autoload :ProfilesIni, 'selenium/webdriver/firefox/profiles_ini'
|
|
29
30
|
autoload :Profile, 'selenium/webdriver/firefox/profile'
|
|
@@ -41,20 +42,6 @@ module Selenium
|
|
|
41
42
|
# until WebDriver Bidi is available.
|
|
42
43
|
DEVTOOLS_VERSION = 85
|
|
43
44
|
|
|
44
|
-
def self.driver_path=(path)
|
|
45
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path=',
|
|
46
|
-
'Selenium::WebDriver::Firefox::Service#driver_path=',
|
|
47
|
-
id: :driver_path
|
|
48
|
-
Selenium::WebDriver::Firefox::Service.driver_path = path
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def self.driver_path
|
|
52
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path',
|
|
53
|
-
'Selenium::WebDriver::Firefox::Service#driver_path',
|
|
54
|
-
id: :driver_path
|
|
55
|
-
Selenium::WebDriver::Firefox::Service.driver_path
|
|
56
|
-
end
|
|
57
|
-
|
|
58
45
|
def self.path=(path)
|
|
59
46
|
Platform.assert_executable path
|
|
60
47
|
@path = path
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module IE
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Driver implementation for Internet Explorer supporting
|
|
26
25
|
# both OSS and W3C dialects of JSON wire protocol.
|
|
@@ -30,6 +29,13 @@ module Selenium
|
|
|
30
29
|
class Driver < WebDriver::Driver
|
|
31
30
|
EXTENSIONS = [DriverExtensions::HasWebStorage].freeze
|
|
32
31
|
|
|
32
|
+
include LocalDriver
|
|
33
|
+
|
|
34
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
35
|
+
caps, url = initialize_local_driver(capabilities, options, service, url)
|
|
36
|
+
super(caps: caps, url: url, **opts)
|
|
37
|
+
end
|
|
38
|
+
|
|
33
39
|
def browser
|
|
34
40
|
:internet_explorer
|
|
35
41
|
end
|
|
@@ -23,16 +23,10 @@ module Selenium
|
|
|
23
23
|
class Service < WebDriver::Service
|
|
24
24
|
DEFAULT_PORT = 5555
|
|
25
25
|
EXECUTABLE = 'IEDriverServer'
|
|
26
|
-
MISSING_TEXT = <<~ERROR
|
|
27
|
-
Unable to find IEDriverServer. Please download the server from
|
|
28
|
-
https://www.selenium.dev/downloads/ and place it somewhere on your PATH.
|
|
29
|
-
More info at https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver.
|
|
30
|
-
ERROR
|
|
31
26
|
SHUTDOWN_SUPPORTED = true
|
|
32
27
|
|
|
33
28
|
private
|
|
34
29
|
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
30
|
def extract_service_args(driver_opts)
|
|
37
31
|
driver_args = super
|
|
38
32
|
driver_opts = driver_opts.dup
|
|
@@ -43,7 +37,7 @@ module Selenium
|
|
|
43
37
|
end
|
|
44
38
|
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
|
45
39
|
driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
|
|
46
|
-
driver_args <<
|
|
40
|
+
driver_args << '--silent' if driver_opts[:silent] == true
|
|
47
41
|
driver_args
|
|
48
42
|
end
|
|
49
43
|
end # Server
|
|
@@ -23,20 +23,6 @@ module Selenium
|
|
|
23
23
|
autoload :Driver, 'selenium/webdriver/ie/driver'
|
|
24
24
|
autoload :Options, 'selenium/webdriver/ie/options'
|
|
25
25
|
autoload :Service, 'selenium/webdriver/ie/service'
|
|
26
|
-
|
|
27
|
-
def self.driver_path=(path)
|
|
28
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::IE#driver_path=',
|
|
29
|
-
'Selenium::WebDriver::IE::Service#driver_path=',
|
|
30
|
-
id: :driver_path
|
|
31
|
-
Selenium::WebDriver::IE::Service.driver_path = path
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def self.driver_path
|
|
35
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::IE#driver_path',
|
|
36
|
-
'Selenium::WebDriver::IE::Service#driver_path',
|
|
37
|
-
id: :driver_path
|
|
38
|
-
Selenium::WebDriver::IE::Service.driver_path
|
|
39
|
-
end
|
|
40
26
|
end # IE
|
|
41
27
|
end # WebDriver
|
|
42
28
|
end # Selenium
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Remote
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# https://w3c.github.io/webdriver/#endpoints
|
|
26
25
|
# @api private
|
|
@@ -60,10 +59,6 @@ module Selenium
|
|
|
60
59
|
fullscreen_window: [:post, 'session/:session_id/window/fullscreen'],
|
|
61
60
|
minimize_window: [:post, 'session/:session_id/window/minimize'],
|
|
62
61
|
maximize_window: [:post, 'session/:session_id/window/maximize'],
|
|
63
|
-
set_window_size: [:post, 'session/:session_id/window/size'],
|
|
64
|
-
get_window_size: [:get, 'session/:session_id/window/size'],
|
|
65
|
-
set_window_position: [:post, 'session/:session_id/window/position'],
|
|
66
|
-
get_window_position: [:get, 'session/:session_id/window/position'],
|
|
67
62
|
set_window_rect: [:post, 'session/:session_id/window/rect'],
|
|
68
63
|
get_window_rect: [:get, 'session/:session_id/window/rect'],
|
|
69
64
|
switch_to_frame: [:post, 'session/:session_id/frame'],
|
|
@@ -130,7 +125,6 @@ module Selenium
|
|
|
130
125
|
#
|
|
131
126
|
|
|
132
127
|
element_click: [:post, 'session/:session_id/element/:id/click'],
|
|
133
|
-
element_tap: [:post, 'session/:session_id/element/:id/tap'],
|
|
134
128
|
element_clear: [:post, 'session/:session_id/element/:id/clear'],
|
|
135
129
|
element_send_keys: [:post, 'session/:session_id/element/:id/value'],
|
|
136
130
|
|
|
@@ -154,9 +148,22 @@ module Selenium
|
|
|
154
148
|
# server extensions
|
|
155
149
|
#
|
|
156
150
|
|
|
157
|
-
upload_file: [:post, 'session/:session_id/se/file']
|
|
158
|
-
}.freeze
|
|
151
|
+
upload_file: [:post, 'session/:session_id/se/file'],
|
|
159
152
|
|
|
153
|
+
#
|
|
154
|
+
# virtual-authenticator
|
|
155
|
+
#
|
|
156
|
+
|
|
157
|
+
add_virtual_authenticator: [:post, 'session/:session_id/webauthn/authenticator'],
|
|
158
|
+
remove_virtual_authenticator: [:delete, 'session/:session_id/webauthn/authenticator/:authenticatorId'],
|
|
159
|
+
add_credential: [:post, 'session/:session_id/webauthn/authenticator/:authenticatorId/credential'],
|
|
160
|
+
get_credentials: [:get, 'session/:session_id/webauthn/authenticator/:authenticatorId/credentials'],
|
|
161
|
+
remove_credential: [:delete,
|
|
162
|
+
'session/:session_id/webauthn/authenticator/:authenticatorId/credentials/:credentialId'],
|
|
163
|
+
remove_all_credentials: [:delete, 'session/:session_id/webauthn/authenticator/:authenticatorId/credentials'],
|
|
164
|
+
set_user_verified: [:post, 'session/:session_id/webauthn/authenticator/:authenticatorId/uv']
|
|
165
|
+
|
|
166
|
+
}.freeze
|
|
160
167
|
end # Bridge
|
|
161
168
|
end # Remote
|
|
162
169
|
end # WebDriver
|
|
@@ -21,6 +21,7 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Remote
|
|
23
23
|
class Bridge
|
|
24
|
+
autoload :COMMANDS, 'selenium/webdriver/remote/bridge/commands'
|
|
24
25
|
include Atoms
|
|
25
26
|
|
|
26
27
|
PORT = 4444
|
|
@@ -30,8 +31,8 @@ module Selenium
|
|
|
30
31
|
|
|
31
32
|
#
|
|
32
33
|
# Initializes the bridge with the given server URL
|
|
33
|
-
# @param [String, URI]
|
|
34
|
-
# @param [Object]
|
|
34
|
+
# @param [String, URI] url url for the remote server
|
|
35
|
+
# @param [Object] http_client an HTTP client instance that implements the same protocol as Http::Default
|
|
35
36
|
# @api private
|
|
36
37
|
#
|
|
37
38
|
|
|
@@ -118,7 +119,7 @@ module Selenium
|
|
|
118
119
|
end
|
|
119
120
|
|
|
120
121
|
def alert=(keys)
|
|
121
|
-
execute :send_alert_text, {}, {value: keys.
|
|
122
|
+
execute :send_alert_text, {}, {value: keys.chars, text: keys}
|
|
122
123
|
end
|
|
123
124
|
|
|
124
125
|
def alert_text
|
|
@@ -146,9 +147,7 @@ module Selenium
|
|
|
146
147
|
end
|
|
147
148
|
|
|
148
149
|
def page_source
|
|
149
|
-
|
|
150
|
-
'if (!source) { source = new XMLSerializer().serializeToString(document); }' \
|
|
151
|
-
'return source;')
|
|
150
|
+
execute :get_page_source
|
|
152
151
|
end
|
|
153
152
|
|
|
154
153
|
#
|
|
@@ -188,6 +187,7 @@ module Selenium
|
|
|
188
187
|
execute :delete_session
|
|
189
188
|
http.close
|
|
190
189
|
rescue *QUIT_ERRORS
|
|
190
|
+
nil
|
|
191
191
|
end
|
|
192
192
|
|
|
193
193
|
def close
|
|
@@ -369,21 +369,10 @@ module Selenium
|
|
|
369
369
|
# actions
|
|
370
370
|
#
|
|
371
371
|
|
|
372
|
-
def action(async
|
|
373
|
-
ActionBuilder.new self,
|
|
374
|
-
Interactions.pointer(:mouse, name: 'mouse'),
|
|
375
|
-
Interactions.key('keyboard'),
|
|
376
|
-
async
|
|
377
|
-
end
|
|
378
|
-
alias_method :actions, :action
|
|
379
|
-
|
|
380
|
-
def mouse
|
|
381
|
-
raise Error::UnsupportedOperationError, '#mouse is no longer supported, use #action instead'
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
def keyboard
|
|
385
|
-
raise Error::UnsupportedOperationError, '#keyboard is no longer supported, use #action instead'
|
|
372
|
+
def action(async: false, devices: [], duration: 250)
|
|
373
|
+
ActionBuilder.new self, async: async, devices: devices, duration: duration
|
|
386
374
|
end
|
|
375
|
+
alias actions action
|
|
387
376
|
|
|
388
377
|
def send_actions(data)
|
|
389
378
|
execute :actions, {}, {actions: data}
|
|
@@ -405,15 +394,15 @@ module Selenium
|
|
|
405
394
|
# TODO: rework file detectors before Selenium 4.0
|
|
406
395
|
if @file_detector
|
|
407
396
|
local_files = keys.first&.split("\n")&.map { |key| @file_detector.call(Array(key)) }&.compact
|
|
408
|
-
if local_files
|
|
397
|
+
if local_files&.any?
|
|
409
398
|
keys = local_files.map { |local_file| upload(local_file) }
|
|
410
399
|
keys = Array(keys.join("\n"))
|
|
411
400
|
end
|
|
412
401
|
end
|
|
413
402
|
|
|
414
403
|
# Keep .split(//) for backward compatibility for now
|
|
415
|
-
text = keys.join
|
|
416
|
-
execute :element_send_keys, {id: element}, {value: text.
|
|
404
|
+
text = keys.join
|
|
405
|
+
execute :element_send_keys, {id: element}, {value: text.chars, text: text}
|
|
417
406
|
end
|
|
418
407
|
|
|
419
408
|
def upload(local_file)
|
|
@@ -430,10 +419,19 @@ module Selenium
|
|
|
430
419
|
end
|
|
431
420
|
|
|
432
421
|
def submit_element(element)
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
422
|
+
script = "/* submitForm */ var form = arguments[0];\n" \
|
|
423
|
+
"while (form.nodeName != \"FORM\" && form.parentNode) {\n " \
|
|
424
|
+
"form = form.parentNode;\n" \
|
|
425
|
+
"}\n" \
|
|
426
|
+
"if (!form) { throw Error('Unable to find containing form element'); }\n" \
|
|
427
|
+
"if (!form.ownerDocument) { throw Error('Unable to find owning document'); }\n" \
|
|
428
|
+
"var e = form.ownerDocument.createEvent('Event');\n" \
|
|
429
|
+
"e.initEvent('submit', true, true);\n" \
|
|
430
|
+
"if (form.dispatchEvent(e)) { HTMLFormElement.prototype.submit.call(form) }\n"
|
|
431
|
+
|
|
432
|
+
execute_script(script, Element::ELEMENT_KEY => element)
|
|
433
|
+
rescue Error::JavascriptError
|
|
434
|
+
raise Error::UnsupportedOperationError, 'To submit an element, it must be nested inside a form element'
|
|
437
435
|
end
|
|
438
436
|
|
|
439
437
|
#
|
|
@@ -521,7 +519,7 @@ module Selenium
|
|
|
521
519
|
Element.new self, element_id_from(execute(:get_active_element))
|
|
522
520
|
end
|
|
523
521
|
|
|
524
|
-
|
|
522
|
+
alias switch_to_active_element active_element
|
|
525
523
|
|
|
526
524
|
def find_element_by(how, what, parent_ref = [])
|
|
527
525
|
how, what = convert_locator(how, what)
|
|
@@ -564,6 +562,39 @@ module Selenium
|
|
|
564
562
|
ShadowRoot.new self, shadow_root_id_from(id)
|
|
565
563
|
end
|
|
566
564
|
|
|
565
|
+
#
|
|
566
|
+
# virtual-authenticator
|
|
567
|
+
#
|
|
568
|
+
|
|
569
|
+
def add_virtual_authenticator(options)
|
|
570
|
+
authenticator_id = execute :add_virtual_authenticator, {}, options.as_json
|
|
571
|
+
VirtualAuthenticator.new(self, authenticator_id, options)
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
def remove_virtual_authenticator(id)
|
|
575
|
+
execute :remove_virtual_authenticator, {authenticatorId: id}
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
def add_credential(credential, id)
|
|
579
|
+
execute :add_credential, {authenticatorId: id}, credential
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def credentials(authenticator_id)
|
|
583
|
+
execute :get_credentials, {authenticatorId: authenticator_id}
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def remove_credential(credential_id, authenticator_id)
|
|
587
|
+
execute :remove_credential, {credentialId: credential_id, authenticatorId: authenticator_id}
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
def remove_all_credentials(authenticator_id)
|
|
591
|
+
execute :remove_all_credentials, {authenticatorId: authenticator_id}
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def user_verified(verified, authenticator_id)
|
|
595
|
+
execute :set_user_verified, {authenticatorId: authenticator_id}, {isUserVerified: verified}
|
|
596
|
+
end
|
|
597
|
+
|
|
567
598
|
private
|
|
568
599
|
|
|
569
600
|
#
|
|
@@ -639,8 +670,6 @@ module Selenium
|
|
|
639
670
|
when 'name'
|
|
640
671
|
how = 'css selector'
|
|
641
672
|
what = "*[name='#{escape_css(what.to_s)}']"
|
|
642
|
-
when 'tag name'
|
|
643
|
-
how = 'css selector'
|
|
644
673
|
end
|
|
645
674
|
|
|
646
675
|
if what.is_a?(Hash)
|
|
@@ -20,14 +20,12 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Remote
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Specification of the desired and/or actual capabilities of the browser that the
|
|
26
25
|
# server is being asked to create.
|
|
27
26
|
#
|
|
28
27
|
|
|
29
28
|
class Capabilities
|
|
30
|
-
|
|
31
29
|
KNOWN = [
|
|
32
30
|
:browser_name,
|
|
33
31
|
:browser_version,
|
|
@@ -59,10 +57,25 @@ module Selenium
|
|
|
59
57
|
# Backward compatibility
|
|
60
58
|
#
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
def version
|
|
61
|
+
WebDriver.logger.deprecate('`Capabilities#version`', '`Capabilities#browser_version`', id: :jwp_caps)
|
|
62
|
+
browser_version
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def version=(value)
|
|
66
|
+
WebDriver.logger.deprecate('`Capabilities#version=`', '`Capabilities#browser_version=`', id: :jwp_caps)
|
|
67
|
+
self.browser_version = value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def platform
|
|
71
|
+
WebDriver.logger.deprecate('`Capabilities#platform`', '`Capabilities#platform_name`', id: :jwp_caps)
|
|
72
|
+
platform_name
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def platform=(value)
|
|
76
|
+
WebDriver.logger.deprecate('`Capabilities#platform=`', '`Capabilities#platform_name=`', id: :jwp_caps)
|
|
77
|
+
self.platform_name = value
|
|
78
|
+
end
|
|
66
79
|
|
|
67
80
|
#
|
|
68
81
|
# Convenience methods for the common choices.
|
|
@@ -70,44 +83,52 @@ module Selenium
|
|
|
70
83
|
|
|
71
84
|
class << self
|
|
72
85
|
def chrome(opts = {})
|
|
86
|
+
WebDriver.logger.deprecate('Remote::Capabilities.chrome', 'Options.chrome', id: :caps_browsers)
|
|
73
87
|
new({
|
|
74
88
|
browser_name: 'chrome'
|
|
75
89
|
}.merge(opts))
|
|
76
90
|
end
|
|
77
91
|
|
|
78
92
|
def edge(opts = {})
|
|
93
|
+
WebDriver.logger.deprecate('Remote::Capabilities.edge', 'Options.edge', id: :caps_browsers)
|
|
79
94
|
new({
|
|
80
95
|
browser_name: 'MicrosoftEdge'
|
|
81
96
|
}.merge(opts))
|
|
82
97
|
end
|
|
83
|
-
|
|
98
|
+
alias microsoftedge edge
|
|
84
99
|
|
|
85
100
|
def firefox(opts = {})
|
|
101
|
+
WebDriver.logger.deprecate('Remote::Capabilities.firefox', 'Options.firefox', id: :caps_browsers)
|
|
86
102
|
new({
|
|
87
103
|
browser_name: 'firefox'
|
|
88
104
|
}.merge(opts))
|
|
89
105
|
end
|
|
90
|
-
|
|
106
|
+
alias ff firefox
|
|
91
107
|
|
|
92
108
|
def safari(opts = {})
|
|
109
|
+
WebDriver.logger.deprecate('Remote::Capabilities.safari', 'Options.safari', id: :caps_browsers)
|
|
93
110
|
new({
|
|
94
|
-
browser_name: Selenium::WebDriver::Safari.technology_preview? ?
|
|
111
|
+
browser_name: Selenium::WebDriver::Safari.technology_preview? ? 'Safari Technology Preview' : 'safari'
|
|
95
112
|
}.merge(opts))
|
|
96
113
|
end
|
|
97
114
|
|
|
98
115
|
def htmlunit(opts = {})
|
|
116
|
+
WebDriver.logger.deprecate('Remote::Capabilities.htmlunit',
|
|
117
|
+
'as argument in constructor',
|
|
118
|
+
id: :caps_browsers)
|
|
99
119
|
new({
|
|
100
120
|
browser_name: 'htmlunit'
|
|
101
121
|
}.merge(opts))
|
|
102
122
|
end
|
|
103
123
|
|
|
104
124
|
def internet_explorer(opts = {})
|
|
125
|
+
WebDriver.logger.deprecate('Remote::Capabilities.ie', 'Options.ie', id: :caps_browsers)
|
|
105
126
|
new({
|
|
106
127
|
browser_name: 'internet explorer',
|
|
107
128
|
platform_name: :windows
|
|
108
129
|
}.merge(opts))
|
|
109
130
|
end
|
|
110
|
-
|
|
131
|
+
alias ie internet_explorer
|
|
111
132
|
|
|
112
133
|
def always_match(capabilities)
|
|
113
134
|
new(always_match: capabilities)
|
|
@@ -134,7 +155,8 @@ module Selenium
|
|
|
134
155
|
|
|
135
156
|
# Remote Server Specific
|
|
136
157
|
if data.key?('webdriver.remote.sessionid')
|
|
137
|
-
caps[:remote_session_id] =
|
|
158
|
+
caps[:remote_session_id] =
|
|
159
|
+
data.delete('webdriver.remote.sessionid')
|
|
138
160
|
end
|
|
139
161
|
|
|
140
162
|
KNOWN.each do |cap|
|
|
@@ -269,7 +291,7 @@ module Selenium
|
|
|
269
291
|
as_json == other.as_json
|
|
270
292
|
end
|
|
271
293
|
|
|
272
|
-
|
|
294
|
+
alias eql? ==
|
|
273
295
|
|
|
274
296
|
protected
|
|
275
297
|
|