selenium-webdriver 4.0.0.beta2 → 4.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/selenium/webdriver/chrome/driver.rb +11 -0
- data/lib/selenium/webdriver/chrome/profile.rb +5 -2
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +0 -17
- data/lib/selenium/webdriver/common/driver_extensions/prints_page.rb +28 -1
- data/lib/selenium/webdriver/common/element.rb +20 -0
- data/lib/selenium/webdriver/common/options.rb +11 -6
- data/lib/selenium/webdriver/common/socket_poller.rb +19 -30
- data/lib/selenium/webdriver/firefox/driver.rb +9 -2
- data/lib/selenium/webdriver/remote/bridge.rb +14 -1
- data/lib/selenium/webdriver/remote/capabilities.rb +105 -52
- data/lib/selenium/webdriver/remote/commands.rb +2 -0
- data/lib/selenium/webdriver/remote/driver.rb +5 -7
- data/lib/selenium/webdriver/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d43cea1b9a19e329eee91c38bb566fc2c7adb76df2da6a7efa2eee908910a9a3
|
4
|
+
data.tar.gz: cd692d2a4f562dffcb0608cfd19adec5e383509d3f150826791c7312969b0aa9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 695aa88517dc97ab25d93a1f0b983bc3a6fa55e48460d5e8ed053e300227b6b1b2693e243b8a439652d921b75eba1ac06384a33fc0c40e2cb4b194ee66483d3f
|
7
|
+
data.tar.gz: acbe3d962300eff073ce447548fb41adb62ac56f238074f3f33c0bb43ccb4ef200daab53f1ff478f20f7efe67d3fcffc34e11d0b0959f929b9c7ffcac9afad0b
|
@@ -48,6 +48,17 @@ module Selenium
|
|
48
48
|
|
49
49
|
private
|
50
50
|
|
51
|
+
def devtools_url
|
52
|
+
uri = URI(devtools_address)
|
53
|
+
response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
|
54
|
+
|
55
|
+
JSON.parse(response)['webSocketDebuggerUrl']
|
56
|
+
end
|
57
|
+
|
58
|
+
def devtools_version
|
59
|
+
Integer(capabilities.browser_version.split('.').first)
|
60
|
+
end
|
61
|
+
|
51
62
|
def devtools_address
|
52
63
|
"http://#{capabilities['goog:chromeOptions']['debuggerAddress']}"
|
53
64
|
end
|
@@ -27,12 +27,11 @@ module Selenium
|
|
27
27
|
class Profile
|
28
28
|
include ProfileHelper
|
29
29
|
|
30
|
-
attr_reader :directory
|
31
|
-
|
32
30
|
def initialize(model = nil)
|
33
31
|
@model = verify_model(model)
|
34
32
|
@extensions = []
|
35
33
|
@encoded_extensions = []
|
34
|
+
@directory = nil
|
36
35
|
end
|
37
36
|
|
38
37
|
def add_extension(path)
|
@@ -45,6 +44,10 @@ module Selenium
|
|
45
44
|
@encoded_extensions << encoded
|
46
45
|
end
|
47
46
|
|
47
|
+
def directory
|
48
|
+
@directory || layout_on_disk
|
49
|
+
end
|
50
|
+
|
48
51
|
#
|
49
52
|
# Set a preference in the profile.
|
50
53
|
#
|
@@ -37,23 +37,6 @@ module Selenium
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
private
|
41
|
-
|
42
|
-
def devtools_version
|
43
|
-
return Firefox::DEVTOOLS_VERSION if browser == :firefox
|
44
|
-
|
45
|
-
Integer(capabilities.browser_version.split('.').first)
|
46
|
-
end
|
47
|
-
|
48
|
-
def devtools_url
|
49
|
-
return devtools_address if devtools_address.include?('/session/')
|
50
|
-
|
51
|
-
uri = URI(devtools_address)
|
52
|
-
response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
|
53
|
-
|
54
|
-
JSON.parse(response)['webSocketDebuggerUrl']
|
55
|
-
end
|
56
|
-
|
57
40
|
end # HasDevTools
|
58
41
|
end # DriverExtensions
|
59
42
|
end # WebDriver
|
@@ -21,8 +21,35 @@ module Selenium
|
|
21
21
|
module WebDriver
|
22
22
|
module DriverExtensions
|
23
23
|
module PrintsPage
|
24
|
+
#
|
25
|
+
# Save a page as a PDF to the given path
|
26
|
+
#
|
27
|
+
# @example Save Printed Page
|
28
|
+
# driver.save_print_page('../printed_page.pdf')
|
29
|
+
#
|
30
|
+
# @param [String] path to where the pdf should be saved
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
#
|
34
|
+
|
35
|
+
def save_print_page(path, **options)
|
36
|
+
File.open(path, 'wb') do |file|
|
37
|
+
content = Base64.decode64 print_page(options)
|
38
|
+
file << content
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Return a Base64 encoded Print Page as a string
|
44
|
+
#
|
45
|
+
# @see https://w3c.github.io/webdriver/#print-page
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
#
|
49
|
+
|
24
50
|
def print_page(**options)
|
25
|
-
options[:
|
51
|
+
options[:pageRanges] = Array(options.delete(:page_ranges)) || []
|
52
|
+
options[:shrinkToFit] = options.delete(:shrink_to_fit) { true }
|
26
53
|
|
27
54
|
@bridge.print_page(options)
|
28
55
|
end
|
@@ -160,6 +160,26 @@ module Selenium
|
|
160
160
|
bridge.element_property self, name
|
161
161
|
end
|
162
162
|
|
163
|
+
#
|
164
|
+
# Gets the computed WAI-ARIA role of element
|
165
|
+
#
|
166
|
+
# @return [String]
|
167
|
+
#
|
168
|
+
|
169
|
+
def aria_role
|
170
|
+
bridge.element_aria_role self
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# Gets the computed WAI-ARIA label of element.
|
175
|
+
#
|
176
|
+
# @return [String]
|
177
|
+
#
|
178
|
+
|
179
|
+
def accessible_name
|
180
|
+
bridge.element_aria_label self
|
181
|
+
end
|
182
|
+
|
163
183
|
#
|
164
184
|
# Get the text content of this element
|
165
185
|
#
|
@@ -134,12 +134,7 @@ module Selenium
|
|
134
134
|
|
135
135
|
def generate_as_json(value, camelize_keys: true)
|
136
136
|
if value.is_a?(Hash)
|
137
|
-
value
|
138
|
-
next if val.respond_to?(:empty?) && val.empty?
|
139
|
-
|
140
|
-
key = convert_json_key(key, camelize: camelize_keys)
|
141
|
-
hash[key] = generate_as_json(val, camelize_keys: camelize?(key))
|
142
|
-
end
|
137
|
+
process_json_hash(value, camelize_keys)
|
143
138
|
elsif value.respond_to?(:as_json)
|
144
139
|
value.as_json
|
145
140
|
elsif value.is_a?(Array)
|
@@ -151,6 +146,16 @@ module Selenium
|
|
151
146
|
end
|
152
147
|
end
|
153
148
|
|
149
|
+
def process_json_hash(value, camelize_keys)
|
150
|
+
value.each_with_object({}) do |(key, val), hash|
|
151
|
+
next if val.respond_to?(:empty?) && val.empty?
|
152
|
+
|
153
|
+
camelize = camelize_keys ? camelize?(key) : false
|
154
|
+
key = convert_json_key(key, camelize: camelize)
|
155
|
+
hash[key] = generate_as_json(val, camelize_keys: camelize)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
154
159
|
def convert_json_key(key, camelize: true)
|
155
160
|
key = key.to_s if key.is_a?(Symbol)
|
156
161
|
key = camel_case(key) if camelize
|
@@ -65,37 +65,26 @@ module Selenium
|
|
65
65
|
arr << Errno::EALREADY if Platform.wsl?
|
66
66
|
}.freeze
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
81
|
-
sockaddr = Socket.pack_sockaddr_in(@port, addr[0][3])
|
82
|
-
|
83
|
-
begin
|
84
|
-
sock.connect_nonblock sockaddr
|
85
|
-
rescue Errno::EINPROGRESS
|
86
|
-
retry if socket_writable?(sock) && conn_completed?(sock)
|
87
|
-
raise Errno::ECONNREFUSED
|
88
|
-
rescue *CONNECTED_ERRORS
|
89
|
-
# yay!
|
90
|
-
end
|
91
|
-
|
92
|
-
sock.close
|
93
|
-
true
|
94
|
-
rescue *NOT_CONNECTED_ERRORS
|
95
|
-
sock&.close
|
96
|
-
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}")
|
97
|
-
false
|
68
|
+
def listening?
|
69
|
+
addr = Socket.getaddrinfo(@host, @port, Socket::AF_INET, Socket::SOCK_STREAM)
|
70
|
+
sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
71
|
+
sockaddr = Socket.pack_sockaddr_in(@port, addr[0][3])
|
72
|
+
|
73
|
+
begin
|
74
|
+
sock.connect_nonblock sockaddr
|
75
|
+
rescue Errno::EINPROGRESS
|
76
|
+
retry if socket_writable?(sock) && conn_completed?(sock)
|
77
|
+
raise Errno::ECONNREFUSED
|
78
|
+
rescue *CONNECTED_ERRORS
|
79
|
+
# yay!
|
98
80
|
end
|
81
|
+
|
82
|
+
sock.close
|
83
|
+
true
|
84
|
+
rescue *NOT_CONNECTED_ERRORS
|
85
|
+
sock&.close
|
86
|
+
WebDriver.logger.debug("polling for socket on #{[@host, @port].inspect}")
|
87
|
+
false
|
99
88
|
end
|
100
89
|
|
101
90
|
def socket_writable?(sock)
|
@@ -40,8 +40,15 @@ module Selenium
|
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
|
-
def
|
44
|
-
"http://#{capabilities['moz:debuggerAddress']}"
|
43
|
+
def devtools_url
|
44
|
+
uri = URI("http://#{capabilities['moz:debuggerAddress']}")
|
45
|
+
response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
|
46
|
+
|
47
|
+
JSON.parse(response)['webSocketDebuggerUrl']
|
48
|
+
end
|
49
|
+
|
50
|
+
def devtools_version
|
51
|
+
Firefox::DEVTOOLS_VERSION
|
45
52
|
end
|
46
53
|
end # Driver
|
47
54
|
end # Firefox
|
@@ -49,7 +49,7 @@ module Selenium
|
|
49
49
|
#
|
50
50
|
|
51
51
|
def create_session(capabilities)
|
52
|
-
response = execute(:new_session, {},
|
52
|
+
response = execute(:new_session, {}, prepare_capabilities_payload(capabilities))
|
53
53
|
|
54
54
|
@session_id = response['sessionId']
|
55
55
|
capabilities = response['capabilities']
|
@@ -458,6 +458,14 @@ module Selenium
|
|
458
458
|
execute :get_element_property, id: element.ref, name: name
|
459
459
|
end
|
460
460
|
|
461
|
+
def element_aria_role(element)
|
462
|
+
execute :get_element_aria_role, id: element.ref
|
463
|
+
end
|
464
|
+
|
465
|
+
def element_aria_label(element)
|
466
|
+
execute :get_element_aria_label, id: element.ref
|
467
|
+
end
|
468
|
+
|
461
469
|
def element_value(element)
|
462
470
|
element_property element, 'value'
|
463
471
|
end
|
@@ -594,6 +602,11 @@ module Selenium
|
|
594
602
|
id['ELEMENT'] || id['element-6066-11e4-a52e-4f735466cecf']
|
595
603
|
end
|
596
604
|
|
605
|
+
def prepare_capabilities_payload(capabilities)
|
606
|
+
capabilities = {firstMatch: [capabilities]} if !capabilities['alwaysMatch'] && !capabilities['firstMatch']
|
607
|
+
{capabilities: capabilities}
|
608
|
+
end
|
609
|
+
|
597
610
|
def convert_locator(how, what)
|
598
611
|
how = SearchContext::FINDERS[how.to_sym] || how
|
599
612
|
|
@@ -40,22 +40,15 @@ module Selenium
|
|
40
40
|
:unhandled_prompt_behavior,
|
41
41
|
:strict_file_interactability,
|
42
42
|
|
43
|
-
# remote-specific
|
44
|
-
:remote_session_id
|
45
|
-
|
46
|
-
# TODO: (AR) deprecate compatibility with OSS-capabilities
|
47
|
-
:implicit_timeout,
|
48
|
-
:page_load_timeout,
|
49
|
-
:script_timeout
|
43
|
+
# remote-specific (webdriver.remote.sessionid)
|
44
|
+
:remote_session_id
|
50
45
|
].freeze
|
51
46
|
|
52
|
-
KNOWN.each do |key|
|
47
|
+
(KNOWN - %i[proxy timeouts]).each do |key|
|
53
48
|
define_method key do
|
54
49
|
@capabilities.fetch(key)
|
55
50
|
end
|
56
51
|
|
57
|
-
next if key == :proxy
|
58
|
-
|
59
52
|
define_method "#{key}=" do |value|
|
60
53
|
@capabilities[key] = value
|
61
54
|
end
|
@@ -89,16 +82,10 @@ module Selenium
|
|
89
82
|
alias_method :microsoftedge, :edge
|
90
83
|
|
91
84
|
def firefox(opts = {})
|
92
|
-
|
93
|
-
|
94
|
-
opts
|
95
|
-
opts[:timeouts]['implicit'] = opts.delete(:implicit_timeout) if opts.key?(:implicit_timeout)
|
96
|
-
opts[:timeouts]['pageLoad'] = opts.delete(:page_load_timeout) if opts.key?(:page_load_timeout)
|
97
|
-
opts[:timeouts]['script'] = opts.delete(:script_timeout) if opts.key?(:script_timeout)
|
98
|
-
opts.delete(:timeouts) if opts[:timeouts].empty?
|
99
|
-
new({browser_name: 'firefox'}.merge(opts))
|
85
|
+
new({
|
86
|
+
browser_name: 'firefox'
|
87
|
+
}.merge(opts))
|
100
88
|
end
|
101
|
-
|
102
89
|
alias_method :ff, :firefox
|
103
90
|
|
104
91
|
def safari(opts = {})
|
@@ -121,18 +108,21 @@ module Selenium
|
|
121
108
|
end
|
122
109
|
alias_method :ie, :internet_explorer
|
123
110
|
|
111
|
+
def always_match(capabilities)
|
112
|
+
new(always_match: capabilities)
|
113
|
+
end
|
114
|
+
|
115
|
+
def first_match(*capabilities)
|
116
|
+
new(first_match: capabilities)
|
117
|
+
end
|
118
|
+
|
124
119
|
#
|
125
120
|
# @api private
|
126
121
|
#
|
127
122
|
|
128
123
|
def json_create(data)
|
129
124
|
data = data.dup
|
130
|
-
|
131
125
|
caps = new
|
132
|
-
(KNOWN - %i[timeouts proxy]).each do |cap|
|
133
|
-
data_value = camel_case(cap)
|
134
|
-
caps[cap] = data.delete(data_value) if data.key?(data_value)
|
135
|
-
end
|
136
126
|
|
137
127
|
process_timeouts(caps, data.delete('timeouts'))
|
138
128
|
|
@@ -146,6 +136,11 @@ module Selenium
|
|
146
136
|
caps[:remote_session_id] = data.delete('webdriver.remote.sessionid')
|
147
137
|
end
|
148
138
|
|
139
|
+
KNOWN.each do |cap|
|
140
|
+
data_value = camel_case(cap)
|
141
|
+
caps[cap] = data.delete(data_value) if data.key?(data_value)
|
142
|
+
end
|
143
|
+
|
149
144
|
# any remaining pairs will be added as is, with no conversion
|
150
145
|
caps.merge!(data)
|
151
146
|
|
@@ -179,8 +174,9 @@ module Selenium
|
|
179
174
|
#
|
180
175
|
|
181
176
|
def initialize(opts = {})
|
182
|
-
@capabilities =
|
183
|
-
self.proxy = opts.delete(:proxy)
|
177
|
+
@capabilities = {}
|
178
|
+
self.proxy = opts.delete(:proxy) if opts[:proxy]
|
179
|
+
@capabilities.merge!(opts)
|
184
180
|
end
|
185
181
|
|
186
182
|
#
|
@@ -205,6 +201,10 @@ module Selenium
|
|
205
201
|
end
|
206
202
|
end
|
207
203
|
|
204
|
+
def proxy
|
205
|
+
@capabilities.fetch(:proxy)
|
206
|
+
end
|
207
|
+
|
208
208
|
def proxy=(proxy)
|
209
209
|
case proxy
|
210
210
|
when Hash
|
@@ -216,33 +216,46 @@ module Selenium
|
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
|
+
def timeouts
|
220
|
+
@capabilities[:timeouts] ||= {}
|
221
|
+
end
|
222
|
+
|
223
|
+
def timeouts=(timeouts)
|
224
|
+
@capabilities[:timeouts] = timeouts
|
225
|
+
end
|
226
|
+
|
227
|
+
def implicit_timeout
|
228
|
+
timeouts[:implicit]
|
229
|
+
end
|
230
|
+
|
231
|
+
def implicit_timeout=(timeout)
|
232
|
+
timeouts[:implicit] = timeout
|
233
|
+
end
|
234
|
+
|
235
|
+
def page_load_timeout
|
236
|
+
timeouts[:page_load] || timeouts[:pageLoad]
|
237
|
+
end
|
238
|
+
|
239
|
+
def page_load_timeout=(timeout)
|
240
|
+
timeouts[:page_load] = timeout
|
241
|
+
end
|
242
|
+
|
243
|
+
def script_timeout
|
244
|
+
timeouts[:script]
|
245
|
+
end
|
246
|
+
|
247
|
+
def script_timeout=(timeout)
|
248
|
+
timeouts[:script] = timeout
|
249
|
+
end
|
250
|
+
|
219
251
|
#
|
220
252
|
# @api private
|
221
253
|
#
|
222
254
|
|
223
255
|
def as_json(*)
|
224
|
-
|
225
|
-
|
226
|
-
@capabilities.each do |key, value|
|
227
|
-
case key
|
228
|
-
when :platform
|
229
|
-
hash['platform'] = value.to_s.upcase
|
230
|
-
when :proxy
|
231
|
-
next unless value
|
232
|
-
|
233
|
-
process_proxy(hash, value)
|
234
|
-
when :unhandled_prompt_behavior
|
235
|
-
hash['unhandledPromptBehavior'] = value.is_a?(Symbol) ? value.to_s.tr('_', ' ') : value
|
236
|
-
when String
|
237
|
-
hash[key.to_s] = value
|
238
|
-
when Symbol
|
239
|
-
hash[self.class.camel_case(key)] = value
|
240
|
-
else
|
241
|
-
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class} / #{value.inspect}"
|
242
|
-
end
|
256
|
+
@capabilities.each_with_object({}) do |(key, value), hash|
|
257
|
+
hash[convert_key(key)] = process_capabilities(key, value, hash)
|
243
258
|
end
|
244
|
-
|
245
|
-
hash
|
246
259
|
end
|
247
260
|
|
248
261
|
def to_json(*)
|
@@ -263,13 +276,53 @@ module Selenium
|
|
263
276
|
|
264
277
|
private
|
265
278
|
|
266
|
-
def
|
267
|
-
|
268
|
-
|
279
|
+
def process_capabilities(key, value, hash)
|
280
|
+
case value
|
281
|
+
when Array
|
282
|
+
value.map { |v| process_capabilities(key, v, hash) }
|
283
|
+
when Hash
|
284
|
+
value.each_with_object({}) do |(k, v), h|
|
285
|
+
h[convert_key(k)] = process_capabilities(k, v, h)
|
286
|
+
end
|
287
|
+
when Capabilities, Options
|
288
|
+
value.as_json
|
289
|
+
else
|
290
|
+
convert_value(key, value)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def convert_key(key)
|
295
|
+
case key
|
296
|
+
when String
|
297
|
+
key.to_s
|
298
|
+
when Symbol
|
299
|
+
self.class.camel_case(key)
|
300
|
+
else
|
301
|
+
raise TypeError, "expected String or Symbol, got #{key.inspect}:#{key.class}"
|
302
|
+
end
|
303
|
+
end
|
269
304
|
|
270
|
-
|
305
|
+
def convert_value(key, value)
|
306
|
+
case key
|
307
|
+
when :platform
|
308
|
+
value.to_s.upcase
|
309
|
+
when :proxy
|
310
|
+
convert_proxy(value)
|
311
|
+
when :unhandled_prompt_behavior
|
312
|
+
value.is_a?(Symbol) ? value.to_s.tr('_', ' ') : value
|
313
|
+
else
|
314
|
+
value
|
315
|
+
end
|
316
|
+
end
|
271
317
|
|
272
|
-
|
318
|
+
def convert_proxy(value)
|
319
|
+
return unless value
|
320
|
+
|
321
|
+
hash = value.as_json
|
322
|
+
hash['proxyType'] &&= hash['proxyType'].downcase
|
323
|
+
hash['noProxy'] = hash['noProxy'].split(', ') if hash['noProxy'].is_a?(String)
|
324
|
+
|
325
|
+
hash
|
273
326
|
end
|
274
327
|
end # Capabilities
|
275
328
|
end # Remote
|
@@ -82,6 +82,8 @@ module Selenium
|
|
82
82
|
get_element_attribute: [:get, 'session/:session_id/element/:id/attribute/:name'],
|
83
83
|
get_element_property: [:get, 'session/:session_id/element/:id/property/:name'],
|
84
84
|
get_element_css_value: [:get, 'session/:session_id/element/:id/css/:property_name'],
|
85
|
+
get_element_aria_role: [:get, 'session/:session_id/element/:id/computedrole'],
|
86
|
+
get_element_aria_label: [:get, 'session/:session_id/element/:id/computedlabel'],
|
85
87
|
get_element_text: [:get, 'session/:session_id/element/:id/text'],
|
86
88
|
get_element_tag_name: [:get, 'session/:session_id/element/:id/name'],
|
87
89
|
get_element_rect: [:get, 'session/:session_id/element/:id/rect'],
|
@@ -44,17 +44,15 @@ module Selenium
|
|
44
44
|
super
|
45
45
|
end
|
46
46
|
|
47
|
-
def print_page(**options)
|
48
|
-
options[:page_ranges] &&= Array(options[:page_ranges])
|
49
|
-
|
50
|
-
@bridge.print_page(options)
|
51
|
-
end
|
52
|
-
|
53
47
|
private
|
54
48
|
|
55
|
-
def
|
49
|
+
def devtools_url
|
56
50
|
capabilities['se:cdp']
|
57
51
|
end
|
52
|
+
|
53
|
+
def devtools_version
|
54
|
+
capabilities['se:cdpVersion'].split('.').first
|
55
|
+
end
|
58
56
|
end # Driver
|
59
57
|
end # Remote
|
60
58
|
end # WebDriver
|
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.0.0.beta3
|
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-
|
13
|
+
date: 2021-04-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|