selenium-webdriver 4.4.0 → 4.8.1
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 +98 -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 +20 -16
- 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 +13 -0
- data/lib/selenium/webdriver/bidi.rb +3 -2
- data/lib/selenium/webdriver/chrome/driver.rb +19 -28
- data/lib/selenium/webdriver/chrome/features.rb +5 -72
- data/lib/selenium/webdriver/chrome/options.rb +3 -237
- data/lib/selenium/webdriver/chrome/profile.rb +3 -83
- data/lib/selenium/webdriver/chrome/service.rb +4 -19
- 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 +11 -48
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +39 -26
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_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 +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +0 -2
- data/lib/selenium/webdriver/common/element.rb +7 -7
- data/lib/selenium/webdriver/common/error.rb +0 -2
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +3 -3
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/scroll.rb +7 -5
- data/lib/selenium/webdriver/common/logger.rb +10 -2
- data/lib/selenium/webdriver/common/options.rb +30 -8
- data/lib/selenium/webdriver/common/platform.rb +4 -1
- data/lib/selenium/webdriver/common/profile_helper.rb +1 -1
- data/lib/selenium/webdriver/common/proxy.rb +1 -1
- data/lib/selenium/webdriver/common/selenium_manager.rb +89 -0
- data/lib/selenium/webdriver/common/service.rb +16 -8
- data/lib/selenium/webdriver/common/service_manager.rb +2 -10
- data/lib/selenium/webdriver/common/shadow_root.rb +1 -2
- data/lib/selenium/webdriver/common/socket_lock.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 +8 -6
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator.rb +0 -1
- data/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb +16 -16
- data/lib/selenium/webdriver/common/websocket_connection.rb +10 -2
- data/lib/selenium/webdriver/common.rb +2 -0
- 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 +3 -6
- data/lib/selenium/webdriver/devtools/pinned_script.rb +0 -2
- data/lib/selenium/webdriver/devtools/request.rb +0 -2
- data/lib/selenium/webdriver/devtools/response.rb +0 -2
- data/lib/selenium/webdriver/devtools.rb +0 -1
- data/lib/selenium/webdriver/edge/driver.rb +20 -3
- data/lib/selenium/webdriver/edge/features.rb +3 -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 -2
- data/lib/selenium/webdriver/firefox/driver.rb +19 -2
- data/lib/selenium/webdriver/firefox/features.rb +5 -2
- data/lib/selenium/webdriver/firefox/options.rb +6 -2
- data/lib/selenium/webdriver/firefox/profile.rb +6 -6
- data/lib/selenium/webdriver/firefox/service.rb +0 -1
- data/lib/selenium/webdriver/ie/driver.rb +20 -1
- data/lib/selenium/webdriver/ie/service.rb +1 -2
- data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +0 -2
- data/lib/selenium/webdriver/remote/bridge.rb +9 -15
- data/lib/selenium/webdriver/remote/capabilities.rb +34 -12
- data/lib/selenium/webdriver/remote/driver.rb +13 -13
- data/lib/selenium/webdriver/remote/http/curb.rb +0 -2
- data/lib/selenium/webdriver/remote/http/default.rb +1 -0
- data/lib/selenium/webdriver/remote/response.rb +0 -1
- data/lib/selenium/webdriver/remote.rb +0 -1
- data/lib/selenium/webdriver/safari/driver.rb +20 -1
- data/lib/selenium/webdriver/safari/features.rb +0 -2
- data/lib/selenium/webdriver/safari/options.rb +5 -1
- data/lib/selenium/webdriver/safari.rb +1 -1
- data/lib/selenium/webdriver/support/color.rb +15 -15
- data/lib/selenium/webdriver/support/guards/guard.rb +0 -2
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +0 -2
- 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 +3 -4
- data/selenium-webdriver.gemspec +8 -9
- metadata +31 -74
- data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +0 -108
|
@@ -25,24 +25,24 @@
|
|
|
25
25
|
module Selenium
|
|
26
26
|
module WebDriver
|
|
27
27
|
class VirtualAuthenticatorOptions
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
TRANSPORT = {ble: "ble", usb: "usb", nfc: "nfc", internal: "internal"}.freeze
|
|
28
|
+
PROTOCOL = {ctap2: 'ctap2', u2f: 'ctap1/u2f'}.freeze
|
|
29
|
+
TRANSPORT = {ble: 'ble', usb: 'usb', nfc: 'nfc', internal: 'internal'}.freeze
|
|
31
30
|
|
|
32
31
|
attr_accessor :protocol, :transport, :resident_key, :user_verification, :user_consenting, :user_verified
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def initialize(
|
|
39
|
-
|
|
40
|
-
@
|
|
41
|
-
@
|
|
42
|
-
@
|
|
43
|
-
@
|
|
44
|
-
@
|
|
45
|
-
|
|
32
|
+
alias resident_key? resident_key
|
|
33
|
+
alias user_verification? user_verification
|
|
34
|
+
alias user_consenting? user_consenting
|
|
35
|
+
alias user_verified? user_verified
|
|
36
|
+
|
|
37
|
+
def initialize(**opts)
|
|
38
|
+
@protocol = opts.delete(:protocol) { :ctap2 }
|
|
39
|
+
@transport = opts.delete(:transport) { :usb }
|
|
40
|
+
@resident_key = opts.delete(:resident_key) { false }
|
|
41
|
+
@user_verification = opts.delete(:user_verification) { false }
|
|
42
|
+
@user_consenting = opts.delete(:user_consenting) { true }
|
|
43
|
+
@user_verified = opts.delete(:user_verified) { false }
|
|
44
|
+
|
|
45
|
+
raise ArgumentError, "Invalid arguments: #{opts.keys}" unless opts.empty?
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
#
|
|
@@ -22,6 +22,11 @@ require 'websocket'
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
class WebSocketConnection
|
|
25
|
+
CONNECTION_ERRORS = [
|
|
26
|
+
Errno::ECONNRESET, # connection is aborted (browser process was killed)
|
|
27
|
+
Errno::EPIPE # broken pipe (browser process was killed)
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
25
30
|
RESPONSE_WAIT_TIMEOUT = 30
|
|
26
31
|
RESPONSE_WAIT_INTERVAL = 0.1
|
|
27
32
|
|
|
@@ -90,6 +95,8 @@ module Selenium
|
|
|
90
95
|
end
|
|
91
96
|
end
|
|
92
97
|
end
|
|
98
|
+
rescue *CONNECTION_ERRORS
|
|
99
|
+
Thread.stop
|
|
93
100
|
end
|
|
94
101
|
end
|
|
95
102
|
|
|
@@ -104,7 +111,7 @@ module Selenium
|
|
|
104
111
|
return {} if message.empty?
|
|
105
112
|
|
|
106
113
|
message = JSON.parse(message)
|
|
107
|
-
messages[message[
|
|
114
|
+
messages[message['id']] = message
|
|
108
115
|
WebDriver.logger.debug "WebSocket <- #{message}"[...MAX_LOG_MESSAGE_SIZE]
|
|
109
116
|
|
|
110
117
|
message
|
|
@@ -122,6 +129,8 @@ module Selenium
|
|
|
122
129
|
Thread.current.report_on_exception = true
|
|
123
130
|
|
|
124
131
|
yield params
|
|
132
|
+
rescue *CONNECTION_ERRORS
|
|
133
|
+
Thread.stop
|
|
125
134
|
end
|
|
126
135
|
end
|
|
127
136
|
|
|
@@ -150,7 +159,6 @@ module Selenium
|
|
|
150
159
|
@id ||= 0
|
|
151
160
|
@id += 1
|
|
152
161
|
end
|
|
153
|
-
|
|
154
162
|
end # BiDi
|
|
155
163
|
end # WebDriver
|
|
156
164
|
end # Selenium
|
|
@@ -22,6 +22,7 @@ require 'selenium/webdriver/common/platform'
|
|
|
22
22
|
require 'selenium/webdriver/common/proxy'
|
|
23
23
|
require 'selenium/webdriver/common/log_entry'
|
|
24
24
|
require 'selenium/webdriver/common/file_reaper'
|
|
25
|
+
require 'selenium/webdriver/common/selenium_manager'
|
|
25
26
|
require 'selenium/webdriver/common/service'
|
|
26
27
|
require 'selenium/webdriver/common/service_manager'
|
|
27
28
|
require 'selenium/webdriver/common/socket_lock'
|
|
@@ -95,3 +96,4 @@ require 'selenium/webdriver/common/driver'
|
|
|
95
96
|
require 'selenium/webdriver/common/element'
|
|
96
97
|
require 'selenium/webdriver/common/shadow_root'
|
|
97
98
|
require 'selenium/webdriver/common/websocket_connection'
|
|
99
|
+
require 'selenium/webdriver/common/child_process'
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
23
|
class ConsoleEvent
|
|
24
|
-
|
|
25
24
|
attr_accessor :type, :timestamp, :args
|
|
26
25
|
|
|
27
26
|
def initialize(type:, timestamp:, args:)
|
|
@@ -31,7 +30,6 @@ module Selenium
|
|
|
31
30
|
arg.key?('value') ? arg['value'] : arg
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
|
-
|
|
35
33
|
end # ConsoleEvent
|
|
36
34
|
end # DevTools
|
|
37
35
|
end # WebDriver
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
23
|
class ExceptionEvent
|
|
24
|
-
|
|
25
24
|
attr_accessor :description, :timestamp, :stacktrace
|
|
26
25
|
|
|
27
26
|
def initialize(description:, timestamp:, stacktrace:)
|
|
@@ -29,7 +28,6 @@ module Selenium
|
|
|
29
28
|
@timestamp = Time.at(timestamp / 1000)
|
|
30
29
|
@stacktrace = stacktrace
|
|
31
30
|
end
|
|
32
|
-
|
|
33
31
|
end # ExceptionEvent
|
|
34
32
|
end # DevTools
|
|
35
33
|
end # WebDriver
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
23
|
class MutationEvent
|
|
24
|
-
|
|
25
24
|
attr_accessor :element, :attribute_name, :current_value, :old_value
|
|
26
25
|
|
|
27
26
|
def initialize(element:, attribute_name:, current_value:, old_value:)
|
|
@@ -30,7 +29,6 @@ module Selenium
|
|
|
30
29
|
@current_value = current_value
|
|
31
30
|
@old_value = old_value
|
|
32
31
|
end
|
|
33
|
-
|
|
34
32
|
end # MutationEvent
|
|
35
33
|
end # DevTools
|
|
36
34
|
end # WebDriver
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Wraps the network request/response interception, providing
|
|
26
25
|
# thread-safety guarantees and handling special cases such as browser
|
|
@@ -31,14 +30,13 @@ module Selenium
|
|
|
31
30
|
#
|
|
32
31
|
|
|
33
32
|
class NetworkInterceptor
|
|
34
|
-
|
|
35
33
|
# CDP fails to get body on certain responses (301) and raises:
|
|
36
34
|
# "Can only get response body on requests captured after headers received."
|
|
37
|
-
CANNOT_GET_BODY_ON_REDIRECT_ERROR_CODE =
|
|
35
|
+
CANNOT_GET_BODY_ON_REDIRECT_ERROR_CODE = '-32000'
|
|
38
36
|
|
|
39
37
|
# CDP fails to operate with intercepted requests.
|
|
40
38
|
# Typical reason is browser cancelling intercepted requests/responses.
|
|
41
|
-
INVALID_INTERCEPTION_ID_ERROR_CODE =
|
|
39
|
+
INVALID_INTERCEPTION_ID_ERROR_CODE = '-32602'
|
|
42
40
|
|
|
43
41
|
def initialize(devtools)
|
|
44
42
|
@devtools = devtools
|
|
@@ -129,7 +127,7 @@ module Selenium
|
|
|
129
127
|
def continue_request(id)
|
|
130
128
|
devtools.fetch.continue_request(request_id: id)
|
|
131
129
|
end
|
|
132
|
-
|
|
130
|
+
alias continue_response continue_request
|
|
133
131
|
|
|
134
132
|
def mutate_request(request)
|
|
135
133
|
devtools.fetch.continue_request(
|
|
@@ -169,7 +167,6 @@ module Selenium
|
|
|
169
167
|
def cancelled?(network_id)
|
|
170
168
|
lock.synchronize { !!cancelled_requests.delete(network_id) }
|
|
171
169
|
end
|
|
172
|
-
|
|
173
170
|
end # NetworkInterceptor
|
|
174
171
|
end # DevTools
|
|
175
172
|
end # WebDriver
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
23
|
class PinnedScript
|
|
24
|
-
|
|
25
24
|
attr_accessor :key, :devtools_identifier, :script
|
|
26
25
|
|
|
27
26
|
def initialize(script)
|
|
@@ -52,7 +51,6 @@ module Selenium
|
|
|
52
51
|
def remove
|
|
53
52
|
"__webdriver_#{key} = undefined"
|
|
54
53
|
end
|
|
55
|
-
|
|
56
54
|
end # PinnedScript
|
|
57
55
|
end # DevTools
|
|
58
56
|
end # WebDriver
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
23
|
class Request
|
|
24
|
-
|
|
25
24
|
attr_accessor :url, :method, :headers, :post_data
|
|
26
25
|
attr_reader :id
|
|
27
26
|
|
|
@@ -60,7 +59,6 @@ module Selenium
|
|
|
60
59
|
def inspect
|
|
61
60
|
%(#<#{self.class.name} @id="#{id}" @method="#{method}" @url="#{url}")
|
|
62
61
|
end
|
|
63
|
-
|
|
64
62
|
end # Request
|
|
65
63
|
end # DevTools
|
|
66
64
|
end # WebDriver
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
23
|
class Response
|
|
24
|
-
|
|
25
24
|
attr_accessor :code, :body, :headers
|
|
26
25
|
attr_reader :id
|
|
27
26
|
|
|
@@ -59,7 +58,6 @@ module Selenium
|
|
|
59
58
|
def inspect
|
|
60
59
|
%(#<#{self.class.name} @id="#{id}" @code="#{code}")
|
|
61
60
|
end
|
|
62
|
-
|
|
63
61
|
end # Response
|
|
64
62
|
end # DevTools
|
|
65
63
|
end # WebDriver
|
|
@@ -17,18 +17,25 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require 'selenium/webdriver/
|
|
20
|
+
require 'selenium/webdriver/chromium/driver'
|
|
21
21
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Edge
|
|
25
|
-
|
|
26
25
|
#
|
|
27
26
|
# Driver implementation for Microsoft Edge.
|
|
28
27
|
# @api private
|
|
29
28
|
#
|
|
30
29
|
|
|
31
|
-
class Driver <
|
|
30
|
+
class Driver < Chromium::Driver
|
|
31
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
32
|
+
raise ArgumentError, "Can't initialize #{self.class} with :url" if url
|
|
33
|
+
|
|
34
|
+
caps = process_options(options, capabilities)
|
|
35
|
+
url = service_url(service || Service.edge)
|
|
36
|
+
super(caps: caps, url: url, **opts)
|
|
37
|
+
end
|
|
38
|
+
|
|
32
39
|
def browser
|
|
33
40
|
:edge
|
|
34
41
|
end
|
|
@@ -38,6 +45,16 @@ module Selenium
|
|
|
38
45
|
def devtools_address
|
|
39
46
|
"http://#{capabilities['ms:edgeOptions']['debuggerAddress']}"
|
|
40
47
|
end
|
|
48
|
+
|
|
49
|
+
def process_options(options, capabilities)
|
|
50
|
+
if options && !options.is_a?(Options)
|
|
51
|
+
raise ArgumentError, ":options must be an instance of #{Options}"
|
|
52
|
+
elsif options.nil? && capabilities.nil?
|
|
53
|
+
options = Options.new
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
super(options, capabilities)
|
|
57
|
+
end
|
|
41
58
|
end # Driver
|
|
42
59
|
end # Edge
|
|
43
60
|
end # WebDriver
|
|
@@ -17,14 +17,13 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require 'selenium/webdriver/
|
|
20
|
+
require 'selenium/webdriver/chromium/features'
|
|
21
21
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Edge
|
|
25
25
|
module Features
|
|
26
|
-
|
|
27
|
-
include WebDriver::Chrome::Features
|
|
26
|
+
include WebDriver::Chromium::Features
|
|
28
27
|
|
|
29
28
|
EDGE_COMMANDS = {
|
|
30
29
|
get_cast_sinks: [:get, 'session/:session_id/ms/cast/get_sinks'],
|
|
@@ -37,7 +36,7 @@ module Selenium
|
|
|
37
36
|
}.freeze
|
|
38
37
|
|
|
39
38
|
def commands(command)
|
|
40
|
-
EDGE_COMMANDS[command] ||
|
|
39
|
+
EDGE_COMMANDS[command] || CHROMIUM_COMMANDS[command] || self.class::COMMANDS[command]
|
|
41
40
|
end
|
|
42
41
|
end # Bridge
|
|
43
42
|
end # Edge
|
|
@@ -17,23 +17,21 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require 'selenium/webdriver/
|
|
20
|
+
require 'selenium/webdriver/chromium/options'
|
|
21
21
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Edge
|
|
25
|
-
class Options <
|
|
25
|
+
class Options < Chromium::Options
|
|
26
26
|
KEY = 'ms:edgeOptions'
|
|
27
27
|
BROWSER = 'MicrosoftEdge'
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
private
|
|
30
30
|
|
|
31
31
|
def enable_logging(browser_options)
|
|
32
32
|
browser_options['ms:loggingPrefs'] = @logging_prefs
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
private
|
|
36
|
-
|
|
37
35
|
def binary_path
|
|
38
36
|
Edge.path
|
|
39
37
|
end
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require 'selenium/webdriver/
|
|
20
|
+
require 'selenium/webdriver/chromium/profile'
|
|
21
21
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
@@ -26,7 +26,7 @@ module Selenium
|
|
|
26
26
|
# @private
|
|
27
27
|
#
|
|
28
28
|
|
|
29
|
-
class Profile <
|
|
29
|
+
class Profile < Chromium::Profile
|
|
30
30
|
end # Profile
|
|
31
31
|
end # Edge
|
|
32
32
|
end # WebDriver
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require 'selenium/webdriver/
|
|
20
|
+
require 'selenium/webdriver/chromium/service'
|
|
21
21
|
|
|
22
22
|
module Selenium
|
|
23
23
|
module WebDriver
|
|
24
24
|
module Edge
|
|
25
|
-
class Service <
|
|
25
|
+
class Service < Chromium::Service
|
|
26
26
|
DEFAULT_PORT = 9515
|
|
27
27
|
EXECUTABLE = 'msedgedriver'
|
|
28
28
|
MISSING_TEXT = <<~ERROR
|
|
@@ -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
|
|
@@ -37,6 +36,14 @@ module Selenium
|
|
|
37
36
|
DriverExtensions::HasWebStorage,
|
|
38
37
|
DriverExtensions::PrintsPage].freeze
|
|
39
38
|
|
|
39
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
40
|
+
raise ArgumentError, "Can't initialize #{self.class} with :url" if url
|
|
41
|
+
|
|
42
|
+
caps = process_options(options, capabilities)
|
|
43
|
+
url = service_url(service || Service.firefox)
|
|
44
|
+
super(caps: caps, url: url, **opts)
|
|
45
|
+
end
|
|
46
|
+
|
|
40
47
|
def browser
|
|
41
48
|
:firefox
|
|
42
49
|
end
|
|
@@ -45,7 +52,7 @@ module Selenium
|
|
|
45
52
|
|
|
46
53
|
def devtools_url
|
|
47
54
|
if capabilities['moz:debuggerAddress'].nil?
|
|
48
|
-
raise(Error::WebDriverError,
|
|
55
|
+
raise(Error::WebDriverError, 'DevTools is not supported by this version of Firefox; use v85 or higher')
|
|
49
56
|
end
|
|
50
57
|
|
|
51
58
|
uri = URI("http://#{capabilities['moz:debuggerAddress']}")
|
|
@@ -57,6 +64,16 @@ module Selenium
|
|
|
57
64
|
def devtools_version
|
|
58
65
|
Firefox::DEVTOOLS_VERSION
|
|
59
66
|
end
|
|
67
|
+
|
|
68
|
+
def process_options(options, capabilities)
|
|
69
|
+
if options && !options.is_a?(Options)
|
|
70
|
+
raise ArgumentError, ":options must be an instance of #{Options}"
|
|
71
|
+
elsif options.nil? && capabilities.nil?
|
|
72
|
+
options = Options.new
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
super(options, capabilities)
|
|
76
|
+
end
|
|
60
77
|
end # Driver
|
|
61
78
|
end # Firefox
|
|
62
79
|
end # WebDriver
|
|
@@ -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,7 +34,11 @@ module Selenium
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def install_addon(path, temporary)
|
|
38
|
-
addon = File.
|
|
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
|
|
39
42
|
|
|
40
43
|
payload = {addon: addon}
|
|
41
44
|
payload[:temporary] = temporary unless temporary.nil?
|
|
@@ -57,7 +57,8 @@ module Selenium
|
|
|
57
57
|
#
|
|
58
58
|
|
|
59
59
|
def initialize(log_level: nil, **opts)
|
|
60
|
-
@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)
|
|
61
62
|
|
|
62
63
|
super(**opts)
|
|
63
64
|
|
|
@@ -107,6 +108,9 @@ module Selenium
|
|
|
107
108
|
#
|
|
108
109
|
|
|
109
110
|
def headless!
|
|
111
|
+
WebDriver.logger.deprecate('`Options#headless!`',
|
|
112
|
+
"`Options#add_argument('-headless')`",
|
|
113
|
+
id: :headless)
|
|
110
114
|
add_argument '-headless'
|
|
111
115
|
end
|
|
112
116
|
|
|
@@ -177,7 +181,7 @@ module Selenium
|
|
|
177
181
|
end
|
|
178
182
|
|
|
179
183
|
def camelize?(key)
|
|
180
|
-
key !=
|
|
184
|
+
key != 'prefs'
|
|
181
185
|
end
|
|
182
186
|
end # Options
|
|
183
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
|
|
@@ -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
|
|
|
@@ -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,9 +29,29 @@ module Selenium
|
|
|
30
29
|
class Driver < WebDriver::Driver
|
|
31
30
|
EXTENSIONS = [DriverExtensions::HasWebStorage].freeze
|
|
32
31
|
|
|
32
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
33
|
+
raise ArgumentError, "Can't initialize #{self.class} with :url" if url
|
|
34
|
+
|
|
35
|
+
caps = process_options(options, capabilities)
|
|
36
|
+
url = service_url(service || Service.ie)
|
|
37
|
+
super(caps: caps, url: url, **opts)
|
|
38
|
+
end
|
|
39
|
+
|
|
33
40
|
def browser
|
|
34
41
|
:internet_explorer
|
|
35
42
|
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def process_options(options, capabilities)
|
|
47
|
+
if options && !options.is_a?(Options)
|
|
48
|
+
raise ArgumentError, ":options must be an instance of #{Options}"
|
|
49
|
+
elsif options.nil? && capabilities.nil?
|
|
50
|
+
options = Options.new
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
super(options, capabilities)
|
|
54
|
+
end
|
|
36
55
|
end # Driver
|
|
37
56
|
end # IE
|
|
38
57
|
end # WebDriver
|
|
@@ -32,7 +32,6 @@ module Selenium
|
|
|
32
32
|
|
|
33
33
|
private
|
|
34
34
|
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
35
|
def extract_service_args(driver_opts)
|
|
37
36
|
driver_args = super
|
|
38
37
|
driver_opts = driver_opts.dup
|
|
@@ -43,7 +42,7 @@ module Selenium
|
|
|
43
42
|
end
|
|
44
43
|
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
|
45
44
|
driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
|
|
46
|
-
driver_args <<
|
|
45
|
+
driver_args << '--silent' if driver_opts[:silent] == true
|
|
47
46
|
driver_args
|
|
48
47
|
end
|
|
49
48
|
end # Server
|
|
@@ -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
|
|
@@ -165,7 +164,6 @@ module Selenium
|
|
|
165
164
|
set_user_verified: [:post, 'session/:session_id/webauthn/authenticator/:authenticatorId/uv']
|
|
166
165
|
|
|
167
166
|
}.freeze
|
|
168
|
-
|
|
169
167
|
end # Bridge
|
|
170
168
|
end # Remote
|
|
171
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
|
|
@@ -186,6 +187,7 @@ module Selenium
|
|
|
186
187
|
execute :delete_session
|
|
187
188
|
http.close
|
|
188
189
|
rescue *QUIT_ERRORS
|
|
190
|
+
nil
|
|
189
191
|
end
|
|
190
192
|
|
|
191
193
|
def close
|
|
@@ -367,18 +369,10 @@ module Selenium
|
|
|
367
369
|
# actions
|
|
368
370
|
#
|
|
369
371
|
|
|
370
|
-
def action(
|
|
371
|
-
ActionBuilder.new self,
|
|
372
|
-
end
|
|
373
|
-
alias_method :actions, :action
|
|
374
|
-
|
|
375
|
-
def mouse
|
|
376
|
-
raise Error::UnsupportedOperationError, '#mouse is no longer supported, use #action instead'
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
def keyboard
|
|
380
|
-
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
|
|
381
374
|
end
|
|
375
|
+
alias actions action
|
|
382
376
|
|
|
383
377
|
def send_actions(data)
|
|
384
378
|
execute :actions, {}, {actions: data}
|
|
@@ -400,7 +394,7 @@ module Selenium
|
|
|
400
394
|
# TODO: rework file detectors before Selenium 4.0
|
|
401
395
|
if @file_detector
|
|
402
396
|
local_files = keys.first&.split("\n")&.map { |key| @file_detector.call(Array(key)) }&.compact
|
|
403
|
-
if local_files
|
|
397
|
+
if local_files&.any?
|
|
404
398
|
keys = local_files.map { |local_file| upload(local_file) }
|
|
405
399
|
keys = Array(keys.join("\n"))
|
|
406
400
|
end
|
|
@@ -425,7 +419,7 @@ module Selenium
|
|
|
425
419
|
end
|
|
426
420
|
|
|
427
421
|
def submit_element(element)
|
|
428
|
-
script = "var form = arguments[0];\n" \
|
|
422
|
+
script = "/* submitForm */ var form = arguments[0];\n" \
|
|
429
423
|
"while (form.nodeName != \"FORM\" && form.parentNode) {\n " \
|
|
430
424
|
"form = form.parentNode;\n" \
|
|
431
425
|
"}\n" \
|
|
@@ -437,7 +431,7 @@ module Selenium
|
|
|
437
431
|
|
|
438
432
|
execute_script(script, Element::ELEMENT_KEY => element)
|
|
439
433
|
rescue Error::JavascriptError
|
|
440
|
-
raise Error::UnsupportedOperationError,
|
|
434
|
+
raise Error::UnsupportedOperationError, 'To submit an element, it must be nested inside a form element'
|
|
441
435
|
end
|
|
442
436
|
|
|
443
437
|
#
|
|
@@ -525,7 +519,7 @@ module Selenium
|
|
|
525
519
|
Element.new self, element_id_from(execute(:get_active_element))
|
|
526
520
|
end
|
|
527
521
|
|
|
528
|
-
|
|
522
|
+
alias switch_to_active_element active_element
|
|
529
523
|
|
|
530
524
|
def find_element_by(how, what, parent_ref = [])
|
|
531
525
|
how, what = convert_locator(how, what)
|