selenium-webdriver 4.1.0 → 4.9.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 +234 -1
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/NOTICE +1 -1
- data/README.md +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 +36 -27
- data/lib/selenium/webdriver/atoms/findElements.js +0 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +0 -0
- data/lib/selenium/webdriver/atoms/isDisplayed.js +0 -0
- data/lib/selenium/webdriver/atoms/mutationListener.js +0 -0
- data/lib/selenium/webdriver/atoms.rb +2 -3
- data/lib/selenium/webdriver/bidi/browsing_context.rb +88 -0
- data/lib/selenium/webdriver/bidi/browsing_context_info.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/base_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/console_log_entry.rb +35 -0
- data/lib/selenium/webdriver/bidi/log/filter_by.rb +40 -0
- data/lib/selenium/webdriver/bidi/log/generic_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log/javascript_log_entry.rb +33 -0
- data/lib/selenium/webdriver/bidi/log_inspector.rb +143 -0
- data/lib/selenium/webdriver/bidi/navigate_result.rb +33 -0
- data/lib/selenium/webdriver/bidi/session.rb +51 -0
- data/lib/selenium/webdriver/bidi.rb +56 -0
- data/lib/selenium/webdriver/chrome/driver.rb +9 -29
- data/lib/selenium/webdriver/chrome/features.rb +6 -68
- data/lib/selenium/webdriver/chrome/options.rb +3 -223
- data/lib/selenium/webdriver/chrome/profile.rb +3 -83
- data/lib/selenium/webdriver/chrome/service.rb +3 -23
- data/lib/selenium/webdriver/chrome.rb +0 -14
- data/lib/selenium/webdriver/chromium/driver.rb +61 -0
- data/lib/selenium/webdriver/chromium/features.rb +103 -0
- data/lib/selenium/webdriver/chromium/options.rb +261 -0
- data/lib/selenium/webdriver/chromium/profile.rb +113 -0
- data/lib/selenium/webdriver/chromium/service.rb +42 -0
- data/lib/selenium/webdriver/chromium.rb +32 -0
- data/lib/selenium/webdriver/common/action_builder.rb +64 -22
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +36 -74
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +0 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/{has_remote_status.rb → has_bidi.rb} +10 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +1 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +2 -69
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +0 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +1 -3
- data/lib/selenium/webdriver/common/driver_finder.rb +44 -0
- data/lib/selenium/webdriver/common/element.rb +8 -8
- data/lib/selenium/webdriver/common/error.rb +1 -3
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/interactions/input_device.rb +10 -4
- data/lib/selenium/webdriver/common/interactions/interaction.rb +12 -25
- data/lib/selenium/webdriver/common/interactions/interactions.rb +24 -4
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -1
- data/lib/selenium/webdriver/common/interactions/key_input.rb +11 -27
- data/lib/selenium/webdriver/common/interactions/none_input.rb +10 -8
- data/lib/selenium/webdriver/common/interactions/pause.rb +49 -0
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +59 -70
- data/lib/selenium/webdriver/common/interactions/pointer_cancel.rb +45 -0
- data/lib/selenium/webdriver/common/interactions/pointer_event_properties.rb +63 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +15 -84
- data/lib/selenium/webdriver/common/interactions/pointer_move.rb +60 -0
- data/lib/selenium/webdriver/common/interactions/pointer_press.rb +85 -0
- data/lib/selenium/webdriver/common/interactions/scroll.rb +59 -0
- data/lib/selenium/webdriver/common/interactions/scroll_origin.rb +48 -0
- data/lib/selenium/webdriver/common/interactions/typing_interaction.rb +54 -0
- data/lib/selenium/webdriver/common/interactions/wheel_actions.rb +113 -0
- data/lib/selenium/webdriver/common/interactions/wheel_input.rb +42 -0
- data/lib/selenium/webdriver/common/keys.rb +1 -0
- data/lib/selenium/webdriver/common/local_driver.rb +55 -0
- data/lib/selenium/webdriver/common/logger.rb +76 -24
- data/lib/selenium/webdriver/common/manager.rb +0 -27
- data/lib/selenium/webdriver/common/options.rb +32 -17
- data/lib/selenium/webdriver/common/platform.rb +8 -5
- data/lib/selenium/webdriver/common/port_prober.rb +1 -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/search_context.rb +0 -6
- data/lib/selenium/webdriver/common/selenium_manager.rb +108 -0
- data/lib/selenium/webdriver/common/service.rb +20 -23
- 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 +3 -5
- data/lib/selenium/webdriver/edge/profile.rb +2 -2
- data/lib/selenium/webdriver/edge/service.rb +2 -6
- data/lib/selenium/webdriver/firefox/driver.rb +9 -2
- data/lib/selenium/webdriver/firefox/features.rb +6 -6
- data/lib/selenium/webdriver/firefox/options.rb +9 -3
- data/lib/selenium/webdriver/firefox/profile.rb +8 -12
- data/lib/selenium/webdriver/firefox/service.rb +0 -6
- data/lib/selenium/webdriver/firefox/util.rb +46 -0
- data/lib/selenium/webdriver/firefox.rb +1 -14
- data/lib/selenium/webdriver/ie/driver.rb +7 -1
- data/lib/selenium/webdriver/ie/service.rb +1 -7
- data/lib/selenium/webdriver/ie.rb +0 -14
- data/lib/selenium/webdriver/remote/{commands.rb → bridge/commands.rb} +15 -8
- data/lib/selenium/webdriver/remote/bridge.rb +65 -35
- data/lib/selenium/webdriver/remote/capabilities.rb +34 -12
- data/lib/selenium/webdriver/remote/driver.rb +19 -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 +7 -12
- data/lib/selenium/webdriver/remote/response.rb +2 -3
- data/lib/selenium/webdriver/remote.rb +0 -1
- data/lib/selenium/webdriver/safari/driver.rb +7 -1
- data/lib/selenium/webdriver/safari/features.rb +0 -2
- data/lib/selenium/webdriver/safari/options.rb +5 -1
- data/lib/selenium/webdriver/safari/service.rb +0 -4
- data/lib/selenium/webdriver/safari.rb +1 -15
- data/lib/selenium/webdriver/support/color.rb +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 +5 -4
- data/selenium-webdriver.gemspec +13 -12
- metadata +70 -73
- data/lib/selenium/webdriver/remote/http/persistent.rb +0 -65
- data/lib/selenium/webdriver/support/cdp/domain.rb.erb +0 -63
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +0 -108
|
@@ -20,59 +20,49 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
class DevTools
|
|
23
|
-
RESPONSE_WAIT_TIMEOUT = 30
|
|
24
|
-
RESPONSE_WAIT_INTERVAL = 0.1
|
|
25
|
-
|
|
26
23
|
autoload :ConsoleEvent, 'selenium/webdriver/devtools/console_event'
|
|
27
24
|
autoload :ExceptionEvent, 'selenium/webdriver/devtools/exception_event'
|
|
28
25
|
autoload :MutationEvent, 'selenium/webdriver/devtools/mutation_event'
|
|
26
|
+
autoload :NetworkInterceptor, 'selenium/webdriver/devtools/network_interceptor'
|
|
29
27
|
autoload :PinnedScript, 'selenium/webdriver/devtools/pinned_script'
|
|
30
28
|
autoload :Request, 'selenium/webdriver/devtools/request'
|
|
31
29
|
autoload :Response, 'selenium/webdriver/devtools/response'
|
|
32
30
|
|
|
33
31
|
def initialize(url:)
|
|
34
|
-
@
|
|
35
|
-
|
|
36
|
-
@messages = []
|
|
32
|
+
@ws = WebSocketConnection.new(url: url)
|
|
37
33
|
@session_id = nil
|
|
38
|
-
@url = url
|
|
39
|
-
|
|
40
|
-
process_handshake
|
|
41
|
-
@socket_thread = attach_socket_listener
|
|
42
34
|
start_session
|
|
43
35
|
end
|
|
44
36
|
|
|
45
37
|
def close
|
|
46
|
-
@
|
|
47
|
-
@socket_thread.exit
|
|
48
|
-
socket.close
|
|
38
|
+
@ws.close
|
|
49
39
|
end
|
|
50
40
|
|
|
51
41
|
def callbacks
|
|
52
|
-
@
|
|
42
|
+
@ws.callbacks
|
|
53
43
|
end
|
|
54
44
|
|
|
55
45
|
def send_cmd(method, **params)
|
|
56
|
-
|
|
57
|
-
data = {id: id, method: method, params: params.reject { |_, v| v.nil? }}
|
|
46
|
+
data = {method: method, params: params.compact}
|
|
58
47
|
data[:sessionId] = @session_id if @session_id
|
|
59
|
-
|
|
60
|
-
WebDriver.logger.debug "DevTools -> #{data}"
|
|
61
|
-
|
|
62
|
-
out_frame = WebSocket::Frame::Outgoing::Client.new(version: ws.version, data: data, type: 'text')
|
|
63
|
-
socket.write(out_frame.to_s)
|
|
64
|
-
|
|
65
|
-
message = wait.until do
|
|
66
|
-
@messages.find { |m| m['id'] == id }
|
|
67
|
-
end
|
|
68
|
-
|
|
48
|
+
message = @ws.send_cmd(**data)
|
|
69
49
|
raise Error::WebDriverError, error_message(message['error']) if message['error']
|
|
70
50
|
|
|
71
51
|
message
|
|
72
52
|
end
|
|
73
53
|
|
|
74
54
|
def method_missing(method, *_args)
|
|
75
|
-
|
|
55
|
+
namespace = "Selenium::DevTools::V#{Selenium::DevTools.version}"
|
|
56
|
+
methods_to_classes = "#{namespace}::METHODS_TO_CLASSES"
|
|
57
|
+
|
|
58
|
+
desired_class = if Object.const_defined?(methods_to_classes)
|
|
59
|
+
# selenium-devtools 0.113 and newer
|
|
60
|
+
"#{namespace}::#{Object.const_get(methods_to_classes)[method]}"
|
|
61
|
+
else
|
|
62
|
+
# selenium-devtools 0.112 and older
|
|
63
|
+
"#{namespace}::#{method.capitalize}"
|
|
64
|
+
end
|
|
65
|
+
|
|
76
66
|
return unless Object.const_defined?(desired_class)
|
|
77
67
|
|
|
78
68
|
self.class.class_eval do
|
|
@@ -91,32 +81,6 @@ module Selenium
|
|
|
91
81
|
|
|
92
82
|
private
|
|
93
83
|
|
|
94
|
-
def process_handshake
|
|
95
|
-
socket.print(ws.to_s)
|
|
96
|
-
ws << socket.readpartial(1024)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def attach_socket_listener
|
|
100
|
-
Thread.new do
|
|
101
|
-
Thread.current.abort_on_exception = true
|
|
102
|
-
Thread.current.report_on_exception = false
|
|
103
|
-
|
|
104
|
-
until socket.eof?
|
|
105
|
-
incoming_frame << socket.readpartial(1024)
|
|
106
|
-
|
|
107
|
-
while (frame = incoming_frame.next)
|
|
108
|
-
message = process_frame(frame)
|
|
109
|
-
next unless message['method']
|
|
110
|
-
|
|
111
|
-
params = message['params']
|
|
112
|
-
callbacks[message['method']].each do |callback|
|
|
113
|
-
@callback_threads.add(callback_thread(params, &callback))
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
84
|
def start_session
|
|
121
85
|
targets = target.get_targets.dig('result', 'targetInfos')
|
|
122
86
|
page_target = targets.find { |target| target['type'] == 'page' }
|
|
@@ -124,70 +88,9 @@ module Selenium
|
|
|
124
88
|
@session_id = session.dig('result', 'sessionId')
|
|
125
89
|
end
|
|
126
90
|
|
|
127
|
-
def incoming_frame
|
|
128
|
-
@incoming_frame ||= WebSocket::Frame::Incoming::Client.new(version: ws.version)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def process_frame(frame)
|
|
132
|
-
message = frame.to_s
|
|
133
|
-
|
|
134
|
-
# Firefox will periodically fail on unparsable empty frame
|
|
135
|
-
return {} if message.empty?
|
|
136
|
-
|
|
137
|
-
message = JSON.parse(message)
|
|
138
|
-
@messages << message
|
|
139
|
-
WebDriver.logger.debug "DevTools <- #{message}"
|
|
140
|
-
|
|
141
|
-
message
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def callback_thread(params)
|
|
145
|
-
Thread.new do
|
|
146
|
-
Thread.current.abort_on_exception = true
|
|
147
|
-
|
|
148
|
-
# We might end up blocked forever when we have an error in event.
|
|
149
|
-
# For example, if network interception event raises error,
|
|
150
|
-
# the browser will keep waiting for the request to be proceeded
|
|
151
|
-
# before returning back to the original thread. In this case,
|
|
152
|
-
# we should at least print the error.
|
|
153
|
-
Thread.current.report_on_exception = true
|
|
154
|
-
|
|
155
|
-
yield params
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def wait
|
|
160
|
-
@wait ||= Wait.new(timeout: RESPONSE_WAIT_TIMEOUT, interval: RESPONSE_WAIT_INTERVAL)
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def socket
|
|
164
|
-
@socket ||= begin
|
|
165
|
-
if URI(@url).scheme == 'wss'
|
|
166
|
-
socket = TCPSocket.new(ws.host, ws.port)
|
|
167
|
-
socket = OpenSSL::SSL::SSLSocket.new(socket, OpenSSL::SSL::SSLContext.new)
|
|
168
|
-
socket.sync_close = true
|
|
169
|
-
socket.connect
|
|
170
|
-
|
|
171
|
-
socket
|
|
172
|
-
else
|
|
173
|
-
TCPSocket.new(ws.host, ws.port)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def ws
|
|
179
|
-
@ws ||= WebSocket::Handshake::Client.new(url: @url)
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def next_id
|
|
183
|
-
@id ||= 0
|
|
184
|
-
@id += 1
|
|
185
|
-
end
|
|
186
|
-
|
|
187
91
|
def error_message(error)
|
|
188
92
|
[error['code'], error['message'], error['data']].join(': ')
|
|
189
93
|
end
|
|
190
|
-
|
|
191
94
|
end # DevTools
|
|
192
95
|
end # WebDriver
|
|
193
96
|
end # Selenium
|
|
@@ -17,18 +17,24 @@
|
|
|
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
|
+
include LocalDriver
|
|
32
|
+
|
|
33
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
34
|
+
caps, url = initialize_local_driver(capabilities, options, service, url)
|
|
35
|
+
super(caps: caps, url: url, **opts)
|
|
36
|
+
end
|
|
37
|
+
|
|
32
38
|
def browser
|
|
33
39
|
:edge
|
|
34
40
|
end
|
|
@@ -17,26 +17,26 @@
|
|
|
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'],
|
|
31
30
|
set_cast_sink_to_use: [:post, 'session/:session_id/ms/cast/set_sink_to_use'],
|
|
32
31
|
start_cast_tab_mirroring: [:post, 'session/:session_id/ms/cast/start_tab_mirroring'],
|
|
32
|
+
start_cast_desktop_mirroring: [:post, 'session/:session_id/ms/cast/start_desktop_mirroring'],
|
|
33
33
|
get_cast_issue_message: [:get, 'session/:session_id/ms/cast/get_issue_message'],
|
|
34
34
|
stop_casting: [:post, 'session/:session_id/ms/cast/stop_casting'],
|
|
35
35
|
send_command: [:post, 'session/:session_id/ms/cdp/execute']
|
|
36
36
|
}.freeze
|
|
37
37
|
|
|
38
38
|
def commands(command)
|
|
39
|
-
EDGE_COMMANDS[command] ||
|
|
39
|
+
EDGE_COMMANDS[command] || CHROMIUM_COMMANDS[command] || self.class::COMMANDS[command]
|
|
40
40
|
end
|
|
41
41
|
end # Bridge
|
|
42
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,18 +17,14 @@
|
|
|
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
|
-
MISSING_TEXT = <<~ERROR
|
|
29
|
-
Unable to find msedgedriver. Please download the server from
|
|
30
|
-
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ and place it somewhere on your PATH.
|
|
31
|
-
ERROR
|
|
32
28
|
SHUTDOWN_SUPPORTED = true
|
|
33
29
|
end # Service
|
|
34
30
|
end # Edge
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Firefox
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Driver implementation for Firefox using GeckoDriver.
|
|
26
25
|
# @api private
|
|
@@ -30,12 +29,20 @@ module Selenium
|
|
|
30
29
|
EXTENSIONS = [DriverExtensions::HasAddons,
|
|
31
30
|
DriverExtensions::FullPageScreenshot,
|
|
32
31
|
DriverExtensions::HasContext,
|
|
32
|
+
DriverExtensions::HasBiDi,
|
|
33
33
|
DriverExtensions::HasDevTools,
|
|
34
34
|
DriverExtensions::HasLogEvents,
|
|
35
35
|
DriverExtensions::HasNetworkInterception,
|
|
36
36
|
DriverExtensions::HasWebStorage,
|
|
37
37
|
DriverExtensions::PrintsPage].freeze
|
|
38
38
|
|
|
39
|
+
include LocalDriver
|
|
40
|
+
|
|
41
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
42
|
+
caps, url = initialize_local_driver(capabilities, options, service, url)
|
|
43
|
+
super(caps: caps, url: url, **opts)
|
|
44
|
+
end
|
|
45
|
+
|
|
39
46
|
def browser
|
|
40
47
|
:firefox
|
|
41
48
|
end
|
|
@@ -44,7 +51,7 @@ module Selenium
|
|
|
44
51
|
|
|
45
52
|
def devtools_url
|
|
46
53
|
if capabilities['moz:debuggerAddress'].nil?
|
|
47
|
-
raise(Error::WebDriverError,
|
|
54
|
+
raise(Error::WebDriverError, 'DevTools is not supported by this version of Firefox; use v85 or higher')
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
uri = URI("http://#{capabilities['moz:debuggerAddress']}")
|
|
@@ -21,7 +21,6 @@ module Selenium
|
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Firefox
|
|
23
23
|
module Features
|
|
24
|
-
|
|
25
24
|
FIREFOX_COMMANDS = {
|
|
26
25
|
get_context: [:get, 'session/:session_id/moz/context'],
|
|
27
26
|
set_context: [:post, 'session/:session_id/moz/context'],
|
|
@@ -35,12 +34,13 @@ module Selenium
|
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def install_addon(path, temporary)
|
|
38
|
-
if
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
addon = if File.directory?(path)
|
|
38
|
+
Zipper.zip(path)
|
|
39
|
+
else
|
|
40
|
+
File.open(path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
|
|
41
|
+
end
|
|
42
42
|
|
|
43
|
-
payload = {
|
|
43
|
+
payload = {addon: addon}
|
|
44
44
|
payload[:temporary] = temporary unless temporary.nil?
|
|
45
45
|
execute :install_addon, {}, payload
|
|
46
46
|
end
|
|
@@ -25,11 +25,12 @@ module Selenium
|
|
|
25
25
|
|
|
26
26
|
KEY = 'moz:firefoxOptions'
|
|
27
27
|
|
|
28
|
-
# see: https://
|
|
28
|
+
# see: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions
|
|
29
29
|
CAPABILITIES = {binary: 'binary',
|
|
30
30
|
args: 'args',
|
|
31
31
|
log: 'log',
|
|
32
32
|
prefs: 'prefs',
|
|
33
|
+
env: 'env',
|
|
33
34
|
android_package: 'androidPackage',
|
|
34
35
|
android_activity: 'androidActivity',
|
|
35
36
|
android_device_serial: 'androidDeviceSerial',
|
|
@@ -56,12 +57,14 @@ module Selenium
|
|
|
56
57
|
#
|
|
57
58
|
|
|
58
59
|
def initialize(log_level: nil, **opts)
|
|
59
|
-
@debugger_address = opts.delete(:debugger_address)
|
|
60
|
+
@debugger_address = opts.delete(:debugger_address) { true }
|
|
61
|
+
opts[:accept_insecure_certs] = true unless opts.key?(:accept_insecure_certs)
|
|
60
62
|
|
|
61
63
|
super(**opts)
|
|
62
64
|
|
|
63
65
|
@options[:args] ||= []
|
|
64
66
|
@options[:prefs] ||= {}
|
|
67
|
+
@options[:env] ||= {}
|
|
65
68
|
@options[:log] ||= {level: log_level} if log_level
|
|
66
69
|
|
|
67
70
|
process_profile(@options.delete(:profile))
|
|
@@ -105,6 +108,9 @@ module Selenium
|
|
|
105
108
|
#
|
|
106
109
|
|
|
107
110
|
def headless!
|
|
111
|
+
WebDriver.logger.deprecate('`Options#headless!`',
|
|
112
|
+
"`Options#add_argument('-headless')`",
|
|
113
|
+
id: :headless)
|
|
108
114
|
add_argument '-headless'
|
|
109
115
|
end
|
|
110
116
|
|
|
@@ -175,7 +181,7 @@ module Selenium
|
|
|
175
181
|
end
|
|
176
182
|
|
|
177
183
|
def camelize?(key)
|
|
178
|
-
key !=
|
|
184
|
+
key != 'prefs'
|
|
179
185
|
end
|
|
180
186
|
end # Options
|
|
181
187
|
end # Firefox
|
|
@@ -26,11 +26,11 @@ module Selenium
|
|
|
26
26
|
VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
|
|
27
27
|
|
|
28
28
|
DEFAULT_PREFERENCES = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
'browser.newtabpage.enabled' => false,
|
|
30
|
+
'browser.startup.homepage' => 'about:blank',
|
|
31
|
+
'browser.usedOnWindows10.introURL' => 'about:blank',
|
|
32
|
+
'network.captive-portal-service.enabled' => false,
|
|
33
|
+
'security.csp.enable' => false
|
|
34
34
|
}.freeze
|
|
35
35
|
|
|
36
36
|
attr_reader :name, :log_file
|
|
@@ -96,7 +96,7 @@ module Selenium
|
|
|
96
96
|
raise TypeError, "expected one of #{VALID_PREFERENCE_TYPES.inspect}, got #{value.inspect}:#{value.class}"
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
if value.is_a?(String) && stringified?(value)
|
|
99
|
+
if value.is_a?(String) && Util.stringified?(value)
|
|
100
100
|
raise ArgumentError, "preference values must be plain strings: #{key.inspect} => #{value.inspect}"
|
|
101
101
|
end
|
|
102
102
|
|
|
@@ -143,7 +143,7 @@ module Selenium
|
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
alias as_json encoded
|
|
147
147
|
|
|
148
148
|
private
|
|
149
149
|
|
|
@@ -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,16 +23,10 @@ module Selenium
|
|
|
23
23
|
class Service < WebDriver::Service
|
|
24
24
|
DEFAULT_PORT = 4444
|
|
25
25
|
EXECUTABLE = 'geckodriver'
|
|
26
|
-
MISSING_TEXT = <<~ERROR
|
|
27
|
-
Unable to find Mozilla geckodriver. Please download the server from
|
|
28
|
-
https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH.
|
|
29
|
-
More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
|
|
30
|
-
ERROR
|
|
31
26
|
SHUTDOWN_SUPPORTED = false
|
|
32
27
|
|
|
33
28
|
private
|
|
34
29
|
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
30
|
def extract_service_args(driver_opts)
|
|
37
31
|
driver_args = super
|
|
38
32
|
driver_opts = driver_opts.dup
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
|
+
# or more contributor license agreements. See the NOTICE file
|
|
5
|
+
# distributed with this work for additional information
|
|
6
|
+
# regarding copyright ownership. The SFC licenses this file
|
|
7
|
+
# to you under the Apache License, Version 2.0 (the
|
|
8
|
+
# "License"); you may not use this file except in compliance
|
|
9
|
+
# with the License. You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing,
|
|
14
|
+
# software distributed under the License is distributed on an
|
|
15
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
+
# KIND, either express or implied. See the License for the
|
|
17
|
+
# specific language governing permissions and limitations
|
|
18
|
+
# under the License.
|
|
19
|
+
|
|
20
|
+
module Selenium
|
|
21
|
+
module WebDriver
|
|
22
|
+
module Firefox
|
|
23
|
+
# @api private
|
|
24
|
+
module Util
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
def app_data_path
|
|
28
|
+
case Platform.os
|
|
29
|
+
when :windows
|
|
30
|
+
"#{ENV.fetch('APPDATA')}\\Mozilla\\Firefox"
|
|
31
|
+
when :macosx
|
|
32
|
+
"#{Platform.home}/Library/Application Support/Firefox"
|
|
33
|
+
when :unix, :linux
|
|
34
|
+
"#{Platform.home}/.mozilla/firefox"
|
|
35
|
+
else
|
|
36
|
+
raise "Unknown os: #{Platform.os}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def stringified?(str)
|
|
41
|
+
str =~ /^".*"$/
|
|
42
|
+
end
|
|
43
|
+
end # Util
|
|
44
|
+
end # Firefox
|
|
45
|
+
end # WebDriver
|
|
46
|
+
end # Selenium
|
|
@@ -24,6 +24,7 @@ require 'rexml/document'
|
|
|
24
24
|
module Selenium
|
|
25
25
|
module WebDriver
|
|
26
26
|
module Firefox
|
|
27
|
+
autoload :Util, 'selenium/webdriver/firefox/util'
|
|
27
28
|
autoload :Extension, 'selenium/webdriver/firefox/extension'
|
|
28
29
|
autoload :ProfilesIni, 'selenium/webdriver/firefox/profiles_ini'
|
|
29
30
|
autoload :Profile, 'selenium/webdriver/firefox/profile'
|
|
@@ -41,20 +42,6 @@ module Selenium
|
|
|
41
42
|
# until WebDriver Bidi is available.
|
|
42
43
|
DEVTOOLS_VERSION = 85
|
|
43
44
|
|
|
44
|
-
def self.driver_path=(path)
|
|
45
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path=',
|
|
46
|
-
'Selenium::WebDriver::Firefox::Service#driver_path=',
|
|
47
|
-
id: :driver_path
|
|
48
|
-
Selenium::WebDriver::Firefox::Service.driver_path = path
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def self.driver_path
|
|
52
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::Firefox#driver_path',
|
|
53
|
-
'Selenium::WebDriver::Firefox::Service#driver_path',
|
|
54
|
-
id: :driver_path
|
|
55
|
-
Selenium::WebDriver::Firefox::Service.driver_path
|
|
56
|
-
end
|
|
57
|
-
|
|
58
45
|
def self.path=(path)
|
|
59
46
|
Platform.assert_executable path
|
|
60
47
|
@path = path
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module IE
|
|
23
|
-
|
|
24
23
|
#
|
|
25
24
|
# Driver implementation for Internet Explorer supporting
|
|
26
25
|
# both OSS and W3C dialects of JSON wire protocol.
|
|
@@ -30,6 +29,13 @@ module Selenium
|
|
|
30
29
|
class Driver < WebDriver::Driver
|
|
31
30
|
EXTENSIONS = [DriverExtensions::HasWebStorage].freeze
|
|
32
31
|
|
|
32
|
+
include LocalDriver
|
|
33
|
+
|
|
34
|
+
def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
|
|
35
|
+
caps, url = initialize_local_driver(capabilities, options, service, url)
|
|
36
|
+
super(caps: caps, url: url, **opts)
|
|
37
|
+
end
|
|
38
|
+
|
|
33
39
|
def browser
|
|
34
40
|
:internet_explorer
|
|
35
41
|
end
|
|
@@ -23,16 +23,10 @@ module Selenium
|
|
|
23
23
|
class Service < WebDriver::Service
|
|
24
24
|
DEFAULT_PORT = 5555
|
|
25
25
|
EXECUTABLE = 'IEDriverServer'
|
|
26
|
-
MISSING_TEXT = <<~ERROR
|
|
27
|
-
Unable to find IEDriverServer. Please download the server from
|
|
28
|
-
https://www.selenium.dev/downloads/ and place it somewhere on your PATH.
|
|
29
|
-
More info at https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver.
|
|
30
|
-
ERROR
|
|
31
26
|
SHUTDOWN_SUPPORTED = true
|
|
32
27
|
|
|
33
28
|
private
|
|
34
29
|
|
|
35
|
-
# NOTE: This processing is deprecated
|
|
36
30
|
def extract_service_args(driver_opts)
|
|
37
31
|
driver_args = super
|
|
38
32
|
driver_opts = driver_opts.dup
|
|
@@ -43,7 +37,7 @@ module Selenium
|
|
|
43
37
|
end
|
|
44
38
|
driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
|
|
45
39
|
driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
|
|
46
|
-
driver_args <<
|
|
40
|
+
driver_args << '--silent' if driver_opts[:silent] == true
|
|
47
41
|
driver_args
|
|
48
42
|
end
|
|
49
43
|
end # Server
|
|
@@ -23,20 +23,6 @@ module Selenium
|
|
|
23
23
|
autoload :Driver, 'selenium/webdriver/ie/driver'
|
|
24
24
|
autoload :Options, 'selenium/webdriver/ie/options'
|
|
25
25
|
autoload :Service, 'selenium/webdriver/ie/service'
|
|
26
|
-
|
|
27
|
-
def self.driver_path=(path)
|
|
28
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::IE#driver_path=',
|
|
29
|
-
'Selenium::WebDriver::IE::Service#driver_path=',
|
|
30
|
-
id: :driver_path
|
|
31
|
-
Selenium::WebDriver::IE::Service.driver_path = path
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def self.driver_path
|
|
35
|
-
WebDriver.logger.deprecate 'Selenium::WebDriver::IE#driver_path',
|
|
36
|
-
'Selenium::WebDriver::IE::Service#driver_path',
|
|
37
|
-
id: :driver_path
|
|
38
|
-
Selenium::WebDriver::IE::Service.driver_path
|
|
39
|
-
end
|
|
40
26
|
end # IE
|
|
41
27
|
end # WebDriver
|
|
42
28
|
end # Selenium
|