selenium-webdriver 3.0.0.beta4.0 → 4.0.0.alpha5
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 +7 -0
- data/CHANGES +679 -0
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/selenium-webdriver.rb +2 -2
- data/lib/selenium/server.rb +23 -16
- data/lib/selenium/webdriver.rb +43 -25
- data/lib/selenium/webdriver/atoms.rb +20 -1
- data/lib/selenium/webdriver/atoms/findElements.js +122 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +84 -11
- data/lib/selenium/webdriver/atoms/isDisplayed.js +100 -0
- data/lib/selenium/webdriver/chrome.rb +15 -20
- data/lib/selenium/webdriver/chrome/bridge.rb +29 -66
- data/lib/selenium/webdriver/{edge/service.rb → chrome/driver.rb} +19 -22
- data/lib/selenium/webdriver/chrome/options.rb +221 -0
- data/lib/selenium/webdriver/chrome/profile.rb +6 -7
- data/lib/selenium/webdriver/chrome/service.rb +20 -20
- data/lib/selenium/webdriver/common.rb +19 -11
- data/lib/selenium/webdriver/common/action_builder.rb +98 -246
- data/lib/selenium/webdriver/common/alert.rb +2 -7
- data/lib/selenium/webdriver/common/driver.rb +89 -51
- data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +45 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +50 -0
- data/lib/selenium/webdriver/common/driver_extensions/{has_input_devices.rb → has_debugger.rb} +12 -25
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +38 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +3 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +3 -3
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +2 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +2 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +2 -2
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +4 -4
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +9 -3
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +3 -5
- data/lib/selenium/webdriver/common/element.rb +32 -10
- data/lib/selenium/webdriver/common/error.rb +103 -121
- data/lib/selenium/webdriver/common/file_reaper.rb +3 -5
- data/lib/selenium/webdriver/common/html5/local_storage.rb +2 -2
- data/lib/selenium/webdriver/common/html5/session_storage.rb +2 -2
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +3 -2
- data/lib/selenium/webdriver/common/interactions/input_device.rb +54 -0
- data/lib/selenium/webdriver/common/interactions/interaction.rb +53 -0
- data/lib/selenium/webdriver/{phantomjs.rb → common/interactions/interactions.rb} +17 -20
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +145 -0
- data/lib/selenium/webdriver/common/interactions/key_input.rb +66 -0
- data/lib/selenium/webdriver/common/interactions/none_input.rb +36 -0
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +363 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +139 -0
- data/lib/selenium/webdriver/common/keys.rb +37 -15
- data/lib/selenium/webdriver/common/log_entry.rb +4 -4
- data/lib/selenium/webdriver/common/logger.rb +147 -0
- data/lib/selenium/webdriver/common/logs.rb +2 -2
- data/lib/selenium/webdriver/common/manager.rb +177 -0
- data/lib/selenium/webdriver/common/navigation.rb +2 -2
- data/lib/selenium/webdriver/common/options.rb +47 -105
- data/lib/selenium/webdriver/common/platform.rb +44 -38
- data/lib/selenium/webdriver/common/port_prober.rb +8 -19
- data/lib/selenium/webdriver/common/profile_helper.rb +13 -5
- data/lib/selenium/webdriver/common/proxy.rb +14 -8
- data/lib/selenium/webdriver/common/search_context.rb +16 -20
- data/lib/selenium/webdriver/common/service.rb +115 -30
- data/lib/selenium/webdriver/common/socket_lock.rb +12 -7
- data/lib/selenium/webdriver/common/socket_poller.rb +29 -22
- data/lib/selenium/webdriver/common/target_locator.rb +6 -6
- data/lib/selenium/webdriver/common/timeouts.rb +2 -2
- data/lib/selenium/webdriver/common/wait.rb +14 -8
- data/lib/selenium/webdriver/common/window.rb +38 -2
- data/lib/selenium/webdriver/common/zipper.rb +3 -5
- data/lib/selenium/webdriver/edge.rb +33 -20
- data/lib/selenium/webdriver/edge_chrome/bridge.rb +30 -0
- data/lib/selenium/webdriver/edge_chrome/driver.rb +38 -0
- data/lib/selenium/webdriver/{common/driver_extensions/has_touch_screen.rb → edge_chrome/options.rb} +10 -12
- data/lib/selenium/webdriver/edge_chrome/profile.rb +33 -0
- data/lib/selenium/webdriver/edge_chrome/service.rb +36 -0
- data/lib/selenium/webdriver/edge_html/driver.rb +39 -0
- data/lib/selenium/webdriver/edge_html/options.rb +91 -0
- data/lib/selenium/webdriver/edge_html/service.rb +47 -0
- data/lib/selenium/webdriver/firefox.rb +24 -29
- data/lib/selenium/webdriver/firefox/bridge.rb +15 -39
- data/lib/selenium/webdriver/firefox/{util.rb → driver.rb} +13 -19
- data/lib/selenium/webdriver/firefox/extension.rb +28 -8
- data/lib/selenium/webdriver/firefox/options.rb +162 -0
- data/lib/selenium/webdriver/firefox/profile.rb +23 -82
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +5 -5
- data/lib/selenium/webdriver/firefox/service.rb +18 -37
- data/lib/selenium/webdriver/ie.rb +13 -19
- data/lib/selenium/webdriver/ie/driver.rb +40 -0
- data/lib/selenium/webdriver/ie/options.rb +118 -0
- data/lib/selenium/webdriver/ie/service.rb +20 -20
- data/lib/selenium/webdriver/remote.rb +15 -17
- data/lib/selenium/webdriver/remote/bridge.rb +281 -300
- data/lib/selenium/webdriver/remote/capabilities.rb +102 -83
- data/lib/selenium/webdriver/remote/commands.rb +132 -192
- data/lib/selenium/webdriver/remote/driver.rb +52 -0
- data/lib/selenium/webdriver/remote/http/common.rb +23 -13
- data/lib/selenium/webdriver/remote/http/curb.rb +10 -7
- data/lib/selenium/webdriver/remote/http/default.rb +52 -32
- data/lib/selenium/webdriver/remote/http/persistent.rb +8 -4
- data/lib/selenium/webdriver/remote/response.rb +32 -35
- data/lib/selenium/webdriver/remote/server_error.rb +2 -2
- data/lib/selenium/webdriver/safari.rb +24 -22
- data/lib/selenium/webdriver/safari/bridge.rb +21 -21
- data/lib/selenium/webdriver/safari/driver.rb +41 -0
- data/lib/selenium/webdriver/safari/options.rb +66 -0
- data/lib/selenium/webdriver/safari/service.rb +8 -24
- data/lib/selenium/webdriver/support.rb +3 -2
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +2 -2
- data/lib/selenium/webdriver/support/block_event_listener.rb +3 -3
- data/lib/selenium/webdriver/support/color.rb +13 -13
- data/lib/selenium/webdriver/support/escaper.rb +2 -2
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
- data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
- data/lib/selenium/webdriver/support/select.rb +20 -21
- data/lib/selenium/webdriver/version.rb +24 -0
- data/selenium-webdriver.gemspec +31 -17
- metadata +331 -248
- data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
- data/lib/selenium/webdriver/common/keyboard.rb +0 -69
- data/lib/selenium/webdriver/common/mouse.rb +0 -88
- data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -81
- data/lib/selenium/webdriver/common/touch_screen.rb +0 -121
- data/lib/selenium/webdriver/common/w3c_error.rb +0 -191
- data/lib/selenium/webdriver/edge/bridge.rb +0 -76
- data/lib/selenium/webdriver/edge/legacy_support.rb +0 -117
- data/lib/selenium/webdriver/firefox/binary.rb +0 -186
- data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +0 -114
- data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
- data/lib/selenium/webdriver/firefox/w3c_bridge.rb +0 -79
- data/lib/selenium/webdriver/ie/bridge.rb +0 -76
- data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -65
- data/lib/selenium/webdriver/phantomjs/service.rb +0 -66
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -682
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -228
- data/lib/selenium/webdriver/remote/w3c_commands.rb +0 -135
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -36,9 +36,7 @@ module Selenium
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def add_extension(path)
|
|
39
|
-
unless File.file?(path)
|
|
40
|
-
raise Error::WebDriverError, "could not find extension at #{path.inspect}"
|
|
41
|
-
end
|
|
39
|
+
raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
|
|
42
40
|
|
|
43
41
|
@extensions << path
|
|
44
42
|
end
|
|
@@ -79,8 +77,8 @@ module Selenium
|
|
|
79
77
|
|
|
80
78
|
extensions.concat(@encoded_extensions)
|
|
81
79
|
|
|
82
|
-
opts = {directory
|
|
83
|
-
opts[
|
|
80
|
+
opts = {'directory' => directory || layout_on_disk}
|
|
81
|
+
opts['extensions'] = extensions if extensions.any?
|
|
84
82
|
opts
|
|
85
83
|
end
|
|
86
84
|
|
|
@@ -99,6 +97,7 @@ module Selenium
|
|
|
99
97
|
|
|
100
98
|
def read_model_prefs
|
|
101
99
|
return {} unless @model
|
|
100
|
+
|
|
102
101
|
JSON.parse File.read(prefs_file_for(@model))
|
|
103
102
|
end
|
|
104
103
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -20,29 +20,29 @@
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
22
|
module Chrome
|
|
23
|
-
#
|
|
24
|
-
# @api private
|
|
25
|
-
#
|
|
26
|
-
|
|
27
23
|
class Service < WebDriver::Service
|
|
28
24
|
DEFAULT_PORT = 9515
|
|
25
|
+
EXECUTABLE = 'chromedriver'
|
|
26
|
+
MISSING_TEXT = <<~ERROR
|
|
27
|
+
Unable to find chromedriver. Please download the server from
|
|
28
|
+
https://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH.
|
|
29
|
+
More info at https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver.
|
|
30
|
+
ERROR
|
|
31
|
+
SHUTDOWN_SUPPORTED = true
|
|
29
32
|
|
|
30
33
|
private
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def cannot_connect_error_text
|
|
45
|
-
"unable to connect to chromedriver #{@host}:#{@port}"
|
|
35
|
+
# Note: This processing is deprecated
|
|
36
|
+
def extract_service_args(driver_opts)
|
|
37
|
+
driver_args = super
|
|
38
|
+
driver_opts = driver_opts.dup
|
|
39
|
+
driver_args << "--log-path=#{driver_opts.delete(:log_path)}" if driver_opts.key?(:log_path)
|
|
40
|
+
driver_args << "--url-base=#{driver_opts.delete(:url_base)}" if driver_opts.key?(:url_base)
|
|
41
|
+
driver_args << "--port-server=#{driver_opts.delete(:port_server)}" if driver_opts.key?(:port_server)
|
|
42
|
+
driver_args << "--whitelisted-ips=#{driver_opts.delete(:whitelisted_ips)}" if driver_opts.key?(:whitelisted_ips)
|
|
43
|
+
driver_args << "--verbose" if driver_opts.key?(:verbose)
|
|
44
|
+
driver_args << "--silent" if driver_opts.key?(:silent)
|
|
45
|
+
driver_args
|
|
46
46
|
end
|
|
47
47
|
end # Service
|
|
48
48
|
end # Chrome
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require 'selenium/webdriver/common/w3c_error'
|
|
21
20
|
require 'selenium/webdriver/common/error'
|
|
22
21
|
require 'selenium/webdriver/common/platform'
|
|
23
22
|
require 'selenium/webdriver/common/proxy'
|
|
@@ -30,33 +29,42 @@ require 'selenium/webdriver/common/port_prober'
|
|
|
30
29
|
require 'selenium/webdriver/common/zipper'
|
|
31
30
|
require 'selenium/webdriver/common/wait'
|
|
32
31
|
require 'selenium/webdriver/common/alert'
|
|
33
|
-
require 'selenium/webdriver/common/mouse'
|
|
34
|
-
require 'selenium/webdriver/common/keyboard'
|
|
35
|
-
require 'selenium/webdriver/common/touch_screen'
|
|
36
32
|
require 'selenium/webdriver/common/target_locator'
|
|
37
33
|
require 'selenium/webdriver/common/navigation'
|
|
38
34
|
require 'selenium/webdriver/common/timeouts'
|
|
39
35
|
require 'selenium/webdriver/common/window'
|
|
36
|
+
require 'selenium/webdriver/common/logger'
|
|
40
37
|
require 'selenium/webdriver/common/logs'
|
|
41
|
-
require 'selenium/webdriver/common/
|
|
38
|
+
require 'selenium/webdriver/common/manager'
|
|
42
39
|
require 'selenium/webdriver/common/search_context'
|
|
40
|
+
require 'selenium/webdriver/common/interactions/key_actions'
|
|
41
|
+
require 'selenium/webdriver/common/interactions/pointer_actions'
|
|
42
|
+
require 'selenium/webdriver/common/interactions/interactions'
|
|
43
|
+
require 'selenium/webdriver/common/interactions/input_device'
|
|
44
|
+
require 'selenium/webdriver/common/interactions/interaction'
|
|
45
|
+
require 'selenium/webdriver/common/interactions/none_input'
|
|
46
|
+
require 'selenium/webdriver/common/interactions/key_input'
|
|
47
|
+
require 'selenium/webdriver/common/interactions/pointer_input'
|
|
43
48
|
require 'selenium/webdriver/common/action_builder'
|
|
44
|
-
require 'selenium/webdriver/common/touch_action_builder'
|
|
45
49
|
require 'selenium/webdriver/common/html5/shared_web_storage'
|
|
46
50
|
require 'selenium/webdriver/common/html5/local_storage'
|
|
47
51
|
require 'selenium/webdriver/common/html5/session_storage'
|
|
48
52
|
require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
|
|
49
53
|
require 'selenium/webdriver/common/driver_extensions/rotatable'
|
|
50
|
-
require 'selenium/webdriver/common/driver_extensions/has_input_devices'
|
|
51
54
|
require 'selenium/webdriver/common/driver_extensions/has_web_storage'
|
|
55
|
+
require 'selenium/webdriver/common/driver_extensions/downloads_files'
|
|
52
56
|
require 'selenium/webdriver/common/driver_extensions/has_location'
|
|
53
57
|
require 'selenium/webdriver/common/driver_extensions/has_session_id'
|
|
54
|
-
require 'selenium/webdriver/common/driver_extensions/has_touch_screen'
|
|
55
58
|
require 'selenium/webdriver/common/driver_extensions/has_remote_status'
|
|
59
|
+
require 'selenium/webdriver/common/driver_extensions/has_network_conditions'
|
|
56
60
|
require 'selenium/webdriver/common/driver_extensions/has_network_connection'
|
|
61
|
+
require 'selenium/webdriver/common/driver_extensions/has_permissions'
|
|
62
|
+
require 'selenium/webdriver/common/driver_extensions/has_debugger'
|
|
57
63
|
require 'selenium/webdriver/common/driver_extensions/uploads_files'
|
|
64
|
+
require 'selenium/webdriver/common/driver_extensions/has_addons'
|
|
65
|
+
require 'selenium/webdriver/common/driver_extensions/has_devtools'
|
|
58
66
|
require 'selenium/webdriver/common/keys'
|
|
59
|
-
require 'selenium/webdriver/common/bridge_helper'
|
|
60
67
|
require 'selenium/webdriver/common/profile_helper'
|
|
68
|
+
require 'selenium/webdriver/common/options'
|
|
61
69
|
require 'selenium/webdriver/common/driver'
|
|
62
70
|
require 'selenium/webdriver/common/element'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
4
|
# or more contributor license agreements. See the NOTICE file
|
|
5
5
|
# distributed with this work for additional information
|
|
@@ -19,342 +19,194 @@
|
|
|
19
19
|
|
|
20
20
|
module Selenium
|
|
21
21
|
module WebDriver
|
|
22
|
-
#
|
|
23
|
-
# The ActionBuilder provides the user a way to set up and perform
|
|
24
|
-
# complex user interactions.
|
|
25
|
-
#
|
|
26
|
-
# This class should not be instantiated directly, but is created by
|
|
27
|
-
# Selenium::WebDriver::DriverExtensions::HasInputDevices#action, which
|
|
28
|
-
# is available on Driver instances that support the user interaction API.
|
|
29
|
-
#
|
|
30
|
-
# @example
|
|
31
|
-
#
|
|
32
|
-
# driver.action.key_down(:shift).
|
|
33
|
-
# click(element).
|
|
34
|
-
# click(second_element).
|
|
35
|
-
# key_up(:shift).
|
|
36
|
-
# drag_and_drop(element, third_element).
|
|
37
|
-
# perform
|
|
38
|
-
#
|
|
39
|
-
|
|
40
22
|
class ActionBuilder
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
23
|
+
include KeyActions # Actions specific to key inputs
|
|
24
|
+
include PointerActions # Actions specific to pointer inputs
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
@devices = {
|
|
47
|
-
mouse: mouse,
|
|
48
|
-
keyboard: keyboard
|
|
49
|
-
}
|
|
26
|
+
attr_reader :devices
|
|
50
27
|
|
|
51
|
-
@actions = []
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
# Performs a modifier key press. Does not release
|
|
56
|
-
# the modifier key - subsequent interactions may assume it's kept pressed.
|
|
57
|
-
# Note that the modifier key is never released implicitly - either
|
|
58
|
-
# #key_up(key) or #send_keys(:null) must be called to release the modifier.
|
|
59
|
-
#
|
|
60
|
-
# Equivalent to:
|
|
61
|
-
# driver.action.click(element).send_keys(key)
|
|
62
|
-
# # or
|
|
63
|
-
# driver.action.click.send_keys(key)
|
|
64
|
-
#
|
|
65
|
-
# @example Press a key
|
|
66
28
|
#
|
|
67
|
-
#
|
|
29
|
+
# Initialize a W3C Action Builder. Differs from previous by requiring a bridge and allowing asynchronous actions.
|
|
30
|
+
# The W3C implementation allows asynchronous actions per device. e.g. A key can be pressed at the same time that
|
|
31
|
+
# the mouse is moving. Keep in mind that pauses must be added for other devices in order to line up the actions
|
|
32
|
+
# correctly when using asynchronous.
|
|
68
33
|
#
|
|
69
|
-
# @
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
# @param [:shift, :alt, :control, :command, :meta] The key to press.
|
|
75
|
-
# @param [Selenium::WebDriver::Element] element An optional element
|
|
76
|
-
# @raise [ArgumentError] if the given key is not a modifier
|
|
34
|
+
# @param [Selenium::WebDriver::Remote::Bridge] bridge the bridge for the current driver instance
|
|
35
|
+
# @param [Selenium::WebDriver::Interactions::PointerInput] mouse PointerInput for the mouse.
|
|
36
|
+
# @param [Selenium::WebDriver::Interactions::KeyInput] keyboard KeyInput for the keyboard.
|
|
37
|
+
# @param [Boolean] async Whether to perform the actions asynchronously per device. Defaults to false for
|
|
38
|
+
# backwards compatibility.
|
|
77
39
|
# @return [ActionBuilder] A self reference.
|
|
78
40
|
#
|
|
79
41
|
|
|
80
|
-
def
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@
|
|
84
|
-
|
|
42
|
+
def initialize(bridge, mouse, keyboard, async = false)
|
|
43
|
+
# For backwards compatibility, automatically include mouse & keyboard
|
|
44
|
+
@bridge = bridge
|
|
45
|
+
@devices = [mouse, keyboard]
|
|
46
|
+
@async = async
|
|
85
47
|
end
|
|
86
48
|
|
|
87
49
|
#
|
|
88
|
-
#
|
|
89
|
-
# Releasing a non-depressed modifier key will yield undefined behaviour.
|
|
90
|
-
#
|
|
91
|
-
# @example Release a key
|
|
50
|
+
# Adds a PointerInput device of the given kind
|
|
92
51
|
#
|
|
93
|
-
#
|
|
52
|
+
# @example Add a touch pointer input device
|
|
94
53
|
#
|
|
95
|
-
#
|
|
54
|
+
# builder = device.action
|
|
55
|
+
# builder.add_pointer_input('touch', :touch)
|
|
96
56
|
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
57
|
+
# @param [String] name name for the device
|
|
58
|
+
# @param [Symbol] kind kind of pointer device to create
|
|
59
|
+
# @return [Interactions::PointerInput] The pointer input added
|
|
99
60
|
#
|
|
100
|
-
# @param [:shift, :alt, :control, :command, :meta] The modifier key to release.
|
|
101
|
-
# @param [Selenium::WebDriver::Element] element An optional element
|
|
102
|
-
# @raise [ArgumentError] if the given key is not a modifier key
|
|
103
|
-
# @return [ActionBuilder] A self reference.
|
|
104
61
|
#
|
|
105
62
|
|
|
106
|
-
def
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
self
|
|
63
|
+
def add_pointer_input(kind, name)
|
|
64
|
+
new_input = Interactions.pointer(kind, name: name)
|
|
65
|
+
add_input(new_input)
|
|
66
|
+
new_input
|
|
111
67
|
end
|
|
112
68
|
|
|
113
69
|
#
|
|
114
|
-
#
|
|
115
|
-
# Element#send_keys(keys) on the active element in two ways:
|
|
116
|
-
#
|
|
117
|
-
# * The modifier keys included in this call are not released.
|
|
118
|
-
# * There is no attempt to re-focus the element - so send_keys(:tab) for switching elements should work.
|
|
70
|
+
# Adds a KeyInput device
|
|
119
71
|
#
|
|
120
|
-
# @example
|
|
72
|
+
# @example Add a key input device
|
|
121
73
|
#
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
# @example Send the text "help" to the currently focused element
|
|
74
|
+
# builder = device.action
|
|
75
|
+
# builder.add_key_input('keyboard2')
|
|
126
76
|
#
|
|
127
|
-
#
|
|
77
|
+
# @param [String] name name for the device
|
|
78
|
+
# @return [Interactions::KeyInput] The key input added
|
|
128
79
|
#
|
|
129
|
-
# @param [Selenium::WebDriver::Element] element An optional element
|
|
130
|
-
# @param [String] keys The keys to be sent.
|
|
131
|
-
# @return [ActionBuilder] A self reference.
|
|
132
|
-
#
|
|
133
|
-
|
|
134
|
-
def send_keys(*args)
|
|
135
|
-
@actions << [:mouse, :click, [args.shift]] if args.first.is_a? Element
|
|
136
80
|
|
|
137
|
-
|
|
138
|
-
|
|
81
|
+
def add_key_input(name)
|
|
82
|
+
new_input = Interactions.key(name)
|
|
83
|
+
add_input(new_input)
|
|
84
|
+
new_input
|
|
139
85
|
end
|
|
140
86
|
|
|
141
87
|
#
|
|
142
|
-
#
|
|
143
|
-
# equivalent to:
|
|
144
|
-
#
|
|
145
|
-
# driver.action.move_to(element).click_and_hold
|
|
146
|
-
#
|
|
147
|
-
# @example Clicking and holding on some element
|
|
88
|
+
# Retrieves the input device for the given name
|
|
148
89
|
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
# @param [Selenium::WebDriver::Element] element the element to move to and click.
|
|
153
|
-
# @return [ActionBuilder] A self reference.
|
|
90
|
+
# @param [String] name name of the input device
|
|
91
|
+
# @return [Selenium::WebDriver::Interactions::InputDevice] input device with given name
|
|
154
92
|
#
|
|
155
93
|
|
|
156
|
-
def
|
|
157
|
-
@
|
|
158
|
-
self
|
|
94
|
+
def get_device(name)
|
|
95
|
+
@devices.find { |device| device.name == name.to_s }
|
|
159
96
|
end
|
|
160
97
|
|
|
161
98
|
#
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
# @example Releasing an element after clicking and holding it
|
|
99
|
+
# Retrieves the current PointerInput devices
|
|
165
100
|
#
|
|
166
|
-
#
|
|
167
|
-
# driver.action.click_and_hold(el).release.perform
|
|
168
|
-
#
|
|
169
|
-
# @return [ActionBuilder] A self reference.
|
|
101
|
+
# @return [Array] array of current PointerInput devices
|
|
170
102
|
#
|
|
171
103
|
|
|
172
|
-
def
|
|
173
|
-
@
|
|
174
|
-
self
|
|
104
|
+
def pointer_inputs
|
|
105
|
+
@devices.select { |device| device.type == Interactions::POINTER }
|
|
175
106
|
end
|
|
176
107
|
|
|
177
108
|
#
|
|
178
|
-
#
|
|
179
|
-
#
|
|
180
|
-
# driver.action.move_to(element).click
|
|
181
|
-
#
|
|
182
|
-
# When no element is passed, the current mouse position will be clicked.
|
|
183
|
-
#
|
|
184
|
-
# @example Clicking on an element
|
|
185
|
-
#
|
|
186
|
-
# el = driver.find_element(id: "some_id")
|
|
187
|
-
# driver.action.click(el).perform
|
|
188
|
-
#
|
|
189
|
-
# @example Clicking at the current mouse position
|
|
109
|
+
# Retrieves the current KeyInput device
|
|
190
110
|
#
|
|
191
|
-
#
|
|
192
|
-
#
|
|
193
|
-
# @param [Selenium::WebDriver::Element] element An optional element to click.
|
|
194
|
-
# @return [ActionBuilder] A self reference.
|
|
111
|
+
# @return [Selenium::WebDriver::Interactions::InputDevice] current KeyInput device
|
|
195
112
|
#
|
|
196
113
|
|
|
197
|
-
def
|
|
198
|
-
@
|
|
199
|
-
self
|
|
114
|
+
def key_inputs
|
|
115
|
+
@devices.select { |device| device.type == Interactions::KEY }
|
|
200
116
|
end
|
|
201
117
|
|
|
202
118
|
#
|
|
203
|
-
#
|
|
119
|
+
# Creates a pause for the given device of the given duration. If no duration is given, the pause will only wait
|
|
120
|
+
# for all actions to complete in that tick.
|
|
204
121
|
#
|
|
205
|
-
#
|
|
122
|
+
# @example Send keys to an element
|
|
206
123
|
#
|
|
207
|
-
#
|
|
208
|
-
#
|
|
209
|
-
#
|
|
210
|
-
#
|
|
124
|
+
# action_builder = driver.action
|
|
125
|
+
# keyboard = action_builder.key_input
|
|
126
|
+
# el = driver.find_element(id: "some_id")
|
|
127
|
+
# driver.action.click(el).pause(keyboard).pause(keyboard).pause(keyboard).send_keys('keys').perform
|
|
211
128
|
#
|
|
212
|
-
# @param [
|
|
129
|
+
# @param [InputDevice] device Input device to pause
|
|
130
|
+
# @param [Float] duration Duration to pause
|
|
213
131
|
# @return [ActionBuilder] A self reference.
|
|
214
132
|
#
|
|
215
133
|
|
|
216
|
-
def
|
|
217
|
-
|
|
134
|
+
def pause(device, duration = nil)
|
|
135
|
+
device.create_pause(duration)
|
|
218
136
|
self
|
|
219
137
|
end
|
|
220
138
|
|
|
221
139
|
#
|
|
222
|
-
#
|
|
223
|
-
# view and its location is calculated using getBoundingClientRect. Then the
|
|
224
|
-
# mouse is moved to optional offset coordinates from the element.
|
|
140
|
+
# Creates multiple pauses for the given device of the given duration.
|
|
225
141
|
#
|
|
226
|
-
#
|
|
227
|
-
#
|
|
228
|
-
# @example Scroll element into view and move the mouse to it
|
|
142
|
+
# @example Send keys to an element
|
|
229
143
|
#
|
|
144
|
+
# action_builder = driver.action
|
|
145
|
+
# keyboard = action_builder.key_input
|
|
230
146
|
# el = driver.find_element(id: "some_id")
|
|
231
|
-
# driver.action.
|
|
232
|
-
#
|
|
233
|
-
# @example
|
|
147
|
+
# driver.action.click(el).pauses(keyboard, 3).send_keys('keys').perform
|
|
234
148
|
#
|
|
235
|
-
#
|
|
236
|
-
#
|
|
237
|
-
#
|
|
238
|
-
# @param [Selenium::WebDriver::Element] element to move to.
|
|
239
|
-
# @param [Integer] right_by Optional offset from the top-left corner. A negative value means
|
|
240
|
-
# coordinates right from the element.
|
|
241
|
-
# @param [Integer] down_by Optional offset from the top-left corner. A negative value means
|
|
242
|
-
# coordinates above the element.
|
|
149
|
+
# @param [InputDevice] device Input device to pause
|
|
150
|
+
# @param [Integer] number of pauses to add for the device
|
|
151
|
+
# @param [Float] duration Duration to pause
|
|
243
152
|
# @return [ActionBuilder] A self reference.
|
|
244
153
|
#
|
|
245
154
|
|
|
246
|
-
def
|
|
247
|
-
|
|
248
|
-
[:mouse, :move_to, [element, Integer(right_by), Integer(down_by)]]
|
|
249
|
-
else
|
|
250
|
-
[:mouse, :move_to, [element]]
|
|
251
|
-
end
|
|
252
|
-
|
|
155
|
+
def pauses(device, number, duration = nil)
|
|
156
|
+
number.times { device.create_pause(duration) }
|
|
253
157
|
self
|
|
254
158
|
end
|
|
255
159
|
|
|
256
160
|
#
|
|
257
|
-
#
|
|
258
|
-
# If the coordinates provided are outside the viewport (the mouse will
|
|
259
|
-
# end up outside the browser window) then the viewport is scrolled to
|
|
260
|
-
# match.
|
|
261
|
-
#
|
|
262
|
-
# @example Move the mouse to a certain offset from its current position
|
|
263
|
-
#
|
|
264
|
-
# driver.action.move_by(100, 100).perform
|
|
265
|
-
#
|
|
266
|
-
# @param [Integer] right_by horizontal offset. A negative value means moving the
|
|
267
|
-
# mouse left.
|
|
268
|
-
# @param [Integer] down_by vertical offset. A negative value means moving the mouse
|
|
269
|
-
# up.
|
|
270
|
-
# @return [ActionBuilder] A self reference.
|
|
271
|
-
# @raise [MoveTargetOutOfBoundsError] if the provided offset is outside
|
|
272
|
-
# the document's boundaries.
|
|
161
|
+
# Executes the actions added to the builder.
|
|
273
162
|
#
|
|
274
163
|
|
|
275
|
-
def
|
|
276
|
-
@
|
|
277
|
-
|
|
164
|
+
def perform
|
|
165
|
+
@bridge.send_actions @devices.map(&:encode).compact
|
|
166
|
+
clear_all_actions
|
|
167
|
+
nil
|
|
278
168
|
end
|
|
279
169
|
|
|
280
170
|
#
|
|
281
|
-
#
|
|
282
|
-
# a move_to to the location of the element.
|
|
283
|
-
#
|
|
284
|
-
# @example Context-click at middle of given element
|
|
285
|
-
#
|
|
286
|
-
# el = driver.find_element(id: "some_id")
|
|
287
|
-
# driver.action.context_click(el).perform
|
|
288
|
-
#
|
|
289
|
-
# @param [Selenium::WebDriver::Element] element An element to context click.
|
|
290
|
-
# @return [ActionBuilder] A self reference.
|
|
171
|
+
# Clears all actions from the builder.
|
|
291
172
|
#
|
|
292
173
|
|
|
293
|
-
def
|
|
294
|
-
@
|
|
295
|
-
self
|
|
174
|
+
def clear_all_actions
|
|
175
|
+
@devices.each(&:clear_actions)
|
|
296
176
|
end
|
|
297
177
|
|
|
298
178
|
#
|
|
299
|
-
#
|
|
300
|
-
# source element, moves to the location of the target element, then
|
|
301
|
-
# releases the mouse.
|
|
302
|
-
#
|
|
303
|
-
# @example Drag and drop one element onto another
|
|
304
|
-
#
|
|
305
|
-
# el1 = driver.find_element(id: "some_id1")
|
|
306
|
-
# el2 = driver.find_element(id: "some_id2")
|
|
307
|
-
# driver.action.drag_and_drop(el1, el2).perform
|
|
308
|
-
#
|
|
309
|
-
# @param [Selenium::WebDriver::Element] source element to emulate button down at.
|
|
310
|
-
# @param [Selenium::WebDriver::Element] target element to move to and release the
|
|
311
|
-
# mouse at.
|
|
312
|
-
# @return [ActionBuilder] A self reference.
|
|
179
|
+
# Releases all action states from the browser.
|
|
313
180
|
#
|
|
314
181
|
|
|
315
|
-
def
|
|
316
|
-
|
|
317
|
-
move_to target
|
|
318
|
-
release target
|
|
319
|
-
|
|
320
|
-
self
|
|
182
|
+
def release_actions
|
|
183
|
+
@bridge.release_actions
|
|
321
184
|
end
|
|
322
185
|
|
|
186
|
+
private
|
|
187
|
+
|
|
323
188
|
#
|
|
324
|
-
#
|
|
325
|
-
# the source element, moves by a given offset, then releases the mouse.
|
|
326
|
-
#
|
|
327
|
-
# @example Drag and drop an element by offset
|
|
189
|
+
# Adds pauses for all devices but the given devices
|
|
328
190
|
#
|
|
329
|
-
#
|
|
330
|
-
# driver.action.drag_and_drop_by(el, 100, 100).perform
|
|
331
|
-
#
|
|
332
|
-
# @param [Selenium::WebDriver::Element] source Element to emulate button down at.
|
|
333
|
-
# @param [Integer] right_by horizontal move offset.
|
|
334
|
-
# @param [Integer] down_by vertical move offset.
|
|
335
|
-
# @param [Selenium::WebDriver::Element] target Element to move to and release the
|
|
336
|
-
# mouse at.
|
|
337
|
-
# @return [ActionBuilder] A self reference.
|
|
191
|
+
# @param [Array[InputDevice]] action_devices Array of Input Devices performing an action in this tick.
|
|
338
192
|
#
|
|
339
193
|
|
|
340
|
-
def
|
|
341
|
-
|
|
342
|
-
move_by right_by, down_by
|
|
343
|
-
release
|
|
194
|
+
def tick(*action_devices)
|
|
195
|
+
return if @async
|
|
344
196
|
|
|
345
|
-
|
|
197
|
+
@devices.each { |device| device.create_pause unless action_devices.include? device }
|
|
346
198
|
end
|
|
347
199
|
|
|
348
200
|
#
|
|
349
|
-
#
|
|
201
|
+
# Adds an InputDevice
|
|
350
202
|
#
|
|
351
203
|
|
|
352
|
-
def
|
|
353
|
-
@
|
|
354
|
-
@devices.
|
|
204
|
+
def add_input(device)
|
|
205
|
+
unless @async
|
|
206
|
+
max_device = @devices.max { |a, b| a.actions.length <=> b.actions.length }
|
|
207
|
+
pauses(device, max_device.actions.length)
|
|
355
208
|
end
|
|
356
|
-
|
|
357
|
-
nil
|
|
209
|
+
@devices << device
|
|
358
210
|
end
|
|
359
211
|
end # ActionBuilder
|
|
360
212
|
end # WebDriver
|