selenium-webdriver 4.0.0.alpha1 → 4.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +8 -1
  3. data/lib/selenium/webdriver/version.rb +1 -1
  4. metadata +2 -26
  5. data/lib/selenium/webdriver/common/bridge_helper.rb +0 -82
  6. data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +0 -36
  7. data/lib/selenium/webdriver/common/keyboard.rb +0 -70
  8. data/lib/selenium/webdriver/common/mouse.rb +0 -89
  9. data/lib/selenium/webdriver/common/options.rb +0 -177
  10. data/lib/selenium/webdriver/common/touch_action_builder.rb +0 -78
  11. data/lib/selenium/webdriver/common/touch_screen.rb +0 -123
  12. data/lib/selenium/webdriver/common/w3c_action_builder.rb +0 -212
  13. data/lib/selenium/webdriver/common/w3c_manager.rb +0 -45
  14. data/lib/selenium/webdriver/common/w3c_options.rb +0 -45
  15. data/lib/selenium/webdriver/edge/bridge.rb +0 -76
  16. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  17. data/lib/selenium/webdriver/firefox/launcher.rb +0 -111
  18. data/lib/selenium/webdriver/firefox/legacy/driver.rb +0 -83
  19. data/lib/selenium/webdriver/firefox/marionette/bridge.rb +0 -49
  20. data/lib/selenium/webdriver/firefox/marionette/driver.rb +0 -90
  21. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  22. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  23. data/lib/selenium/webdriver/firefox/util.rb +0 -46
  24. data/lib/selenium/webdriver/remote/oss/bridge.rb +0 -594
  25. data/lib/selenium/webdriver/remote/oss/commands.rb +0 -223
  26. data/lib/selenium/webdriver/remote/w3c/bridge.rb +0 -605
  27. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +0 -310
  28. data/lib/selenium/webdriver/remote/w3c/commands.rb +0 -157
@@ -1,223 +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
- module Selenium
21
- module WebDriver
22
- module Remote
23
- module OSS
24
-
25
- #
26
- # https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#command-reference
27
- # @api private
28
- #
29
-
30
- class Bridge
31
-
32
- COMMANDS = {
33
- get_capabilities: [:get, 'session/:session_id'],
34
- status: [:get, 'status'],
35
-
36
- #
37
- # basic driver
38
- #
39
-
40
- get_current_url: [:get, 'session/:session_id/url'],
41
- get: [:post, 'session/:session_id/url'],
42
- go_forward: [:post, 'session/:session_id/forward'],
43
- go_back: [:post, 'session/:session_id/back'],
44
- refresh: [:post, 'session/:session_id/refresh'],
45
- quit: [:delete, 'session/:session_id'],
46
- close: [:delete, 'session/:session_id/window'],
47
- get_page_source: [:get, 'session/:session_id/source'],
48
- get_title: [:get, 'session/:session_id/title'],
49
- find_element: [:post, 'session/:session_id/element'],
50
- find_elements: [:post, 'session/:session_id/elements'],
51
- get_active_element: [:post, 'session/:session_id/element/active'],
52
-
53
- #
54
- # window handling
55
- #
56
-
57
- get_current_window_handle: [:get, 'session/:session_id/window_handle'],
58
- get_window_handles: [:get, 'session/:session_id/window_handles'],
59
- set_window_size: [:post, 'session/:session_id/window/:window_handle/size'],
60
- set_window_position: [:post, 'session/:session_id/window/:window_handle/position'],
61
- get_window_size: [:get, 'session/:session_id/window/:window_handle/size'],
62
- get_window_position: [:get, 'session/:session_id/window/:window_handle/position'],
63
- maximize_window: [:post, 'session/:session_id/window/:window_handle/maximize'],
64
-
65
- #
66
- # script execution
67
- #
68
-
69
- execute_script: [:post, 'session/:session_id/execute'],
70
- execute_async_script: [:post, 'session/:session_id/execute_async'],
71
-
72
- #
73
- # screenshot
74
- #
75
-
76
- screenshot: [:get, 'session/:session_id/screenshot'],
77
-
78
- #
79
- # alerts
80
- #
81
-
82
- dismiss_alert: [:post, 'session/:session_id/dismiss_alert'],
83
- accept_alert: [:post, 'session/:session_id/accept_alert'],
84
- get_alert_text: [:get, 'session/:session_id/alert_text'],
85
- set_alert_value: [:post, 'session/:session_id/alert_text'],
86
- set_authentication: [:post, 'session/:session_id/alert/credentials'],
87
-
88
- #
89
- # target locator
90
- #
91
-
92
- switch_to_frame: [:post, 'session/:session_id/frame'],
93
- switch_to_parent_frame: [:post, 'session/:session_id/frame/parent'],
94
- switch_to_window: [:post, 'session/:session_id/window'],
95
-
96
- #
97
- # options
98
- #
99
-
100
- get_cookies: [:get, 'session/:session_id/cookie'],
101
- add_cookie: [:post, 'session/:session_id/cookie'],
102
- delete_all_cookies: [:delete, 'session/:session_id/cookie'],
103
- delete_cookie: [:delete, 'session/:session_id/cookie/:name'],
104
-
105
- #
106
- # timeouts
107
- #
108
-
109
- implicitly_wait: [:post, 'session/:session_id/timeouts/implicit_wait'],
110
- set_script_timeout: [:post, 'session/:session_id/timeouts/async_script'],
111
- set_timeout: [:post, 'session/:session_id/timeouts'],
112
-
113
- #
114
- # element
115
- #
116
-
117
- describe_element: [:get, 'session/:session_id/element/:id'],
118
- find_child_element: [:post, 'session/:session_id/element/:id/element'],
119
- find_child_elements: [:post, 'session/:session_id/element/:id/elements'],
120
- click_element: [:post, 'session/:session_id/element/:id/click'],
121
- submit_element: [:post, 'session/:session_id/element/:id/submit'],
122
- get_element_value: [:get, 'session/:session_id/element/:id/value'],
123
- send_keys_to_element: [:post, 'session/:session_id/element/:id/value'],
124
- upload_file: [:post, 'session/:session_id/file'],
125
- get_element_tag_name: [:get, 'session/:session_id/element/:id/name'],
126
- clear_element: [:post, 'session/:session_id/element/:id/clear'],
127
- is_element_selected: [:get, 'session/:session_id/element/:id/selected'],
128
- is_element_enabled: [:get, 'session/:session_id/element/:id/enabled'],
129
- get_element_attribute: [:get, 'session/:session_id/element/:id/attribute/:name'],
130
- element_equals: [:get, 'session/:session_id/element/:id/equals/:other'],
131
- is_element_displayed: [:get, 'session/:session_id/element/:id/displayed'],
132
- get_element_location: [:get, 'session/:session_id/element/:id/location'],
133
- get_element_location_once_scrolled_into_view: [:get, 'session/:session_id/element/:id/location_in_view'],
134
- get_element_size: [:get, 'session/:session_id/element/:id/size'],
135
- drag_element: [:post, 'session/:session_id/element/:id/drag'],
136
- get_element_value_of_css_property: [:get, 'session/:session_id/element/:id/css/:property_name'],
137
- get_element_text: [:get, 'session/:session_id/element/:id/text'],
138
-
139
- #
140
- # rotatable
141
- #
142
-
143
- get_screen_orientation: [:get, 'session/:session_id/orientation'],
144
- set_screen_orientation: [:post, 'session/:session_id/orientation'],
145
-
146
- #
147
- # interactions API
148
- #
149
-
150
- click: [:post, 'session/:session_id/click'],
151
- double_click: [:post, 'session/:session_id/doubleclick'],
152
- mouse_down: [:post, 'session/:session_id/buttondown'],
153
- mouse_up: [:post, 'session/:session_id/buttonup'],
154
- mouse_move_to: [:post, 'session/:session_id/moveto'],
155
- send_modifier_key_to_active_element: [:post, 'session/:session_id/modifier'],
156
- send_keys_to_active_element: [:post, 'session/:session_id/keys'],
157
-
158
- #
159
- # html 5
160
- #
161
-
162
- execute_sql: [:post, 'session/:session_id/execute_sql'],
163
-
164
- get_location: [:get, 'session/:session_id/location'],
165
- set_location: [:post, 'session/:session_id/location'],
166
-
167
- get_app_cache: [:get, 'session/:session_id/application_cache'],
168
- get_app_cache_status: [:get, 'session/:session_id/application_cache/status'],
169
- clear_app_cache: [:delete, 'session/:session_id/application_cache/clear'],
170
-
171
- get_network_connection: [:get, 'session/:session_id/network_connection'],
172
- set_network_connection: [:post, 'session/:session_id/network_connection'],
173
-
174
- get_local_storage_item: [:get, 'session/:session_id/local_storage/key/:key'],
175
- remove_local_storage_item: [:delete, 'session/:session_id/local_storage/key/:key'],
176
- get_local_storage_keys: [:get, 'session/:session_id/local_storage'],
177
- set_local_storage_item: [:post, 'session/:session_id/local_storage'],
178
- clear_local_storage: [:delete, 'session/:session_id/local_storage'],
179
- get_local_storage_size: [:get, 'session/:session_id/local_storage/size'],
180
-
181
- get_session_storage_item: [:get, 'session/:session_id/session_storage/key/:key'],
182
- remove_session_storage_item: [:delete, 'session/:session_id/session_storage/key/:key'],
183
- get_session_storage_keys: [:get, 'session/:session_id/session_storage'],
184
- set_session_storage_item: [:post, 'session/:session_id/session_storage'],
185
- clear_session_storage: [:delete, 'session/:session_id/session_storage'],
186
- get_session_storage_size: [:get, 'session/:session_id/session_storage/size'],
187
-
188
- #
189
- # ime
190
- #
191
-
192
- ime_get_available_engines: [:get, 'session/:session_id/ime/available_engines'],
193
- ime_get_active_engine: [:get, 'session/:session_id/ime/active_engine'],
194
- ime_is_activated: [:get, 'session/:session_id/ime/activated'],
195
- ime_deactivate: [:post, 'session/:session_id/ime/deactivate'],
196
- ime_activate_engine: [:post, 'session/:session_id/ime/activate'],
197
-
198
- #
199
- # touch
200
- #
201
-
202
- touch_single_tap: [:post, 'session/:session_id/touch/click'],
203
- touch_double_tap: [:post, 'session/:session_id/touch/doubleclick'],
204
- touch_long_press: [:post, 'session/:session_id/touch/longclick'],
205
- touch_down: [:post, 'session/:session_id/touch/down'],
206
- touch_up: [:post, 'session/:session_id/touch/up'],
207
- touch_move: [:post, 'session/:session_id/touch/move'],
208
- touch_scroll: [:post, 'session/:session_id/touch/scroll'],
209
- touch_flick: [:post, 'session/:session_id/touch/flick'],
210
-
211
- #
212
- # logs
213
- #
214
-
215
- get_available_log_types: [:get, 'session/:session_id/log/types'],
216
- get_log: [:post, 'session/:session_id/log']
217
- }.freeze
218
-
219
- end # Bridge
220
- end # OSS
221
- end # Remote
222
- end # WebDriver
223
- end # Selenium
@@ -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