selenium-webdriver 2.53.4 → 3.8.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 +7 -0
- data/CHANGES +363 -10
- data/LICENSE +1 -1
- data/README.md +2 -3
- data/lib/selenium-webdriver.rb +0 -2
- data/lib/selenium/server.rb +69 -70
- data/lib/selenium/webdriver.rb +32 -23
- data/lib/selenium/webdriver/atoms.rb +18 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +8 -0
- data/lib/selenium/webdriver/chrome.rb +8 -6
- data/lib/selenium/webdriver/chrome/driver.rb +112 -0
- data/lib/selenium/webdriver/chrome/options.rb +168 -0
- data/lib/selenium/webdriver/chrome/profile.rb +17 -17
- data/lib/selenium/webdriver/chrome/service.rb +22 -89
- data/lib/selenium/webdriver/common.rb +13 -6
- data/lib/selenium/webdriver/common/action_builder.rb +49 -57
- data/lib/selenium/webdriver/common/alert.rb +5 -15
- data/lib/selenium/webdriver/common/bridge_helper.rb +10 -17
- data/lib/selenium/webdriver/common/driver.rb +53 -68
- data/lib/selenium/webdriver/common/driver_extensions/{has_input_devices.rb → has_addons.rb} +13 -23
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +4 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +4 -7
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +0 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +0 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +1 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +0 -5
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +4 -9
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +7 -7
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +2 -7
- data/lib/selenium/webdriver/common/element.rb +57 -39
- data/lib/selenium/webdriver/common/error.rb +204 -106
- data/lib/selenium/webdriver/common/file_reaper.rb +3 -11
- data/lib/selenium/webdriver/common/html5/local_storage.rb +6 -10
- data/lib/selenium/webdriver/common/html5/session_storage.rb +6 -10
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +7 -18
- data/lib/selenium/webdriver/{safari/options.rb → common/interactions/input_device.rb} +20 -31
- data/lib/selenium/webdriver/common/interactions/interaction.rb +50 -0
- data/lib/selenium/webdriver/{safari/browser.rb → common/interactions/interactions.rb} +16 -15
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +143 -0
- data/lib/selenium/webdriver/common/interactions/key_input.rb +62 -0
- data/lib/selenium/webdriver/{android.rb → common/interactions/none_input.rb} +11 -6
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +353 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +132 -0
- data/lib/selenium/webdriver/common/keyboard.rb +7 -14
- data/lib/selenium/webdriver/common/keys.rb +99 -82
- data/lib/selenium/webdriver/common/log_entry.rb +3 -6
- data/lib/selenium/webdriver/common/logger.rb +140 -0
- data/lib/selenium/webdriver/common/logs.rb +2 -6
- data/lib/selenium/webdriver/common/mouse.rb +9 -14
- data/lib/selenium/webdriver/common/navigation.rb +2 -6
- data/lib/selenium/webdriver/common/options.rb +20 -23
- data/lib/selenium/webdriver/common/platform.rb +70 -97
- data/lib/selenium/webdriver/common/port_prober.rb +3 -4
- data/lib/selenium/webdriver/common/profile_helper.rb +6 -11
- data/lib/selenium/webdriver/common/proxy.rb +58 -72
- data/lib/selenium/webdriver/common/search_context.rb +22 -29
- data/lib/selenium/webdriver/common/service.rb +161 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +6 -14
- data/lib/selenium/webdriver/common/socket_poller.rb +5 -12
- data/lib/selenium/webdriver/common/target_locator.rb +11 -15
- data/lib/selenium/webdriver/common/timeouts.rb +4 -8
- data/lib/selenium/webdriver/common/touch_action_builder.rb +2 -6
- data/lib/selenium/webdriver/common/touch_screen.rb +19 -23
- data/lib/selenium/webdriver/common/w3c_action_builder.rb +209 -0
- data/lib/selenium/webdriver/{phantomjs.rb → common/w3c_options.rb} +16 -14
- data/lib/selenium/webdriver/common/wait.rb +6 -13
- data/lib/selenium/webdriver/common/window.rb +48 -17
- data/lib/selenium/webdriver/common/zipper.rb +6 -10
- data/lib/selenium/webdriver/edge.rb +5 -12
- data/lib/selenium/webdriver/edge/bridge.rb +32 -63
- data/lib/selenium/webdriver/edge/driver.rb +73 -0
- data/lib/selenium/webdriver/edge/service.rb +18 -87
- data/lib/selenium/webdriver/firefox.rb +20 -11
- data/lib/selenium/webdriver/firefox/binary.rb +40 -56
- data/lib/selenium/webdriver/firefox/driver.rb +48 -0
- data/lib/selenium/webdriver/firefox/extension.rb +18 -8
- data/lib/selenium/webdriver/firefox/extension/prefs.json +3 -11
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +13 -22
- data/lib/selenium/webdriver/firefox/legacy/driver.rb +79 -0
- data/lib/selenium/webdriver/{iphone.rb → firefox/marionette/bridge.rb} +25 -6
- data/lib/selenium/webdriver/firefox/marionette/driver.rb +96 -0
- data/lib/selenium/webdriver/firefox/options.rb +149 -0
- data/lib/selenium/webdriver/firefox/profile.rb +46 -46
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +8 -18
- data/lib/selenium/webdriver/firefox/service.rb +23 -83
- data/lib/selenium/webdriver/firefox/util.rb +0 -4
- data/lib/selenium/webdriver/ie.rb +4 -8
- data/lib/selenium/webdriver/ie/driver.rb +90 -0
- data/lib/selenium/webdriver/ie/options.rb +136 -0
- data/lib/selenium/webdriver/ie/service.rb +58 -0
- data/lib/selenium/webdriver/remote.rb +8 -16
- data/lib/selenium/webdriver/remote/bridge.rb +96 -565
- data/lib/selenium/webdriver/remote/capabilities.rb +76 -94
- data/lib/selenium/webdriver/remote/driver.rb +49 -0
- data/lib/selenium/webdriver/remote/http/common.rb +22 -20
- data/lib/selenium/webdriver/remote/http/curb.rb +9 -12
- data/lib/selenium/webdriver/remote/http/default.rb +54 -41
- data/lib/selenium/webdriver/remote/http/persistent.rb +9 -8
- data/lib/selenium/webdriver/remote/oss/bridge.rb +586 -0
- data/lib/selenium/webdriver/remote/oss/commands.rb +221 -0
- data/lib/selenium/webdriver/remote/response.rb +39 -27
- data/lib/selenium/webdriver/remote/server_error.rb +1 -5
- data/lib/selenium/webdriver/remote/w3c/bridge.rb +573 -0
- data/lib/selenium/webdriver/remote/w3c/capabilities.rb +290 -0
- data/lib/selenium/webdriver/remote/w3c/commands.rb +148 -0
- data/lib/selenium/webdriver/safari.rb +20 -29
- data/lib/selenium/webdriver/{firefox/w3c_bridge.rb → safari/driver.rb} +21 -30
- data/lib/selenium/webdriver/safari/service.rb +57 -0
- data/lib/selenium/webdriver/support.rb +1 -2
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +17 -4
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -5
- data/lib/selenium/webdriver/support/color.rb +57 -42
- data/lib/selenium/webdriver/support/escaper.rb +41 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +36 -40
- data/lib/selenium/webdriver/support/select.rb +33 -86
- data/selenium-webdriver.gemspec +22 -25
- metadata +254 -261
- data/lib/selenium-client.rb +0 -21
- data/lib/selenium/client.rb +0 -57
- data/lib/selenium/client/base.rb +0 -151
- data/lib/selenium/client/driver.rb +0 -29
- data/lib/selenium/client/errors.rb +0 -28
- data/lib/selenium/client/extensions.rb +0 -132
- data/lib/selenium/client/idiomatic.rb +0 -507
- data/lib/selenium/client/javascript_expression_builder.rb +0 -135
- data/lib/selenium/client/javascript_frameworks/jquery.rb +0 -32
- data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -32
- data/lib/selenium/client/legacy_driver.rb +0 -1722
- data/lib/selenium/client/protocol.rb +0 -123
- data/lib/selenium/client/selenium_helper.rb +0 -49
- data/lib/selenium/rake/server_task.rb +0 -176
- data/lib/selenium/webdriver/android/bridge.rb +0 -68
- data/lib/selenium/webdriver/chrome/bridge.rb +0 -139
- data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -28
- data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -61
- data/lib/selenium/webdriver/common/html5/location.rb +0 -19
- data/lib/selenium/webdriver/common/w3c_error.rb +0 -194
- data/lib/selenium/webdriver/edge/legacy_support.rb +0 -117
- data/lib/selenium/webdriver/firefox/bridge.rb +0 -89
- data/lib/selenium/webdriver/ie/bridge.rb +0 -88
- data/lib/selenium/webdriver/ie/server.rb +0 -133
- data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
- data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -78
- data/lib/selenium/webdriver/phantomjs/service.rb +0 -130
- data/lib/selenium/webdriver/remote/commands.rb +0 -211
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -668
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -236
- data/lib/selenium/webdriver/remote/w3c_commands.rb +0 -132
- data/lib/selenium/webdriver/safari/bridge.rb +0 -135
- data/lib/selenium/webdriver/safari/resources/client.js +0 -7255
- data/lib/selenium/webdriver/safari/server.rb +0 -187
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
1
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
2
|
# or more contributor license agreements. See the NOTICE file
|
|
5
3
|
# distributed with this work for additional information
|
|
@@ -19,13 +17,11 @@
|
|
|
19
17
|
|
|
20
18
|
module Selenium
|
|
21
19
|
module WebDriver
|
|
22
|
-
|
|
23
20
|
#
|
|
24
21
|
# @api private
|
|
25
22
|
#
|
|
26
23
|
|
|
27
24
|
class SocketLock
|
|
28
|
-
|
|
29
25
|
def initialize(port, timeout)
|
|
30
26
|
@port = port
|
|
31
27
|
@timeout = timeout
|
|
@@ -36,7 +32,7 @@ module Selenium
|
|
|
36
32
|
# execution block if the lock could be successfully obtained.
|
|
37
33
|
#
|
|
38
34
|
|
|
39
|
-
def locked
|
|
35
|
+
def locked
|
|
40
36
|
lock
|
|
41
37
|
|
|
42
38
|
begin
|
|
@@ -51,13 +47,10 @@ module Selenium
|
|
|
51
47
|
def lock
|
|
52
48
|
max_time = Time.now + @timeout
|
|
53
49
|
|
|
54
|
-
until can_lock? || Time.now >= max_time
|
|
55
|
-
sleep 0.1
|
|
56
|
-
end
|
|
50
|
+
sleep 0.1 until can_lock? || Time.now >= max_time
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
end
|
|
52
|
+
return if did_lock?
|
|
53
|
+
raise Error::WebDriverError, "unable to bind to locking port #{@port} within #{@timeout} seconds"
|
|
61
54
|
end
|
|
62
55
|
|
|
63
56
|
def release
|
|
@@ -70,14 +63,13 @@ module Selenium
|
|
|
70
63
|
|
|
71
64
|
true
|
|
72
65
|
rescue SocketError, Errno::EADDRINUSE, Errno::EBADF => ex
|
|
73
|
-
|
|
66
|
+
WebDriver.logger.debug("#{self}: #{ex.message}")
|
|
74
67
|
false
|
|
75
68
|
end
|
|
76
69
|
|
|
77
70
|
def did_lock?
|
|
78
|
-
|
|
71
|
+
!@server.nil?
|
|
79
72
|
end
|
|
80
|
-
|
|
81
73
|
end # SocketLock
|
|
82
74
|
end # WebDriver
|
|
83
75
|
end # Selenium
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
1
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
2
|
# or more contributor license agreements. See the NOTICE file
|
|
5
3
|
# distributed with this work for additional information
|
|
@@ -23,7 +21,6 @@ require 'socket'
|
|
|
23
21
|
module Selenium
|
|
24
22
|
module WebDriver
|
|
25
23
|
class SocketPoller
|
|
26
|
-
|
|
27
24
|
def initialize(host, port, timeout = 0, interval = 0.25)
|
|
28
25
|
@host = host
|
|
29
26
|
@port = Integer(port)
|
|
@@ -50,7 +47,7 @@ module Selenium
|
|
|
50
47
|
#
|
|
51
48
|
|
|
52
49
|
def closed?
|
|
53
|
-
with_timeout {
|
|
50
|
+
with_timeout { !listening? }
|
|
54
51
|
end
|
|
55
52
|
|
|
56
53
|
private
|
|
@@ -81,11 +78,8 @@ module Selenium
|
|
|
81
78
|
begin
|
|
82
79
|
sock.connect_nonblock sockaddr
|
|
83
80
|
rescue Errno::EINPROGRESS
|
|
84
|
-
if IO.select(nil, [sock], nil, CONNECT_TIMEOUT)
|
|
85
|
-
|
|
86
|
-
else
|
|
87
|
-
raise Errno::ECONNREFUSED
|
|
88
|
-
end
|
|
81
|
+
retry if IO.select(nil, [sock], nil, CONNECT_TIMEOUT)
|
|
82
|
+
raise Errno::ECONNREFUSED
|
|
89
83
|
rescue *CONNECTED_ERRORS
|
|
90
84
|
# yay!
|
|
91
85
|
end
|
|
@@ -94,12 +88,12 @@ module Selenium
|
|
|
94
88
|
true
|
|
95
89
|
rescue *NOT_CONNECTED_ERRORS
|
|
96
90
|
sock.close if sock
|
|
97
|
-
|
|
91
|
+
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}")
|
|
98
92
|
false
|
|
99
93
|
end
|
|
100
94
|
end
|
|
101
95
|
|
|
102
|
-
def with_timeout
|
|
96
|
+
def with_timeout
|
|
103
97
|
max_time = time_now + @timeout
|
|
104
98
|
|
|
105
99
|
(
|
|
@@ -118,7 +112,6 @@ module Selenium
|
|
|
118
112
|
def time_now
|
|
119
113
|
Time.now
|
|
120
114
|
end
|
|
121
|
-
|
|
122
115
|
end # SocketPoller
|
|
123
116
|
end # WebDriver
|
|
124
117
|
end # Selenium
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
1
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
2
|
# or more contributor license agreements. See the NOTICE file
|
|
5
3
|
# distributed with this work for additional information
|
|
@@ -20,7 +18,6 @@
|
|
|
20
18
|
module Selenium
|
|
21
19
|
module WebDriver
|
|
22
20
|
class TargetLocator
|
|
23
|
-
|
|
24
21
|
#
|
|
25
22
|
# @api private
|
|
26
23
|
#
|
|
@@ -34,7 +31,7 @@ module Selenium
|
|
|
34
31
|
#
|
|
35
32
|
|
|
36
33
|
def frame(id)
|
|
37
|
-
@bridge.
|
|
34
|
+
@bridge.switch_to_frame id
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
#
|
|
@@ -42,7 +39,7 @@ module Selenium
|
|
|
42
39
|
#
|
|
43
40
|
|
|
44
41
|
def parent_frame
|
|
45
|
-
@bridge.
|
|
42
|
+
@bridge.switch_to_parent_frame
|
|
46
43
|
end
|
|
47
44
|
|
|
48
45
|
#
|
|
@@ -58,27 +55,27 @@ module Selenium
|
|
|
58
55
|
def window(id)
|
|
59
56
|
if block_given?
|
|
60
57
|
original = begin
|
|
61
|
-
@bridge.
|
|
58
|
+
@bridge.window_handle
|
|
62
59
|
rescue Error::NoSuchWindowError
|
|
63
60
|
nil
|
|
64
61
|
end
|
|
65
62
|
|
|
66
|
-
unless @bridge.
|
|
63
|
+
unless @bridge.window_handles.include? id
|
|
67
64
|
raise Error::NoSuchWindowError, "The specified identifier '#{id}' is not found in the window handle list"
|
|
68
65
|
end
|
|
69
66
|
|
|
70
|
-
@bridge.
|
|
67
|
+
@bridge.switch_to_window id
|
|
71
68
|
|
|
72
69
|
begin
|
|
73
70
|
returned = yield
|
|
74
71
|
ensure
|
|
75
|
-
current_handles = @bridge.
|
|
72
|
+
current_handles = @bridge.window_handles
|
|
76
73
|
original = current_handles.first unless current_handles.include? original
|
|
77
|
-
@bridge.
|
|
74
|
+
@bridge.switch_to_window original
|
|
78
75
|
returned
|
|
79
76
|
end
|
|
80
77
|
else
|
|
81
|
-
@bridge.
|
|
78
|
+
@bridge.switch_to_window id
|
|
82
79
|
end
|
|
83
80
|
end
|
|
84
81
|
|
|
@@ -89,7 +86,7 @@ module Selenium
|
|
|
89
86
|
#
|
|
90
87
|
|
|
91
88
|
def active_element
|
|
92
|
-
@bridge.
|
|
89
|
+
@bridge.switch_to_active_element
|
|
93
90
|
end
|
|
94
91
|
|
|
95
92
|
#
|
|
@@ -97,7 +94,7 @@ module Selenium
|
|
|
97
94
|
#
|
|
98
95
|
|
|
99
96
|
def default_content
|
|
100
|
-
@bridge.
|
|
97
|
+
@bridge.switch_to_default_content
|
|
101
98
|
end
|
|
102
99
|
|
|
103
100
|
#
|
|
@@ -107,7 +104,6 @@ module Selenium
|
|
|
107
104
|
def alert
|
|
108
105
|
Alert.new(@bridge)
|
|
109
106
|
end
|
|
110
|
-
|
|
111
107
|
end # TargetLocator
|
|
112
108
|
end # WebDriver
|
|
113
|
-
end
|
|
109
|
+
end # Selenium
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
1
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
2
|
# or more contributor license agreements. See the NOTICE file
|
|
5
3
|
# distributed with this work for additional information
|
|
@@ -20,7 +18,6 @@
|
|
|
20
18
|
module Selenium
|
|
21
19
|
module WebDriver
|
|
22
20
|
class Timeouts
|
|
23
|
-
|
|
24
21
|
def initialize(bridge)
|
|
25
22
|
@bridge = bridge
|
|
26
23
|
end
|
|
@@ -30,7 +27,7 @@ module Selenium
|
|
|
30
27
|
#
|
|
31
28
|
|
|
32
29
|
def implicit_wait=(seconds)
|
|
33
|
-
@bridge.
|
|
30
|
+
@bridge.implicit_wait_timeout = Integer(seconds * 1000)
|
|
34
31
|
end
|
|
35
32
|
|
|
36
33
|
#
|
|
@@ -40,7 +37,7 @@ module Selenium
|
|
|
40
37
|
#
|
|
41
38
|
|
|
42
39
|
def script_timeout=(seconds)
|
|
43
|
-
@bridge.
|
|
40
|
+
@bridge.script_timeout = Integer(seconds * 1000)
|
|
44
41
|
end
|
|
45
42
|
|
|
46
43
|
#
|
|
@@ -49,9 +46,8 @@ module Selenium
|
|
|
49
46
|
#
|
|
50
47
|
|
|
51
48
|
def page_load=(seconds)
|
|
52
|
-
@bridge.
|
|
49
|
+
@bridge.timeout 'page load', Integer(seconds * 1000)
|
|
53
50
|
end
|
|
54
|
-
|
|
55
51
|
end # Timeouts
|
|
56
52
|
end # WebDriver
|
|
57
|
-
end # Selenium
|
|
53
|
+
end # Selenium
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
1
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
2
|
# or more contributor license agreements. See the NOTICE file
|
|
5
3
|
# distributed with this work for additional information
|
|
@@ -20,7 +18,6 @@
|
|
|
20
18
|
module Selenium
|
|
21
19
|
module WebDriver
|
|
22
20
|
class TouchActionBuilder < ActionBuilder
|
|
23
|
-
|
|
24
21
|
#
|
|
25
22
|
# @api private
|
|
26
23
|
#
|
|
@@ -31,7 +28,7 @@ module Selenium
|
|
|
31
28
|
end
|
|
32
29
|
|
|
33
30
|
def scroll(*args)
|
|
34
|
-
unless [2,3].include? args.size
|
|
31
|
+
unless [2, 3].include? args.size
|
|
35
32
|
raise ArgumentError, "wrong number of arguments, expected 2..3, got #{args.size}"
|
|
36
33
|
end
|
|
37
34
|
|
|
@@ -40,7 +37,7 @@ module Selenium
|
|
|
40
37
|
end
|
|
41
38
|
|
|
42
39
|
def flick(*args)
|
|
43
|
-
unless [2,4].include? args.size
|
|
40
|
+
unless [2, 4].include? args.size
|
|
44
41
|
raise ArgumentError, "wrong number of arguments, expected 2 or 4, got #{args.size}"
|
|
45
42
|
end
|
|
46
43
|
|
|
@@ -77,7 +74,6 @@ module Selenium
|
|
|
77
74
|
@actions << [:touch_screen, :move, [x, y]]
|
|
78
75
|
self
|
|
79
76
|
end
|
|
80
|
-
|
|
81
77
|
end # TouchActionBuilder
|
|
82
78
|
end # WebDriver
|
|
83
79
|
end # Selenium
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
1
|
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
2
|
# or more contributor license agreements. See the NOTICE file
|
|
5
3
|
# distributed with this work for additional information
|
|
@@ -20,8 +18,7 @@
|
|
|
20
18
|
module Selenium
|
|
21
19
|
module WebDriver
|
|
22
20
|
class TouchScreen
|
|
23
|
-
FLICK_SPEED = {
|
|
24
|
-
|
|
21
|
+
FLICK_SPEED = {normal: 0, fast: 1}.freeze
|
|
25
22
|
|
|
26
23
|
#
|
|
27
24
|
# @api private
|
|
@@ -33,43 +30,43 @@ module Selenium
|
|
|
33
30
|
|
|
34
31
|
def single_tap(element)
|
|
35
32
|
assert_element element
|
|
36
|
-
@bridge.
|
|
33
|
+
@bridge.touch_single_tap element.ref
|
|
37
34
|
end
|
|
38
35
|
|
|
39
36
|
def double_tap(element)
|
|
40
37
|
assert_element element
|
|
41
|
-
@bridge.
|
|
38
|
+
@bridge.touch_double_tap element.ref
|
|
42
39
|
end
|
|
43
40
|
|
|
44
41
|
def long_press(element)
|
|
45
42
|
assert_element element
|
|
46
|
-
@bridge.
|
|
43
|
+
@bridge.touch_long_press element.ref
|
|
47
44
|
end
|
|
48
45
|
|
|
49
46
|
def down(x, y = nil)
|
|
50
47
|
x, y = coords_from x, y
|
|
51
|
-
@bridge.
|
|
48
|
+
@bridge.touch_down x, y
|
|
52
49
|
end
|
|
53
50
|
|
|
54
51
|
def up(x, y = nil)
|
|
55
52
|
x, y = coords_from x, y
|
|
56
|
-
@bridge.
|
|
53
|
+
@bridge.touch_up x, y
|
|
57
54
|
end
|
|
58
55
|
|
|
59
56
|
def move(x, y = nil)
|
|
60
57
|
x, y = coords_from x, y
|
|
61
|
-
@bridge.
|
|
58
|
+
@bridge.touch_move x, y
|
|
62
59
|
end
|
|
63
60
|
|
|
64
61
|
def scroll(*args)
|
|
65
62
|
case args.size
|
|
66
63
|
when 2
|
|
67
64
|
x_offset, y_offset = args
|
|
68
|
-
@bridge.
|
|
65
|
+
@bridge.touch_scroll nil, Integer(x_offset), Integer(y_offset)
|
|
69
66
|
when 3
|
|
70
67
|
element, x_offset, y_offset = args
|
|
71
68
|
assert_element element
|
|
72
|
-
@bridge.
|
|
69
|
+
@bridge.touch_scroll element.ref, Integer(x_offset), Integer(y_offset)
|
|
73
70
|
else
|
|
74
71
|
raise ArgumentError, "wrong number of arguments, expected 2..3, got #{args.size}"
|
|
75
72
|
end
|
|
@@ -79,22 +76,22 @@ module Selenium
|
|
|
79
76
|
case args.size
|
|
80
77
|
when 2
|
|
81
78
|
x_speed, y_speed = args
|
|
82
|
-
@bridge.
|
|
79
|
+
@bridge.touch_flick Integer(x_speed), Integer(y_speed)
|
|
83
80
|
when 4
|
|
84
81
|
element, xoffset, yoffset, speed = args
|
|
85
82
|
|
|
86
83
|
assert_element element
|
|
87
|
-
flick_speed = FLICK_SPEED[speed.to_sym]
|
|
88
84
|
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
if (speed.is_a?(String) || speed.is_a?(Symbol)) && FLICK_SPEED.keys.include?(speed.to_sym)
|
|
86
|
+
WebDriver.logger.deprecate "Passing #{speed.inspect} speed",
|
|
87
|
+
"Integer or Selenium::WebDriver::TouchScreen::FLICK_SPEED[:#{speed}]"
|
|
88
|
+
speed = FLICK_SPEED[speed.to_sym]
|
|
91
89
|
end
|
|
92
90
|
|
|
93
|
-
@bridge.
|
|
91
|
+
@bridge.touch_element_flick element.ref, Integer(xoffset), Integer(yoffset), Integer(speed)
|
|
94
92
|
else
|
|
95
93
|
raise ArgumentError, "wrong number of arguments, expected 2 or 4, got #{args.size}"
|
|
96
94
|
end
|
|
97
|
-
|
|
98
95
|
end
|
|
99
96
|
|
|
100
97
|
private
|
|
@@ -107,18 +104,17 @@ module Selenium
|
|
|
107
104
|
raise ArgumentError, "expected #{point.inspect} to respond to :x and :y"
|
|
108
105
|
end
|
|
109
106
|
|
|
110
|
-
x
|
|
107
|
+
x = point.x
|
|
108
|
+
y = point.y
|
|
111
109
|
end
|
|
112
110
|
|
|
113
111
|
[Integer(x), Integer(y)]
|
|
114
112
|
end
|
|
115
113
|
|
|
116
114
|
def assert_element(element)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
end
|
|
115
|
+
return if element.is_a? Element
|
|
116
|
+
raise TypeError, "expected #{Element}, got #{element.inspect}:#{element.class}"
|
|
120
117
|
end
|
|
121
|
-
|
|
122
118
|
end # TouchScreen
|
|
123
119
|
end # WebDriver
|
|
124
120
|
end # Selenium
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
|
3
|
+
# distributed with this work for additional information
|
|
4
|
+
# regarding copyright ownership. The SFC licenses this file
|
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
|
6
|
+
# "License"); you may not use this file except in compliance
|
|
7
|
+
# with the License. You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
18
|
+
module Selenium
|
|
19
|
+
module WebDriver
|
|
20
|
+
class W3CActionBuilder
|
|
21
|
+
include KeyActions # Actions specific to key inputs
|
|
22
|
+
include PointerActions # Actions specific to pointer inputs
|
|
23
|
+
attr_reader :devices
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Initialize a W3C Action Builder. Differs from previous by requiring a bridge and allowing asynchronous actions.
|
|
27
|
+
# The W3C implementation allows asynchronous actions per device. e.g. A key can be pressed at the same time that
|
|
28
|
+
# the mouse is moving. Keep in mind that pauses must be added for other devices in order to line up the actions
|
|
29
|
+
# correctly when using asynchronous.
|
|
30
|
+
#
|
|
31
|
+
# @param [Selenium::WebDriver::Remote::W3CBridge] bridge the bridge for the current driver instance
|
|
32
|
+
# @param [Selenium::WebDriver::Interactions::PointerInput] mouse PointerInput for the mouse.
|
|
33
|
+
# @param [Selenium::WebDriver::Interactions::KeyInput] keyboard KeyInput for the keyboard.
|
|
34
|
+
# @param [Boolean] async Whether to perform the actions asynchronously per device. Defaults to false for
|
|
35
|
+
# backwards compatibility.
|
|
36
|
+
# @return [W3CActionBuilder] A self reference.
|
|
37
|
+
#
|
|
38
|
+
|
|
39
|
+
def initialize(bridge, mouse, keyboard, async = false)
|
|
40
|
+
# For backwards compatibility, automatically include mouse & keyboard
|
|
41
|
+
@bridge = bridge
|
|
42
|
+
@devices = [mouse, keyboard]
|
|
43
|
+
@async = async
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Adds a PointerInput device of the given kind
|
|
48
|
+
#
|
|
49
|
+
# @example Add a touch pointer input device
|
|
50
|
+
#
|
|
51
|
+
# builder = device.action
|
|
52
|
+
# builder.add_pointer_input('touch', :touch)
|
|
53
|
+
#
|
|
54
|
+
# @param [String] name name for the device
|
|
55
|
+
# @param [Symbol] kind kind of pointer device to create
|
|
56
|
+
# @return [Interactions::PointerInput] The pointer input added
|
|
57
|
+
#
|
|
58
|
+
#
|
|
59
|
+
|
|
60
|
+
def add_pointer_input(kind, name)
|
|
61
|
+
new_input = Interactions.pointer(kind, name: name)
|
|
62
|
+
add_input(new_input)
|
|
63
|
+
new_input
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# Adds a KeyInput device
|
|
68
|
+
#
|
|
69
|
+
# @example Add a key input device
|
|
70
|
+
#
|
|
71
|
+
# builder = device.action
|
|
72
|
+
# builder.add_key_input('keyboard2')
|
|
73
|
+
#
|
|
74
|
+
# @param [String] name name for the device
|
|
75
|
+
# @return [Interactions::KeyInput] The key input added
|
|
76
|
+
#
|
|
77
|
+
|
|
78
|
+
def add_key_input(name)
|
|
79
|
+
new_input = Interactions.key(name)
|
|
80
|
+
add_input(new_input)
|
|
81
|
+
new_input
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Retrieves the input device for the given name
|
|
86
|
+
#
|
|
87
|
+
# @param [String] name name of the input device
|
|
88
|
+
# @return [Selenium::WebDriver::Interactions::InputDevice] input device with given name
|
|
89
|
+
#
|
|
90
|
+
|
|
91
|
+
def get_device(name)
|
|
92
|
+
@devices.find { |device| device.name == name.to_s }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Retrieves the current PointerInput devices
|
|
97
|
+
#
|
|
98
|
+
# @return [Array] array of current PointerInput devices
|
|
99
|
+
#
|
|
100
|
+
|
|
101
|
+
def pointer_inputs
|
|
102
|
+
@devices.select { |device| device.type == Interactions::POINTER }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
#
|
|
106
|
+
# Retrieves the current KeyInput device
|
|
107
|
+
#
|
|
108
|
+
# @return [Selenium::WebDriver::Interactions::InputDevice] current KeyInput device
|
|
109
|
+
#
|
|
110
|
+
|
|
111
|
+
def key_inputs
|
|
112
|
+
@devices.select { |device| device.type == Interactions::KEY }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# Creates a pause for the given device of the given duration. If no duration is given, the pause will only wait
|
|
117
|
+
# for all actions to complete in that tick.
|
|
118
|
+
#
|
|
119
|
+
# @example Send keys to an element
|
|
120
|
+
#
|
|
121
|
+
# action_builder = driver.action
|
|
122
|
+
# keyboard = action_builder.key_input
|
|
123
|
+
# el = driver.find_element(id: "some_id")
|
|
124
|
+
# driver.action.click(el).pause(keyboard).pause(keyboard).pause(keyboard).send_keys('keys').perform
|
|
125
|
+
#
|
|
126
|
+
# @param [InputDevice] device Input device to pause
|
|
127
|
+
# @param [Float] duration Duration to pause
|
|
128
|
+
# @return [W3CActionBuilder] A self reference.
|
|
129
|
+
#
|
|
130
|
+
|
|
131
|
+
def pause(device, duration = nil)
|
|
132
|
+
device.create_pause(duration)
|
|
133
|
+
self
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
#
|
|
137
|
+
# Creates multiple pauses for the given device of the given duration.
|
|
138
|
+
#
|
|
139
|
+
# @example Send keys to an element
|
|
140
|
+
#
|
|
141
|
+
# action_builder = driver.action
|
|
142
|
+
# keyboard = action_builder.key_input
|
|
143
|
+
# el = driver.find_element(id: "some_id")
|
|
144
|
+
# driver.action.click(el).pauses(keyboard, 3).send_keys('keys').perform
|
|
145
|
+
#
|
|
146
|
+
# @param [InputDevice] device Input device to pause
|
|
147
|
+
# @param [Integer] number of pauses to add for the device
|
|
148
|
+
# @param [Float] duration Duration to pause
|
|
149
|
+
# @return [W3CActionBuilder] A self reference.
|
|
150
|
+
#
|
|
151
|
+
|
|
152
|
+
def pauses(device, number, duration = nil)
|
|
153
|
+
number.times { device.create_pause(duration) }
|
|
154
|
+
self
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
#
|
|
158
|
+
# Executes the actions added to the builder.
|
|
159
|
+
#
|
|
160
|
+
|
|
161
|
+
def perform
|
|
162
|
+
@bridge.send_actions @devices.map(&:encode).compact
|
|
163
|
+
clear_all_actions
|
|
164
|
+
nil
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# Clears all actions from the builder.
|
|
169
|
+
#
|
|
170
|
+
|
|
171
|
+
def clear_all_actions
|
|
172
|
+
@devices.each(&:clear_actions)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
#
|
|
176
|
+
# Releases all action states from the browser.
|
|
177
|
+
#
|
|
178
|
+
|
|
179
|
+
def release_actions
|
|
180
|
+
@bridge.release_actions
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
private
|
|
184
|
+
|
|
185
|
+
#
|
|
186
|
+
# Adds pauses for all devices but the given devices
|
|
187
|
+
#
|
|
188
|
+
# @param [Array[InputDevice]] action_devices Array of Input Devices performing an action in this tick.
|
|
189
|
+
#
|
|
190
|
+
|
|
191
|
+
def tick(*action_devices)
|
|
192
|
+
return if @async
|
|
193
|
+
@devices.each { |device| device.create_pause unless action_devices.include? device }
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
#
|
|
197
|
+
# Adds an InputDevice
|
|
198
|
+
#
|
|
199
|
+
|
|
200
|
+
def add_input(device)
|
|
201
|
+
unless @async
|
|
202
|
+
max_device = @devices.max { |a, b| a.actions.length <=> b.actions.length }
|
|
203
|
+
pauses(device, max_device.actions.length)
|
|
204
|
+
end
|
|
205
|
+
@devices << device
|
|
206
|
+
end
|
|
207
|
+
end # W3CActionBuilder
|
|
208
|
+
end # WebDriver
|
|
209
|
+
end # Selenium
|