selenium-webdriver 4.0.0 → 4.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c06a2d4e78b10cc31c89baf7ac72014ca43bf4425b0825ede55d942ef90ae47a
4
- data.tar.gz: f3d005b5469d38ab07c6a35a032c65b69f97c54ecbd648bbaf5217f43e1a9457
3
+ metadata.gz: 40e4bef1fdee7ae817c56466ec231be400d677d56a8c8f46b797c6b3eba28de9
4
+ data.tar.gz: a9c1af31f12db6096f06c2a89e487e40ea2bb53b8f6e46e5f77a3046f149bb34
5
5
  SHA512:
6
- metadata.gz: dba83257a6a44f2a68fdea7f7c7ae30b2d27802407d22b42bd4262b3ba8a71be00b90de4a1850428a208392ce6ecc63db20b30af8b2b14d910d5a7c20be9c32e
7
- data.tar.gz: f9bf4b3098e9e9b5487c766e33ccdebda51f4854f3aaf896af12b26875644ab691530700af80d84fc15b73369e27742568aba375800975da9c81fc8e46beeb9d
6
+ metadata.gz: b5325d0fe9f5fdb721ed4a6daa1384d7876dc7a072dd52f46c73d76b1614434c123fff2b4a9d7de01538968eddfbad57f2e1a87f4dce0e560a850dcf21988840
7
+ data.tar.gz: 3b345ac66d051c32267d1c4ef9b2dd70aea36e2c4e5bb35ce30197d748effca8fed460824d1961ad5a39340358fc9be3f200708a38557e5e878b09be1b0d61c0
data/CHANGES CHANGED
@@ -1,3 +1,42 @@
1
+ 4.1.0 (2021-11-18)
2
+ =========================
3
+
4
+ DevTools:
5
+ * Released selenium-devtools 0.95.0 (supports CDP v85, v93, v94, v95)
6
+ * Released selenium-devtools 0.96.0 (supports CDP v85, v94, v95, v96)
7
+ * Added support for secure websockets (#10017)
8
+
9
+ Ruby:
10
+ * Execute Script supports ShadowRoots (#10019)
11
+ * Fixed bug preventing zipping temp files on Windows (#9987)
12
+ * Sang Pumpkin Carol (thanks Jari!)
13
+
14
+ 4.0.3 (2021-10-20)
15
+ =========================
16
+
17
+ Firefox:
18
+ * Fixed bug avoiding camel casing prefs (#9944 thanks @glaszig)
19
+
20
+ Ruby:
21
+ * Fixed bug in Select class for finding by index (#9945)
22
+
23
+ Remote:
24
+ * Fixed bug preventing sending keys with an empty value
25
+
26
+ 4.0.2 (2021-10-19)
27
+ =========================
28
+
29
+ Server:
30
+ * Fixed bug in new download code.
31
+
32
+ 4.0.1 (2021-10-19)
33
+ =========================
34
+
35
+ Server:
36
+ * Fixed download by pointing to new storage location.
37
+ - Only supports Selenium 4 versions
38
+ * Added default value for Server::get and Server::download to use the latest server version
39
+
1
40
  4.0.0 (2021-10-13)
2
41
  =========================
3
42
 
@@ -57,45 +57,39 @@ module Selenium
57
57
 
58
58
  CL_RESET = WebDriver::Platform.windows? ? '' : "\r\e[0K"
59
59
 
60
- def self.get(required_version, opts = {})
61
- new(download(required_version), opts)
62
- end
60
+ class << self
61
+ #
62
+ # Download the given version of the selenium-server jar and return instance
63
+ #
64
+ # @param [String, Symbol] required_version X.Y.Z defaults to ':latest'
65
+ # @param [Hash] opts
66
+ # @return [Selenium::Server]
67
+ #
63
68
 
64
- #
65
- # Download the given version of the selenium-server-standalone jar.
66
- #
69
+ def get(required_version = :latest, opts = {})
70
+ new(download(required_version), opts)
71
+ end
67
72
 
68
- class << self
69
- def download(required_version)
73
+ #
74
+ # Download the given version of the selenium-server jar and return location
75
+ #
76
+ # @param [String, Symbol] required_version X.Y.Z defaults to ':latest'
77
+ # @return [String] location of downloaded file
78
+ #
79
+
80
+ def download(required_version = :latest)
70
81
  required_version = latest if required_version == :latest
71
- download_file_name = "selenium-server-standalone-#{required_version}.jar"
82
+ download_file_name = "selenium-server-#{required_version}.jar"
72
83
 
73
84
  return download_file_name if File.exist? download_file_name
74
85
 
75
86
  begin
76
- File.open(download_file_name, 'wb') do |destination|
77
- net_http_start('selenium-release.storage.googleapis.com') do |http|
78
- resp = http.request_get("/#{required_version[/(\d+\.\d+)\./, 1]}/#{download_file_name}") do |response|
79
- total = response.content_length
80
- progress = 0
81
- segment_count = 0
82
-
83
- response.read_body do |segment|
84
- progress += segment.length
85
- segment_count += 1
87
+ server = 'https://github.com/seleniumhq/selenium/releases/download'
88
+ released = Net::HTTP.get_response(URI.parse("#{server}/selenium-#{required_version}/#{download_file_name}"))
89
+ redirected = URI.parse released.header['location']
86
90
 
87
- if (segment_count % 15).zero?
88
- percent = progress.fdiv(total) * 100
89
- print "#{CL_RESET}Downloading #{download_file_name}: #{percent.to_i}% (#{progress} / #{total})"
90
- segment_count = 0
91
- end
92
-
93
- destination.write(segment)
94
- end
95
- end
96
-
97
- raise Error, "#{resp.code} for #{download_file_name}" unless resp.is_a? Net::HTTPSuccess
98
- end
91
+ File.open(download_file_name, 'wb') do |destination|
92
+ download_server(redirected, destination)
99
93
  end
100
94
  rescue StandardError
101
95
  FileUtils.rm download_file_name if File.exist? download_file_name
@@ -106,30 +100,57 @@ module Selenium
106
100
  end
107
101
 
108
102
  #
109
- # Ask Google Code what the latest selenium-server-standalone version is.
103
+ # Ask GitHub what the latest selenium-server version is.
110
104
  #
111
105
 
112
106
  def latest
113
- require 'rexml/document'
114
- net_http_start('selenium-release.storage.googleapis.com') do |http|
115
- versions = REXML::Document.new(http.get('/').body).root.get_elements('//Contents/Key').map do |e|
116
- e.text[/selenium-server-standalone-(\d+\.\d+\.\d+)\.jar/, 1]
107
+ @latest ||= begin
108
+ net_http_start('api.github.com') do |http|
109
+ json = http.get('/repos/seleniumhq/selenium/releases').body
110
+ all_assets = JSON.parse(json).map { |release| release['assets'] }.flatten
111
+ server_assets = all_assets.map { |asset| asset['name'][/selenium-server-(\d+\.\d+\.\d+)\.jar/, 1] }.compact
112
+ server_assets.map { |version| Gem::Version.new(version) }.max.version
117
113
  end
118
-
119
- versions.compact.map { |version| Gem::Version.new(version) }.max.version
120
114
  end
121
115
  end
122
116
 
117
+ # @api private
118
+
123
119
  def net_http_start(address, &block)
124
120
  http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
125
-
126
121
  if http_proxy
127
122
  http_proxy = "http://#{http_proxy}" unless http_proxy.start_with?('http://')
128
123
  uri = URI.parse(http_proxy)
129
124
 
130
125
  Net::HTTP.start(address, nil, uri.host, uri.port, &block)
131
126
  else
132
- Net::HTTP.start(address, &block)
127
+ Net::HTTP.start(address, use_ssl: true, &block)
128
+ end
129
+ end
130
+
131
+ def download_server(uri, destination)
132
+ net_http_start('github-releases.githubusercontent.com') do |http|
133
+ request = Net::HTTP::Get.new uri
134
+ resp = http.request(request) do |response|
135
+ total = response.content_length
136
+ progress = 0
137
+ segment_count = 0
138
+
139
+ response.read_body do |segment|
140
+ progress += segment.length
141
+ segment_count += 1
142
+
143
+ if (segment_count % 15).zero?
144
+ percent = progress.fdiv(total) * 100
145
+ print "#{CL_RESET}Downloading #{destination.path}: #{percent.to_i}% (#{progress} / #{total})"
146
+ segment_count = 0
147
+ end
148
+
149
+ destination.write(segment)
150
+ end
151
+ end
152
+
153
+ raise Error, "#{resp.code} for #{destination.path}" unless resp.is_a? Net::HTTPSuccess
133
154
  end
134
155
  end
135
156
  end
@@ -200,10 +221,6 @@ module Selenium
200
221
 
201
222
  private
202
223
 
203
- def selenium4?
204
- @jar.match?(/[^.]4\./) || @jar.include?('deploy')
205
- end
206
-
207
224
  def stop_process
208
225
  return unless @process.alive?
209
226
 
@@ -222,10 +239,7 @@ module Selenium
222
239
  @process ||= begin
223
240
  # extract any additional_args that start with -D as options
224
241
  properties = @additional_args.dup - @additional_args.delete_if { |arg| arg[/^-D/] }
225
- args = ['-jar', @jar]
226
- args << @role if selenium4?
227
- args << (selenium4? ? '--port' : '-port')
228
- args << @port.to_s
242
+ args = ['-jar', @jar, @role, '--port', @port.to_s]
229
243
  server_command = ['java'] + properties + args + @additional_args
230
244
  cp = ChildProcess.build(*server_command)
231
245
  WebDriver.logger.debug("Executing Process #{server_command}")
@@ -108,8 +108,8 @@ function gd(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4
108
108
  function hd(a){return a.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,"")}function id(a){var b=[];Yc?jd(a,b):kd(a,b);a=qa(b,hd);return hd(a.join("\n")).replace(/\xa0/g," ")}
109
109
  function ld(a,b,c){if(S(a,"BR"))b.push("");else{var d=S(a,"TD"),e=V(a,"display"),f=!d&&!(0<=oa(md,e)),g=void 0!==a.previousElementSibling?a.previousElementSibling:gb(a.previousSibling);g=g?V(g,"display"):"";var h=V(a,"float")||V(a,"cssFloat")||V(a,"styleFloat");!f||"run-in"==g&&"none"==h||/^[\s\xa0]*$/.test(b[b.length-1]||"")||b.push("");var n=ed(a),u=null,p=null;n&&(u=V(a,"white-space"),p=V(a,"text-transform"));l(a.childNodes,function(G){c(G,b,n,u,p)});a=b[b.length-1]||"";!d&&"table-cell"!=e||!a||
110
110
  za(a)||(b[b.length-1]+=" ");f&&"run-in"!=e&&!/^[\s\xa0]*$/.test(a)&&b.push("")}}function kd(a,b){ld(a,b,function(c,d,e,f,g){3==c.nodeType&&e?nd(c,d,f,g):S(c)&&kd(c,d)})}var md="inline inline-block inline-table none table-cell table-column table-column-group".split(" ");
111
- function nd(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(/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";za(c)&&0==a.lastIndexOf(" ",0)&&(a=a.substr(1));
112
- b.push(c+a)}function dd(a){if(Mc){if("relative"==V(a,"position"))return 1;a=V(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return od(a)}function od(a){var b=1,c=V(a,"opacity");c&&(b=Number(c));(a=Zc(a))&&(b*=od(a));return b}
111
+ function nd(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(t?/(^|\s|\b)(\S)/g:/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(e,f,g){return f+g.toUpperCase()}):"uppercase"==d?a=a.toUpperCase():"lowercase"==d&&(a=a.toLowerCase());c=b.pop()||"";za(c)&&0==a.lastIndexOf(" ",
112
+ 0)&&(a=a.substr(1));b.push(c+a)}function dd(a){if(Mc){if("relative"==V(a,"position"))return 1;a=V(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return od(a)}function od(a){var b=1,c=V(a,"opacity");c&&(b=Number(c));(a=Zc(a))&&(b*=od(a));return b}
113
113
  function pd(a,b,c,d,e){if(3==a.nodeType&&c)nd(a,b,d,e);else if(S(a))if(S(a,"CONTENT")||S(a,"SLOT")){for(var f=a;f.parentNode;)f=f.parentNode;f instanceof ShadowRoot?(a=S(a,"CONTENT")?a.getDistributedNodes():a.assignedNodes(),l(a,function(g){pd(g,b,c,d,e)})):jd(a,b)}else if(S(a,"SHADOW")){for(f=a;f.parentNode;)f=f.parentNode;if(f instanceof ShadowRoot&&(a=f))for(a=a.olderShadowRoot;a;)l(a.childNodes,function(g){pd(g,b,c,d,e)}),a=a.olderShadowRoot}else jd(a,b)}
114
114
  function jd(a,b){a.shadowRoot&&l(a.shadowRoot.childNodes,function(c){pd(c,b,!0,null,null)});ld(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)||pd(c,d,e,f,g)})};var qd={C:function(a,b){return!(!a.querySelectorAll||!a.querySelector)&&!/^\d.*/.test(b)},o:function(a,b){var c=eb(b),d="string"===typeof a?c.a.getElementById(a):a;return d?Uc(d,"id")==a&&b!=d&&hb(b,d)?d:ua(mb(c,"*"),function(e){return Uc(e,"id")==a&&b!=e&&hb(b,e)}):null},j:function(a,b){if(!a)return[];if(qd.C(b,a))try{return b.querySelectorAll("#"+qd.T(a))}catch(c){return[]}b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"id")==a})},T:function(a){return a.replace(/([\s'"\\#.:;,!?+<>=~*^$|%&@`{}\-\/\[\]\(\)])/g,
115
115
  "\\$1")}};var Y={},rd={};Y.N=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return ua(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.K=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return pa(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.o=function(a,b){return Y.N(a,b,!1)};Y.j=function(a,b){return Y.K(a,b,!1)};rd.o=function(a,b){return Y.N(a,b,!0)};
@@ -50,7 +50,7 @@ module Selenium
50
50
  #
51
51
  # @example
52
52
  # options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])
53
- # driver = Selenium::WebDriver.for(:chrome, options: options)
53
+ # driver = Selenium::WebDriver.for(:chrome, capabilities: options)
54
54
  #
55
55
  # @param [Profile] :profile An instance of a Chrome::Profile Class
56
56
  # @param [Array] :encoded_extensions List of extensions that do not need to be Base64 encoded
@@ -179,8 +179,6 @@ module Selenium
179
179
  def camel_case(str)
180
180
  str.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
181
181
  end
182
- end
183
-
184
- # Options
182
+ end # Options
185
183
  end # WebDriver
186
184
  end # Selenium
@@ -73,16 +73,10 @@ module Selenium
73
73
  def from_json(json)
74
74
  data = decoded(json)
75
75
 
76
- # can't use Tempfile here since it doesn't support File::BINARY mode on 1.8
77
- # can't use Dir.mktmpdir(&blk) because of http://jira.codehaus.org/browse/JRUBY-4082
78
- tmp_dir = Dir.mktmpdir
79
- begin
80
- zip_path = File.join(tmp_dir, "webdriver-profile-duplicate-#{json.hash}.zip")
76
+ Tempfile.create do |zip_path|
81
77
  File.open(zip_path, 'wb') { |zip_file| zip_file << Base64.decode64(data) }
82
78
 
83
79
  new Zipper.unzip(zip_path)
84
- ensure
85
- FileUtils.rm_rf tmp_dir
86
80
  end
87
81
  end
88
82
  end # ClassMethods
@@ -72,16 +72,10 @@ module Selenium
72
72
  private
73
73
 
74
74
  def with_tmp_zip(&blk)
75
- # can't use Tempfile here since it doesn't support File::BINARY mode on 1.8
76
- # can't use Dir.mktmpdir(&blk) because of http://jira.codehaus.org/browse/JRUBY-4082
77
- tmp_dir = Dir.mktmpdir
78
- zip_path = File.join(tmp_dir, 'webdriver-zip')
79
-
80
- begin
75
+ # Don't use Tempfile since it lacks rb_file_s_rename permission on Windows.
76
+ Dir.mktmpdir do |tmp_dir|
77
+ zip_path = File.join(tmp_dir, 'webdriver-zip')
81
78
  Zip::File.open(zip_path, Zip::File::CREATE, &blk)
82
- ensure
83
- FileUtils.rm_rf tmp_dir
84
- FileUtils.rm_rf zip_path
85
79
  end
86
80
  end
87
81
 
@@ -161,7 +161,18 @@ module Selenium
161
161
  end
162
162
 
163
163
  def socket
164
- @socket ||= TCPSocket.new(ws.host, ws.port)
164
+ @socket ||= begin
165
+ if URI(@url).scheme == 'wss'
166
+ socket = TCPSocket.new(ws.host, ws.port)
167
+ socket = OpenSSL::SSL::SSLSocket.new(socket, OpenSSL::SSL::SSLContext.new)
168
+ socket.sync_close = true
169
+ socket.connect
170
+
171
+ socket
172
+ else
173
+ TCPSocket.new(ws.host, ws.port)
174
+ end
175
+ end
165
176
  end
166
177
 
167
178
  def ws
@@ -44,7 +44,7 @@ module Selenium
44
44
  #
45
45
  # @example
46
46
  # options = Selenium::WebDriver::Firefox::Options.new(args: ['--host=127.0.0.1'])
47
- # driver = Selenium::WebDriver.for :firefox, options: options
47
+ # driver = Selenium::WebDriver.for :firefox, capabilities: options
48
48
  #
49
49
  # @param [Hash] opts the pre-defined options to create the Firefox::Options with
50
50
  # @option opts [String] :binary Path to the Firefox executable to use
@@ -175,7 +175,7 @@ module Selenium
175
175
  end
176
176
 
177
177
  def camelize?(key)
178
- key != :prefs
178
+ key != "prefs"
179
179
  end
180
180
  end # Options
181
181
  end # Firefox
@@ -52,12 +52,12 @@ module Selenium
52
52
  #
53
53
  # @example
54
54
  # options = Selenium::WebDriver::IE::Options.new(args: ['--host=127.0.0.1'])
55
- # driver = Selenium::WebDriver.for(:ie, options: options)
55
+ # driver = Selenium::WebDriver.for(:ie, capabilities: options)
56
56
  #
57
57
  # @example
58
58
  # options = Selenium::WebDriver::IE::Options.new
59
59
  # options.element_scroll_behavior = Selenium::WebDriver::IE::Options::SCROLL_BOTTOM
60
- # driver = Selenium::WebDriver.for(:ie, options: options)
60
+ # driver = Selenium::WebDriver.for(:ie, capabilities: options)
61
61
  #
62
62
  # @param [Hash] opts the pre-defined options
63
63
  # @option opts [Array<String>] args
@@ -404,7 +404,7 @@ module Selenium
404
404
  def send_keys_to_element(element, keys)
405
405
  # TODO: rework file detectors before Selenium 4.0
406
406
  if @file_detector
407
- local_files = keys.first.split("\n").map { |key| @file_detector.call(Array(key)) }.compact
407
+ local_files = keys.first&.split("\n")&.map { |key| @file_detector.call(Array(key)) }&.compact
408
408
  if local_files.any?
409
409
  keys = local_files.map { |local_file| upload(local_file) }
410
410
  keys = Array(keys.join("\n"))
@@ -604,6 +604,9 @@ module Selenium
604
604
  element_id = element_id_from(arg)
605
605
  return Element.new(self, element_id) if element_id
606
606
 
607
+ shadow_root_id = shadow_root_id_from(arg)
608
+ return ShadowRoot.new self, shadow_root_id if shadow_root_id
609
+
607
610
  arg.each { |k, v| arg[k] = unwrap_script_result(v) }
608
611
  else
609
612
  arg
@@ -23,13 +23,14 @@ require 'selenium/webdriver/remote/server_error'
23
23
  module Selenium
24
24
  module WebDriver
25
25
  module Remote
26
- autoload :Bridge, 'selenium/webdriver/remote/bridge'
27
- autoload :Driver, 'selenium/webdriver/remote/driver'
28
- autoload :Response, 'selenium/webdriver/remote/response'
26
+ autoload :Bridge, 'selenium/webdriver/remote/bridge'
27
+ autoload :Driver, 'selenium/webdriver/remote/driver'
28
+ autoload :Response, 'selenium/webdriver/remote/response'
29
29
  autoload :Capabilities, 'selenium/webdriver/remote/capabilities'
30
- autoload :COMMANDS, 'selenium/webdriver/remote/commands'
30
+ autoload :COMMANDS, 'selenium/webdriver/remote/commands'
31
+
31
32
  module Http
32
- autoload :Common, 'selenium/webdriver/remote/http/common'
33
+ autoload :Common, 'selenium/webdriver/remote/http/common'
33
34
  autoload :Default, 'selenium/webdriver/remote/http/default'
34
35
  end
35
36
  end
@@ -258,7 +258,7 @@ module Selenium
258
258
  end
259
259
 
260
260
  def find_by_index(index)
261
- options.select { |option| option.dom_attribute(:index) == index.to_s }
261
+ options.select { |option| option.property(:index) == index }
262
262
  end
263
263
 
264
264
  def find_by_value(value)
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- VERSION = '4.0.0'
22
+ VERSION = '4.1.0'
23
23
  end # WebDriver
24
24
  end # Selenium
@@ -75,7 +75,7 @@ module Selenium
75
75
  #
76
76
  # WebDriver.for :firefox, profile: 'some-profile'
77
77
  # WebDriver.for :firefox, profile: Profile.new
78
- # WebDriver.for :remote, url: "http://localhost:4444/wd/hub", desired_capabilities: caps
78
+ # WebDriver.for :remote, url: "http://localhost:4444/wd/hub", capabilities: caps
79
79
  #
80
80
  # One special argument is not passed on to the bridges, :listener.
81
81
  # You can pass a listener for this option to get notified of WebDriver events.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium-webdriver
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Rodionov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-10-13 00:00:00.000000000 Z
13
+ date: 2021-11-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: childprocess