selenium-webdriver 3.4.0 → 3.4.1

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 (44) hide show
  1. data/CHANGES +35 -1
  2. data/Gemfile.lock +54 -0
  3. data/lib/selenium/webdriver.rb +8 -10
  4. data/lib/selenium/webdriver/chrome.rb +2 -1
  5. data/lib/selenium/webdriver/chrome/{bridge.rb → driver.rb} +47 -32
  6. data/lib/selenium/webdriver/chrome/options.rb +170 -0
  7. data/lib/selenium/webdriver/common/driver.rb +20 -39
  8. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +5 -0
  9. data/lib/selenium/webdriver/common/element.rb +5 -1
  10. data/lib/selenium/webdriver/common/logger.rb +10 -0
  11. data/lib/selenium/webdriver/common/w3c_error.rb +2 -2
  12. data/lib/selenium/webdriver/edge.rb +2 -1
  13. data/lib/selenium/webdriver/edge/bridge.rb +2 -91
  14. data/lib/selenium/webdriver/edge/driver.rb +80 -0
  15. data/lib/selenium/webdriver/firefox.rb +6 -3
  16. data/lib/selenium/webdriver/firefox/driver.rb +50 -0
  17. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  18. data/lib/selenium/webdriver/firefox/legacy/driver.rb +81 -0
  19. data/lib/selenium/webdriver/firefox/marionette/driver.rb +101 -0
  20. data/lib/selenium/webdriver/firefox/options.rb +139 -0
  21. data/lib/selenium/webdriver/ie.rb +1 -1
  22. data/lib/selenium/webdriver/ie/{bridge.rb → driver.rb} +13 -13
  23. data/lib/selenium/webdriver/phantomjs.rb +1 -1
  24. data/lib/selenium/webdriver/phantomjs/{bridge.rb → driver.rb} +10 -13
  25. data/lib/selenium/webdriver/remote.rb +11 -13
  26. data/lib/selenium/webdriver/remote/bridge.rb +87 -586
  27. data/lib/selenium/webdriver/remote/capabilities.rb +3 -1
  28. data/lib/selenium/webdriver/remote/driver.rb +44 -0
  29. data/lib/selenium/webdriver/remote/http/default.rb +1 -1
  30. data/lib/selenium/webdriver/remote/oss/bridge.rb +586 -0
  31. data/lib/selenium/webdriver/remote/{commands.rb → oss/commands.rb} +9 -5
  32. data/lib/selenium/webdriver/remote/oss/driver.rb +44 -0
  33. data/lib/selenium/webdriver/remote/w3c/bridge.rb +573 -0
  34. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +266 -0
  35. data/lib/selenium/webdriver/remote/{w3c_commands.rb → w3c/commands.rb} +9 -4
  36. data/lib/selenium/webdriver/remote/w3c/driver.rb +41 -0
  37. data/lib/selenium/webdriver/safari.rb +3 -6
  38. data/lib/selenium/webdriver/safari/{bridge.rb → driver.rb} +14 -6
  39. data/selenium-webdriver.gemspec +1 -3
  40. metadata +29 -45
  41. data/lib/selenium/webdriver/firefox/bridge.rb +0 -70
  42. data/lib/selenium/webdriver/firefox/w3c_bridge.rb +0 -114
  43. data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -663
  44. data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -231
@@ -139,7 +139,7 @@ module Selenium
139
139
  caps = new
140
140
  caps.browser_name = data.delete('browserName')
141
141
  caps.version = data.delete('version')
142
- caps.platform = data.delete('platform').downcase.tr(' ','_').to_sym if data.key?('platform')
142
+ caps.platform = data.delete('platform').downcase.tr(' ', '_').to_sym if data.key?('platform')
143
143
  caps.javascript_enabled = data.delete('javascriptEnabled')
144
144
  caps.css_selectors_enabled = data.delete('cssSelectorsEnabled')
145
145
  caps.takes_screenshot = data.delete('takesScreenshot')
@@ -154,6 +154,7 @@ module Selenium
154
154
  end
155
155
  end
156
156
 
157
+ #
157
158
  # @option :browser_name [String] required browser name
158
159
  # @option :version [String] required browser version number
159
160
  # @option :platform [Symbol] one of :any, :win, :mac, or :x
@@ -208,6 +209,7 @@ module Selenium
208
209
  end
209
210
  end
210
211
 
212
+ #
211
213
  # @api private
212
214
  #
213
215
 
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
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
+
24
+ #
25
+ # Driver implementation for remote server.
26
+ # @api private
27
+ #
28
+
29
+ module Driver
30
+
31
+ def self.new(**opts)
32
+ listener = opts.delete(:listener)
33
+ bridge = Bridge.handshake(opts)
34
+ if bridge.dialect == :w3c
35
+ W3C::Driver.new(bridge, listener: listener)
36
+ else
37
+ OSS::Driver.new(bridge, listener: listener)
38
+ end
39
+ end
40
+
41
+ end # Driver
42
+ end # Remote
43
+ end # WebDriver
44
+ end # Selenium
@@ -45,7 +45,7 @@ module Selenium
45
45
  # @param [Numeric] value - Timeout in seconds to apply to both open timeout and read timeouts.
46
46
  # @deprecated Please set the specific desired timeout {#read_timeout} or {#open_timeout} directly.
47
47
  def timeout=(value)
48
- WebDriver.logger.warn 'Selenium::WebDriver::Remote::Http::Default#timeout= is deprecated. Use #read_timeout= or #open_timeout= instead'
48
+ WebDriver.logger.deprecate ':timeout=', '#read_timeout= and #open_timeout='
49
49
  self.open_timeout = value
50
50
  self.read_timeout = value
51
51
  end
@@ -0,0 +1,586 @@
1
+ # encoding: utf-8
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
+ # Low level bridge to the remote server implementing JSON wire
27
+ # protocol (OSS dialect), through which the rest of the API works.
28
+ # @api private
29
+ #
30
+
31
+ class Bridge < Remote::Bridge
32
+
33
+ def initialize(capabilities, session_id, **opts)
34
+ @capabilities = capabilities
35
+ @session_id = session_id
36
+ super(opts)
37
+ end
38
+
39
+ def dialect
40
+ :oss
41
+ end
42
+
43
+ def commands(command)
44
+ COMMANDS[command]
45
+ end
46
+
47
+ def status
48
+ execute :status
49
+ end
50
+
51
+ def get(url)
52
+ execute :get, {}, {url: url}
53
+ end
54
+
55
+ def session_capabilities
56
+ Capabilities.json_create execute(:get_capabilities)
57
+ end
58
+
59
+ def implicit_wait_timeout=(milliseconds)
60
+ execute :implicitly_wait, {}, {ms: milliseconds}
61
+ end
62
+
63
+ def script_timeout=(milliseconds)
64
+ execute :set_script_timeout, {}, {ms: milliseconds}
65
+ end
66
+
67
+ def timeout(type, milliseconds)
68
+ execute :set_timeout, {}, {type: type, ms: milliseconds}
69
+ end
70
+
71
+ #
72
+ # alerts
73
+ #
74
+
75
+ def accept_alert
76
+ execute :accept_alert
77
+ end
78
+
79
+ def dismiss_alert
80
+ execute :dismiss_alert
81
+ end
82
+
83
+ def alert=(keys)
84
+ execute :set_alert_value, {}, {text: keys.to_s}
85
+ end
86
+
87
+ def alert_text
88
+ execute :get_alert_text
89
+ end
90
+
91
+ def authentication(credentials)
92
+ execute :set_authentication, {}, credentials
93
+ end
94
+
95
+ #
96
+ # navigation
97
+ #
98
+
99
+ def go_back
100
+ execute :go_back
101
+ end
102
+
103
+ def go_forward
104
+ execute :go_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 :get_page_source
117
+ end
118
+
119
+ def switch_to_window(name)
120
+ execute :switch_to_window, {}, {name: name}
121
+ end
122
+
123
+ def switch_to_frame(id)
124
+ execute :switch_to_frame, {}, {id: id}
125
+ end
126
+
127
+ def switch_to_parent_frame
128
+ execute :switch_to_parent_frame
129
+ end
130
+
131
+ def switch_to_default_content
132
+ switch_to_frame(nil)
133
+ end
134
+
135
+ def quit
136
+ execute :quit
137
+ http.close
138
+ rescue *http.quit_errors
139
+ end
140
+
141
+ def close
142
+ execute :close
143
+ end
144
+
145
+ def refresh
146
+ execute :refresh
147
+ end
148
+
149
+ #
150
+ # window handling
151
+ #
152
+
153
+ def window_handles
154
+ execute :get_window_handles
155
+ end
156
+
157
+ def window_handle
158
+ execute :get_current_window_handle
159
+ end
160
+
161
+ def resize_window(width, height, handle = :current)
162
+ execute :set_window_size, {window_handle: handle},
163
+ {width: width,
164
+ height: height}
165
+ end
166
+
167
+ def maximize_window(handle = :current)
168
+ execute :maximize_window, window_handle: handle
169
+ end
170
+
171
+ def window_size(handle = :current)
172
+ data = execute :get_window_size, window_handle: handle
173
+
174
+ Dimension.new data['width'], data['height']
175
+ end
176
+
177
+ def reposition_window(x, y, handle = :current)
178
+ execute :set_window_position, {window_handle: handle},
179
+ {x: x, y: y}
180
+ end
181
+
182
+ def window_position(handle = :current)
183
+ data = execute :get_window_position, window_handle: handle
184
+
185
+ Point.new data['x'], data['y']
186
+ end
187
+
188
+ def screenshot
189
+ execute :screenshot
190
+ end
191
+
192
+ #
193
+ # HTML 5
194
+ #
195
+
196
+ def local_storage_item(key, value = nil)
197
+ if value
198
+ execute :set_local_storage_item, {}, {key: key, value: value}
199
+ else
200
+ execute :get_local_storage_item, key: key
201
+ end
202
+ end
203
+
204
+ def remove_local_storage_item(key)
205
+ execute :remove_local_storage_item, key: key
206
+ end
207
+
208
+ def local_storage_keys
209
+ execute :get_local_storage_keys
210
+ end
211
+
212
+ def clear_local_storage
213
+ execute :clear_local_storage
214
+ end
215
+
216
+ def local_storage_size
217
+ execute :get_local_storage_size
218
+ end
219
+
220
+ def session_storage_item(key, value = nil)
221
+ if value
222
+ execute :set_session_storage_item, {}, {key: key, value: value}
223
+ else
224
+ execute :get_session_storage_item, key: key
225
+ end
226
+ end
227
+
228
+ def remove_session_storage_item(key)
229
+ execute :remove_session_storage_item, key: key
230
+ end
231
+
232
+ def session_storage_keys
233
+ execute :get_session_storage_keys
234
+ end
235
+
236
+ def clear_session_storage
237
+ execute :clear_session_storage
238
+ end
239
+
240
+ def session_storage_size
241
+ execute :get_session_storage_size
242
+ end
243
+
244
+ def location
245
+ obj = execute(:get_location) || {}
246
+ Location.new obj['latitude'], obj['longitude'], obj['altitude']
247
+ end
248
+
249
+ def set_location(lat, lon, alt)
250
+ loc = {latitude: lat, longitude: lon, altitude: alt}
251
+ execute :set_location, {}, {location: loc}
252
+ end
253
+
254
+ def network_connection
255
+ execute :get_network_connection
256
+ end
257
+
258
+ def network_connection=(type)
259
+ execute :set_network_connection, {}, {parameters: {type: type}}
260
+ end
261
+
262
+ #
263
+ # javascript execution
264
+ #
265
+
266
+ def execute_script(script, *args)
267
+ assert_javascript_enabled
268
+
269
+ result = execute :execute_script, {}, {script: script, args: args}
270
+ unwrap_script_result result
271
+ end
272
+
273
+ def execute_async_script(script, *args)
274
+ assert_javascript_enabled
275
+
276
+ result = execute :execute_async_script, {}, {script: script, args: args}
277
+ unwrap_script_result result
278
+ end
279
+
280
+ #
281
+ # cookies
282
+ #
283
+
284
+ def options
285
+ @options ||= WebDriver::Options.new(self)
286
+ end
287
+
288
+ def add_cookie(cookie)
289
+ execute :add_cookie, {}, {cookie: cookie}
290
+ end
291
+
292
+ def delete_cookie(name)
293
+ execute :delete_cookie, name: name
294
+ end
295
+
296
+ def cookies
297
+ execute :get_cookies
298
+ end
299
+
300
+ def delete_all_cookies
301
+ execute :delete_all_cookies
302
+ end
303
+
304
+ #
305
+ # actions
306
+ #
307
+
308
+ #
309
+ # @return [ActionBuilder]
310
+ # @api public
311
+ #
312
+
313
+ def action
314
+ ActionBuilder.new Mouse.new(self), Keyboard.new(self)
315
+ end
316
+
317
+ def mouse
318
+ WebDriver.logger.deprecate 'Driver#mouse', 'driver.action.<command>.perform'
319
+ Mouse.new self
320
+ end
321
+
322
+ def keyboard
323
+ WebDriver.logger.deprecate 'Driver#keyboard', 'driver.action.<command>.perform'
324
+ Keyboard.new self
325
+ end
326
+
327
+ def click_element(element)
328
+ execute :click_element, id: element
329
+ end
330
+
331
+ def click
332
+ execute :click, {}, {button: 0}
333
+ end
334
+
335
+ def double_click
336
+ execute :double_click
337
+ end
338
+
339
+ def context_click
340
+ execute :click, {}, {button: 2}
341
+ end
342
+
343
+ def mouse_down
344
+ execute :mouse_down
345
+ end
346
+
347
+ def mouse_up
348
+ execute :mouse_up
349
+ end
350
+
351
+ def mouse_move_to(element, x = nil, y = nil)
352
+ params = {element: element}
353
+
354
+ if x && y
355
+ params[:xoffset] = x
356
+ params[:yoffset] = y
357
+ end
358
+
359
+ execute :mouse_move_to, {}, params
360
+ end
361
+
362
+ def send_keys_to_active_element(key)
363
+ execute :send_keys_to_active_element, {}, {value: key}
364
+ end
365
+
366
+ def send_keys_to_element(element, keys)
367
+ if @file_detector
368
+ local_file = @file_detector.call(keys)
369
+ keys = upload(local_file) if local_file
370
+ end
371
+
372
+ execute :send_keys_to_element, {id: element}, {value: Array(keys)}
373
+ end
374
+
375
+ def upload(local_file)
376
+ unless File.file?(local_file)
377
+ raise Error::WebDriverError, "you may only upload files: #{local_file.inspect}"
378
+ end
379
+
380
+ execute :upload_file, {}, {file: Zipper.zip_file(local_file)}
381
+ end
382
+
383
+ def clear_element(element)
384
+ execute :clear_element, id: element
385
+ end
386
+
387
+ def submit_element(element)
388
+ execute :submit_element, id: element
389
+ end
390
+
391
+ def drag_element(element, right_by, down_by)
392
+ execute :drag_element, {id: element}, {x: right_by, y: down_by}
393
+ end
394
+
395
+ def touch_single_tap(element)
396
+ execute :touch_single_tap, {}, {element: element}
397
+ end
398
+
399
+ def touch_double_tap(element)
400
+ execute :touch_double_tap, {}, {element: element}
401
+ end
402
+
403
+ def touch_long_press(element)
404
+ execute :touch_long_press, {}, {element: element}
405
+ end
406
+
407
+ def touch_down(x, y)
408
+ execute :touch_down, {}, {x: x, y: y}
409
+ end
410
+
411
+ def touch_up(x, y)
412
+ execute :touch_up, {}, {x: x, y: y}
413
+ end
414
+
415
+ def touch_move(x, y)
416
+ execute :touch_move, {}, {x: x, y: y}
417
+ end
418
+
419
+ def touch_scroll(element, x, y)
420
+ if element
421
+ execute :touch_scroll, {}, {element: element,
422
+ xoffset: x,
423
+ yoffset: y}
424
+ else
425
+ execute :touch_scroll, {}, {xoffset: x, yoffset: y}
426
+ end
427
+ end
428
+
429
+ def touch_flick(xspeed, yspeed)
430
+ execute :touch_flick, {}, {xspeed: xspeed, yspeed: yspeed}
431
+ end
432
+
433
+ def touch_element_flick(element, right_by, down_by, speed)
434
+ execute :touch_flick, {}, {element: element,
435
+ xoffset: right_by,
436
+ yoffset: down_by,
437
+ speed: speed}
438
+ end
439
+
440
+ def screen_orientation=(orientation)
441
+ execute :set_screen_orientation, {}, {orientation: orientation}
442
+ end
443
+
444
+ def screen_orientation
445
+ execute :get_screen_orientation
446
+ end
447
+
448
+ #
449
+ # logs
450
+ #
451
+
452
+ def available_log_types
453
+ types = execute :get_available_log_types
454
+ Array(types).map(&:to_sym)
455
+ end
456
+
457
+ def log(type)
458
+ data = execute :get_log, {}, {type: type.to_s}
459
+
460
+ Array(data).map do |l|
461
+ begin
462
+ LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
463
+ rescue KeyError
464
+ next
465
+ end
466
+ end
467
+ end
468
+
469
+ #
470
+ # element properties
471
+ #
472
+
473
+ def element_tag_name(element)
474
+ execute :get_element_tag_name, id: element
475
+ end
476
+
477
+ def element_attribute(element, name)
478
+ execute :get_element_attribute, id: element.ref, name: name
479
+ end
480
+
481
+ # Backwards compatibility for w3c
482
+ def element_property(element, name)
483
+ execute_script 'return arguments[0][arguments[1]]', element, name
484
+ end
485
+
486
+ def element_value(element)
487
+ execute :get_element_value, id: element
488
+ end
489
+
490
+ def element_text(element)
491
+ execute :get_element_text, id: element
492
+ end
493
+
494
+ def element_location(element)
495
+ data = execute :get_element_location, id: element
496
+
497
+ Point.new data['x'], data['y']
498
+ end
499
+
500
+ def element_rect(element)
501
+ loc = execute :get_element_location, id: element
502
+ size = execute :get_element_size, id: element
503
+
504
+ Rectangle.new loc['x'], loc['y'], size['width'], size['height']
505
+ end
506
+
507
+ def element_location_once_scrolled_into_view(element)
508
+ data = execute :get_element_location_once_scrolled_into_view, id: element
509
+
510
+ Point.new data['x'], data['y']
511
+ end
512
+
513
+ def element_size(element)
514
+ data = execute :get_element_size, id: element
515
+
516
+ Dimension.new data['width'], data['height']
517
+ end
518
+
519
+ def element_enabled?(element)
520
+ execute :is_element_enabled, id: element
521
+ end
522
+
523
+ def element_selected?(element)
524
+ execute :is_element_selected, id: element
525
+ end
526
+
527
+ def element_displayed?(element)
528
+ execute :is_element_displayed, id: element
529
+ end
530
+
531
+ def element_value_of_css_property(element, prop)
532
+ execute :get_element_value_of_css_property, id: element, property_name: prop
533
+ end
534
+
535
+ #
536
+ # finding elements
537
+ #
538
+
539
+ def active_element
540
+ Element.new self, element_id_from(execute(:get_active_element))
541
+ end
542
+
543
+ alias_method :switch_to_active_element, :active_element
544
+
545
+ def find_element_by(how, what, parent = nil)
546
+ id = if parent
547
+ execute :find_child_element, {id: parent}, {using: how, value: what}
548
+ else
549
+ execute :find_element, {}, {using: how, value: what}
550
+ end
551
+
552
+ Element.new self, element_id_from(id)
553
+ end
554
+
555
+ def find_elements_by(how, what, parent = nil)
556
+ ids = if parent
557
+ execute :find_child_elements, {id: parent}, {using: how, value: what}
558
+ else
559
+ execute :find_elements, {}, {using: how, value: what}
560
+ end
561
+
562
+ ids.map { |id| Element.new self, element_id_from(id) }
563
+ end
564
+
565
+ private
566
+
567
+ def assert_javascript_enabled
568
+ return if capabilities.javascript_enabled?
569
+ raise Error::UnsupportedOperationError, 'underlying webdriver instance does not support javascript'
570
+ end
571
+
572
+ #
573
+ # executes a command on the remote server.
574
+ #
575
+ # Returns the 'value' of the returned payload
576
+ #
577
+
578
+ def execute(*args)
579
+ super['value']
580
+ end
581
+
582
+ end # Bridge
583
+ end # OSS
584
+ end # Remote
585
+ end # WebDriver
586
+ end # Selenium