selenium-webdriver 4.1.0 → 4.28.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 +446 -1
- data/Gemfile +4 -0
- data/LICENSE +1 -1
- data/NOTICE +1 -1
- data/README.md +3 -3
- 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 +41 -43
- data/lib/selenium/webdriver/atoms/findElements.js +52 -50
- data/lib/selenium/webdriver/atoms/getAttribute.js +6 -100
- data/lib/selenium/webdriver/atoms/isDisplayed.js +24 -96
- 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 +100 -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/{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_handler.rb +65 -0
- data/lib/selenium/webdriver/bidi/log_inspector.rb +147 -0
- data/lib/selenium/webdriver/bidi/network.rb +82 -0
- data/lib/selenium/webdriver/bidi/session.rb +51 -0
- data/lib/selenium/webdriver/bidi/struct.rb +42 -0
- data/lib/selenium/webdriver/bidi.rb +67 -0
- data/lib/selenium/webdriver/chrome/driver.rb +9 -29
- data/lib/selenium/webdriver/chrome/features.rb +9 -67
- 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 +5 -19
- data/lib/selenium/webdriver/chrome.rb +0 -16
- data/lib/selenium/webdriver/chromium/driver.rb +61 -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 +60 -22
- data/lib/selenium/webdriver/common/child_process.rb +136 -0
- data/lib/selenium/webdriver/common/driver.rb +54 -89
- 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_fedcm_dialog.rb +55 -0
- 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 +9 -3
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +8 -68
- 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 +97 -0
- data/lib/selenium/webdriver/common/element.rb +8 -8
- data/lib/selenium/webdriver/common/error.rb +29 -4
- data/lib/selenium/webdriver/common/fedcm/account.rb +49 -0
- data/lib/selenium/webdriver/common/fedcm/dialog.rb +74 -0
- data/lib/selenium/webdriver/common/fedcm.rb +27 -0
- 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 -71
- data/lib/selenium/webdriver/common/{driver_extensions/has_network_connection.rb → interactions/pointer_cancel.rb} +19 -11
- 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 +114 -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 +53 -0
- data/lib/selenium/webdriver/common/logger.rb +93 -28
- data/lib/selenium/webdriver/common/manager.rb +2 -29
- data/lib/selenium/webdriver/common/network.rb +64 -0
- data/lib/selenium/webdriver/common/options.rb +19 -19
- data/lib/selenium/webdriver/common/platform.rb +12 -52
- 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 +4 -4
- data/lib/selenium/webdriver/common/script.rb +45 -0
- data/lib/selenium/webdriver/common/search_context.rb +10 -8
- data/lib/selenium/webdriver/common/selenium_manager.rb +104 -0
- data/lib/selenium/webdriver/common/service.rb +24 -26
- data/lib/selenium/webdriver/common/service_manager.rb +9 -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 +3 -3
- data/lib/selenium/webdriver/common/takes_screenshot.rb +6 -5
- data/lib/selenium/webdriver/common/target_locator.rb +5 -5
- 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/wait.rb +1 -1
- data/lib/selenium/webdriver/common/websocket_connection.rb +176 -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 +27 -5
- 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 +8 -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 +9 -2
- data/lib/selenium/webdriver/firefox/features.rb +11 -7
- data/lib/selenium/webdriver/firefox/options.rb +10 -16
- data/lib/selenium/webdriver/firefox/profile.rb +21 -17
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +1 -1
- data/lib/selenium/webdriver/firefox/service.rb +1 -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/features.rb +34 -0
- data/lib/selenium/webdriver/ie/options.rb +6 -4
- data/lib/selenium/webdriver/ie/service.rb +1 -22
- data/lib/selenium/webdriver/ie.rb +4 -17
- data/lib/selenium/webdriver/remote/bidi_bridge.rb +66 -0
- data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +22 -9
- data/lib/selenium/webdriver/remote/bridge/locator_converter.rb +76 -0
- data/lib/selenium/webdriver/remote/bridge.rb +158 -100
- data/lib/selenium/webdriver/remote/capabilities.rb +5 -55
- 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 +26 -6
- data/lib/selenium/webdriver/remote/http/curb.rb +10 -6
- data/lib/selenium/webdriver/remote/http/default.rb +8 -14
- data/lib/selenium/webdriver/remote/response.rb +14 -22
- data/lib/selenium/webdriver/remote/server_error.rb +2 -2
- data/lib/selenium/webdriver/remote.rb +3 -2
- 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 +22 -22
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
- data/lib/selenium/webdriver/support/guards/guard.rb +14 -14
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -3
- data/lib/selenium/webdriver/support/guards.rb +4 -4
- 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 +7 -5
- data/selenium-webdriver.gemspec +22 -16
- metadata +137 -47
- 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
@@ -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
|
@@ -60,75 +59,16 @@ module Selenium
|
|
60
59
|
# @yieldparam [Proc] continue block which proceeds with the request and optionally yields response
|
61
60
|
#
|
62
61
|
|
63
|
-
def intercept(&
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
62
|
+
def intercept(&)
|
63
|
+
if browser == :firefox
|
64
|
+
WebDriver.logger.deprecate(
|
65
|
+
'Driver#intercept on Firefox',
|
66
|
+
'the new bidi.network.add_intercept method',
|
67
|
+
id: :intercept
|
123
68
|
)
|
124
69
|
end
|
125
|
-
|
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.
|
70
|
+
@interceptor ||= DevTools::NetworkInterceptor.new(devtools)
|
71
|
+
@interceptor.intercept(&)
|
132
72
|
end
|
133
73
|
end # HasNetworkInterception
|
134
74
|
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
|
#
|
@@ -62,7 +61,7 @@ module Selenium
|
|
62
61
|
#
|
63
62
|
# Unpins script making it undefined for the subsequent calls.
|
64
63
|
#
|
65
|
-
# @param [DevTools::PinnedScript]
|
64
|
+
# @param [DevTools::PinnedScript] script
|
66
65
|
#
|
67
66
|
|
68
67
|
def unpin_script(script)
|
@@ -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,97 @@
|
|
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, service_class)
|
24
|
+
WebDriver.logger.deprecate('DriverFinder.path(options, service_class)',
|
25
|
+
'DriverFinder.new(options, service).driver_path')
|
26
|
+
new(options, service_class.new).driver_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(options, service)
|
30
|
+
@options = options
|
31
|
+
@service = service
|
32
|
+
end
|
33
|
+
|
34
|
+
def browser_path
|
35
|
+
paths[:browser_path]
|
36
|
+
end
|
37
|
+
|
38
|
+
def driver_path
|
39
|
+
paths[:driver_path]
|
40
|
+
end
|
41
|
+
|
42
|
+
def browser_path?
|
43
|
+
!browser_path.nil? && !browser_path.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def paths
|
49
|
+
@paths ||= begin
|
50
|
+
path = @service.class.driver_path
|
51
|
+
path = path.call if path.is_a?(Proc)
|
52
|
+
exe = @service.class::EXECUTABLE
|
53
|
+
if path
|
54
|
+
WebDriver.logger.debug("Skipping Selenium Manager; path to #{exe} specified in service class: #{path}")
|
55
|
+
Platform.assert_executable(path)
|
56
|
+
{driver_path: path}
|
57
|
+
else
|
58
|
+
output = SeleniumManager.binary_paths(*to_args)
|
59
|
+
formatted = {driver_path: Platform.cygwin_path(output['driver_path'], only_cygwin: true),
|
60
|
+
browser_path: Platform.cygwin_path(output['browser_path'], only_cygwin: true)}
|
61
|
+
Platform.assert_executable(formatted[:driver_path])
|
62
|
+
|
63
|
+
browser_path = formatted[:browser_path]
|
64
|
+
Platform.assert_executable(browser_path)
|
65
|
+
if @options.respond_to?(:binary) && @options.binary.nil?
|
66
|
+
@options.binary = browser_path
|
67
|
+
@options.browser_version = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
formatted
|
71
|
+
end
|
72
|
+
rescue StandardError => e
|
73
|
+
WebDriver.logger.error("Exception occurred: #{e.message}")
|
74
|
+
WebDriver.logger.error("Backtrace:\n\t#{e.backtrace&.join("\n\t")}")
|
75
|
+
raise Error::NoSuchDriverError, "Unable to obtain #{exe}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_args
|
80
|
+
args = ['--browser', @options.browser_name]
|
81
|
+
if @options.browser_version
|
82
|
+
args << '--browser-version'
|
83
|
+
args << @options.browser_version
|
84
|
+
end
|
85
|
+
if @options.respond_to?(:binary) && !@options.binary.nil?
|
86
|
+
args << '--browser-path'
|
87
|
+
args << @options.binary.gsub('\\', '\\\\\\')
|
88
|
+
end
|
89
|
+
if @options.proxy
|
90
|
+
args << '--proxy'
|
91
|
+
args << (@options.proxy.ssl || @options.proxy.http)
|
92
|
+
end
|
93
|
+
args
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -43,10 +43,10 @@ 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
|
-
@id
|
49
|
+
[@id, @bridge].hash
|
50
50
|
end
|
51
51
|
|
52
52
|
#
|
@@ -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
|
@@ -20,7 +20,6 @@
|
|
20
20
|
module Selenium
|
21
21
|
module WebDriver
|
22
22
|
module Error
|
23
|
-
|
24
23
|
#
|
25
24
|
# Returns exception from its string representation.
|
26
25
|
# @param [String, nil] error
|
@@ -29,13 +28,34 @@ module Selenium
|
|
29
28
|
def self.for_error(error)
|
30
29
|
return if error.nil?
|
31
30
|
|
32
|
-
klass_name = error.split
|
33
|
-
const_get("#{klass_name}Error", false)
|
31
|
+
klass_name = error.split.map(&:capitalize).join.sub(/Error$/, '')
|
32
|
+
const_get(:"#{klass_name}Error", false)
|
34
33
|
rescue NameError
|
35
34
|
WebDriverError
|
36
35
|
end
|
37
36
|
|
38
|
-
|
37
|
+
SUPPORT_MSG = 'For documentation on this error, please visit:'
|
38
|
+
ERROR_URL = 'https://www.selenium.dev/documentation/webdriver/troubleshooting/errors'
|
39
|
+
|
40
|
+
URLS = {
|
41
|
+
NoSuchElementError: "#{ERROR_URL}#no-such-element-exception",
|
42
|
+
StaleElementReferenceError: "#{ERROR_URL}#stale-element-reference-exception",
|
43
|
+
InvalidSelectorError: "#{ERROR_URL}#invalid-selector-exception",
|
44
|
+
NoSuchDriverError: "#{ERROR_URL}/driver_location"
|
45
|
+
}.freeze
|
46
|
+
|
47
|
+
class WebDriverError < StandardError
|
48
|
+
def initialize(msg = '')
|
49
|
+
# Remove this conditional when all the error pages have been documented
|
50
|
+
super(URLS[class_name] ? "#{msg}; #{SUPPORT_MSG} #{URLS[class_name]}" : msg)
|
51
|
+
end
|
52
|
+
|
53
|
+
# steep:ignore:start
|
54
|
+
def class_name
|
55
|
+
self.class.name.split('::')&.last&.to_sym
|
56
|
+
end
|
57
|
+
# steep:ignore:end
|
58
|
+
end
|
39
59
|
|
40
60
|
#
|
41
61
|
# An element could not be located on the page using the given search parameters.
|
@@ -214,6 +234,11 @@ module Selenium
|
|
214
234
|
|
215
235
|
class UnsupportedOperationError < WebDriverError; end
|
216
236
|
|
237
|
+
#
|
238
|
+
# Indicates that driver was not specified and could not be located.
|
239
|
+
#
|
240
|
+
|
241
|
+
class NoSuchDriverError < WebDriverError; end
|
217
242
|
end # Error
|
218
243
|
end # WebDriver
|
219
244
|
end # Selenium
|
@@ -0,0 +1,49 @@
|
|
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 FedCM
|
23
|
+
# Represents an account displayed in a FedCm account list.
|
24
|
+
# See: https://w3c-fedid.github.io/FedCM/#dictdef-identityprovideraccount
|
25
|
+
# https://w3c-fedid.github.io/FedCM/#webdriver-accountlist
|
26
|
+
class Account
|
27
|
+
LOGIN_STATE_SIGNIN = 'SignIn'
|
28
|
+
LOGIN_STATE_SIGNUP = 'SignUp'
|
29
|
+
|
30
|
+
attr_reader :account_id, :email, :name, :given_name, :picture_url,
|
31
|
+
:idp_config_url, :login_state, :terms_of_service_url, :privacy_policy_url
|
32
|
+
|
33
|
+
# steep:ignore:start
|
34
|
+
def initialize(**args)
|
35
|
+
@account_id = args['accountId']
|
36
|
+
@email = args['email']
|
37
|
+
@name = args['name']
|
38
|
+
@given_name = args['givenName']
|
39
|
+
@picture_url = args['pictureUrl']
|
40
|
+
@idp_config_url = args['idpConfigUrl']
|
41
|
+
@login_state = args['loginState']
|
42
|
+
@terms_of_service_url = args['termsOfServiceUrl']
|
43
|
+
@privacy_policy_url = args['privacyPolicyUrl']
|
44
|
+
end
|
45
|
+
# steep:ignore:end
|
46
|
+
end # Account
|
47
|
+
end # FedCM
|
48
|
+
end # WebDriver
|
49
|
+
end # Selenium
|
@@ -0,0 +1,74 @@
|
|
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 FedCM
|
23
|
+
class Dialog
|
24
|
+
def initialize(bridge)
|
25
|
+
@bridge = bridge
|
26
|
+
end
|
27
|
+
|
28
|
+
DIALOG_TYPE_ACCOUNT_LIST = 'AccountChooser'
|
29
|
+
DIALOG_TYPE_AUTO_REAUTH = 'AutoReauthn'
|
30
|
+
|
31
|
+
# Closes the dialog as if the user had clicked X.
|
32
|
+
def click
|
33
|
+
@bridge.click_fedcm_dialog_button
|
34
|
+
end
|
35
|
+
|
36
|
+
# Closes the dialog as if the user had clicked X.
|
37
|
+
def cancel
|
38
|
+
@bridge.cancel_fedcm_dialog
|
39
|
+
end
|
40
|
+
|
41
|
+
# Selects an account as if the user had clicked on it.
|
42
|
+
#
|
43
|
+
# @param [Integer] index The index of the account to select from the list returned by get_accounts.
|
44
|
+
def select_account(index)
|
45
|
+
@bridge.select_fedcm_account index
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the type of the open dialog.
|
49
|
+
#
|
50
|
+
# One of DIALOG_TYPE_ACCOUNT_LIST and DIALOG_TYPE_AUTO_REAUTH.
|
51
|
+
def type
|
52
|
+
@bridge.fedcm_dialog_type
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the title of the dialog.
|
56
|
+
def title
|
57
|
+
@bridge.fedcm_title
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the subtitle of the dialog or nil if none.
|
61
|
+
def subtitle
|
62
|
+
@bridge.fedcm_subtitle
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the accounts shown in the account chooser.
|
66
|
+
#
|
67
|
+
# If this is an auto reauth dialog, returns the single account that is being signed in.
|
68
|
+
def accounts
|
69
|
+
@bridge.fedcm_account_list.map { |account| Account.new(**account) }
|
70
|
+
end
|
71
|
+
end # Dialog
|
72
|
+
end # FedCM
|
73
|
+
end # WebDriver
|
74
|
+
end # Selenium
|
@@ -0,0 +1,27 @@
|
|
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 FedCM
|
23
|
+
autoload :Account, 'fedcm/account'
|
24
|
+
autoload :Dialog, 'fedcm/dialog'
|
25
|
+
end # FedCM
|
26
|
+
end # WebDriver
|
27
|
+
end # Selenium
|
@@ -22,8 +22,15 @@ require 'securerandom'
|
|
22
22
|
module Selenium
|
23
23
|
module WebDriver
|
24
24
|
module Interactions
|
25
|
+
#
|
26
|
+
# Superclass for the input device sources
|
27
|
+
# Manages Array of Interaction instances for the device
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
|
25
32
|
class InputDevice
|
26
|
-
attr_reader :name, :actions
|
33
|
+
attr_reader :name, :actions, :type
|
27
34
|
|
28
35
|
def initialize(name = nil)
|
29
36
|
@name = name || SecureRandom.uuid
|
@@ -44,9 +51,8 @@ module Selenium
|
|
44
51
|
add_action(Pause.new(self, duration))
|
45
52
|
end
|
46
53
|
|
47
|
-
def
|
48
|
-
actions
|
49
|
-
actions.empty?
|
54
|
+
def encode
|
55
|
+
{type: type, id: name, actions: @actions.map(&:encode)} unless @actions.empty?
|
50
56
|
end
|
51
57
|
end # InputDevice
|
52
58
|
end # Interactions
|
@@ -20,37 +20,24 @@
|
|
20
20
|
module Selenium
|
21
21
|
module WebDriver
|
22
22
|
module Interactions
|
23
|
-
|
24
|
-
|
23
|
+
#
|
24
|
+
# Superclass for classes defining actions
|
25
|
+
# Do not initialize directly, only use subclass
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
#
|
25
29
|
|
26
|
-
|
30
|
+
class Interaction
|
31
|
+
attr_reader :type
|
27
32
|
|
28
33
|
def initialize(source)
|
29
|
-
|
30
|
-
raise TypeError,
|
31
|
-
"#{source.type} is not a valid input type"
|
32
|
-
end
|
33
|
-
|
34
|
-
@source = source
|
34
|
+
assert_source(source)
|
35
35
|
end
|
36
|
-
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
super(source)
|
41
|
-
@duration = duration
|
37
|
+
def assert_source(_source)
|
38
|
+
raise NotImplementedError, 'subclass responsibility'
|
42
39
|
end
|
43
|
-
|
44
|
-
def type
|
45
|
-
PAUSE
|
46
|
-
end
|
47
|
-
|
48
|
-
def encode
|
49
|
-
output = {type: type}
|
50
|
-
output[:duration] = (@duration * 1000).to_i if @duration
|
51
|
-
output
|
52
|
-
end
|
53
|
-
end # Interaction
|
40
|
+
end
|
54
41
|
end # Interactions
|
55
42
|
end # WebDriver
|
56
43
|
end # Selenium
|
@@ -23,20 +23,40 @@ module Selenium
|
|
23
23
|
KEY = :key
|
24
24
|
POINTER = :pointer
|
25
25
|
NONE = :none
|
26
|
-
|
26
|
+
WHEEL = :wheel
|
27
|
+
|
28
|
+
#
|
29
|
+
# Class methods for initializing known Input devices
|
30
|
+
#
|
27
31
|
|
28
32
|
class << self
|
29
|
-
def key(name)
|
33
|
+
def key(name = nil)
|
30
34
|
KeyInput.new(name)
|
31
35
|
end
|
32
36
|
|
33
|
-
def pointer(kind,
|
34
|
-
PointerInput.new(kind,
|
37
|
+
def pointer(kind = :mouse, name: nil)
|
38
|
+
PointerInput.new(kind, name: name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def mouse(name: nil)
|
42
|
+
pointer(name: name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def pen(name: nil)
|
46
|
+
pointer(:pen, name: name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def touch(name: nil)
|
50
|
+
pointer(:touch, name: name)
|
35
51
|
end
|
36
52
|
|
37
53
|
def none(name = nil)
|
38
54
|
NoneInput.new(name)
|
39
55
|
end
|
56
|
+
|
57
|
+
def wheel(name = nil)
|
58
|
+
WheelInput.new(name)
|
59
|
+
end
|
40
60
|
end
|
41
61
|
end # Interactions
|
42
62
|
end # WebDriver
|
@@ -134,12 +134,16 @@ module Selenium
|
|
134
134
|
#
|
135
135
|
|
136
136
|
def key_action(*args, action: nil, device: nil)
|
137
|
-
key_input =
|
137
|
+
key_input = key_input(device)
|
138
138
|
click(args.shift) if args.first.is_a? Element
|
139
139
|
key_input.send(action, args.last)
|
140
140
|
tick(key_input)
|
141
141
|
self
|
142
142
|
end
|
143
|
+
|
144
|
+
def key_input(name = nil)
|
145
|
+
device(name: name, type: Interactions::KEY) || add_key_input('keyboard')
|
146
|
+
end
|
143
147
|
end # KeyActions
|
144
148
|
end # WebDriver
|
145
149
|
end # Selenium
|