selenium-webdriver 4.9.1 → 4.10.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: 382f56851a268a1f44ed42a9a0ec85d5136540df32711606657bf8961a95b6b1
4
- data.tar.gz: edbf74e77ed56b92fe01cfe6493b8db901ebc7cdb3df9b4d561f03cb5a91dcda
3
+ metadata.gz: 57f5a526cd47137c459f2eb349f03fbebc28b428a4d1eba1aed962cb8b32f0d4
4
+ data.tar.gz: 0e246eec8fc308f54bb651245cebaf3610a5abf4f6027728a6e96210b72a397e
5
5
  SHA512:
6
- metadata.gz: 84260d58d81b2be75717e10d597bdeaf7c7b36bec5483d664fe19a6c5891967a176ef26d8806ea160a4f229b051d1ede4fa20d244e4b0c08f8409ccac8f640ca
7
- data.tar.gz: 40af1b4e6fa0f6a85b608ce485336b0b7ba10ad35e7c8749c81c78808ba506d5a6294933b5771b3b5cb413f2b57b447af62dd236ce3e6ca4ed25f1949cc07bf6
6
+ metadata.gz: 679674b291a9b3da8d41a917ed782d14743150b524767a915e464e39751971ce9420e7a21127dcf10ca070f3bd7bff14a61690c028b013daab8d638550f38a61
7
+ data.tar.gz: a39c8fdecf8a60ad8736aa3392bba7f540c692bdba451546463b8db4e9b967d81d1d30ca665aedb99901e6f173deb3af29fcdfcd7d7c087783b8e24358ae8814
data/CHANGES CHANGED
@@ -1,3 +1,18 @@
1
+ 4.10.0 (2023-06-07)
2
+ =========================
3
+ Ruby:
4
+ * Implement proxy support for Selenium Manager
5
+ * Prevent setting driver log level in Safari
6
+ * Change all Selenium Manager logging to :debug (#12145)
7
+ * Error messages include links to documentation
8
+ * Add custom error class for driver location and improve error logic
9
+
10
+ BiDi:
11
+ * Released selenium-devtools 0.114.0 (supports CDP v85, v112, v113, v114)
12
+
13
+ Edge:
14
+ * Add support for webview2
15
+
1
16
  4.9.1 (2023-05-08)
2
17
  =========================
3
18
  Ruby:
Binary file
Binary file
Binary file
@@ -113,10 +113,9 @@ function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.repla
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)};
116
- rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=100);return function(d){var e=Z.u(a);if(e===d)return!1;e=
117
- W(e);d=W(d);var f=Math.abs(e.a+e.width-d.a),g=Math.abs(e.b+e.height-d.b);g=Math.abs(e.b-(d.b+d.height))<=c||g<=c;return(Math.abs(e.a-(d.a+d.width))<=c||f<=c)&&g?!0:Math.sqrt(Math.pow(Math.abs(e.a+e.width/2-(d.a+d.width/2)),2)+Math.pow(Math.abs(e.b+e.height/2-(d.b+d.height/2)),2))<=c}},u:function(a){if(ha(a)&&1==a.nodeType)return a;if(ea(a))return Z.u(a.call(null));if(ha(a)){var b;a:{if(b=sd(a)){var c=td[b];if(c&&ea(c.o)){b=c.o(a[b],Bc.document);break a}}throw new P(61,"Unsupported locator strategy: "+
118
- b);}if(!b)throw new P(7,"No element has been found by "+JSON.stringify(a));return b}throw new P(61,"Selector is of wrong type: "+JSON.stringify(a));}};Z.P={left:Z.V,right:Z.aa,above:Z.R,below:Z.S,near:Z.W};Z.O={left:Z.u,right:Z.u,above:Z.u,below:Z.u,near:Z.u};
119
- Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c};
116
+ rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=50);return function(d){var e=Z.u(a);if(e===d)return!1;e=W(e);
117
+ d=W(d);e=new U(e.a-c,e.b-c,e.width+2*c,e.height+2*c);return e.a<=d.a+d.width&&d.a<=e.a+e.width&&e.b<=d.b+d.height&&d.b<=e.b+e.height}},u:function(a){if(ha(a)&&1==a.nodeType)return a;if(ea(a))return Z.u(a.call(null));if(ha(a)){var b;a:{if(b=sd(a)){var c=td[b];if(c&&ea(c.o)){b=c.o(a[b],Bc.document);break a}}throw new P(61,"Unsupported locator strategy: "+b);}if(!b)throw new P(7,"No element has been found by "+JSON.stringify(a));return b}throw new P(61,"Selector is of wrong type: "+JSON.stringify(a));
118
+ }};Z.P={left:Z.V,right:Z.aa,above:Z.R,below:Z.S,near:Z.W};Z.O={left:Z.u,right:Z.u,above:Z.u,below:Z.u,near:Z.u};Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c};
120
119
  Z.ba=function(a,b){function c(f){f=W(f);return Math.sqrt(Math.pow(d-(f.a+Math.max(1,f.width)/2),2)+Math.pow(e-(f.b+Math.max(1,f.height)/2),2))}a=W(a);var d=a.a+Math.max(1,a.width)/2,e=a.b+Math.max(1,a.height)/2;xa(b,function(f,g){return c(f)-c(g)});return b};Z.o=function(a,b){a=Z.j(a,b);return 0==a.length?null:a[0]};
121
120
  Z.j=function(a,b){if(!a.hasOwnProperty("root")||!a.hasOwnProperty("filters"))throw new P(61,"Locator not suitable for relative locators: "+JSON.stringify(a));var c=a.filters,d=da(c);if("array"!=d&&("object"!=d||"number"!=typeof c.length))throw new P(61,"Targets should be an array: "+JSON.stringify(a));var e;S(a.root)?e=[a.root]:e=ud(a.root,b);return 0==e.length?[]:Z.U(e,a.filters)};var vd={o:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)[0]||null},j:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)}};var td={className:Dc,"class name":Dc,css:Nc,"css selector":Nc,relative:Z,id:qd,linkText:Y,"link text":Y,name:{o:function(a,b){b=mb(eb(b),"*",null,b);return ua(b,function(c){return Uc(c,"name")==a})},j:function(a,b){b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"name")==a})}},partialLinkText:rd,"partial link text":rd,tagName:vd,"tag name":vd,xpath:T};function sd(a){for(var b in a)if(a.hasOwnProperty(b))return b;return null}
122
121
  function ud(a,b){var c=sd(a);if(c){var d=td[c];if(d&&ea(d.j))return d.j(a[c],b||Bc.document)}throw new P(61,"Unsupported locator strategy: "+c);};ca("_",ud);; return this._.apply(null,arguments);}).apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);}
@@ -26,17 +26,20 @@ module Selenium
26
26
  path ||= Platform.find_binary(klass::EXECUTABLE)
27
27
 
28
28
  path ||= begin
29
- SeleniumManager.driver_path(options)
29
+ SeleniumManager.driver_path(options) unless options.is_a?(Remote::Capabilities)
30
30
  rescue StandardError => e
31
- WebDriver.logger.warn("Unable to obtain driver using Selenium Manager\n #{e.message}",
32
- id: :selenium_manager)
33
- nil
31
+ raise Error::NoSuchDriverError, "Unable to obtain #{klass::EXECUTABLE} using Selenium Manager; #{e.message}"
32
+ end
33
+
34
+ begin
35
+ Platform.assert_file(path)
36
+ Platform.assert_executable(path)
37
+ rescue TypeError
38
+ raise Error::NoSuchDriverError, "Unable to locate or obtain #{klass::EXECUTABLE}"
39
+ rescue Error::WebDriverError => e
40
+ raise Error::NoSuchDriverError, "#{klass::EXECUTABLE} located, but: #{e.message}"
34
41
  end
35
- msg = "Unable to locate the #{klass::EXECUTABLE} executable; for more information on how to install drivers, " \
36
- 'see https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/'
37
- raise Error::WebDriverError, msg unless path
38
42
 
39
- Platform.assert_executable path
40
43
  path
41
44
  end
42
45
  end
@@ -34,13 +34,20 @@ module Selenium
34
34
  WebDriverError
35
35
  end
36
36
 
37
+ SUPPORT_MSG = 'For documentation on this error, please visit:'
38
+ ERROR_URL = 'https://www.selenium.dev/documentation/webdriver/troubleshooting/errors'
39
+
37
40
  class WebDriverError < StandardError; end
38
41
 
39
42
  #
40
43
  # An element could not be located on the page using the given search parameters.
41
44
  #
42
45
 
43
- class NoSuchElementError < WebDriverError; end
46
+ class NoSuchElementError < WebDriverError
47
+ def initialize(msg = '')
48
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#no-such-element-exception")
49
+ end
50
+ end
44
51
 
45
52
  #
46
53
  # A command to switch to a frame could not be satisfied because the frame could not be found.
@@ -58,7 +65,11 @@ module Selenium
58
65
  # A command failed because the referenced element is no longer attached to the DOM.
59
66
  #
60
67
 
61
- class StaleElementReferenceError < WebDriverError; end
68
+ class StaleElementReferenceError < WebDriverError
69
+ def initialize(msg = '')
70
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#stale-element-reference-exception")
71
+ end
72
+ end
62
73
 
63
74
  #
64
75
  # A command failed because the referenced shadow root is no longer attached to the DOM.
@@ -132,7 +143,11 @@ module Selenium
132
143
  # Argument was an invalid selector.
133
144
  #
134
145
 
135
- class InvalidSelectorError < WebDriverError; end
146
+ class InvalidSelectorError < WebDriverError
147
+ def initialize(msg = '')
148
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#invalid-selector-exception")
149
+ end
150
+ end
136
151
 
137
152
  #
138
153
  # A new session could not be created.
@@ -212,6 +227,16 @@ module Selenium
212
227
  #
213
228
 
214
229
  class UnsupportedOperationError < WebDriverError; end
230
+
231
+ #
232
+ # Indicates that driver was not specified and could not be located.
233
+ #
234
+
235
+ class NoSuchDriverError < WebDriverError
236
+ def initialize(msg = '')
237
+ super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}/driver_location")
238
+ end
239
+ end
215
240
  end # Error
216
241
  end # WebDriver
217
242
  end # Selenium
@@ -41,7 +41,7 @@ module Selenium
41
41
  :debug?,
42
42
  :info?,
43
43
  :warn?,
44
- :error, :error?,
44
+ :error?,
45
45
  :fatal, :fatal?,
46
46
  :level
47
47
 
@@ -127,16 +127,20 @@ module Selenium
127
127
  # @yield see #deprecate
128
128
  #
129
129
  def info(message, id: [], &block)
130
- unless @first_warning
131
- @first_warning = true
132
- info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
133
- "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
134
- end
135
- end
136
-
137
130
  discard_or_log(:info, message, id, &block)
138
131
  end
139
132
 
133
+ #
134
+ # Used to supply information that suggests an error occurred
135
+ #
136
+ # @param [String] message
137
+ # @param [Symbol, Array<Sybmol>] id
138
+ # @yield see #deprecate
139
+ #
140
+ def error(message, id: [], &block)
141
+ discard_or_log(:error, message, id, &block)
142
+ end
143
+
140
144
  #
141
145
  # Used to supply information that suggests action be taken by user
142
146
  #
@@ -192,6 +196,15 @@ module Selenium
192
196
  return if (@ignored & id).any?
193
197
  return if @allowed.any? && (@allowed & id).none?
194
198
 
199
+ return if ::Logger::Severity.const_get(level.upcase) < @logger.level
200
+
201
+ unless @first_warning
202
+ @first_warning = true
203
+ info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
204
+ "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
205
+ end
206
+ end
207
+
195
208
  msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
196
209
  msg += " #{yield}" if block_given?
197
210
 
@@ -152,7 +152,7 @@ module Selenium
152
152
  'socksUsername' => socks_username,
153
153
  'socksPassword' => socks_password,
154
154
  'socksVersion' => socks_version
155
- }.delete_if { |_k, v| v.nil? }
155
+ }.compact
156
156
 
157
157
  json_result if json_result.length > 1
158
158
  end
@@ -27,19 +27,31 @@ module Selenium
27
27
  # @api private
28
28
  #
29
29
  class SeleniumManager
30
- BIN_PATH = '../../../../../bin'
31
-
32
30
  class << self
31
+ attr_writer :bin_path
32
+
33
+ def bin_path
34
+ @bin_path ||= '../../../../../bin'
35
+ end
36
+
33
37
  # @param [Options] options browser options.
34
38
  # @return [String] the path to the correct driver.
35
39
  def driver_path(options)
36
40
  message = 'applicable driver not found; attempting to install with Selenium Manager (Beta)'
37
- WebDriver.logger.info(message, id: :selenium_manager)
41
+ WebDriver.logger.debug(message, id: :selenium_manager)
38
42
 
39
- unless options.is_a?(Options)
40
- raise ArgumentError, "SeleniumManager requires a WebDriver::Options instance, not #{options.inspect}"
41
- end
43
+ command = generate_command(binary, options)
44
+
45
+ location = run(*command)
46
+ WebDriver.logger.debug("Driver found at #{location}", id: :selenium_manager)
47
+ Platform.assert_executable location
48
+
49
+ location
50
+ end
51
+
52
+ private
42
53
 
54
+ def generate_command(binary, options)
43
55
  command = [binary, '--browser', options.browser_name, '--output', 'json']
44
56
  if options.browser_version
45
57
  command << '--browser-version'
@@ -49,21 +61,18 @@ module Selenium
49
61
  command << '--browser-path'
50
62
  command << options.binary.gsub('\\', '\\\\\\')
51
63
  end
64
+ if options.proxy
65
+ command << '--proxy'
66
+ (command << options.proxy.ssl) || options.proxy.http
67
+ end
52
68
  command << '--debug' if WebDriver.logger.debug?
53
-
54
- location = run(*command)
55
- WebDriver.logger.debug("Driver found at #{location}", id: :selenium_manager)
56
- Platform.assert_executable location
57
-
58
- location
69
+ command
59
70
  end
60
71
 
61
- private
62
-
63
72
  # @return [String] the path to the correct selenium manager
64
73
  def binary
65
74
  @binary ||= begin
66
- path = File.expand_path(BIN_PATH, __FILE__)
75
+ path = File.expand_path(bin_path, __FILE__)
67
76
  path << if Platform.windows?
68
77
  '/windows/selenium-manager.exe'
69
78
  elsif Platform.mac?
@@ -72,11 +81,18 @@ module Selenium
72
81
  '/linux/selenium-manager'
73
82
  end
74
83
  location = File.expand_path(path, __FILE__)
75
- unless location.is_a?(String) && File.exist?(location) && File.executable?(location)
76
- raise Error::WebDriverError, 'Unable to obtain Selenium Manager'
84
+
85
+ begin
86
+ Platform.assert_file(location)
87
+ Platform.assert_executable(location)
88
+ rescue TypeError
89
+ raise Error::WebDriverError,
90
+ "Unable to locate or obtain Selenium Manager binary; #{location} is not a valid file object"
91
+ rescue Error::WebDriverError => e
92
+ raise Error::WebDriverError, "Selenium Manager binary located, but #{e.message}"
77
93
  end
78
94
 
79
- WebDriver.logger.debug("Selenium Manager found at #{location}", id: :selenium_manager)
95
+ WebDriver.logger.debug("Selenium Manager binary found at #{location}", id: :selenium_manager)
80
96
  location
81
97
  end
82
98
  end
@@ -89,15 +105,16 @@ module Selenium
89
105
  json_output = stdout.empty? ? nil : JSON.parse(stdout)
90
106
  result = json_output&.dig('result', 'message')
91
107
  rescue StandardError => e
92
- raise Error::WebDriverError, "Unsuccessful command executed: #{command}", e.message
108
+ raise Error::WebDriverError, "Unsuccessful command executed: #{command}; #{e.message}"
93
109
  end
94
110
 
95
- if status.exitstatus.positive?
96
- raise Error::WebDriverError, "Unsuccessful command executed: #{command}\n#{result}#{stderr}"
111
+ (json_output&.fetch('logs') || []).each do |log|
112
+ level = log['level'].casecmp('info').zero? ? 'debug' : log['level'].downcase
113
+ WebDriver.logger.send(level, log['message'], id: :selenium_manager)
97
114
  end
98
115
 
99
- json_output['logs'].each do |log|
100
- WebDriver.logger.send(log['level'].downcase, log['message'], id: :selenium_manager)
116
+ if status.exitstatus.positive?
117
+ raise Error::WebDriverError, "Unsuccessful command executed: #{command}\n#{result}#{stderr}"
101
118
  end
102
119
 
103
120
  result
@@ -26,6 +26,20 @@ module Selenium
26
26
  KEY = 'ms:edgeOptions'
27
27
  BROWSER = 'MicrosoftEdge'
28
28
 
29
+ #
30
+ # Changes the browser name enable webview2
31
+ # see: https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/webdriver
32
+ # Automation of WebView2 apps with Microsoft Edge WebDriver
33
+ #
34
+ # @example Enable webview2
35
+ # options = Selenium::WebDriver::Edge::Options.new
36
+ # options.webview2!
37
+ #
38
+
39
+ def webview2!
40
+ @options[:browser_name] = 'webview2'
41
+ end
42
+
29
43
  private
30
44
 
31
45
  def enable_logging(browser_options)
@@ -24,6 +24,16 @@ module Selenium
24
24
  DEFAULT_PORT = 7050
25
25
  EXECUTABLE = 'safaridriver'
26
26
  SHUTDOWN_SUPPORTED = false
27
+
28
+ def initialize(path: nil, port: nil, log: nil, args: nil)
29
+ raise Error::WebDriverError, 'Safari Service does not support setting log output' if log
30
+
31
+ super
32
+ end
33
+
34
+ def log=(*)
35
+ raise Error::WebDriverError, 'Safari Service does not support setting log output'
36
+ end
27
37
  end # Service
28
38
  end # Safari
29
39
  end # WebDriver
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- VERSION = '4.9.1'
22
+ VERSION = '4.10.0'
23
23
  end # WebDriver
24
24
  end # Selenium
@@ -54,6 +54,7 @@ Gem::Specification.new do |s|
54
54
  s.add_runtime_dependency 'websocket', ['~> 1.0']
55
55
 
56
56
  s.add_development_dependency 'rack', ['~> 2.0']
57
+ s.add_development_dependency 'rake', ['~> 13.0']
57
58
  s.add_development_dependency 'rspec', ['~> 3.0']
58
59
  s.add_development_dependency 'rubocop', ['~> 1.42']
59
60
  s.add_development_dependency 'rubocop-performance', ['~> 1.15']
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.9.1
4
+ version: 4.10.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: 2023-05-08 00:00:00.000000000 Z
13
+ date: 2023-06-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rexml
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '13.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '13.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement