selenium-webdriver 4.1.0 → 4.2.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 +46 -1
- data/LICENSE +1 -1
- data/NOTICE +1 -1
- data/lib/selenium/server.rb +14 -9
- data/lib/selenium/webdriver/bidi/session.rb +38 -0
- data/lib/selenium/webdriver/bidi.rb +55 -0
- data/lib/selenium/webdriver/chrome/features.rb +5 -0
- data/lib/selenium/webdriver/chrome/options.rb +19 -19
- data/lib/selenium/webdriver/common/action_builder.rb +108 -21
- data/lib/selenium/webdriver/common/driver.rb +2 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_bidi.rb +38 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +10 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +1 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +1 -1
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +1 -1
- data/lib/selenium/webdriver/common/element.rb +1 -1
- data/lib/selenium/webdriver/common/error.rb +1 -1
- 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 +49 -43
- 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 +57 -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/platform.rb +4 -4
- data/lib/selenium/webdriver/common/search_context.rb +0 -6
- data/lib/selenium/webdriver/common/service_manager.rb +2 -3
- data/lib/selenium/webdriver/common/shadow_root.rb +1 -1
- data/lib/selenium/webdriver/common/socket_poller.rb +1 -1
- data/lib/selenium/webdriver/common/websocket_connection.rb +149 -0
- data/lib/selenium/webdriver/common.rb +14 -2
- data/lib/selenium/webdriver/devtools/request.rb +1 -1
- data/lib/selenium/webdriver/devtools/response.rb +1 -1
- data/lib/selenium/webdriver/devtools.rb +5 -112
- data/lib/selenium/webdriver/edge/features.rb +1 -0
- data/lib/selenium/webdriver/firefox/driver.rb +1 -0
- data/lib/selenium/webdriver/firefox/features.rb +2 -5
- data/lib/selenium/webdriver/firefox/options.rb +3 -1
- data/lib/selenium/webdriver/firefox/profile.rb +1 -5
- data/lib/selenium/webdriver/firefox/util.rb +46 -0
- data/lib/selenium/webdriver/firefox.rb +1 -0
- data/lib/selenium/webdriver/remote/bridge.rb +21 -19
- data/lib/selenium/webdriver/remote/commands.rb +0 -5
- data/lib/selenium/webdriver/remote/http/default.rb +6 -12
- data/lib/selenium/webdriver/remote/response.rb +2 -2
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +4 -4
- data/lib/selenium/webdriver/support/color.rb +7 -7
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +1 -1
- data/lib/selenium/webdriver/support/guards.rb +1 -1
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +1 -0
- data/selenium-webdriver.gemspec +7 -4
- metadata +55 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5767633e16bd3296a248757bd01f157c6441a7780d3bcfd972a7c03f94237d54
|
4
|
+
data.tar.gz: 6e82108ff5bd955eeb68e2b7a8e23aa9c766d900f46bbb4e7d3a9475b00a7ceb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 792f2a87bb8c1f78c8e7fef7242d9b42026473e9fcb2c8a586e5d1af04188f0026b7b7e0c300b3d9cc3d709a8a7efe0dc6050edd69df1af3b1c397f40a1b0fd8
|
7
|
+
data.tar.gz: 840b9619f535ea1f67d603de69d88e5fcf8ca324a9198b68f9e418f1ebde25bae9d40cfda6c65c8fce9321ae21a84b88ef91c57ae99105a95d191dbf28f1f0e5
|
data/CHANGES
CHANGED
@@ -1,4 +1,49 @@
|
|
1
|
-
4.
|
1
|
+
4.2.0 (unreleased)
|
2
|
+
=========================
|
3
|
+
|
4
|
+
BiDi:
|
5
|
+
* Released selenium-devtools 0.97.0 (supports CDP v85, v95, v96, v97)
|
6
|
+
* Released selenium-devtools 0.98.0 (supports CDP v85, v96, v97, v98)
|
7
|
+
* Released selenium-devtools 0.99.0 (supports CDP v85, v97, v98, v99)
|
8
|
+
* Released selenium-devtools 0.100.0 (supports CDP v85, v98, v99, v100)
|
9
|
+
* Released selenium-devtools 0.101.0 (supports CDP v85, v99, v100, v101)
|
10
|
+
* Released selenium-devtools 0.102.0 (supports CDP v85, v100, v101, v102)
|
11
|
+
* Implement simple BiDi connection
|
12
|
+
* Fix bug in initial BiDi implementation (thanks Boris Petrov!)
|
13
|
+
* Fix bug with mutating headers in request interception (#10574)
|
14
|
+
* Fix bug with empty response headers (thanks Viren Negi!)
|
15
|
+
|
16
|
+
Firefox:
|
17
|
+
* Add support to Firefox Options for environment capability
|
18
|
+
* Use addon parameter instead of path parameter to avoid using file detector
|
19
|
+
* Restore #from_name method to Firefox profile (#10146)
|
20
|
+
|
21
|
+
Chromium:
|
22
|
+
* Add support for casting desktop
|
23
|
+
|
24
|
+
Ruby:
|
25
|
+
* Updated minimum required Ruby version to 2.7
|
26
|
+
* Fix bug by not attempting to stop service process when it's not started (#10015)
|
27
|
+
* Fix bug to not stop service process when it's not started (thanks Atsushi Tatsuma!)
|
28
|
+
* Use driver endpoint to get page source instead of JavaScript
|
29
|
+
* Add zenkaku_hankaku key support
|
30
|
+
* Fix download support of Selenium Server
|
31
|
+
* Do not convert Tag Name to CSS Selector
|
32
|
+
|
33
|
+
ActionBuilder:
|
34
|
+
* Raise error if input device not found
|
35
|
+
* Move `TypingInteraction` from `Interactions::KeyInput` to `Interactions` module
|
36
|
+
* Throw better errors for `PointerInput` methods
|
37
|
+
* Allow each action interaction class to validate its own source
|
38
|
+
* Set all Interactions classes to private
|
39
|
+
* Allow device names to use a default id if one is not specified
|
40
|
+
* Deprecate default mouse and keyboard values in constructor, favoring devices parameter
|
41
|
+
* Add support for pointer event properties
|
42
|
+
* Implement scroll wheel support
|
43
|
+
* Deprecate ordered pair parameters for pause method in favor of keywords
|
44
|
+
* Deprecate move to element with offset changing origin to top left of element
|
45
|
+
|
46
|
+
4.1.0 (2021-11-22)
|
2
47
|
=========================
|
3
48
|
|
4
49
|
DevTools:
|
data/LICENSE
CHANGED
@@ -187,7 +187,7 @@
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
188
188
|
identification within third-party archives.
|
189
189
|
|
190
|
-
Copyright
|
190
|
+
Copyright 2022 Software Freedom Conservancy (SFC)
|
191
191
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
193
193
|
you may not use this file except in compliance with the License.
|
data/NOTICE
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
Copyright 2011-
|
1
|
+
Copyright 2011-2022 Software Freedom Conservancy
|
2
2
|
Copyright 2004-2011 Selenium committers
|
data/lib/selenium/server.rb
CHANGED
@@ -84,8 +84,8 @@ module Selenium
|
|
84
84
|
return download_file_name if File.exist? download_file_name
|
85
85
|
|
86
86
|
begin
|
87
|
-
|
88
|
-
released = Net::HTTP.get_response(URI.parse(
|
87
|
+
download_location = available_assets[download_file_name]['browser_download_url']
|
88
|
+
released = Net::HTTP.get_response(URI.parse(download_location))
|
89
89
|
redirected = URI.parse released.header['location']
|
90
90
|
|
91
91
|
File.open(download_file_name, 'wb') do |destination|
|
@@ -105,19 +105,24 @@ module Selenium
|
|
105
105
|
|
106
106
|
def latest
|
107
107
|
@latest ||= begin
|
108
|
-
|
109
|
-
|
110
|
-
all_assets = JSON.parse(json).map { |release| release['assets'] }.flatten
|
111
|
-
server_assets = all_assets.map { |asset| asset['name'][/selenium-server-(\d+\.\d+\.\d+)\.jar/, 1] }.compact
|
112
|
-
server_assets.map { |version| Gem::Version.new(version) }.max.version
|
113
|
-
end
|
108
|
+
available = available_assets.keys.map { |key| key[/selenium-server-(\d+\.\d+\.\d+)\.jar/, 1] }
|
109
|
+
available.map { |asset| Gem::Version.new(asset) }.max.to_s
|
114
110
|
end
|
115
111
|
end
|
116
112
|
|
117
113
|
# @api private
|
118
114
|
|
115
|
+
def available_assets
|
116
|
+
@available_assets ||= net_http_start('api.github.com') do |http|
|
117
|
+
json = http.get('/repos/seleniumhq/selenium/releases').body
|
118
|
+
all_assets = JSON.parse(json).map { |release| release['assets'] }.flatten
|
119
|
+
server_assets = all_assets.select { |asset| asset['name'].match(/selenium-server-(\d+\.\d+\.\d+)\.jar/) }
|
120
|
+
server_assets.each_with_object({}) { |asset, hash| hash[asset.delete('name')] = asset }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
119
124
|
def net_http_start(address, &block)
|
120
|
-
http_proxy = ENV
|
125
|
+
http_proxy = ENV.fetch('http_proxy', nil) || ENV.fetch('HTTP_PROXY', nil)
|
121
126
|
if http_proxy
|
122
127
|
http_proxy = "http://#{http_proxy}" unless http_proxy.start_with?('http://')
|
123
128
|
uri = URI.parse(http_proxy)
|
@@ -0,0 +1,38 @@
|
|
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 BiDi
|
23
|
+
class Session
|
24
|
+
Status = Struct.new(:ready, :message)
|
25
|
+
|
26
|
+
def initialize(bidi)
|
27
|
+
@bidi = bidi
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
status = @bidi.send_cmd('session.status')
|
32
|
+
Status.new(status['ready'], status['message'])
|
33
|
+
end
|
34
|
+
|
35
|
+
end # Session
|
36
|
+
end # BiDi
|
37
|
+
end # WebDriver
|
38
|
+
end # Selenium
|
@@ -0,0 +1,55 @@
|
|
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 BiDi
|
23
|
+
autoload :Session, 'selenium/webdriver/bidi/session'
|
24
|
+
|
25
|
+
def initialize(url:)
|
26
|
+
@ws = WebSocketConnection.new(url: url)
|
27
|
+
end
|
28
|
+
|
29
|
+
def close
|
30
|
+
@ws.close
|
31
|
+
end
|
32
|
+
|
33
|
+
def callbacks
|
34
|
+
@ws.callbacks
|
35
|
+
end
|
36
|
+
|
37
|
+
def session
|
38
|
+
Session.new(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_cmd(method, **params)
|
42
|
+
data = {method: method, params: params.compact}
|
43
|
+
message = @ws.send_cmd(**data)
|
44
|
+
raise Error::WebDriverError, error_message(message) if message['error']
|
45
|
+
|
46
|
+
message['result']
|
47
|
+
end
|
48
|
+
|
49
|
+
def error_message(message)
|
50
|
+
"#{message['error']}: #{message['message']}\n#{message['stacktrace']}"
|
51
|
+
end
|
52
|
+
|
53
|
+
end # BiDi
|
54
|
+
end # WebDriver
|
55
|
+
end # Selenium
|
@@ -27,6 +27,7 @@ module Selenium
|
|
27
27
|
get_cast_sinks: [:get, 'session/:session_id/goog/cast/get_sinks'],
|
28
28
|
set_cast_sink_to_use: [:post, 'session/:session_id/goog/cast/set_sink_to_use'],
|
29
29
|
start_cast_tab_mirroring: [:post, 'session/:session_id/goog/cast/start_tab_mirroring'],
|
30
|
+
start_cast_desktop_mirroring: [:post, 'session/:session_id/goog/cast/start_desktop_mirroring'],
|
30
31
|
get_cast_issue_message: [:get, 'session/:session_id/goog/cast/get_issue_message'],
|
31
32
|
stop_casting: [:post, 'session/:session_id/goog/cast/stop_casting'],
|
32
33
|
get_network_conditions: [:get, 'session/:session_id/chromium/network_conditions'],
|
@@ -62,6 +63,10 @@ module Selenium
|
|
62
63
|
execute :start_cast_tab_mirroring, {}, {sinkName: name}
|
63
64
|
end
|
64
65
|
|
66
|
+
def start_cast_desktop_mirroring(name)
|
67
|
+
execute :start_cast_desktop_mirroring, {}, {sinkName: name}
|
68
|
+
end
|
69
|
+
|
65
70
|
def stop_casting(name)
|
66
71
|
execute :stop_casting, {}, {sinkName: name}
|
67
72
|
end
|
@@ -52,22 +52,22 @@ module Selenium
|
|
52
52
|
# options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])
|
53
53
|
# driver = Selenium::WebDriver.for(:chrome, capabilities: options)
|
54
54
|
#
|
55
|
-
# @param [Profile]
|
56
|
-
# @param [Array] :encoded_extensions List of extensions that do not need to be Base64 encoded
|
55
|
+
# @param [Profile] profile An instance of a Chrome::Profile Class
|
57
56
|
# @param [Hash] opts the pre-defined options to create the Chrome::Options with
|
58
|
-
# @option opts [Array
|
59
|
-
# @option opts [String]
|
60
|
-
# @option opts [
|
61
|
-
# @option opts [
|
62
|
-
# @option opts [
|
63
|
-
# @option opts [Hash]
|
64
|
-
# @option opts [Hash]
|
65
|
-
# @option opts [
|
66
|
-
# @option opts [
|
67
|
-
# @option opts [
|
68
|
-
# @option opts [String]
|
69
|
-
# @option opts [
|
70
|
-
# @option opts [
|
57
|
+
# @option opts [Array] encoded_extensions List of extensions that do not need to be Base64 encoded
|
58
|
+
# @option opts [Array<String>] args List of command-line arguments to use when starting Chrome
|
59
|
+
# @option opts [String] binary Path to the Chrome executable to use
|
60
|
+
# @option opts [Hash] prefs A hash with each entry consisting of the name of the preference and its value
|
61
|
+
# @option opts [Array<String>] extensions A list of paths to (.crx) Chrome extensions to install on startup
|
62
|
+
# @option opts [Hash] options A hash for raw options
|
63
|
+
# @option opts [Hash] emulation A hash for raw emulation options
|
64
|
+
# @option opts [Hash] local_state A hash for the Local State file in the user data folder
|
65
|
+
# @option opts [Boolean] detach whether browser is closed when the driver is sent the quit command
|
66
|
+
# @option opts [String] debugger_address address of a Chrome debugger server to connect to
|
67
|
+
# @option opts [Array<String>] exclude_switches command line switches to exclude
|
68
|
+
# @option opts [String] minidump_path Directory to store Chrome minidumps (linux only)
|
69
|
+
# @option opts [Hash] perf_logging_prefs A hash for performance logging preferences
|
70
|
+
# @option opts [Array<String>] window_types A list of window types to appear in the list of window handles
|
71
71
|
#
|
72
72
|
|
73
73
|
def initialize(profile: nil, **opts)
|
@@ -87,7 +87,7 @@ module Selenium
|
|
87
87
|
@logging_prefs = options.delete(:logging_prefs) || {}
|
88
88
|
@encoded_extensions = @options.delete(:encoded_extensions) || []
|
89
89
|
@extensions = []
|
90
|
-
|
90
|
+
@options.delete(:extensions).each { |ext| validate_extension(ext) }
|
91
91
|
end
|
92
92
|
|
93
93
|
#
|
@@ -112,11 +112,11 @@ module Selenium
|
|
112
112
|
# options = Selenium::WebDriver::Chrome::Options.new
|
113
113
|
# options.extensions = extensions
|
114
114
|
#
|
115
|
-
# @param [Array<String>]
|
115
|
+
# @param [Array<String>] extensions A list of paths to (.crx) Chrome extensions to install on startup
|
116
116
|
#
|
117
117
|
|
118
118
|
def extensions=(extensions)
|
119
|
-
extensions.each(
|
119
|
+
extensions.each { |ext| validate_extension(ext) }
|
120
120
|
end
|
121
121
|
|
122
122
|
#
|
@@ -234,7 +234,7 @@ module Selenium
|
|
234
234
|
|
235
235
|
return if (@encoded_extensions + @extensions).empty?
|
236
236
|
|
237
|
-
options['extensions'] = @encoded_extensions + @extensions.map(
|
237
|
+
options['extensions'] = @encoded_extensions + @extensions.map { |ext| encode_extension(ext) }
|
238
238
|
end
|
239
239
|
|
240
240
|
def binary_path
|
@@ -22,6 +22,7 @@ module Selenium
|
|
22
22
|
class ActionBuilder
|
23
23
|
include KeyActions # Actions specific to key inputs
|
24
24
|
include PointerActions # Actions specific to pointer inputs
|
25
|
+
include WheelActions # Actions specific to wheel inputs
|
25
26
|
|
26
27
|
attr_reader :devices
|
27
28
|
|
@@ -31,19 +32,40 @@ module Selenium
|
|
31
32
|
# the mouse is moving. Keep in mind that pauses must be added for other devices in order to line up the actions
|
32
33
|
# correctly when using asynchronous.
|
33
34
|
#
|
34
|
-
# @param [Selenium::WebDriver::Remote::Bridge] bridge the bridge for the current driver instance
|
35
|
-
# @param [Selenium::WebDriver::Interactions::PointerInput]
|
36
|
-
# @param [Selenium::WebDriver::Interactions::KeyInput]
|
37
|
-
# @param [Boolean]
|
38
|
-
# backwards compatibility.
|
35
|
+
# @param [Selenium::WebDriver::Remote::Bridge] bridge the bridge for the current driver instance.
|
36
|
+
# @param [Selenium::WebDriver::Interactions::PointerInput] deprecated_mouse PointerInput for the mouse.
|
37
|
+
# @param [Selenium::WebDriver::Interactions::KeyInput] deprecated_keyboard KeyInput for the keyboard.
|
38
|
+
# @param [Boolean] deprecated_async Whether to perform the actions asynchronously per device.
|
39
|
+
# Defaults to false for backwards compatibility.
|
40
|
+
# @param [Array<Selenium::WebDriver::Interactions::InputDevices>] devices list of valid sources of input.
|
41
|
+
# @param [Boolean] async Whether to perform the actions asynchronously per device.
|
39
42
|
# @return [ActionBuilder] A self reference.
|
40
43
|
#
|
41
44
|
|
42
|
-
def initialize(bridge,
|
43
|
-
|
45
|
+
def initialize(bridge, deprecated_mouse = nil, deprecated_keyboard = nil, deprecated_async = nil,
|
46
|
+
devices: [], async: false, duration: 250)
|
44
47
|
@bridge = bridge
|
45
|
-
@
|
46
|
-
|
48
|
+
@duration = duration
|
49
|
+
|
50
|
+
@async = if deprecated_async.nil?
|
51
|
+
async
|
52
|
+
else
|
53
|
+
WebDriver.logger.deprecate('initializing ActionBuilder with async parameter',
|
54
|
+
':async keyword',
|
55
|
+
id: :action_async)
|
56
|
+
deprecated_async
|
57
|
+
end
|
58
|
+
|
59
|
+
@devices = []
|
60
|
+
if deprecated_keyboard || deprecated_mouse
|
61
|
+
WebDriver.logger.deprecate "initializing ActionBuilder with keyboard and mouse parameters",
|
62
|
+
"devices keyword or, even better, Driver#action",
|
63
|
+
id: :action_devices
|
64
|
+
add_input(deprecated_mouse)
|
65
|
+
add_input(deprecated_keyboard)
|
66
|
+
else
|
67
|
+
Array(devices).each { |device| add_input(device) }
|
68
|
+
end
|
47
69
|
end
|
48
70
|
|
49
71
|
#
|
@@ -61,9 +83,7 @@ module Selenium
|
|
61
83
|
#
|
62
84
|
|
63
85
|
def add_pointer_input(kind, name)
|
64
|
-
|
65
|
-
add_input(new_input)
|
66
|
-
new_input
|
86
|
+
add_input(Interactions.pointer(kind, name: name))
|
67
87
|
end
|
68
88
|
|
69
89
|
#
|
@@ -79,9 +99,23 @@ module Selenium
|
|
79
99
|
#
|
80
100
|
|
81
101
|
def add_key_input(name)
|
82
|
-
|
83
|
-
|
84
|
-
|
102
|
+
add_input(Interactions.key(name))
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Adds a WheelInput device
|
107
|
+
#
|
108
|
+
# @example Add a wheel input device
|
109
|
+
#
|
110
|
+
# builder = device.action
|
111
|
+
# builder.add_wheel_input('wheel2')
|
112
|
+
#
|
113
|
+
# @param [String] name name for the device
|
114
|
+
# @return [Interactions::WheelInput] The wheel input added
|
115
|
+
#
|
116
|
+
|
117
|
+
def add_wheel_input(name)
|
118
|
+
add_input(Interactions.wheel(name))
|
85
119
|
end
|
86
120
|
|
87
121
|
#
|
@@ -92,7 +126,26 @@ module Selenium
|
|
92
126
|
#
|
93
127
|
|
94
128
|
def get_device(name)
|
95
|
-
|
129
|
+
WebDriver.logger.deprecate('#get_device with name parameter',
|
130
|
+
'#device with :name or :type keyword',
|
131
|
+
id: :get_device)
|
132
|
+
device(name: name)
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Retrieves the input device for the given name or type
|
137
|
+
#
|
138
|
+
# @param [String] name name of the input device
|
139
|
+
# @param [String] type name of the input device
|
140
|
+
# @return [Selenium::WebDriver::Interactions::InputDevice] input device with given name or type
|
141
|
+
#
|
142
|
+
|
143
|
+
def device(name: nil, type: nil)
|
144
|
+
input = @devices.find { |device| (device.name == name.to_s || name.nil?) && (device.type == type || type.nil?) }
|
145
|
+
|
146
|
+
raise(ArgumentError, "Can not find device: #{name}") if name && input.nil?
|
147
|
+
|
148
|
+
input
|
96
149
|
end
|
97
150
|
|
98
151
|
#
|
@@ -115,6 +168,16 @@ module Selenium
|
|
115
168
|
@devices.select { |device| device.type == Interactions::KEY }
|
116
169
|
end
|
117
170
|
|
171
|
+
#
|
172
|
+
# Retrieves the current WheelInput device
|
173
|
+
#
|
174
|
+
# @return [Selenium::WebDriver::Interactions::InputDevice] current WheelInput devices
|
175
|
+
#
|
176
|
+
|
177
|
+
def wheel_inputs
|
178
|
+
@devices.select { |device| device.type == Interactions::WHEEL }
|
179
|
+
end
|
180
|
+
|
118
181
|
#
|
119
182
|
# Creates a pause for the given device of the given duration. If no duration is given, the pause will only wait
|
120
183
|
# for all actions to complete in that tick.
|
@@ -131,8 +194,11 @@ module Selenium
|
|
131
194
|
# @return [ActionBuilder] A self reference.
|
132
195
|
#
|
133
196
|
|
134
|
-
def pause(
|
135
|
-
|
197
|
+
def pause(deprecated_device = nil, deprecated_duration = nil, device: nil, duration: 0)
|
198
|
+
deprecate_method(deprecated_device, deprecated_duration)
|
199
|
+
|
200
|
+
device ||= deprecated_device || pointer_input
|
201
|
+
device.create_pause(deprecated_duration || duration)
|
136
202
|
self
|
137
203
|
end
|
138
204
|
|
@@ -152,7 +218,14 @@ module Selenium
|
|
152
218
|
# @return [ActionBuilder] A self reference.
|
153
219
|
#
|
154
220
|
|
155
|
-
def pauses(
|
221
|
+
def pauses(deprecated_device = nil, deprecated_number = nil, deprecated_duration = nil,
|
222
|
+
device: nil, number: nil, duration: 0)
|
223
|
+
deprecate_method(deprecated_device, deprecated_duration, deprecated_number, method: :pauses)
|
224
|
+
|
225
|
+
number ||= deprecated_number || 2
|
226
|
+
device ||= deprecated_device || pointer_input
|
227
|
+
duration ||= deprecated_duration || 0
|
228
|
+
|
156
229
|
number.times { device.create_pause(duration) }
|
157
230
|
self
|
158
231
|
end
|
@@ -162,7 +235,7 @@ module Selenium
|
|
162
235
|
#
|
163
236
|
|
164
237
|
def perform
|
165
|
-
@bridge.send_actions @devices.
|
238
|
+
@bridge.send_actions @devices.filter_map(&:encode)
|
166
239
|
clear_all_actions
|
167
240
|
nil
|
168
241
|
end
|
@@ -202,12 +275,26 @@ module Selenium
|
|
202
275
|
#
|
203
276
|
|
204
277
|
def add_input(device)
|
278
|
+
device = Interactions.send(device) if device.is_a?(Symbol) && Interactions.respond_to?(device)
|
279
|
+
|
280
|
+
raise TypeError, "#{device.inspect} is not a valid InputDevice" unless device.is_a?(Interactions::InputDevice)
|
281
|
+
|
205
282
|
unless @async
|
206
283
|
max_device = @devices.max { |a, b| a.actions.length <=> b.actions.length }
|
207
|
-
pauses(device, max_device.actions.length)
|
284
|
+
pauses(device: device, number: max_device.actions.length) if max_device
|
208
285
|
end
|
209
286
|
@devices << device
|
287
|
+
device
|
210
288
|
end
|
289
|
+
|
290
|
+
def deprecate_method(device = nil, duration = nil, number = nil, method: :pause)
|
291
|
+
return unless device || number || duration
|
292
|
+
|
293
|
+
WebDriver.logger.deprecate "ActionBuilder##{method} with ordered parameters",
|
294
|
+
':device, :duration, :number keywords',
|
295
|
+
id: method
|
296
|
+
end
|
297
|
+
|
211
298
|
end # ActionBuilder
|
212
299
|
end # WebDriver
|
213
300
|
end # Selenium
|
@@ -0,0 +1,38 @@
|
|
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 DriverExtensions
|
23
|
+
module HasBiDi
|
24
|
+
|
25
|
+
#
|
26
|
+
# Retrieves WebDriver BiDi connection.
|
27
|
+
#
|
28
|
+
# @return [BiDi]
|
29
|
+
#
|
30
|
+
|
31
|
+
def bidi
|
32
|
+
@bidi ||= Selenium::WebDriver::BiDi.new(url: capabilities[:web_socket_url])
|
33
|
+
end
|
34
|
+
|
35
|
+
end # HasBiDi
|
36
|
+
end # DriverExtensions
|
37
|
+
end # WebDriver
|
38
|
+
end # Selenium
|
@@ -52,6 +52,16 @@ module Selenium
|
|
52
52
|
@bridge.start_cast_tab_mirroring(name)
|
53
53
|
end
|
54
54
|
|
55
|
+
#
|
56
|
+
# Starts a tab mirroring session on a specific receiver target.
|
57
|
+
#
|
58
|
+
# @param [String] name the sink to use as the target
|
59
|
+
#
|
60
|
+
|
61
|
+
def start_cast_desktop_mirroring(name)
|
62
|
+
@bridge.start_cast_desktop_mirroring(name)
|
63
|
+
end
|
64
|
+
|
55
65
|
#
|
56
66
|
# Gets error messages when there is any issue in a Cast session.
|
57
67
|
#
|
@@ -27,8 +27,7 @@ module Selenium
|
|
27
27
|
# a `with` statement. The state of the context on the server is
|
28
28
|
# saved before entering the block, and restored upon exiting it.
|
29
29
|
#
|
30
|
-
# @param [String]
|
31
|
-
# @param [String] value what to set the permission to
|
30
|
+
# @param [String] value which context gets set (either 'chrome' or 'content')
|
32
31
|
#
|
33
32
|
|
34
33
|
def context=(value)
|
@@ -114,7 +114,7 @@ module Selenium
|
|
114
114
|
execute_script(mutation_listener)
|
115
115
|
devtools.page.add_script_to_evaluate_on_new_document(source: mutation_listener)
|
116
116
|
|
117
|
-
devtools.runtime.on(:binding_called
|
117
|
+
devtools.runtime.on(:binding_called) { |event| log_mutation_event(event) }
|
118
118
|
end
|
119
119
|
|
120
120
|
def log_mutation_event(params)
|
@@ -29,7 +29,7 @@ module Selenium
|
|
29
29
|
def self.for_error(error)
|
30
30
|
return if error.nil?
|
31
31
|
|
32
|
-
klass_name = error.split
|
32
|
+
klass_name = error.split.map(&:capitalize).join.sub(/Error$/, '')
|
33
33
|
const_get("#{klass_name}Error", false)
|
34
34
|
rescue NameError
|
35
35
|
WebDriverError
|