selenium-webdriver 4.0.0.alpha5 → 4.0.0.alpha6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +38 -0
- data/LICENSE +1 -1
- data/lib/selenium/webdriver/atoms/findElements.js +1 -1
- data/lib/selenium/webdriver/chrome/bridge.rb +4 -6
- data/lib/selenium/webdriver/chrome/driver.rb +4 -0
- data/lib/selenium/webdriver/chrome/options.rb +24 -19
- data/lib/selenium/webdriver/common.rb +1 -0
- data/lib/selenium/webdriver/common/driver.rb +55 -23
- data/lib/selenium/webdriver/common/logger.rb +1 -1
- data/lib/selenium/webdriver/common/manager.rb +5 -0
- data/lib/selenium/webdriver/common/options.rb +32 -9
- data/lib/selenium/webdriver/common/port_prober.rb +4 -6
- data/lib/selenium/webdriver/common/service.rb +12 -106
- data/lib/selenium/webdriver/common/service_manager.rb +151 -0
- data/lib/selenium/webdriver/devtools.rb +118 -0
- data/lib/selenium/webdriver/devtools/accessibility.rb +62 -0
- data/lib/selenium/webdriver/devtools/animation.rb +98 -0
- data/lib/selenium/webdriver/devtools/application_cache.rb +64 -0
- data/lib/selenium/webdriver/devtools/audits.rb +61 -0
- data/lib/selenium/webdriver/devtools/background_service.rb +67 -0
- data/lib/selenium/webdriver/devtools/browser.rb +123 -0
- data/lib/selenium/webdriver/devtools/cache_storage.rb +73 -0
- data/lib/selenium/webdriver/devtools/cast.rb +70 -0
- data/lib/selenium/webdriver/devtools/console.rb +57 -0
- data/lib/selenium/webdriver/devtools/css.rb +165 -0
- data/lib/selenium/webdriver/devtools/database.rb +64 -0
- data/lib/selenium/webdriver/devtools/debugger.rb +229 -0
- data/lib/selenium/webdriver/devtools/device_orientation.rb +53 -0
- data/lib/selenium/webdriver/devtools/dom.rb +320 -0
- data/lib/selenium/webdriver/devtools/domdebugger.rb +93 -0
- data/lib/selenium/webdriver/devtools/domsnapshot.rb +65 -0
- data/lib/selenium/webdriver/devtools/domstorage.rb +79 -0
- data/lib/selenium/webdriver/devtools/emulation.rb +180 -0
- data/lib/selenium/webdriver/devtools/fetch.rb +97 -0
- data/lib/selenium/webdriver/devtools/headless_experimental.rb +61 -0
- data/lib/selenium/webdriver/devtools/heap_profiler.rb +107 -0
- data/lib/selenium/webdriver/devtools/indexed_db.rb +100 -0
- data/lib/selenium/webdriver/devtools/input.rb +140 -0
- data/lib/selenium/webdriver/devtools/inspector.rb +55 -0
- data/lib/selenium/webdriver/devtools/io.rb +59 -0
- data/lib/selenium/webdriver/devtools/layer_tree.rb +95 -0
- data/lib/selenium/webdriver/devtools/log.rb +66 -0
- data/lib/selenium/webdriver/devtools/media.rb +57 -0
- data/lib/selenium/webdriver/devtools/memory.rb +86 -0
- data/lib/selenium/webdriver/devtools/network.rb +228 -0
- data/lib/selenium/webdriver/devtools/overlay.rb +157 -0
- data/lib/selenium/webdriver/devtools/page.rb +374 -0
- data/lib/selenium/webdriver/devtools/performance.rb +63 -0
- data/lib/selenium/webdriver/devtools/profiler.rb +111 -0
- data/lib/selenium/webdriver/devtools/runtime.rb +193 -0
- data/lib/selenium/webdriver/devtools/schema.rb +46 -0
- data/lib/selenium/webdriver/devtools/security.rb +71 -0
- data/lib/selenium/webdriver/devtools/service_worker.rb +116 -0
- data/lib/selenium/webdriver/devtools/storage.rb +95 -0
- data/lib/selenium/webdriver/devtools/system_info.rb +50 -0
- data/lib/selenium/webdriver/devtools/target.rb +141 -0
- data/lib/selenium/webdriver/devtools/tethering.rb +55 -0
- data/lib/selenium/webdriver/devtools/tracing.rb +76 -0
- data/lib/selenium/webdriver/devtools/web_audio.rb +70 -0
- data/lib/selenium/webdriver/devtools/web_authn.rb +94 -0
- data/lib/selenium/webdriver/edge_chrome/bridge.rb +9 -2
- data/lib/selenium/webdriver/edge_chrome/driver.rb +4 -0
- data/lib/selenium/webdriver/edge_chrome/options.rb +2 -0
- data/lib/selenium/webdriver/edge_html/options.rb +2 -9
- data/lib/selenium/webdriver/firefox/bridge.rb +1 -1
- data/lib/selenium/webdriver/firefox/driver.rb +4 -0
- data/lib/selenium/webdriver/firefox/options.rb +5 -10
- data/lib/selenium/webdriver/ie/options.rb +7 -10
- data/lib/selenium/webdriver/remote/bridge.rb +3 -13
- data/lib/selenium/webdriver/remote/capabilities.rb +11 -6
- data/lib/selenium/webdriver/safari/bridge.rb +1 -1
- data/lib/selenium/webdriver/safari/driver.rb +4 -0
- data/lib/selenium/webdriver/safari/options.rb +1 -8
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +77 -0
- data/lib/selenium/webdriver/support/color.rb +2 -2
- data/lib/selenium/webdriver/version.rb +1 -1
- data/selenium-webdriver.gemspec +2 -2
- metadata +53 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4dbf1d975d636f48a1f346ffdb79c19d612287f1f4b625e150ff586b290be49
|
4
|
+
data.tar.gz: 1835a0d9d692b3d158a596fc081b132984e458e372c7ab882b17a10bdfc48a81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d33d076a090456d98b7361f9d890ad97ca5771ef832f609a0145dcbc19a149602ff4cfceb71d882307954017ce971aa0f4197cd612add189770f0c9b4267aacf
|
7
|
+
data.tar.gz: c84c80cf18da2e301122a350df46db0fb35455e1c88738ffff7bb5b784c622a1bb2b63c68fffe885c65fd445133427ac1632562b02473f5fa76c5a02d8649db1
|
data/CHANGES
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
4.0.0.alpha6 (2020-05-28)
|
2
|
+
=========================
|
3
|
+
|
4
|
+
Chrome:
|
5
|
+
* Added DevTools classes and methods generated from the CDP specification.
|
6
|
+
It currently supports commands and events and provides Rubyish API:
|
7
|
+
driver.devtools.page.navigate(url: 'http://google.com')
|
8
|
+
driver.devtools.console.clear_messages
|
9
|
+
driver.devtools.page.enable
|
10
|
+
driver.devtools.page.on(:load_event_fired) do |params|
|
11
|
+
puts("Page loaded in #{params['timestamp']}")
|
12
|
+
end
|
13
|
+
Check https://chromedevtools.github.io/devtools-protocol/ for more information
|
14
|
+
about possible commands and events. Please note that this API is considered
|
15
|
+
to be experimental and may change any time before stable 4.0 release.
|
16
|
+
* Fixed an issue when passing :prompt_for_download (or similar snake_cased
|
17
|
+
symbols) in Options#prefs would be ignored by Chrome because Selenium
|
18
|
+
would internally convert it to camelCased format (:promptForDownload).
|
19
|
+
Now :prefs are left intact.
|
20
|
+
|
21
|
+
Edge:
|
22
|
+
* Fixed an issue when Driver#execute_cdp would not work for Chromium-based
|
23
|
+
Edge browser.
|
24
|
+
|
25
|
+
Ruby:
|
26
|
+
* Deprecated passing :desired_capabilities and :options to driver initialization
|
27
|
+
in favor of :capabilities. They now can be combined in an array to make
|
28
|
+
custom capabilities requirements:
|
29
|
+
caps = Selenium::WebDriver::Remote::Capabilities.chrome
|
30
|
+
opts = Selenium::WebDriver::Chrome::Options.new
|
31
|
+
Selenium::WebDriver.for(:remote, capabilities: :chrome)
|
32
|
+
Selenium::WebDriver.for(:remote, capabilities: caps)
|
33
|
+
Selenium::WebDriver.for(:remote, capabilities: opts)
|
34
|
+
Selenium::WebDriver.for(:remote, capabilities: [caps, opts])
|
35
|
+
* Deprecated passing Hash to :capabilities in favor of Remote::Capabilities object.
|
36
|
+
* Updated minimum require Ruby version to 2.5.
|
37
|
+
* Improved keyword arguments handling to avoid warnings in Ruby 2.7.
|
38
|
+
|
1
39
|
4.0.0.alpha5 (2020-03-18)
|
2
40
|
=========================
|
3
41
|
|
data/LICENSE
CHANGED
@@ -187,7 +187,7 @@
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
188
188
|
identification within third-party archives.
|
189
189
|
|
190
|
-
Copyright
|
190
|
+
Copyright 2020 Software Freedom Conservancy (SFC)
|
191
191
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
193
193
|
you may not use this file except in compliance with the License.
|
@@ -110,7 +110,7 @@ function jd(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4
|
|
110
110
|
function kd(a){return a.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,"")}function ld(a){var b=[];$c?md(a,b):nd(a,b);a=pa(b,kd);return kd(a.join("\n")).replace(/\xa0/g," ")}
|
111
111
|
function od(a,b,c){if(T(a,"BR"))b.push("");else{var d=T(a,"TD"),e=W(a,"display"),f=!d&&!(0<=na(pd,e)),g=k(a.previousElementSibling)?a.previousElementSibling:fb(a.previousSibling);g=g?W(g,"display"):"";var h=W(a,"float")||W(a,"cssFloat")||W(a,"styleFloat");!f||"run-in"==g&&"none"==h||/^[\s\xa0]*$/.test(b[b.length-1]||"")||b.push("");var n=hd(a),t=null,p=null;n&&(t=W(a,"white-space"),p=W(a,"text-transform"));r(a.childNodes,function(G){c(G,b,n,t,p)});a=b[b.length-1]||"";!d&&"table-cell"!=e||!a||wa(a)||
|
112
112
|
(b[b.length-1]+=" ");f&&"run-in"!=e&&!/^[\s\xa0]*$/.test(a)&&b.push("")}}function nd(a,b){od(a,b,function(c,d,e,f,g){3==c.nodeType&&e?qd(c,d,f,g):T(c)&&nd(c,d)})}var pd="inline inline-block inline-table none table-cell table-column table-column-group".split(" ");
|
113
|
-
function qd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(
|
113
|
+
function qd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.replace(/(\r\n|\r|\n)/g,"\n");if("normal"==c||"nowrap"==c)a=a.replace(/\n/g," ");a="pre"==c||"pre-wrap"==c?a.replace(/[ \f\t\v\u2028\u2029]/g,"\u00a0"):a.replace(/[ \f\t\v\u2028\u2029]+/g," ");"capitalize"==d?a=a.replace(/(^|\s|\b)(\S)/g,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";wa(c)&&0==a.lastIndexOf(" ",0)&&(a=a.substr(1));b.push(c+a)}
|
114
114
|
function gd(a){if(Oc){if("relative"==W(a,"position"))return 1;a=W(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return rd(a)}function rd(a){var b=1,c=W(a,"opacity");c&&(b=Number(c));(a=ad(a))&&(b*=rd(a));return b}
|
115
115
|
function sd(a,b,c,d,e){if(3==a.nodeType&&c)qd(a,b,d,e);else if(T(a))if(T(a,"CONTENT")||T(a,"SLOT")){for(var f=a;f.parentNode;)f=f.parentNode;f instanceof ShadowRoot?(a=T(a,"CONTENT")?a.getDistributedNodes():a.assignedNodes(),r(a,function(g){sd(g,b,c,d,e)})):md(a,b)}else if(T(a,"SHADOW")){for(f=a;f.parentNode;)f=f.parentNode;if(f instanceof ShadowRoot&&(a=f))for(a=a.olderShadowRoot;a;)r(a.childNodes,function(g){sd(g,b,c,d,e)}),a=a.olderShadowRoot}else md(a,b)}
|
116
116
|
function md(a,b){a.shadowRoot&&r(a.shadowRoot.childNodes,function(c){sd(c,b,!0,null,null)});od(a,b,function(c,d,e,f,g){var h=null;1==c.nodeType?h=c:3==c.nodeType&&(h=c);null!=h&&(null!=h.assignedSlot||h.getDestinationInsertionPoints&&0<h.getDestinationInsertionPoints().length)||sd(c,d,e,f,g)})};var td={A:function(a,b){return!(!a.querySelectorAll||!a.querySelector)&&!/^\d.*/.test(b)},o:function(a,b){var c=db(b),d=l(a)?c.a.getElementById(a):a;return d?Wc(d,"id")==a&&b!=d&&gb(b,d)?d:ta(lb(c,"*"),function(e){return Wc(e,"id")==a&&b!=e&&gb(b,e)}):null},j:function(a,b){if(!a)return[];if(td.A(b,a))try{return b.querySelectorAll("#"+td.R(a))}catch(c){return[]}b=lb(db(b),"*",null,b);return oa(b,function(c){return Wc(c,"id")==a})},R:function(a){return a.replace(/([\s'"\\#.:;,!?+<>=~*^$|%&@`{}\-\/\[\]\(\)])/g,
|
@@ -20,7 +20,7 @@
|
|
20
20
|
module Selenium
|
21
21
|
module WebDriver
|
22
22
|
module Chrome
|
23
|
-
|
23
|
+
class Bridge < WebDriver::Remote::Bridge
|
24
24
|
|
25
25
|
COMMANDS = {
|
26
26
|
get_network_conditions: [:get, 'session/:session_id/chromium/network_conditions'],
|
@@ -55,11 +55,9 @@ module Selenium
|
|
55
55
|
data = execute :get_log, {}, {type: type.to_s}
|
56
56
|
|
57
57
|
Array(data).map do |l|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
next
|
62
|
-
end
|
58
|
+
LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
|
59
|
+
rescue KeyError
|
60
|
+
next
|
63
61
|
end
|
64
62
|
end
|
65
63
|
end # Bridge
|
@@ -24,6 +24,7 @@ module Selenium
|
|
24
24
|
attr_accessor :profile
|
25
25
|
|
26
26
|
KEY = 'goog:chromeOptions'
|
27
|
+
BROWSER = 'chrome'
|
27
28
|
|
28
29
|
# see: http://chromedriver.chromium.org/capabilities
|
29
30
|
CAPABILITIES = {args: 'args',
|
@@ -74,7 +75,7 @@ module Selenium
|
|
74
75
|
#
|
75
76
|
|
76
77
|
def initialize(profile: nil, encoded_extensions: nil, **opts)
|
77
|
-
super(opts)
|
78
|
+
super(**opts)
|
78
79
|
|
79
80
|
@profile = profile
|
80
81
|
@options[:encoded_extensions] = encoded_extensions if encoded_extensions
|
@@ -179,30 +180,23 @@ module Selenium
|
|
179
180
|
@options[:emulation] = opts
|
180
181
|
end
|
181
182
|
|
182
|
-
|
183
|
-
# @api private
|
184
|
-
#
|
185
|
-
|
186
|
-
def as_json(*)
|
187
|
-
options = super
|
188
|
-
|
189
|
-
if @profile
|
190
|
-
options['args'] ||= []
|
191
|
-
options['args'] << "--user-data-dir=#{@profile[:directory]}"
|
192
|
-
end
|
183
|
+
private
|
193
184
|
|
185
|
+
def process_browser_options(browser_options)
|
186
|
+
options = browser_options[KEY]
|
194
187
|
options['binary'] ||= binary_path if binary_path
|
195
|
-
|
196
|
-
|
188
|
+
(options['args'] || []) << "--user-data-dir=#{@profile[:directory]}" if @profile
|
189
|
+
merge_extensions(options)
|
190
|
+
end
|
197
191
|
|
198
|
-
|
199
|
-
|
192
|
+
def merge_extensions(browser_options)
|
193
|
+
extensions = browser_options['extensions'] || []
|
194
|
+
encoded_extensions = browser_options.delete(:encoded_extensions) || []
|
200
195
|
|
201
|
-
|
196
|
+
browser_options['extensions'] = extensions.map(&method(:encode_extension)) + encoded_extensions
|
197
|
+
browser_options.delete('extensions') if browser_options['extensions'].empty?
|
202
198
|
end
|
203
199
|
|
204
|
-
private
|
205
|
-
|
206
200
|
def binary_path
|
207
201
|
Chrome.path
|
208
202
|
end
|
@@ -215,6 +209,17 @@ module Selenium
|
|
215
209
|
raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
|
216
210
|
raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
|
217
211
|
end
|
212
|
+
|
213
|
+
def generate_as_json(value, camelize_keys: true)
|
214
|
+
if value.is_a?(Hash)
|
215
|
+
value.each_with_object({}) do |(key, val), hash|
|
216
|
+
key = convert_json_key(key, camelize: camelize_keys)
|
217
|
+
hash[key] = generate_as_json(val, camelize_keys: key != 'prefs')
|
218
|
+
end
|
219
|
+
else
|
220
|
+
super
|
221
|
+
end
|
222
|
+
end
|
218
223
|
end # Options
|
219
224
|
end # Chrome
|
220
225
|
end # WebDriver
|
@@ -23,6 +23,7 @@ require 'selenium/webdriver/common/proxy'
|
|
23
23
|
require 'selenium/webdriver/common/log_entry'
|
24
24
|
require 'selenium/webdriver/common/file_reaper'
|
25
25
|
require 'selenium/webdriver/common/service'
|
26
|
+
require 'selenium/webdriver/common/service_manager'
|
26
27
|
require 'selenium/webdriver/common/socket_lock'
|
27
28
|
require 'selenium/webdriver/common/socket_poller'
|
28
29
|
require 'selenium/webdriver/common/port_prober'
|
@@ -43,21 +43,21 @@ module Selenium
|
|
43
43
|
def for(browser, opts = {})
|
44
44
|
case browser
|
45
45
|
when :chrome
|
46
|
-
Chrome::Driver.new(opts)
|
46
|
+
Chrome::Driver.new(**opts)
|
47
47
|
when :internet_explorer, :ie
|
48
|
-
IE::Driver.new(opts)
|
48
|
+
IE::Driver.new(**opts)
|
49
49
|
when :safari
|
50
|
-
Safari::Driver.new(opts)
|
50
|
+
Safari::Driver.new(**opts)
|
51
51
|
when :firefox, :ff
|
52
|
-
Firefox::Driver.new(opts)
|
52
|
+
Firefox::Driver.new(**opts)
|
53
53
|
when :edge
|
54
|
-
Edge::Driver.new(opts)
|
54
|
+
Edge::Driver.new(**opts)
|
55
55
|
when :edge_chrome
|
56
|
-
EdgeChrome::Driver.new(opts)
|
56
|
+
EdgeChrome::Driver.new(**opts)
|
57
57
|
when :edge_html
|
58
|
-
EdgeHtml::Driver.new(opts)
|
58
|
+
EdgeHtml::Driver.new(**opts)
|
59
59
|
when :remote
|
60
|
-
Remote::Driver.new(opts)
|
60
|
+
Remote::Driver.new(**opts)
|
61
61
|
else
|
62
62
|
raise ArgumentError, "unknown driver: #{browser.inspect}"
|
63
63
|
end
|
@@ -73,7 +73,7 @@ module Selenium
|
|
73
73
|
|
74
74
|
def initialize(bridge: nil, listener: nil, **opts)
|
75
75
|
@service = nil
|
76
|
-
bridge ||= create_bridge(opts)
|
76
|
+
bridge ||= create_bridge(**opts)
|
77
77
|
@bridge = listener ? Support::EventFiringBridge.new(bridge, listener) : bridge
|
78
78
|
end
|
79
79
|
|
@@ -296,36 +296,68 @@ module Selenium
|
|
296
296
|
|
297
297
|
def create_bridge(**opts)
|
298
298
|
opts[:url] ||= service_url(opts)
|
299
|
+
caps = opts.delete(:capabilities)
|
300
|
+
# Note: This is deprecated
|
301
|
+
cap_array = caps.is_a?(Hash) ? [caps] : Array(caps)
|
302
|
+
|
303
|
+
desired_capabilities = opts.delete(:desired_capabilities)
|
304
|
+
if desired_capabilities
|
305
|
+
WebDriver.logger.deprecate(':desired_capabilities as a parameter for driver initialization',
|
306
|
+
':capabilities with an Array value of capabilities/options if necessary',
|
307
|
+
id: :desired_capabilities)
|
308
|
+
desired_capabilities = Remote::Capabilities.new(desired_capabilities) if desired_capabilities.is_a?(Hash)
|
309
|
+
cap_array << desired_capabilities
|
310
|
+
end
|
299
311
|
|
300
|
-
desired_capabilities = opts.delete(:desired_capabilities) || Remote::Capabilities.send(browser || :new)
|
301
312
|
options = opts.delete(:options)
|
313
|
+
if options
|
314
|
+
WebDriver.logger.deprecate(':options as a parameter for driver initialization',
|
315
|
+
':capabilities with an Array of value capabilities/options if necessary',
|
316
|
+
id: :browser_options)
|
317
|
+
cap_array << options
|
318
|
+
end
|
302
319
|
|
303
|
-
|
304
|
-
raise ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
320
|
+
capabilities = generate_capabilities(cap_array)
|
305
321
|
|
306
|
-
|
322
|
+
bridge_opts = {http_client: opts.delete(:http_client), url: opts.delete(:url)}
|
323
|
+
raise ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
|
307
324
|
|
308
|
-
|
309
|
-
bridge.extend Object.const_get("#{namespacing[0, namespacing.length - 1].join('::')}::Bridge")
|
310
|
-
end
|
325
|
+
bridge = (respond_to?(:bridge_class) ? bridge_class : Remote::Bridge).new(**bridge_opts)
|
311
326
|
|
312
|
-
bridge.create_session(
|
327
|
+
bridge.create_session(capabilities)
|
313
328
|
bridge
|
314
329
|
end
|
315
330
|
|
331
|
+
def generate_capabilities(cap_array)
|
332
|
+
cap_array.map { |cap|
|
333
|
+
if cap.is_a? Symbol
|
334
|
+
cap = Remote::Capabilities.send(cap)
|
335
|
+
elsif cap.is_a? Hash
|
336
|
+
WebDriver.logger.deprecate("passing a Hash value to :capabilities",
|
337
|
+
'Capabilities instance initialized with the Hash, or build values with Options class',
|
338
|
+
id: :capabilities_hash)
|
339
|
+
cap = Remote::Capabilities.new(cap)
|
340
|
+
elsif !cap.respond_to? :as_json
|
341
|
+
msg = ":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not"
|
342
|
+
raise ArgumentError, msg
|
343
|
+
end
|
344
|
+
cap&.as_json
|
345
|
+
}.inject(:merge) || Remote::Capabilities.send(browser || :new)
|
346
|
+
end
|
347
|
+
|
316
348
|
def service_url(opts)
|
317
|
-
|
349
|
+
service_config = opts.delete(:service)
|
318
350
|
%i[driver_opts driver_path port].each do |key|
|
319
351
|
next unless opts.key? key
|
320
352
|
|
321
353
|
WebDriver.logger.deprecate(":#{key}", ':service with an instance of Selenium::WebDriver::Service',
|
322
354
|
id: "service_#{key}".to_sym)
|
323
355
|
end
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
@service.
|
356
|
+
service_config ||= Service.send(browser,
|
357
|
+
args: opts.delete(:driver_opts),
|
358
|
+
path: opts.delete(:driver_path),
|
359
|
+
port: opts.delete(:port))
|
360
|
+
@service = service_config.launch
|
329
361
|
@service.uri
|
330
362
|
end
|
331
363
|
end # Driver
|
@@ -36,6 +36,7 @@ module Selenium
|
|
36
36
|
# @option opts [String] :value A value
|
37
37
|
# @option opts [String] :path ('/') A path
|
38
38
|
# @option opts [String] :secure (false) A boolean
|
39
|
+
# @option opts [String] :same_site (Strict or Lax) currently supported only in chrome 80+ versions
|
39
40
|
# @option opts [Time,DateTime,Numeric,nil] :expires (nil) Expiry date, either as a Time, DateTime, or seconds since epoch.
|
40
41
|
#
|
41
42
|
# @raise [ArgumentError] if :name or :value is not specified
|
@@ -48,6 +49,9 @@ module Selenium
|
|
48
49
|
opts[:path] ||= '/'
|
49
50
|
opts[:secure] ||= false
|
50
51
|
|
52
|
+
same_site = opts.delete(:same_site)
|
53
|
+
opts[:sameSite] = same_site if same_site
|
54
|
+
|
51
55
|
obj = opts.delete(:expires)
|
52
56
|
opts[:expiry] = seconds_from(obj).to_i if obj
|
53
57
|
|
@@ -169,6 +173,7 @@ module Selenium
|
|
169
173
|
path: cookie['path'],
|
170
174
|
domain: cookie['domain'] && strip_port(cookie['domain']),
|
171
175
|
expires: cookie['expiry'] && datetime_at(cookie['expiry']),
|
176
|
+
same_site: cookie['sameSite'],
|
172
177
|
secure: cookie['secure']
|
173
178
|
}
|
174
179
|
end
|
@@ -20,6 +20,19 @@
|
|
20
20
|
module Selenium
|
21
21
|
module WebDriver
|
22
22
|
class Options
|
23
|
+
W3C_OPTIONS = %i[browser_name browser_version platform_name accept_insecure_certs page_load_strategy proxy
|
24
|
+
set_window_rect timeouts unhandled_prompt_behavior strict_file_interactability].freeze
|
25
|
+
|
26
|
+
W3C_OPTIONS.each do |key|
|
27
|
+
define_method key do
|
28
|
+
@options[key]
|
29
|
+
end
|
30
|
+
|
31
|
+
define_method "#{key}=" do |value|
|
32
|
+
@options[key] = value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
23
36
|
attr_accessor :options
|
24
37
|
|
25
38
|
def initialize(options: nil, **opts)
|
@@ -31,6 +44,7 @@ module Selenium
|
|
31
44
|
else
|
32
45
|
opts
|
33
46
|
end
|
47
|
+
@options[:browser_name] = self.class::BROWSER
|
34
48
|
end
|
35
49
|
|
36
50
|
#
|
@@ -55,22 +69,30 @@ module Selenium
|
|
55
69
|
def as_json(*)
|
56
70
|
options = @options.dup
|
57
71
|
|
58
|
-
|
72
|
+
w3c_options = options.select { |key, _val| W3C_OPTIONS.include?(key) }
|
73
|
+
options.delete_if { |key, _val| W3C_OPTIONS.include?(key) }
|
74
|
+
|
75
|
+
self.class::CAPABILITIES.each do |capability_alias, capability_name|
|
59
76
|
capability_value = options.delete(capability_alias)
|
60
|
-
|
77
|
+
options[capability_name] = capability_value unless capability_value.nil?
|
61
78
|
end
|
62
|
-
|
79
|
+
browser_options = defined?(self.class::KEY) ? {self.class::KEY => options} : options
|
80
|
+
|
81
|
+
process_browser_options(browser_options) if private_methods(false).include?(:process_browser_options)
|
82
|
+
generate_as_json(w3c_options.merge(browser_options))
|
63
83
|
end
|
64
84
|
|
65
85
|
private
|
66
86
|
|
67
|
-
def generate_as_json(value)
|
87
|
+
def generate_as_json(value, camelize_keys: true)
|
68
88
|
if value.respond_to?(:as_json)
|
69
89
|
value.as_json
|
70
90
|
elsif value.is_a?(Hash)
|
71
|
-
value.each_with_object({})
|
91
|
+
value.each_with_object({}) do |(key, val), hash|
|
92
|
+
hash[convert_json_key(key, camelize: camelize_keys)] = generate_as_json(val, camelize_keys: camelize_keys)
|
93
|
+
end
|
72
94
|
elsif value.is_a?(Array)
|
73
|
-
value.map(
|
95
|
+
value.map { |val| generate_as_json(val, camelize_keys: camelize_keys) }
|
74
96
|
elsif value.is_a?(Symbol)
|
75
97
|
value.to_s
|
76
98
|
else
|
@@ -78,15 +100,16 @@ module Selenium
|
|
78
100
|
end
|
79
101
|
end
|
80
102
|
|
81
|
-
def convert_json_key(key)
|
82
|
-
key =
|
103
|
+
def convert_json_key(key, camelize: true)
|
104
|
+
key = key.to_s if key.is_a?(Symbol)
|
105
|
+
key = camel_case(key) if camelize
|
83
106
|
return key if key.is_a?(String)
|
84
107
|
|
85
108
|
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}"
|
86
109
|
end
|
87
110
|
|
88
111
|
def camel_case(str)
|
89
|
-
str.
|
112
|
+
str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
|
90
113
|
end
|
91
114
|
end # Options
|
92
115
|
end # WebDriver
|
@@ -32,12 +32,10 @@ module Selenium
|
|
32
32
|
|
33
33
|
def self.free?(port)
|
34
34
|
Platform.interfaces.each do |host|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# ignored - some machines appear unable to bind to some of their interfaces
|
40
|
-
end
|
35
|
+
TCPServer.new(host, port).close
|
36
|
+
rescue *IGNORED_ERRORS => e
|
37
|
+
WebDriver.logger.debug("port prober could not bind to #{host}:#{port} (#{e.message})")
|
38
|
+
# ignored - some machines appear unable to bind to some of their interfaces
|
41
39
|
end
|
42
40
|
|
43
41
|
true
|