selenium-webdriver 4.1.0 → 4.12.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 +271 -1
- 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 +36 -39
- data/lib/selenium/webdriver/atoms/findElements.js +4 -5
- data/lib/selenium/webdriver/atoms/getAttribute.js +1 -1
- data/lib/selenium/webdriver/atoms/isDisplayed.js +1 -1
- 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 +0 -22
- data/lib/selenium/webdriver/chrome.rb +0 -16
- 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 +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 +64 -22
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +31 -81
- 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 +45 -0
- data/lib/selenium/webdriver/common/element.rb +8 -8
- data/lib/selenium/webdriver/common/error.rb +28 -5
- 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 +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 +13 -17
- data/lib/selenium/webdriver/common/platform.rb +5 -51
- 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/search_context.rb +0 -6
- data/lib/selenium/webdriver/common/selenium_manager.rb +129 -0
- data/lib/selenium/webdriver/common/service.rb +17 -30
- data/lib/selenium/webdriver/common/service_manager.rb +8 -15
- data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
- data/lib/selenium/webdriver/common/socket_lock.rb +3 -3
- data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
- 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 +17 -5
- data/lib/selenium/webdriver/edge/profile.rb +2 -2
- data/lib/selenium/webdriver/edge/service.rb +1 -7
- data/lib/selenium/webdriver/edge.rb +0 -2
- 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 +7 -16
- data/lib/selenium/webdriver/firefox/profile.rb +8 -12
- data/lib/selenium/webdriver/firefox/service.rb +0 -18
- 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/options.rb +4 -3
- data/lib/selenium/webdriver/ie/service.rb +0 -22
- 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 +65 -35
- data/lib/selenium/webdriver/remote/capabilities.rb +3 -53
- data/lib/selenium/webdriver/remote/driver.rb +31 -14
- 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 +8 -14
- data/lib/selenium/webdriver/remote/response.rb +2 -3
- data/lib/selenium/webdriver/remote/server_error.rb +1 -1
- 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 +10 -4
- data/lib/selenium/webdriver/safari.rb +1 -15
- data/lib/selenium/webdriver/support/color.rb +22 -22
- 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 +6 -4
- data/selenium-webdriver.gemspec +14 -12
- metadata +73 -63
- 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
|
@@ -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',
|
|
@@ -44,7 +45,7 @@ module Selenium
|
|
|
44
45
|
#
|
|
45
46
|
# @example
|
|
46
47
|
# options = Selenium::WebDriver::Firefox::Options.new(args: ['--host=127.0.0.1'])
|
|
47
|
-
# driver = Selenium::WebDriver.for :firefox,
|
|
48
|
+
# driver = Selenium::WebDriver.for :firefox, options: options
|
|
48
49
|
#
|
|
49
50
|
# @param [Hash] opts the pre-defined options to create the Firefox::Options with
|
|
50
51
|
# @option opts [String] :binary Path to the Firefox executable to use
|
|
@@ -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))
|
|
@@ -96,18 +99,6 @@ module Selenium
|
|
|
96
99
|
@options[:prefs][name] = value
|
|
97
100
|
end
|
|
98
101
|
|
|
99
|
-
#
|
|
100
|
-
# Run Firefox in headless mode.
|
|
101
|
-
#
|
|
102
|
-
# @example Enable headless mode
|
|
103
|
-
# options = Selenium::WebDriver::Firefox::Options.new
|
|
104
|
-
# options.headless!
|
|
105
|
-
#
|
|
106
|
-
|
|
107
|
-
def headless!
|
|
108
|
-
add_argument '-headless'
|
|
109
|
-
end
|
|
110
|
-
|
|
111
102
|
#
|
|
112
103
|
# Sets Firefox profile.
|
|
113
104
|
#
|
|
@@ -175,7 +166,7 @@ module Selenium
|
|
|
175
166
|
end
|
|
176
167
|
|
|
177
168
|
def camelize?(key)
|
|
178
|
-
key !=
|
|
169
|
+
key != 'prefs'
|
|
179
170
|
end
|
|
180
171
|
end # Options
|
|
181
172
|
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
|
|
|
@@ -160,7 +160,7 @@ module Selenium
|
|
|
160
160
|
destination = File.join(directory, 'extensions')
|
|
161
161
|
|
|
162
162
|
@extensions.each do |name, extension|
|
|
163
|
-
WebDriver.logger.debug({
|
|
163
|
+
WebDriver.logger.debug({extension: name}.inspect, id: :firefox_profile)
|
|
164
164
|
extension.write_to(destination)
|
|
165
165
|
end
|
|
166
166
|
end
|
|
@@ -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,25 +23,7 @@ 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
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
|
-
def extract_service_args(driver_opts)
|
|
37
|
-
driver_args = super
|
|
38
|
-
driver_opts = driver_opts.dup
|
|
39
|
-
driver_args << "--binary=#{driver_opts[:binary]}" if driver_opts.key?(:binary)
|
|
40
|
-
driver_args << "--log=#{driver_opts[:log]}" if driver_opts.key?(:log)
|
|
41
|
-
driver_args << "--marionette-port=#{driver_opts[:marionette_port]}" if driver_opts.key?(:marionette_port)
|
|
42
|
-
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
|
43
|
-
driver_args
|
|
44
|
-
end
|
|
45
27
|
end # Service
|
|
46
28
|
end # Firefox
|
|
47
29
|
end # WebDriver
|
|
@@ -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(options: nil, service: nil, url: nil, **opts)
|
|
35
|
+
caps, url = initialize_local_driver(options, service, url)
|
|
36
|
+
super(caps: caps, url: url, **opts)
|
|
37
|
+
end
|
|
38
|
+
|
|
33
39
|
def browser
|
|
34
40
|
:internet_explorer
|
|
35
41
|
end
|
|
@@ -41,7 +41,8 @@ module Selenium
|
|
|
41
41
|
use_per_process_proxy: 'ie.usePerProcessProxy',
|
|
42
42
|
use_legacy_file_upload_dialog_handling: 'ie.useLegacyFileUploadDialogHandling',
|
|
43
43
|
attach_to_edge_chrome: 'ie.edgechromium',
|
|
44
|
-
edge_executable_path: 'ie.edgepath'
|
|
44
|
+
edge_executable_path: 'ie.edgepath',
|
|
45
|
+
ignore_process_match: 'ie.ignoreprocessmatch'
|
|
45
46
|
}.freeze
|
|
46
47
|
BROWSER = 'internet explorer'
|
|
47
48
|
|
|
@@ -52,12 +53,12 @@ module Selenium
|
|
|
52
53
|
#
|
|
53
54
|
# @example
|
|
54
55
|
# options = Selenium::WebDriver::IE::Options.new(args: ['--host=127.0.0.1'])
|
|
55
|
-
# driver = Selenium::WebDriver.for(:ie,
|
|
56
|
+
# driver = Selenium::WebDriver.for(:ie, options: options)
|
|
56
57
|
#
|
|
57
58
|
# @example
|
|
58
59
|
# options = Selenium::WebDriver::IE::Options.new
|
|
59
60
|
# options.element_scroll_behavior = Selenium::WebDriver::IE::Options::SCROLL_BOTTOM
|
|
60
|
-
# driver = Selenium::WebDriver.for(:ie,
|
|
61
|
+
# driver = Selenium::WebDriver.for(:ie, options: options)
|
|
61
62
|
#
|
|
62
63
|
# @param [Hash] opts the pre-defined options
|
|
63
64
|
# @option opts [Array<String>] args
|
|
@@ -23,29 +23,7 @@ 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
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
|
-
def extract_service_args(driver_opts)
|
|
37
|
-
driver_args = super
|
|
38
|
-
driver_opts = driver_opts.dup
|
|
39
|
-
driver_args << "--log-level=#{driver_opts[:log_level].to_s.upcase}" if driver_opts.key?(:log_level)
|
|
40
|
-
driver_args << "--log-file=#{driver_opts[:log_file]}" if driver_opts.key?(:log_file)
|
|
41
|
-
if driver_opts.key?(:implementation)
|
|
42
|
-
driver_args << "--implementation=#{driver_opts[:implementation].to_s.upcase}"
|
|
43
|
-
end
|
|
44
|
-
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
|
45
|
-
driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
|
|
46
|
-
driver_args << "--silent" if driver_opts[:silent] == true
|
|
47
|
-
driver_args
|
|
48
|
-
end
|
|
49
27
|
end # Server
|
|
50
28
|
end # IE
|
|
51
29
|
end # WebDriver
|
|
@@ -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,20 +394,21 @@ 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)
|
|
420
409
|
unless File.file?(local_file)
|
|
421
|
-
WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!"
|
|
410
|
+
WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!",
|
|
411
|
+
id: :file_detector)
|
|
422
412
|
raise Error::WebDriverError, "You are trying to work with something that isn't a file."
|
|
423
413
|
end
|
|
424
414
|
|
|
@@ -430,10 +420,19 @@ module Selenium
|
|
|
430
420
|
end
|
|
431
421
|
|
|
432
422
|
def submit_element(element)
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
423
|
+
script = "/* submitForm */ var form = arguments[0];\n" \
|
|
424
|
+
"while (form.nodeName != \"FORM\" && form.parentNode) {\n " \
|
|
425
|
+
"form = form.parentNode;\n" \
|
|
426
|
+
"}\n" \
|
|
427
|
+
"if (!form) { throw Error('Unable to find containing form element'); }\n" \
|
|
428
|
+
"if (!form.ownerDocument) { throw Error('Unable to find owning document'); }\n" \
|
|
429
|
+
"var e = form.ownerDocument.createEvent('Event');\n" \
|
|
430
|
+
"e.initEvent('submit', true, true);\n" \
|
|
431
|
+
"if (form.dispatchEvent(e)) { HTMLFormElement.prototype.submit.call(form) }\n"
|
|
432
|
+
|
|
433
|
+
execute_script(script, Element::ELEMENT_KEY => element)
|
|
434
|
+
rescue Error::JavascriptError
|
|
435
|
+
raise Error::UnsupportedOperationError, 'To submit an element, it must be nested inside a form element'
|
|
437
436
|
end
|
|
438
437
|
|
|
439
438
|
#
|
|
@@ -445,7 +444,7 @@ module Selenium
|
|
|
445
444
|
end
|
|
446
445
|
|
|
447
446
|
def element_attribute(element, name)
|
|
448
|
-
WebDriver.logger.
|
|
447
|
+
WebDriver.logger.debug "Using script for :getAttribute of #{name}", id: :script
|
|
449
448
|
execute_atom :getAttribute, element, name
|
|
450
449
|
end
|
|
451
450
|
|
|
@@ -505,7 +504,7 @@ module Selenium
|
|
|
505
504
|
end
|
|
506
505
|
|
|
507
506
|
def element_displayed?(element)
|
|
508
|
-
WebDriver.logger.
|
|
507
|
+
WebDriver.logger.debug 'Using script for :isDisplayed', id: :script
|
|
509
508
|
execute_atom :isDisplayed, element
|
|
510
509
|
end
|
|
511
510
|
|
|
@@ -521,7 +520,7 @@ module Selenium
|
|
|
521
520
|
Element.new self, element_id_from(execute(:get_active_element))
|
|
522
521
|
end
|
|
523
522
|
|
|
524
|
-
|
|
523
|
+
alias switch_to_active_element active_element
|
|
525
524
|
|
|
526
525
|
def find_element_by(how, what, parent_ref = [])
|
|
527
526
|
how, what = convert_locator(how, what)
|
|
@@ -564,6 +563,39 @@ module Selenium
|
|
|
564
563
|
ShadowRoot.new self, shadow_root_id_from(id)
|
|
565
564
|
end
|
|
566
565
|
|
|
566
|
+
#
|
|
567
|
+
# virtual-authenticator
|
|
568
|
+
#
|
|
569
|
+
|
|
570
|
+
def add_virtual_authenticator(options)
|
|
571
|
+
authenticator_id = execute :add_virtual_authenticator, {}, options.as_json
|
|
572
|
+
VirtualAuthenticator.new(self, authenticator_id, options)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def remove_virtual_authenticator(id)
|
|
576
|
+
execute :remove_virtual_authenticator, {authenticatorId: id}
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
def add_credential(credential, id)
|
|
580
|
+
execute :add_credential, {authenticatorId: id}, credential
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
def credentials(authenticator_id)
|
|
584
|
+
execute :get_credentials, {authenticatorId: authenticator_id}
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
def remove_credential(credential_id, authenticator_id)
|
|
588
|
+
execute :remove_credential, {credentialId: credential_id, authenticatorId: authenticator_id}
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
def remove_all_credentials(authenticator_id)
|
|
592
|
+
execute :remove_all_credentials, {authenticatorId: authenticator_id}
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
def user_verified(verified, authenticator_id)
|
|
596
|
+
execute :set_user_verified, {authenticatorId: authenticator_id}, {isUserVerified: verified}
|
|
597
|
+
end
|
|
598
|
+
|
|
567
599
|
private
|
|
568
600
|
|
|
569
601
|
#
|
|
@@ -584,7 +616,7 @@ module Selenium
|
|
|
584
616
|
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
|
585
617
|
end
|
|
586
618
|
|
|
587
|
-
WebDriver.logger.
|
|
619
|
+
WebDriver.logger.debug("-> #{verb.to_s.upcase} #{path}", id: :command)
|
|
588
620
|
http.call(verb, path, command_hash)['value']
|
|
589
621
|
end
|
|
590
622
|
|
|
@@ -639,8 +671,6 @@ module Selenium
|
|
|
639
671
|
when 'name'
|
|
640
672
|
how = 'css selector'
|
|
641
673
|
what = "*[name='#{escape_css(what.to_s)}']"
|
|
642
|
-
when 'tag name'
|
|
643
|
-
how = 'css selector'
|
|
644
674
|
end
|
|
645
675
|
|
|
646
676
|
if what.is_a?(Hash)
|
|
@@ -653,7 +683,7 @@ module Selenium
|
|
|
653
683
|
[how, what]
|
|
654
684
|
end
|
|
655
685
|
|
|
656
|
-
ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])
|
|
686
|
+
ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]()])/
|
|
657
687
|
UNICODE_CODE_POINT = 30
|
|
658
688
|
|
|
659
689
|
# Escapes invalid characters in CSS selector.
|
|
@@ -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,
|
|
@@ -55,60 +53,11 @@ module Selenium
|
|
|
55
53
|
end
|
|
56
54
|
end
|
|
57
55
|
|
|
58
|
-
#
|
|
59
|
-
# Backward compatibility
|
|
60
|
-
#
|
|
61
|
-
|
|
62
|
-
alias_method :version, :browser_version
|
|
63
|
-
alias_method :version=, :browser_version=
|
|
64
|
-
alias_method :platform, :platform_name
|
|
65
|
-
alias_method :platform=, :platform_name=
|
|
66
|
-
|
|
67
56
|
#
|
|
68
57
|
# Convenience methods for the common choices.
|
|
69
58
|
#
|
|
70
59
|
|
|
71
60
|
class << self
|
|
72
|
-
def chrome(opts = {})
|
|
73
|
-
new({
|
|
74
|
-
browser_name: 'chrome'
|
|
75
|
-
}.merge(opts))
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def edge(opts = {})
|
|
79
|
-
new({
|
|
80
|
-
browser_name: 'MicrosoftEdge'
|
|
81
|
-
}.merge(opts))
|
|
82
|
-
end
|
|
83
|
-
alias_method :microsoftedge, :edge
|
|
84
|
-
|
|
85
|
-
def firefox(opts = {})
|
|
86
|
-
new({
|
|
87
|
-
browser_name: 'firefox'
|
|
88
|
-
}.merge(opts))
|
|
89
|
-
end
|
|
90
|
-
alias_method :ff, :firefox
|
|
91
|
-
|
|
92
|
-
def safari(opts = {})
|
|
93
|
-
new({
|
|
94
|
-
browser_name: Selenium::WebDriver::Safari.technology_preview? ? "Safari Technology Preview" : 'safari'
|
|
95
|
-
}.merge(opts))
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def htmlunit(opts = {})
|
|
99
|
-
new({
|
|
100
|
-
browser_name: 'htmlunit'
|
|
101
|
-
}.merge(opts))
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def internet_explorer(opts = {})
|
|
105
|
-
new({
|
|
106
|
-
browser_name: 'internet explorer',
|
|
107
|
-
platform_name: :windows
|
|
108
|
-
}.merge(opts))
|
|
109
|
-
end
|
|
110
|
-
alias_method :ie, :internet_explorer
|
|
111
|
-
|
|
112
61
|
def always_match(capabilities)
|
|
113
62
|
new(always_match: capabilities)
|
|
114
63
|
end
|
|
@@ -134,7 +83,8 @@ module Selenium
|
|
|
134
83
|
|
|
135
84
|
# Remote Server Specific
|
|
136
85
|
if data.key?('webdriver.remote.sessionid')
|
|
137
|
-
caps[:remote_session_id] =
|
|
86
|
+
caps[:remote_session_id] =
|
|
87
|
+
data.delete('webdriver.remote.sessionid')
|
|
138
88
|
end
|
|
139
89
|
|
|
140
90
|
KNOWN.each do |cap|
|
|
@@ -269,7 +219,7 @@ module Selenium
|
|
|
269
219
|
as_json == other.as_json
|
|
270
220
|
end
|
|
271
221
|
|
|
272
|
-
|
|
222
|
+
alias eql? ==
|
|
273
223
|
|
|
274
224
|
protected
|
|
275
225
|
|