selenium-webdriver 3.142.6 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +369 -5
  3. data/Gemfile +3 -1
  4. data/LICENSE +1 -1
  5. data/NOTICE +2 -0
  6. data/README.md +4 -5
  7. data/lib/selenium/server.rb +69 -63
  8. data/lib/selenium/webdriver/atoms/findElements.js +122 -0
  9. data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
  10. data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
  11. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  12. data/lib/selenium/webdriver/chrome/driver.rb +26 -70
  13. data/lib/selenium/webdriver/chrome/{bridge.rb → features.rb} +50 -12
  14. data/lib/selenium/webdriver/chrome/options.rb +128 -53
  15. data/lib/selenium/webdriver/chrome/profile.rb +8 -5
  16. data/lib/selenium/webdriver/chrome/service.rb +8 -15
  17. data/lib/selenium/webdriver/chrome.rb +10 -9
  18. data/lib/selenium/webdriver/common/action_builder.rb +97 -249
  19. data/lib/selenium/webdriver/common/driver.rb +112 -23
  20. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
  21. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +51 -0
  22. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
  23. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +77 -0
  24. data/lib/selenium/webdriver/common/driver_extensions/{has_touch_screen.rb → has_cdp.rb} +10 -8
  25. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +45 -0
  26. data/lib/selenium/webdriver/{firefox/util.rb → common/driver_extensions/has_devtools.rb} +16 -19
  27. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +38 -0
  28. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
  29. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +144 -0
  30. data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +30 -0
  31. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +17 -0
  32. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  33. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +136 -0
  34. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -11
  35. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +77 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  38. data/lib/selenium/webdriver/common/element.rb +82 -22
  39. data/lib/selenium/webdriver/common/error.rb +32 -196
  40. data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
  41. data/lib/selenium/webdriver/common/interactions/key_actions.rb +5 -5
  42. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +13 -13
  43. data/lib/selenium/webdriver/common/log_entry.rb +2 -2
  44. data/lib/selenium/webdriver/common/logger.rb +50 -15
  45. data/lib/selenium/webdriver/common/manager.rb +15 -15
  46. data/lib/selenium/webdriver/common/options.rb +184 -0
  47. data/lib/selenium/webdriver/common/platform.rb +6 -1
  48. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  49. data/lib/selenium/webdriver/common/profile_helper.rb +11 -9
  50. data/lib/selenium/webdriver/common/proxy.rb +6 -3
  51. data/lib/selenium/webdriver/common/search_context.rb +7 -3
  52. data/lib/selenium/webdriver/common/service.rb +17 -125
  53. data/lib/selenium/webdriver/common/service_manager.rb +151 -0
  54. data/lib/selenium/webdriver/common/shadow_root.rb +87 -0
  55. data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
  56. data/lib/selenium/webdriver/common/socket_poller.rb +2 -2
  57. data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
  58. data/lib/selenium/webdriver/common/target_locator.rb +32 -4
  59. data/lib/selenium/webdriver/common/timeouts.rb +31 -4
  60. data/lib/selenium/webdriver/common/wait.rb +1 -1
  61. data/lib/selenium/webdriver/common/window.rb +0 -4
  62. data/lib/selenium/webdriver/common/zipper.rb +3 -9
  63. data/lib/selenium/webdriver/common.rb +24 -17
  64. data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
  65. data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
  66. data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
  67. data/lib/selenium/webdriver/devtools/pinned_script.rb +59 -0
  68. data/lib/selenium/webdriver/devtools/request.rb +67 -0
  69. data/lib/selenium/webdriver/devtools/response.rb +66 -0
  70. data/lib/selenium/webdriver/devtools.rb +193 -0
  71. data/lib/selenium/webdriver/edge/driver.rb +7 -29
  72. data/lib/selenium/webdriver/edge/features.rb +44 -0
  73. data/lib/selenium/webdriver/edge/options.rb +11 -48
  74. data/lib/selenium/webdriver/{common/w3c_manager.rb → edge/profile.rb} +7 -19
  75. data/lib/selenium/webdriver/edge/service.rb +10 -26
  76. data/lib/selenium/webdriver/edge.rb +11 -14
  77. data/lib/selenium/webdriver/firefox/driver.rb +31 -19
  78. data/lib/selenium/webdriver/firefox/extension.rb +8 -0
  79. data/lib/selenium/webdriver/firefox/features.rb +66 -0
  80. data/lib/selenium/webdriver/firefox/options.rb +71 -50
  81. data/lib/selenium/webdriver/firefox/profile.rb +21 -71
  82. data/lib/selenium/webdriver/firefox/service.rb +5 -9
  83. data/lib/selenium/webdriver/firefox.rb +22 -20
  84. data/lib/selenium/webdriver/ie/driver.rb +1 -47
  85. data/lib/selenium/webdriver/ie/options.rb +15 -46
  86. data/lib/selenium/webdriver/ie/service.rb +13 -15
  87. data/lib/selenium/webdriver/ie.rb +8 -7
  88. data/lib/selenium/webdriver/remote/bridge.rb +561 -86
  89. data/lib/selenium/webdriver/remote/capabilities.rb +159 -123
  90. data/lib/selenium/webdriver/remote/commands.rb +163 -0
  91. data/lib/selenium/webdriver/remote/driver.rb +22 -12
  92. data/lib/selenium/webdriver/remote/http/common.rb +0 -5
  93. data/lib/selenium/webdriver/remote/http/default.rb +17 -20
  94. data/lib/selenium/webdriver/remote/http/persistent.rb +11 -6
  95. data/lib/selenium/webdriver/remote/response.rb +16 -47
  96. data/lib/selenium/webdriver/remote.rb +15 -12
  97. data/lib/selenium/webdriver/safari/driver.rb +3 -31
  98. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +3 -3
  99. data/lib/selenium/webdriver/safari/options.rb +10 -29
  100. data/lib/selenium/webdriver/safari/service.rb +4 -8
  101. data/lib/selenium/webdriver/safari.rb +17 -9
  102. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  103. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +63 -0
  104. data/lib/selenium/webdriver/support/cdp_client_generator.rb +108 -0
  105. data/lib/selenium/webdriver/support/color.rb +2 -2
  106. data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
  107. data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
  108. data/lib/selenium/webdriver/{firefox/marionette/bridge.rb → support/guards/guard_condition.rb} +22 -19
  109. data/lib/selenium/webdriver/support/guards.rb +95 -0
  110. data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
  111. data/lib/selenium/webdriver/support/select.rb +3 -3
  112. data/lib/selenium/webdriver/support.rb +1 -0
  113. data/lib/selenium/webdriver/version.rb +1 -1
  114. data/lib/selenium/webdriver.rb +13 -13
  115. data/selenium-webdriver.gemspec +28 -12
  116. metadata +129 -69
  117. data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
  118. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
  119. data/lib/selenium/webdriver/common/keyboard.rb +0 -70
  120. data/lib/selenium/webdriver/common/mouse.rb +0 -89
  121. data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
  122. data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
  123. data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
  124. data/lib/selenium/webdriver/edge/bridge.rb +0 -76
  125. data/lib/selenium/webdriver/firefox/binary.rb +0 -187
  126. data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
  127. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  128. data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
  129. data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
  130. data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
  131. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  132. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  133. data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
  134. data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
  135. data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
  136. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
  137. data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
@@ -1,605 +0,0 @@
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
- require 'json'
21
-
22
- module Selenium
23
- module WebDriver
24
- module Remote
25
- module W3C
26
-
27
- #
28
- # Low level bridge to the remote server implementing JSON wire
29
- # protocol (W3C dialect), through which the rest of the API works.
30
- # @api private
31
- #
32
-
33
- class Bridge < Remote::Bridge
34
-
35
- def initialize(capabilities, session_id, **opts)
36
- @capabilities = capabilities
37
- @session_id = session_id
38
- super(opts)
39
- end
40
-
41
- def dialect
42
- :w3c
43
- end
44
-
45
- def commands(command)
46
- case command
47
- when :status
48
- Remote::OSS::Bridge::COMMANDS[command]
49
- else
50
- COMMANDS[command]
51
- end
52
- end
53
-
54
- def status
55
- execute :status
56
- end
57
-
58
- def get(url)
59
- execute :get, {}, {url: url}
60
- end
61
-
62
- def implicit_wait_timeout=(milliseconds)
63
- timeout('implicit', milliseconds)
64
- end
65
-
66
- def script_timeout=(milliseconds)
67
- timeout('script', milliseconds)
68
- end
69
-
70
- def timeout(type, milliseconds)
71
- type = 'pageLoad' if type == 'page load'
72
- execute :set_timeout, {}, {type => milliseconds}
73
- end
74
-
75
- #
76
- # alerts
77
- #
78
-
79
- def accept_alert
80
- execute :accept_alert
81
- end
82
-
83
- def dismiss_alert
84
- execute :dismiss_alert
85
- end
86
-
87
- def alert=(keys)
88
- execute :send_alert_text, {}, {value: keys.split(//), text: keys}
89
- end
90
-
91
- def alert_text
92
- execute :get_alert_text
93
- end
94
-
95
- #
96
- # navigation
97
- #
98
-
99
- def go_back
100
- execute :back
101
- end
102
-
103
- def go_forward
104
- execute :forward
105
- end
106
-
107
- def url
108
- execute :get_current_url
109
- end
110
-
111
- def title
112
- execute :get_title
113
- end
114
-
115
- def page_source
116
- execute_script('var source = document.documentElement.outerHTML;' \
117
- 'if (!source) { source = new XMLSerializer().serializeToString(document); }' \
118
- 'return source;')
119
- end
120
-
121
- #
122
- # Create a new top-level browsing context
123
- # https://w3c.github.io/webdriver/#new-window
124
- # @param type [String] Supports two values: 'tab' and 'window'.
125
- # Use 'tab' if you'd like the new window to share an OS-level window
126
- # with the current browsing context.
127
- # Use 'window' otherwise
128
- # @return [Hash] Containing 'handle' with the value of the window handle
129
- # and 'type' with the value of the created window type
130
- #
131
- def new_window(type)
132
- execute :new_window, {}, {type: type}
133
- end
134
-
135
- def switch_to_window(name)
136
- execute :switch_to_window, {}, {handle: name}
137
- end
138
-
139
- def switch_to_frame(id)
140
- id = find_element_by('id', id) if id.is_a? String
141
- execute :switch_to_frame, {}, {id: id}
142
- end
143
-
144
- def switch_to_parent_frame
145
- execute :switch_to_parent_frame
146
- end
147
-
148
- def switch_to_default_content
149
- switch_to_frame nil
150
- end
151
-
152
- QUIT_ERRORS = [IOError].freeze
153
-
154
- def quit
155
- execute :delete_session
156
- http.close
157
- rescue *QUIT_ERRORS
158
- end
159
-
160
- def close
161
- execute :close_window
162
- end
163
-
164
- def refresh
165
- execute :refresh
166
- end
167
-
168
- #
169
- # window handling
170
- #
171
-
172
- def window_handles
173
- execute :get_window_handles
174
- end
175
-
176
- def window_handle
177
- execute :get_window_handle
178
- end
179
-
180
- def resize_window(width, height, handle = :current)
181
- raise Error::WebDriverError, 'Switch to desired window before changing its size' unless handle == :current
182
-
183
- set_window_rect(width: width, height: height)
184
- end
185
-
186
- def window_size(handle = :current)
187
- raise Error::UnsupportedOperationError, 'Switch to desired window before getting its size' unless handle == :current
188
-
189
- data = execute :get_window_rect
190
-
191
- Dimension.new data['width'], data['height']
192
- end
193
-
194
- def minimize_window
195
- execute :minimize_window
196
- end
197
-
198
- def maximize_window(handle = :current)
199
- raise Error::UnsupportedOperationError, 'Switch to desired window before changing its size' unless handle == :current
200
-
201
- execute :maximize_window
202
- end
203
-
204
- def full_screen_window
205
- execute :fullscreen_window
206
- end
207
-
208
- def reposition_window(x, y)
209
- set_window_rect(x: x, y: y)
210
- end
211
-
212
- def window_position
213
- data = execute :get_window_rect
214
- Point.new data['x'], data['y']
215
- end
216
-
217
- def set_window_rect(x: nil, y: nil, width: nil, height: nil)
218
- params = {x: x, y: y, width: width, height: height}
219
- params.update(params) { |_k, v| Integer(v) unless v.nil? }
220
- execute :set_window_rect, {}, params
221
- end
222
-
223
- def window_rect
224
- data = execute :get_window_rect
225
- Rectangle.new data['x'], data['y'], data['width'], data['height']
226
- end
227
-
228
- def screenshot
229
- execute :take_screenshot
230
- end
231
-
232
- #
233
- # HTML 5
234
- #
235
-
236
- def local_storage_item(key, value = nil)
237
- if value
238
- execute_script("localStorage.setItem('#{key}', '#{value}')")
239
- else
240
- execute_script("return localStorage.getItem('#{key}')")
241
- end
242
- end
243
-
244
- def remove_local_storage_item(key)
245
- execute_script("localStorage.removeItem('#{key}')")
246
- end
247
-
248
- def local_storage_keys
249
- execute_script('return Object.keys(localStorage)')
250
- end
251
-
252
- def clear_local_storage
253
- execute_script('localStorage.clear()')
254
- end
255
-
256
- def local_storage_size
257
- execute_script('return localStorage.length')
258
- end
259
-
260
- def session_storage_item(key, value = nil)
261
- if value
262
- execute_script("sessionStorage.setItem('#{key}', '#{value}')")
263
- else
264
- execute_script("return sessionStorage.getItem('#{key}')")
265
- end
266
- end
267
-
268
- def remove_session_storage_item(key)
269
- execute_script("sessionStorage.removeItem('#{key}')")
270
- end
271
-
272
- def session_storage_keys
273
- execute_script('return Object.keys(sessionStorage)')
274
- end
275
-
276
- def clear_session_storage
277
- execute_script('sessionStorage.clear()')
278
- end
279
-
280
- def session_storage_size
281
- execute_script('return sessionStorage.length')
282
- end
283
-
284
- def location
285
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting location'
286
- end
287
-
288
- def set_location(_lat, _lon, _alt)
289
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting location'
290
- end
291
-
292
- def network_connection
293
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting network connection'
294
- end
295
-
296
- def network_connection=(_type)
297
- raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting network connection'
298
- end
299
-
300
- #
301
- # javascript execution
302
- #
303
-
304
- def execute_script(script, *args)
305
- result = execute :execute_script, {}, {script: script, args: args}
306
- unwrap_script_result result
307
- end
308
-
309
- def execute_async_script(script, *args)
310
- result = execute :execute_async_script, {}, {script: script, args: args}
311
- unwrap_script_result result
312
- end
313
-
314
- #
315
- # cookies
316
- #
317
-
318
- def manage
319
- @manage ||= WebDriver::W3CManager.new(self)
320
- end
321
-
322
- def add_cookie(cookie)
323
- execute :add_cookie, {}, {cookie: cookie}
324
- end
325
-
326
- def delete_cookie(name)
327
- execute :delete_cookie, name: name
328
- end
329
-
330
- def cookie(name)
331
- execute :get_cookie, name: name
332
- end
333
-
334
- def cookies
335
- execute :get_all_cookies
336
- end
337
-
338
- def delete_all_cookies
339
- execute :delete_all_cookies
340
- end
341
-
342
- #
343
- # actions
344
- #
345
-
346
- def action(async = false)
347
- W3CActionBuilder.new self,
348
- Interactions.pointer(:mouse, name: 'mouse'),
349
- Interactions.key('keyboard'),
350
- async
351
- end
352
- alias_method :actions, :action
353
-
354
- def mouse
355
- raise Error::UnsupportedOperationError, '#mouse is no longer supported, use #action instead'
356
- end
357
-
358
- def keyboard
359
- raise Error::UnsupportedOperationError, '#keyboard is no longer supported, use #action instead'
360
- end
361
-
362
- def send_actions(data)
363
- execute :actions, {}, {actions: data}
364
- end
365
-
366
- def release_actions
367
- execute :release_actions
368
- end
369
-
370
- def click_element(element)
371
- execute :element_click, id: element
372
- end
373
-
374
- def send_keys_to_element(element, keys)
375
- # TODO: rework file detectors before Selenium 4.0
376
- if @file_detector
377
- local_files = keys.first.split("\n").map { |key| @file_detector.call(Array(key)) }.compact
378
- if local_files.any?
379
- keys = local_files.map { |local_file| upload(local_file) }
380
- keys = Array(keys.join("\n"))
381
- end
382
- end
383
-
384
- # Keep .split(//) for backward compatibility for now
385
- text = keys.join('')
386
- execute :element_send_keys, {id: element}, {value: text.split(//), text: text}
387
- end
388
-
389
- def upload(local_file)
390
- unless File.file?(local_file)
391
- WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!")
392
- raise Error::WebDriverError, "You are trying to work with something that isn't a file."
393
- end
394
-
395
- execute :upload_file, {}, {file: Zipper.zip_file(local_file)}
396
- end
397
-
398
- def clear_element(element)
399
- execute :element_clear, id: element
400
- end
401
-
402
- def submit_element(element)
403
- form = find_element_by('xpath', "./ancestor-or-self::form", element)
404
- execute_script("var e = arguments[0].ownerDocument.createEvent('Event');" \
405
- "e.initEvent('submit', true, true);" \
406
- 'if (arguments[0].dispatchEvent(e)) { arguments[0].submit() }', form.as_json)
407
- end
408
-
409
- def drag_element(element, right_by, down_by)
410
- execute :drag_element, {id: element}, {x: right_by, y: down_by}
411
- end
412
-
413
- def touch_single_tap(element)
414
- execute :touch_single_tap, {}, {element: element}
415
- end
416
-
417
- def touch_double_tap(element)
418
- execute :touch_double_tap, {}, {element: element}
419
- end
420
-
421
- def touch_long_press(element)
422
- execute :touch_long_press, {}, {element: element}
423
- end
424
-
425
- def touch_down(x, y)
426
- execute :touch_down, {}, {x: x, y: y}
427
- end
428
-
429
- def touch_up(x, y)
430
- execute :touch_up, {}, {x: x, y: y}
431
- end
432
-
433
- def touch_move(x, y)
434
- execute :touch_move, {}, {x: x, y: y}
435
- end
436
-
437
- def touch_scroll(element, x, y)
438
- if element
439
- execute :touch_scroll, {}, {element: element,
440
- xoffset: x,
441
- yoffset: y}
442
- else
443
- execute :touch_scroll, {}, {xoffset: x, yoffset: y}
444
- end
445
- end
446
-
447
- def touch_flick(xspeed, yspeed)
448
- execute :touch_flick, {}, {xspeed: xspeed, yspeed: yspeed}
449
- end
450
-
451
- def touch_element_flick(element, right_by, down_by, speed)
452
- execute :touch_flick, {}, {element: element,
453
- xoffset: right_by,
454
- yoffset: down_by,
455
- speed: speed}
456
- end
457
-
458
- def screen_orientation=(orientation)
459
- execute :set_screen_orientation, {}, {orientation: orientation}
460
- end
461
-
462
- def screen_orientation
463
- execute :get_screen_orientation
464
- end
465
-
466
- #
467
- # element properties
468
- #
469
-
470
- def element_tag_name(element)
471
- execute :get_element_tag_name, id: element
472
- end
473
-
474
- def element_attribute(element, name)
475
- WebDriver.logger.info "Using script for :getAttribute of #{name}"
476
- execute_atom :getAttribute, element, name
477
- end
478
-
479
- def element_property(element, name)
480
- execute :get_element_property, id: element.ref, name: name
481
- end
482
-
483
- def element_value(element)
484
- element_property element, 'value'
485
- end
486
-
487
- def element_text(element)
488
- execute :get_element_text, id: element
489
- end
490
-
491
- def element_location(element)
492
- data = execute :get_element_rect, id: element
493
-
494
- Point.new data['x'], data['y']
495
- end
496
-
497
- def element_rect(element)
498
- data = execute :get_element_rect, id: element
499
-
500
- Rectangle.new data['x'], data['y'], data['width'], data['height']
501
- end
502
-
503
- def element_location_once_scrolled_into_view(element)
504
- send_keys_to_element(element, [''])
505
- element_location(element)
506
- end
507
-
508
- def element_size(element)
509
- data = execute :get_element_rect, id: element
510
-
511
- Dimension.new data['width'], data['height']
512
- end
513
-
514
- def element_enabled?(element)
515
- execute :is_element_enabled, id: element
516
- end
517
-
518
- def element_selected?(element)
519
- execute :is_element_selected, id: element
520
- end
521
-
522
- def element_displayed?(element)
523
- WebDriver.logger.info 'Using script for :isDisplayed'
524
- execute_atom :isDisplayed, element
525
- end
526
-
527
- def element_value_of_css_property(element, prop)
528
- execute :get_element_css_value, id: element, property_name: prop
529
- end
530
-
531
- #
532
- # finding elements
533
- #
534
-
535
- def active_element
536
- Element.new self, element_id_from(execute(:get_active_element))
537
- end
538
-
539
- alias_method :switch_to_active_element, :active_element
540
-
541
- def find_element_by(how, what, parent = nil)
542
- how, what = convert_locators(how, what)
543
-
544
- id = if parent
545
- execute :find_child_element, {id: parent}, {using: how, value: what}
546
- else
547
- execute :find_element, {}, {using: how, value: what}
548
- end
549
- Element.new self, element_id_from(id)
550
- end
551
-
552
- def find_elements_by(how, what, parent = nil)
553
- how, what = convert_locators(how, what)
554
-
555
- ids = if parent
556
- execute :find_child_elements, {id: parent}, {using: how, value: what}
557
- else
558
- execute :find_elements, {}, {using: how, value: what}
559
- end
560
-
561
- ids.map { |id| Element.new self, element_id_from(id) }
562
- end
563
-
564
- private
565
-
566
- def execute(*)
567
- super['value']
568
- end
569
-
570
- def convert_locators(how, what)
571
- case how
572
- when 'class name'
573
- how = 'css selector'
574
- what = ".#{escape_css(what)}"
575
- when 'id'
576
- how = 'css selector'
577
- what = "##{escape_css(what)}"
578
- when 'name'
579
- how = 'css selector'
580
- what = "*[name='#{escape_css(what)}']"
581
- when 'tag name'
582
- how = 'css selector'
583
- end
584
- [how, what]
585
- end
586
-
587
- ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]\(\)])/.freeze
588
- UNICODE_CODE_POINT = 30
589
-
590
- # Escapes invalid characters in CSS selector.
591
- # @see https://mathiasbynens.be/notes/css-escapes
592
- def escape_css(string)
593
- string = string.gsub(ESCAPE_CSS_REGEXP) { |match| "\\#{match}" }
594
- if !string.empty? && string[0] =~ /[[:digit:]]/
595
- string = "\\#{UNICODE_CODE_POINT + Integer(string[0])} #{string[1..-1]}"
596
- end
597
-
598
- string
599
- end
600
-
601
- end # Bridge
602
- end # W3C
603
- end # Remote
604
- end # WebDriver
605
- end # Selenium