selenium-webdriver 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
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