selenium-webdriver 4.1.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 +182 -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 +35 -26
- 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 +19 -28
- 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 +4 -19
- 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 +72 -22
- data/lib/selenium/webdriver/common/child_process.rb +124 -0
- data/lib/selenium/webdriver/common/driver.rb +50 -70
- 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/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/logger.rb +10 -2
- 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/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 +89 -0
- data/lib/selenium/webdriver/common/service.rb +16 -8
- data/lib/selenium/webdriver/common/service_manager.rb +4 -13
- data/lib/selenium/webdriver/common/shadow_root.rb +2 -3
- data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
- data/lib/selenium/webdriver/common/socket_poller.rb +1 -1
- 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 +19 -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 +6 -113
- data/lib/selenium/webdriver/edge/driver.rb +20 -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 -2
- data/lib/selenium/webdriver/firefox/driver.rb +20 -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 +7 -11
- data/lib/selenium/webdriver/firefox/service.rb +0 -1
- data/lib/selenium/webdriver/firefox/util.rb +46 -0
- data/lib/selenium/webdriver/firefox.rb +1 -14
- data/lib/selenium/webdriver/ie/driver.rb +20 -1
- data/lib/selenium/webdriver/ie/service.rb +1 -2
- 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 +59 -30
- data/lib/selenium/webdriver/remote/capabilities.rb +34 -12
- data/lib/selenium/webdriver/remote/driver.rb +14 -15
- data/lib/selenium/webdriver/remote/http/curb.rb +0 -2
- 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 +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 -15
- data/lib/selenium/webdriver/support/color.rb +20 -20
- 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 +4 -4
- data/selenium-webdriver.gemspec +13 -11
- metadata +68 -59
- 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 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
|
|
@@ -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,7 +28,7 @@ module Selenium
|
|
|
29
28
|
def self.for_error(error)
|
|
30
29
|
return if error.nil?
|
|
31
30
|
|
|
32
|
-
klass_name = error.split
|
|
31
|
+
klass_name = error.split.map(&:capitalize).join.sub(/Error$/, '')
|
|
33
32
|
const_get("#{klass_name}Error", false)
|
|
34
33
|
rescue NameError
|
|
35
34
|
WebDriverError
|
|
@@ -213,7 +212,6 @@ module Selenium
|
|
|
213
212
|
#
|
|
214
213
|
|
|
215
214
|
class UnsupportedOperationError < WebDriverError; end
|
|
216
|
-
|
|
217
215
|
end # Error
|
|
218
216
|
end # WebDriver
|
|
219
217
|
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
|
|
@@ -20,17 +20,18 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Interactions
|
|
23
|
+
#
|
|
24
|
+
# Creates actions specific to Key Input devices
|
|
25
|
+
#
|
|
26
|
+
# @api private
|
|
27
|
+
#
|
|
28
|
+
|
|
23
29
|
class KeyInput < InputDevice
|
|
24
30
|
SUBTYPES = {down: :keyDown, up: :keyUp, pause: :pause}.freeze
|
|
25
31
|
|
|
26
|
-
def
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def encode
|
|
31
|
-
return nil if no_actions?
|
|
32
|
-
|
|
33
|
-
{type: type, id: name, actions: @actions.map(&:encode)}
|
|
32
|
+
def initialize(name = nil)
|
|
33
|
+
super
|
|
34
|
+
@type = Interactions::KEY
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def create_key_down(key)
|
|
@@ -41,25 +42,8 @@ module Selenium
|
|
|
41
42
|
add_action(TypingInteraction.new(self, :up, key))
|
|
42
43
|
end
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def initialize(source, type, key)
|
|
48
|
-
super(source)
|
|
49
|
-
@type = assert_type(type)
|
|
50
|
-
@key = Keys.encode_key(key)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def assert_type(type)
|
|
54
|
-
raise TypeError, "#{type.inspect} is not a valid key subtype" unless KeyInput::SUBTYPES.key? type
|
|
55
|
-
|
|
56
|
-
KeyInput::SUBTYPES[type]
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def encode
|
|
60
|
-
{type: @type, value: @key}
|
|
61
|
-
end
|
|
62
|
-
end # TypingInteraction
|
|
45
|
+
# Backward compatibility in case anyone called this directly
|
|
46
|
+
class TypingInteraction < Interactions::TypingInteraction; end
|
|
63
47
|
end # KeyInput
|
|
64
48
|
end # Interactions
|
|
65
49
|
end # WebDriver
|
|
@@ -20,15 +20,17 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Interactions
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
#
|
|
24
|
+
# Creates actions specific to null input source
|
|
25
|
+
# This is primarily used for adding pauses
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
class NoneInput < InputDevice
|
|
31
|
+
def initialize(name = nil)
|
|
32
|
+
super
|
|
33
|
+
@type = Interactions::NONE
|
|
32
34
|
end
|
|
33
35
|
end # NoneInput
|
|
34
36
|
end # Interactions
|
|
@@ -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 Interactions
|
|
23
|
+
#
|
|
24
|
+
# Action to create a waiting period between actions
|
|
25
|
+
# Also used for synchronizing actions across devices
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
|
|
30
|
+
class Pause < Interaction
|
|
31
|
+
def initialize(source, duration = nil)
|
|
32
|
+
super(source)
|
|
33
|
+
@duration = duration
|
|
34
|
+
@type = :pause
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def assert_source(source)
|
|
38
|
+
raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? InputDevice
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def encode
|
|
42
|
+
output = {type: type}
|
|
43
|
+
output[:duration] = (@duration * 1000).to_i if @duration
|
|
44
|
+
output
|
|
45
|
+
end
|
|
46
|
+
end # Pause
|
|
47
|
+
end # Interactions
|
|
48
|
+
end # WebDriver
|
|
49
|
+
end # Selenium
|
|
@@ -23,11 +23,12 @@ module Selenium
|
|
|
23
23
|
attr_writer :default_move_duration
|
|
24
24
|
|
|
25
25
|
#
|
|
26
|
-
#
|
|
26
|
+
# By default this is set to 250ms in the ActionBuilder constructor
|
|
27
|
+
# It can be overridden with default_move_duration=
|
|
27
28
|
#
|
|
28
29
|
|
|
29
30
|
def default_move_duration
|
|
30
|
-
@default_move_duration ||= 0
|
|
31
|
+
@default_move_duration ||= @duration / 1000.0 # convert ms to seconds
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
#
|
|
@@ -45,8 +46,8 @@ module Selenium
|
|
|
45
46
|
# @return [ActionBuilder] A self reference.
|
|
46
47
|
#
|
|
47
48
|
|
|
48
|
-
def pointer_down(button, device: nil)
|
|
49
|
-
button_action(button,
|
|
49
|
+
def pointer_down(button = :left, device: nil, **opts)
|
|
50
|
+
button_action(button, :create_pointer_down, device: device, **opts)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
#
|
|
@@ -62,21 +63,20 @@ module Selenium
|
|
|
62
63
|
# @return [ActionBuilder] A self reference.
|
|
63
64
|
#
|
|
64
65
|
|
|
65
|
-
def pointer_up(button, device: nil)
|
|
66
|
-
button_action(button,
|
|
66
|
+
def pointer_up(button = :left, device: nil, **opts)
|
|
67
|
+
button_action(button, :create_pointer_up, device: device, **opts)
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
#
|
|
70
|
-
# Moves the
|
|
71
|
-
#
|
|
72
|
-
# mouse is moved to optional offset coordinates from the element.
|
|
71
|
+
# Moves the pointer to the in-view center point of the given element.
|
|
72
|
+
# Then the pointer is moved to optional offset coordinates.
|
|
73
73
|
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
74
|
+
# The element is not scrolled into view.
|
|
75
|
+
# MoveTargetOutOfBoundsError will be raised if element with offset is outside the viewport
|
|
76
76
|
#
|
|
77
|
-
#
|
|
77
|
+
# When using offsets, both coordinates need to be passed.
|
|
78
78
|
#
|
|
79
|
-
# @example
|
|
79
|
+
# @example Move the pointer to element
|
|
80
80
|
#
|
|
81
81
|
# el = driver.find_element(id: "some_id")
|
|
82
82
|
# driver.action.move_to(el).perform
|
|
@@ -87,69 +87,60 @@ module Selenium
|
|
|
87
87
|
# driver.action.move_to(el, 100, 100).perform
|
|
88
88
|
#
|
|
89
89
|
# @param [Selenium::WebDriver::Element] element to move to.
|
|
90
|
-
# @param [Integer] right_by Optional offset from the
|
|
91
|
-
# coordinates to the left of the
|
|
92
|
-
# @param [Integer] down_by Optional offset from the
|
|
93
|
-
# coordinates
|
|
90
|
+
# @param [Integer] right_by Optional offset from the in-view center of the
|
|
91
|
+
# element. A negative value means coordinates to the left of the center.
|
|
92
|
+
# @param [Integer] down_by Optional offset from the in-view center of the
|
|
93
|
+
# element. A negative value means coordinates to the top of the center.
|
|
94
94
|
# @param [Symbol || String] device optional name of the PointerInput device to move.
|
|
95
95
|
# @return [ActionBuilder] A self reference.
|
|
96
96
|
#
|
|
97
97
|
|
|
98
|
-
def move_to(element, right_by = nil, down_by = nil,
|
|
99
|
-
pointer =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
left = -left_offset + (right_by || 0)
|
|
106
|
-
top = -top_offset + (down_by || 0)
|
|
107
|
-
else
|
|
108
|
-
left = 0
|
|
109
|
-
top = 0
|
|
110
|
-
end
|
|
111
|
-
pointer.create_pointer_move(duration: default_move_duration,
|
|
112
|
-
x: left,
|
|
113
|
-
y: top,
|
|
114
|
-
element: element)
|
|
98
|
+
def move_to(element, right_by = nil, down_by = nil, **opts)
|
|
99
|
+
pointer = pointer_input(opts.delete(:device))
|
|
100
|
+
pointer.create_pointer_move(duration: opts.delete(:duration) || default_move_duration,
|
|
101
|
+
x: right_by || 0,
|
|
102
|
+
y: down_by || 0,
|
|
103
|
+
origin: element,
|
|
104
|
+
**opts)
|
|
115
105
|
tick(pointer)
|
|
116
106
|
self
|
|
117
107
|
end
|
|
118
108
|
|
|
119
109
|
#
|
|
120
|
-
# Moves the
|
|
121
|
-
# If the coordinates provided are outside the viewport (the mouse will
|
|
122
|
-
# end up outside the browser window) then the viewport is scrolled to
|
|
123
|
-
# match.
|
|
110
|
+
# Moves the pointer from its current position by the given offset.
|
|
124
111
|
#
|
|
125
|
-
#
|
|
112
|
+
# The viewport is not scrolled if the coordinates provided are outside the viewport.
|
|
113
|
+
# MoveTargetOutOfBoundsError will be raised if the offsets are outside the viewport
|
|
114
|
+
#
|
|
115
|
+
# @example Move the pointer to a certain offset from its current position
|
|
126
116
|
#
|
|
127
117
|
# driver.action.move_by(100, 100).perform
|
|
128
118
|
#
|
|
129
|
-
# @param [Integer] right_by horizontal offset. A negative value means moving the
|
|
130
|
-
# @param [Integer] down_by vertical offset. A negative value means moving the
|
|
119
|
+
# @param [Integer] right_by horizontal offset. A negative value means moving the pointer left.
|
|
120
|
+
# @param [Integer] down_by vertical offset. A negative value means moving the pointer up.
|
|
131
121
|
# @param [Symbol || String] device optional name of the PointerInput device to move
|
|
132
122
|
# @return [ActionBuilder] A self reference.
|
|
133
123
|
# @raise [MoveTargetOutOfBoundsError] if the provided offset is outside the document's boundaries.
|
|
134
124
|
#
|
|
135
125
|
|
|
136
|
-
def move_by(right_by, down_by, device: nil)
|
|
137
|
-
pointer =
|
|
138
|
-
pointer.create_pointer_move(duration:
|
|
126
|
+
def move_by(right_by, down_by, device: nil, duration: default_move_duration, **opts)
|
|
127
|
+
pointer = pointer_input(device)
|
|
128
|
+
pointer.create_pointer_move(duration: duration,
|
|
139
129
|
x: Integer(right_by),
|
|
140
130
|
y: Integer(down_by),
|
|
141
|
-
origin: Interactions::PointerMove::POINTER
|
|
131
|
+
origin: Interactions::PointerMove::POINTER,
|
|
132
|
+
**opts)
|
|
142
133
|
tick(pointer)
|
|
143
134
|
self
|
|
144
135
|
end
|
|
145
136
|
|
|
146
137
|
#
|
|
147
|
-
# Moves the
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
138
|
+
# Moves the pointer to a given location in the viewport.
|
|
139
|
+
#
|
|
140
|
+
# The viewport is not scrolled if the coordinates provided are outside the viewport.
|
|
141
|
+
# MoveTargetOutOfBoundsError will be raised if the offsets are outside the viewport
|
|
151
142
|
#
|
|
152
|
-
# @example Move the
|
|
143
|
+
# @example Move the pointer to a certain position in the viewport
|
|
153
144
|
#
|
|
154
145
|
# driver.action.move_to_location(100, 100).perform
|
|
155
146
|
#
|
|
@@ -160,12 +151,13 @@ module Selenium
|
|
|
160
151
|
# @raise [MoveTargetOutOfBoundsError] if the provided x or y value is outside the document's boundaries.
|
|
161
152
|
#
|
|
162
153
|
|
|
163
|
-
def move_to_location(x, y, device: nil)
|
|
164
|
-
pointer =
|
|
165
|
-
pointer.create_pointer_move(duration:
|
|
154
|
+
def move_to_location(x, y, device: nil, duration: default_move_duration, **opts)
|
|
155
|
+
pointer = pointer_input(device)
|
|
156
|
+
pointer.create_pointer_move(duration: duration,
|
|
166
157
|
x: Integer(x),
|
|
167
158
|
y: Integer(y),
|
|
168
|
-
origin: Interactions::PointerMove::VIEWPORT
|
|
159
|
+
origin: Interactions::PointerMove::VIEWPORT,
|
|
160
|
+
**opts)
|
|
169
161
|
tick(pointer)
|
|
170
162
|
self
|
|
171
163
|
end
|
|
@@ -186,9 +178,9 @@ module Selenium
|
|
|
186
178
|
# @return [ActionBuilder] A self reference.
|
|
187
179
|
#
|
|
188
180
|
|
|
189
|
-
def click_and_hold(element = nil, device: nil)
|
|
181
|
+
def click_and_hold(element = nil, button: nil, device: nil)
|
|
190
182
|
move_to(element, device: device) if element
|
|
191
|
-
pointer_down(:left, device: device)
|
|
183
|
+
pointer_down(button || :left, device: device)
|
|
192
184
|
self
|
|
193
185
|
end
|
|
194
186
|
|
|
@@ -205,8 +197,8 @@ module Selenium
|
|
|
205
197
|
# @return [ActionBuilder] A self reference.
|
|
206
198
|
#
|
|
207
199
|
|
|
208
|
-
def release(device: nil)
|
|
209
|
-
pointer_up(:left, device: device)
|
|
200
|
+
def release(button: nil, device: nil)
|
|
201
|
+
pointer_up(button || :left, device: device)
|
|
210
202
|
self
|
|
211
203
|
end
|
|
212
204
|
|
|
@@ -232,10 +224,10 @@ module Selenium
|
|
|
232
224
|
# @return [ActionBuilder] A self reference.
|
|
233
225
|
#
|
|
234
226
|
|
|
235
|
-
def click(element = nil, device: nil)
|
|
227
|
+
def click(element = nil, button: nil, device: nil)
|
|
236
228
|
move_to(element, device: device) if element
|
|
237
|
-
pointer_down(:left, device: device)
|
|
238
|
-
pointer_up(:left, device: device)
|
|
229
|
+
pointer_down(button || :left, device: device)
|
|
230
|
+
pointer_up(button || :left, device: device)
|
|
239
231
|
self
|
|
240
232
|
end
|
|
241
233
|
|
|
@@ -290,10 +282,7 @@ module Selenium
|
|
|
290
282
|
#
|
|
291
283
|
|
|
292
284
|
def context_click(element = nil, device: nil)
|
|
293
|
-
|
|
294
|
-
pointer_down(:right, device: device)
|
|
295
|
-
pointer_up(:right, device: device)
|
|
296
|
-
self
|
|
285
|
+
click(element, button: :right, device: device)
|
|
297
286
|
end
|
|
298
287
|
|
|
299
288
|
#
|
|
@@ -348,15 +337,15 @@ module Selenium
|
|
|
348
337
|
|
|
349
338
|
private
|
|
350
339
|
|
|
351
|
-
def button_action(button, action
|
|
352
|
-
pointer =
|
|
353
|
-
pointer.send(action, button)
|
|
340
|
+
def button_action(button, action, device: nil, **opts)
|
|
341
|
+
pointer = pointer_input(device)
|
|
342
|
+
pointer.send(action, button, **opts)
|
|
354
343
|
tick(pointer)
|
|
355
344
|
self
|
|
356
345
|
end
|
|
357
346
|
|
|
358
|
-
def
|
|
359
|
-
|
|
347
|
+
def pointer_input(name = nil)
|
|
348
|
+
device(name: name, type: Interactions::POINTER) || add_pointer_input(:mouse, 'mouse')
|
|
360
349
|
end
|
|
361
350
|
end # PointerActions
|
|
362
351
|
end # WebDriver
|