selenium-webdriver 2.53.3 → 3.142.7

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.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +665 -8
  3. data/Gemfile +2 -0
  4. data/LICENSE +1 -1
  5. data/README.md +2 -3
  6. data/lib/selenium/server.rb +76 -73
  7. data/lib/selenium/webdriver/atoms/getAttribute.js +7 -0
  8. data/lib/selenium/webdriver/atoms/isDisplayed.js +102 -0
  9. data/lib/selenium/webdriver/{phantomjs.rb → atoms.rb} +10 -14
  10. data/lib/selenium/webdriver/chrome/bridge.rb +30 -101
  11. data/lib/selenium/webdriver/chrome/driver.rb +127 -0
  12. data/lib/selenium/webdriver/chrome/options.rb +190 -0
  13. data/lib/selenium/webdriver/chrome/profile.rb +21 -20
  14. data/lib/selenium/webdriver/chrome/service.rb +26 -93
  15. data/lib/selenium/webdriver/chrome.rb +15 -6
  16. data/lib/selenium/webdriver/common/action_builder.rb +52 -58
  17. data/lib/selenium/webdriver/common/alert.rb +7 -15
  18. data/lib/selenium/webdriver/common/bridge_helper.rb +18 -22
  19. data/lib/selenium/webdriver/common/driver.rb +72 -72
  20. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +45 -0
  21. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +50 -0
  22. data/lib/selenium/webdriver/common/driver_extensions/{has_input_devices.rb → has_debugger.rb} +11 -27
  23. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +6 -10
  24. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +51 -0
  25. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +7 -8
  26. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +51 -0
  27. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +2 -4
  28. data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +2 -4
  29. data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +3 -5
  30. data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +2 -5
  31. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +6 -9
  32. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +9 -7
  33. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +3 -8
  34. data/lib/selenium/webdriver/common/element.rb +59 -39
  35. data/lib/selenium/webdriver/common/error.rb +259 -104
  36. data/lib/selenium/webdriver/common/file_reaper.rb +6 -14
  37. data/lib/selenium/webdriver/common/html5/local_storage.rb +8 -10
  38. data/lib/selenium/webdriver/common/html5/session_storage.rb +8 -10
  39. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +8 -16
  40. data/lib/selenium/webdriver/common/interactions/input_device.rb +54 -0
  41. data/lib/selenium/webdriver/common/interactions/interaction.rb +53 -0
  42. data/lib/selenium/webdriver/{safari/browser.rb → common/interactions/interactions.rb} +17 -14
  43. data/lib/selenium/webdriver/common/interactions/key_actions.rb +145 -0
  44. data/lib/selenium/webdriver/common/interactions/key_input.rb +66 -0
  45. data/lib/selenium/webdriver/{android.rb → common/interactions/none_input.rb} +14 -6
  46. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +363 -0
  47. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +139 -0
  48. data/lib/selenium/webdriver/common/keyboard.rb +10 -14
  49. data/lib/selenium/webdriver/common/keys.rb +102 -82
  50. data/lib/selenium/webdriver/common/log_entry.rb +7 -8
  51. data/lib/selenium/webdriver/common/logger.rb +115 -0
  52. data/lib/selenium/webdriver/common/logs.rb +4 -6
  53. data/lib/selenium/webdriver/common/manager.rb +177 -0
  54. data/lib/selenium/webdriver/common/mouse.rb +12 -14
  55. data/lib/selenium/webdriver/common/navigation.rb +4 -6
  56. data/lib/selenium/webdriver/common/options.rb +26 -127
  57. data/lib/selenium/webdriver/common/platform.rb +75 -101
  58. data/lib/selenium/webdriver/common/port_prober.rb +7 -19
  59. data/lib/selenium/webdriver/common/profile_helper.rb +8 -11
  60. data/lib/selenium/webdriver/common/proxy.rb +68 -74
  61. data/lib/selenium/webdriver/common/search_context.rb +28 -37
  62. data/lib/selenium/webdriver/common/service.rb +219 -0
  63. data/lib/selenium/webdriver/common/socket_lock.rb +15 -16
  64. data/lib/selenium/webdriver/common/socket_poller.rb +30 -28
  65. data/lib/selenium/webdriver/common/target_locator.rb +16 -18
  66. data/lib/selenium/webdriver/common/timeouts.rb +6 -8
  67. data/lib/selenium/webdriver/common/touch_action_builder.rb +5 -10
  68. data/lib/selenium/webdriver/common/touch_screen.rb +22 -23
  69. data/lib/selenium/webdriver/common/w3c_action_builder.rb +212 -0
  70. data/lib/selenium/webdriver/common/w3c_manager.rb +45 -0
  71. data/lib/selenium/webdriver/common/wait.rb +17 -16
  72. data/lib/selenium/webdriver/common/window.rb +50 -17
  73. data/lib/selenium/webdriver/common/zipper.rb +9 -13
  74. data/lib/selenium/webdriver/common.rb +21 -7
  75. data/lib/selenium/webdriver/edge/bridge.rb +34 -63
  76. data/lib/selenium/webdriver/edge/driver.rb +66 -0
  77. data/lib/selenium/webdriver/edge/options.rb +80 -0
  78. data/lib/selenium/webdriver/edge/service.rb +23 -95
  79. data/lib/selenium/webdriver/edge.rb +13 -13
  80. data/lib/selenium/webdriver/firefox/binary.rb +45 -60
  81. data/lib/selenium/webdriver/firefox/driver.rb +50 -0
  82. data/lib/selenium/webdriver/firefox/extension/prefs.json +3 -12
  83. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  84. data/lib/selenium/webdriver/firefox/extension.rb +20 -10
  85. data/lib/selenium/webdriver/firefox/launcher.rb +16 -22
  86. data/lib/selenium/webdriver/firefox/legacy/driver.rb +83 -0
  87. data/lib/selenium/webdriver/firefox/marionette/bridge.rb +49 -0
  88. data/lib/selenium/webdriver/firefox/marionette/driver.rb +90 -0
  89. data/lib/selenium/webdriver/firefox/options.rb +162 -0
  90. data/lib/selenium/webdriver/firefox/profile.rb +47 -48
  91. data/lib/selenium/webdriver/firefox/profiles_ini.rb +11 -18
  92. data/lib/selenium/webdriver/firefox/service.rb +24 -95
  93. data/lib/selenium/webdriver/firefox/util.rb +2 -4
  94. data/lib/selenium/webdriver/firefox.rb +27 -12
  95. data/lib/selenium/webdriver/ie/driver.rb +85 -0
  96. data/lib/selenium/webdriver/ie/options.rb +138 -0
  97. data/lib/selenium/webdriver/ie/service.rb +54 -0
  98. data/lib/selenium/webdriver/ie.rb +12 -10
  99. data/lib/selenium/webdriver/remote/bridge.rb +100 -564
  100. data/lib/selenium/webdriver/remote/capabilities.rb +98 -100
  101. data/lib/selenium/webdriver/remote/driver.rb +51 -0
  102. data/lib/selenium/webdriver/remote/http/common.rb +34 -22
  103. data/lib/selenium/webdriver/remote/http/curb.rb +13 -14
  104. data/lib/selenium/webdriver/remote/http/default.rb +62 -43
  105. data/lib/selenium/webdriver/remote/http/persistent.rb +12 -9
  106. data/lib/selenium/webdriver/remote/oss/bridge.rb +594 -0
  107. data/lib/selenium/webdriver/remote/oss/commands.rb +223 -0
  108. data/lib/selenium/webdriver/remote/response.rb +48 -28
  109. data/lib/selenium/webdriver/remote/server_error.rb +3 -5
  110. data/lib/selenium/webdriver/remote/w3c/bridge.rb +605 -0
  111. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +310 -0
  112. data/lib/selenium/webdriver/remote/w3c/commands.rb +157 -0
  113. data/lib/selenium/webdriver/remote.rb +10 -16
  114. data/lib/selenium/webdriver/safari/bridge.rb +17 -101
  115. data/lib/selenium/webdriver/{firefox/w3c_bridge.rb → safari/driver.rb} +27 -25
  116. data/lib/selenium/webdriver/safari/options.rb +29 -31
  117. data/lib/selenium/webdriver/safari/service.rb +38 -0
  118. data/lib/selenium/webdriver/safari.rb +27 -27
  119. data/lib/selenium/webdriver/support/abstract_event_listener.rb +19 -4
  120. data/lib/selenium/webdriver/support/block_event_listener.rb +3 -5
  121. data/lib/selenium/webdriver/support/color.rb +60 -43
  122. data/lib/selenium/webdriver/support/escaper.rb +43 -0
  123. data/lib/selenium/webdriver/support/event_firing_bridge.rb +39 -41
  124. data/lib/selenium/webdriver/support/select.rb +45 -97
  125. data/lib/selenium/webdriver/support.rb +3 -2
  126. data/lib/selenium/webdriver/{iphone.rb → version.rb} +3 -7
  127. data/lib/selenium/webdriver.rb +36 -23
  128. data/lib/selenium-webdriver.rb +2 -2
  129. data/selenium-webdriver.gemspec +42 -29
  130. metadata +331 -262
  131. data/lib/selenium/client/base.rb +0 -151
  132. data/lib/selenium/client/driver.rb +0 -29
  133. data/lib/selenium/client/errors.rb +0 -28
  134. data/lib/selenium/client/extensions.rb +0 -132
  135. data/lib/selenium/client/idiomatic.rb +0 -507
  136. data/lib/selenium/client/javascript_expression_builder.rb +0 -135
  137. data/lib/selenium/client/javascript_frameworks/jquery.rb +0 -32
  138. data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -32
  139. data/lib/selenium/client/legacy_driver.rb +0 -1722
  140. data/lib/selenium/client/protocol.rb +0 -123
  141. data/lib/selenium/client/selenium_helper.rb +0 -49
  142. data/lib/selenium/client.rb +0 -57
  143. data/lib/selenium/rake/server_task.rb +0 -176
  144. data/lib/selenium/webdriver/android/bridge.rb +0 -68
  145. data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -28
  146. data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -61
  147. data/lib/selenium/webdriver/common/html5/location.rb +0 -19
  148. data/lib/selenium/webdriver/common/w3c_error.rb +0 -194
  149. data/lib/selenium/webdriver/edge/legacy_support.rb +0 -117
  150. data/lib/selenium/webdriver/firefox/bridge.rb +0 -89
  151. data/lib/selenium/webdriver/ie/bridge.rb +0 -88
  152. data/lib/selenium/webdriver/ie/server.rb +0 -133
  153. data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
  154. data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -78
  155. data/lib/selenium/webdriver/phantomjs/service.rb +0 -130
  156. data/lib/selenium/webdriver/remote/commands.rb +0 -211
  157. data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -668
  158. data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -236
  159. data/lib/selenium/webdriver/remote/w3c_commands.rb +0 -132
  160. data/lib/selenium/webdriver/safari/resources/client.js +0 -7255
  161. data/lib/selenium/webdriver/safari/server.rb +0 -187
  162. data/lib/selenium-client.rb +0 -21
@@ -0,0 +1,363 @@
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 PointerActions
23
+ attr_writer :default_move_duration
24
+
25
+ #
26
+ # The overridable duration for movement used by methods in this module
27
+ #
28
+
29
+ def default_move_duration
30
+ @default_move_duration ||= 0.25 # 250 milliseconds
31
+ end
32
+
33
+ #
34
+ # Presses (without releasing) at the current location of the PointerInput device. This is equivalent to:
35
+ #
36
+ # driver.action.click_and_hold(nil)
37
+ #
38
+ # @example Clicking and holding at the current location
39
+ #
40
+ # driver.action.pointer_down(:left).perform
41
+ #
42
+ # @param [Selenium::WebDriver::Interactions::PointerPress::BUTTONS] button the button to press.
43
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
44
+ # that will be pressed
45
+ # @return [W3CActionBuilder] A self reference.
46
+ #
47
+
48
+ def pointer_down(button, device: nil)
49
+ button_action(button, action: :create_pointer_down, device: device)
50
+ end
51
+
52
+ #
53
+ # Releases the pressed mouse button at the current mouse location of the PointerInput device.
54
+ #
55
+ # @example Releasing a button after clicking and holding
56
+ #
57
+ # driver.action.pointer_down(:left).pointer_up(:left).perform
58
+ #
59
+ # @param [Selenium::WebDriver::Interactions::PointerPress::BUTTONS] button the button to release.
60
+ # @param [Symbol || String] device optional name of the PointerInput device with the button that will
61
+ # be released
62
+ # @return [W3CActionBuilder] A self reference.
63
+ #
64
+
65
+ def pointer_up(button, device: nil)
66
+ button_action(button, action: :create_pointer_up, device: device)
67
+ end
68
+
69
+ #
70
+ # Moves the mouse to the middle of the given element. The element is scrolled into
71
+ # view and its location is calculated using getBoundingClientRect. Then the
72
+ # mouse is moved to optional offset coordinates from the element.
73
+ #
74
+ # This is adapted to be backward compatible from non-W3C actions. W3C calculates offset from the center point
75
+ # of the element
76
+ #
77
+ # Note that when using offsets, both coordinates need to be passed.
78
+ #
79
+ # @example Scroll element into view and move the mouse to it
80
+ #
81
+ # el = driver.find_element(id: "some_id")
82
+ # driver.action.move_to(el).perform
83
+ #
84
+ # @example
85
+ #
86
+ # el = driver.find_element(id: "some_id")
87
+ # driver.action.move_to(el, 100, 100).perform
88
+ #
89
+ # @param [Selenium::WebDriver::Element] element to move to.
90
+ # @param [Integer] right_by Optional offset from the top-left corner. A negative value means
91
+ # coordinates to the left of the element.
92
+ # @param [Integer] down_by Optional offset from the top-left corner. A negative value means
93
+ # coordinates above the element.
94
+ # @param [Symbol || String] device optional name of the PointerInput device to move.
95
+ # @return [W3CActionBuilder] A self reference.
96
+ #
97
+
98
+ def move_to(element, right_by = nil, down_by = nil, device: nil)
99
+ pointer = get_pointer(device)
100
+ # New actions offset is from center of element
101
+ if right_by || down_by
102
+ size = element.size
103
+ left_offset = (size[:width] / 2).to_i
104
+ top_offset = (size[:height] / 2).to_i
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)
115
+ tick(pointer)
116
+ self
117
+ end
118
+
119
+ #
120
+ # Moves the mouse from its current position by the given offset.
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.
124
+ #
125
+ # @example Move the mouse to a certain offset from its current position
126
+ #
127
+ # driver.action.move_by(100, 100).perform
128
+ #
129
+ # @param [Integer] right_by horizontal offset. A negative value means moving the mouse left.
130
+ # @param [Integer] down_by vertical offset. A negative value means moving the mouse up.
131
+ # @param [Symbol || String] device optional name of the PointerInput device to move
132
+ # @return [W3CActionBuilder] A self reference.
133
+ # @raise [MoveTargetOutOfBoundsError] if the provided offset is outside the document's boundaries.
134
+ #
135
+
136
+ def move_by(right_by, down_by, device: nil)
137
+ pointer = get_pointer(device)
138
+ pointer.create_pointer_move(duration: default_move_duration,
139
+ x: Integer(right_by),
140
+ y: Integer(down_by),
141
+ origin: Interactions::PointerMove::POINTER)
142
+ tick(pointer)
143
+ self
144
+ end
145
+
146
+ #
147
+ # Moves the mouse to a given location in the viewport.
148
+ # If the coordinates provided are outside the viewport (the mouse will
149
+ # end up outside the browser window) then the viewport is scrolled to
150
+ # match.
151
+ #
152
+ # @example Move the mouse to a certain position in the viewport
153
+ #
154
+ # driver.action.move_to_location(100, 100).perform
155
+ #
156
+ # @param [Integer] x horizontal position. Equivalent to a css 'left' value.
157
+ # @param [Integer] y vertical position. Equivalent to a css 'top' value.
158
+ # @param [Symbol || String] device optional name of the PointerInput device to move
159
+ # @return [W3CActionBuilder] A self reference.
160
+ # @raise [MoveTargetOutOfBoundsError] if the provided x or y value is outside the document's boundaries.
161
+ #
162
+
163
+ def move_to_location(x, y, device: nil)
164
+ pointer = get_pointer(device)
165
+ pointer.create_pointer_move(duration: default_move_duration,
166
+ x: Integer(x),
167
+ y: Integer(y),
168
+ origin: Interactions::PointerMove::VIEWPORT)
169
+ tick(pointer)
170
+ self
171
+ end
172
+
173
+ #
174
+ # Clicks (without releasing) in the middle of the given element. This is
175
+ # equivalent to:
176
+ #
177
+ # driver.action.move_to(element).click_and_hold
178
+ #
179
+ # @example Clicking and holding on some element
180
+ #
181
+ # el = driver.find_element(id: "some_id")
182
+ # driver.action.click_and_hold(el).perform
183
+ #
184
+ # @param [Selenium::WebDriver::Element] element the element to move to and click.
185
+ # @param [Symbol || String] device optional name of the PointerInput device to click with
186
+ # @return [W3CActionBuilder] A self reference.
187
+ #
188
+
189
+ def click_and_hold(element = nil, device: nil)
190
+ move_to(element, device: device) if element
191
+ pointer_down(:left, device: device)
192
+ self
193
+ end
194
+
195
+ #
196
+ # Releases the depressed left mouse button at the current mouse location.
197
+ #
198
+ # @example Releasing an element after clicking and holding it
199
+ #
200
+ # el = driver.find_element(id: "some_id")
201
+ # driver.action.click_and_hold(el).release.perform
202
+ #
203
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
204
+ # that will be released
205
+ # @return [W3CActionBuilder] A self reference.
206
+ #
207
+
208
+ def release(device: nil)
209
+ pointer_up(:left, device: device)
210
+ self
211
+ end
212
+
213
+ #
214
+ # Clicks in the middle of the given element. Equivalent to:
215
+ #
216
+ # driver.action.move_to(element).click
217
+ #
218
+ # When no element is passed, the current mouse position will be clicked.
219
+ #
220
+ # @example Clicking on an element
221
+ #
222
+ # el = driver.find_element(id: "some_id")
223
+ # driver.action.click(el).perform
224
+ #
225
+ # @example Clicking at the current mouse position
226
+ #
227
+ # driver.action.click.perform
228
+ #
229
+ # @param [Selenium::WebDriver::Element] element An optional element to click.
230
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
231
+ # that will be clicked
232
+ # @return [W3CActionBuilder] A self reference.
233
+ #
234
+
235
+ def click(element = nil, device: nil)
236
+ move_to(element, device: device) if element
237
+ pointer_down(:left, device: device)
238
+ pointer_up(:left, device: device)
239
+ self
240
+ end
241
+
242
+ #
243
+ # Performs a double-click at middle of the given element. Equivalent to:
244
+ #
245
+ # driver.action.move_to(element).double_click
246
+ #
247
+ # When no element is passed, the current mouse position will be double-clicked.
248
+ #
249
+ # @example Double-click an element
250
+ #
251
+ # el = driver.find_element(id: "some_id")
252
+ # driver.action.double_click(el).perform
253
+ #
254
+ # @example Double-clicking at the current mouse position
255
+ #
256
+ # driver.action.double_click.perform
257
+ #
258
+ # @param [Selenium::WebDriver::Element] element An optional element to move to.
259
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
260
+ # that will be double-clicked
261
+ # @return [W3CActionBuilder] A self reference.
262
+ #
263
+
264
+ def double_click(element = nil, device: nil)
265
+ move_to(element, device: device) if element
266
+ click(device: device)
267
+ click(device: device)
268
+ self
269
+ end
270
+
271
+ #
272
+ # Performs a context-click at middle of the given element. First performs
273
+ # a move_to to the location of the element.
274
+ #
275
+ # When no element is passed, the current mouse position will be context-clicked.
276
+ #
277
+ # @example Context-click at middle of given element
278
+ #
279
+ # el = driver.find_element(id: "some_id")
280
+ # driver.action.context_click(el).perform
281
+ #
282
+ # @example Context-clicking at the current mouse position
283
+ #
284
+ # driver.action.context_click.perform
285
+ #
286
+ # @param [Selenium::WebDriver::Element] element An element to context click.
287
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
288
+ # that will be context-clicked
289
+ # @return [W3CActionBuilder] A self reference.
290
+ #
291
+
292
+ def context_click(element = nil, device: nil)
293
+ move_to(element, device: device) if element
294
+ pointer_down(:right, device: device)
295
+ pointer_up(:right, device: device)
296
+ self
297
+ end
298
+
299
+ #
300
+ # A convenience method that performs click-and-hold at the location of the
301
+ # source element, moves to the location of the target element, then
302
+ # releases the mouse.
303
+ #
304
+ # @example Drag and drop one element onto another
305
+ #
306
+ # el1 = driver.find_element(id: "some_id1")
307
+ # el2 = driver.find_element(id: "some_id2")
308
+ # driver.action.drag_and_drop(el1, el2).perform
309
+ #
310
+ # @param [Selenium::WebDriver::Element] source element to emulate button down at.
311
+ # @param [Selenium::WebDriver::Element] target element to move to and release the
312
+ # mouse at.
313
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
314
+ # that will perform the drag and drop
315
+ # @return [W3CActionBuilder] A self reference.
316
+ #
317
+
318
+ def drag_and_drop(source, target, device: nil)
319
+ click_and_hold(source, device: device)
320
+ move_to(target, device: device)
321
+ release(device: device)
322
+ self
323
+ end
324
+
325
+ #
326
+ # A convenience method that performs click-and-hold at the location of
327
+ # the source element, moves by a given offset, then releases the mouse.
328
+ #
329
+ # @example Drag and drop an element by offset
330
+ #
331
+ # el = driver.find_element(id: "some_id1")
332
+ # driver.action.drag_and_drop_by(el, 100, 100).perform
333
+ #
334
+ # @param [Selenium::WebDriver::Element] source Element to emulate button down at.
335
+ # @param [Integer] right_by horizontal move offset.
336
+ # @param [Integer] down_by vertical move offset.
337
+ # @param [Symbol || String] device optional name of the PointerInput device with the button
338
+ # that will perform the drag and drop
339
+ # @return [W3CActionBuilder] A self reference.
340
+ #
341
+
342
+ def drag_and_drop_by(source, right_by, down_by, device: nil)
343
+ click_and_hold(source, device: device)
344
+ move_by(right_by, down_by, device: device)
345
+ release(device: device)
346
+ self
347
+ end
348
+
349
+ private
350
+
351
+ def button_action(button, action: nil, device: nil)
352
+ pointer = get_pointer(device)
353
+ pointer.send(action, button)
354
+ tick(pointer)
355
+ self
356
+ end
357
+
358
+ def get_pointer(device = nil)
359
+ get_device(device) || pointer_inputs.first
360
+ end
361
+ end # PointerActions
362
+ end # WebDriver
363
+ end # Selenium
@@ -0,0 +1,139 @@
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
+ class PointerInput < InputDevice
24
+ KIND = {mouse: :mouse, pen: :pen, touch: :touch}.freeze
25
+
26
+ attr_reader :kind
27
+
28
+ def initialize(kind, name: nil)
29
+ super(name)
30
+ @kind = assert_kind(kind)
31
+ end
32
+
33
+ def type
34
+ Interactions::POINTER
35
+ end
36
+
37
+ def encode
38
+ return nil if no_actions?
39
+
40
+ output = {type: type, id: name, actions: @actions.map(&:encode)}
41
+ output[:parameters] = {pointerType: kind}
42
+ output
43
+ end
44
+
45
+ def assert_kind(pointer)
46
+ raise TypeError, "#{pointer.inspect} is not a valid pointer type" unless KIND.key? pointer
47
+
48
+ KIND[pointer]
49
+ end
50
+
51
+ def create_pointer_move(duration: 0, x: 0, y: 0, element: nil, origin: nil)
52
+ add_action(PointerMove.new(self, duration, x, y, element: element, origin: origin))
53
+ end
54
+
55
+ def create_pointer_down(button)
56
+ add_action(PointerPress.new(self, :down, button))
57
+ end
58
+
59
+ def create_pointer_up(button)
60
+ add_action(PointerPress.new(self, :up, button))
61
+ end
62
+
63
+ def create_pointer_cancel
64
+ add_action(PointerCancel.new(self))
65
+ end
66
+ end # PointerInput
67
+
68
+ class PointerPress < Interaction
69
+ BUTTONS = {left: 0, middle: 1, right: 2}.freeze
70
+ DIRECTIONS = {down: :pointerDown, up: :pointerUp}.freeze
71
+
72
+ def initialize(source, direction, button)
73
+ super(source)
74
+ @direction = assert_direction(direction)
75
+ @button = assert_button(button)
76
+ end
77
+
78
+ def type
79
+ @direction
80
+ end
81
+
82
+ def assert_button(button)
83
+ if button.is_a? Symbol
84
+ raise TypeError, "#{button.inspect} is not a valid button!" unless BUTTONS.key? button
85
+
86
+ button = BUTTONS[button]
87
+ end
88
+ raise ArgumentError, 'Button number cannot be negative!' unless button >= 0
89
+
90
+ button
91
+ end
92
+
93
+ def assert_direction(direction)
94
+ raise TypeError, "#{direction.inspect} is not a valid button direction" unless DIRECTIONS.key? direction
95
+
96
+ DIRECTIONS[direction]
97
+ end
98
+
99
+ def encode
100
+ {type: type, button: @button}
101
+ end
102
+ end # PointerPress
103
+
104
+ class PointerMove < Interaction
105
+ VIEWPORT = :viewport
106
+ POINTER = :pointer
107
+ ORIGINS = [VIEWPORT, POINTER].freeze
108
+
109
+ def initialize(source, duration, x, y, element: nil, origin: nil)
110
+ super(source)
111
+ @duration = duration * 1000
112
+ @x_offset = x
113
+ @y_offset = y
114
+ @origin = element || origin
115
+ end
116
+
117
+ def type
118
+ :pointerMove
119
+ end
120
+
121
+ def encode
122
+ output = {type: type, duration: @duration.to_i, x: @x_offset, y: @y_offset}
123
+ output[:origin] = @origin
124
+ output
125
+ end
126
+ end # Move
127
+
128
+ class PointerCancel < Interaction
129
+ def type
130
+ :pointerCancel
131
+ end
132
+
133
+ def encode
134
+ {type: type}
135
+ end
136
+ end # Cancel
137
+ end # Interactions
138
+ end # WebDriver
139
+ end # Selenium
@@ -1,5 +1,5 @@
1
- # encoding: utf-8
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,19 +19,17 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
-
23
22
  #
24
23
  # @api private
25
24
  # @see ActionBuilder
26
25
 
27
26
  class Keyboard
28
-
29
27
  def initialize(bridge)
30
28
  @bridge = bridge
31
29
  end
32
30
 
33
31
  def send_keys(*keys)
34
- @bridge.sendKeysToActiveElement Keys.encode(keys)
32
+ @bridge.send_keys_to_active_element Keys.encode(keys)
35
33
  end
36
34
 
37
35
  #
@@ -43,7 +41,7 @@ module Selenium
43
41
  def press(key)
44
42
  assert_modifier key
45
43
 
46
- @bridge.sendKeysToActiveElement Keys.encode([key])
44
+ @bridge.send_keys_to_active_element Keys.encode([key])
47
45
  end
48
46
 
49
47
  #
@@ -55,20 +53,18 @@ module Selenium
55
53
  def release(key)
56
54
  assert_modifier key
57
55
 
58
- @bridge.sendKeysToActiveElement Keys.encode([key])
56
+ @bridge.send_keys_to_active_element Keys.encode([key])
59
57
  end
60
58
 
61
59
  private
62
60
 
63
- MODIFIERS = [:control, :shift, :alt, :command, :meta]
61
+ MODIFIERS = %i[control shift alt command meta].freeze
64
62
 
65
63
  def assert_modifier(key)
66
- unless MODIFIERS.include? key
67
- raise ArgumentError,
68
- "#{key.inspect} is not a modifier key, expected one of #{MODIFIERS.inspect}"
69
- end
70
- end
64
+ return if MODIFIERS.include? key
71
65
 
66
+ raise ArgumentError, "#{key.inspect} is not a modifier key, expected one of #{MODIFIERS.inspect}"
67
+ end
72
68
  end # Keyboard
73
69
  end # WebDriver
74
- end # Selenium
70
+ end # Selenium