capybara 3.29.0 → 3.30.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +19 -1
- data/README.md +1 -1
- data/lib/capybara/config.rb +7 -3
- data/lib/capybara/helpers.rb +3 -1
- data/lib/capybara/node/actions.rb +23 -19
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +3 -3
- data/lib/capybara/node/element.rb +10 -8
- data/lib/capybara/node/finders.rb +12 -10
- data/lib/capybara/node/matchers.rb +39 -33
- data/lib/capybara/node/simple.rb +3 -1
- data/lib/capybara/queries/ancestor_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +17 -4
- data/lib/capybara/queries/sibling_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +4 -1
- data/lib/capybara/rack_test/driver.rb +1 -1
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/selector.rb +22 -16
- data/lib/capybara/selector/css.rb +1 -1
- data/lib/capybara/selector/definition.rb +2 -2
- data/lib/capybara/selector/definition/button.rb +7 -2
- data/lib/capybara/selector/definition/checkbox.rb +2 -2
- data/lib/capybara/selector/definition/css.rb +3 -1
- data/lib/capybara/selector/definition/datalist_input.rb +1 -1
- data/lib/capybara/selector/definition/datalist_option.rb +1 -1
- data/lib/capybara/selector/definition/element.rb +1 -1
- data/lib/capybara/selector/definition/field.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/label.rb +3 -1
- data/lib/capybara/selector/definition/radio_button.rb +2 -2
- data/lib/capybara/selector/definition/select.rb +1 -1
- data/lib/capybara/selector/definition/table.rb +5 -2
- data/lib/capybara/selector/filter_set.rb +11 -9
- data/lib/capybara/selector/filters/base.rb +6 -1
- data/lib/capybara/selector/filters/locator_filter.rb +1 -1
- data/lib/capybara/selector/selector.rb +4 -2
- data/lib/capybara/selenium/driver.rb +19 -11
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -2
- data/lib/capybara/selenium/extensions/html5_drag.rb +6 -5
- data/lib/capybara/selenium/node.rb +6 -4
- data/lib/capybara/selenium/nodes/chrome_node.rb +7 -3
- data/lib/capybara/selenium/nodes/edge_node.rb +3 -1
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/server.rb +15 -3
- data/lib/capybara/server/checker.rb +1 -1
- data/lib/capybara/server/middleware.rb +20 -10
- data/lib/capybara/session.rb +10 -8
- data/lib/capybara/session/config.rb +6 -2
- data/lib/capybara/session/matchers.rb +6 -6
- data/lib/capybara/spec/public/test.js +11 -0
- data/lib/capybara/spec/session/all_spec.rb +15 -0
- data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +4 -0
- data/lib/capybara/spec/session/click_button_spec.rb +5 -0
- data/lib/capybara/spec/session/find_spec.rb +20 -0
- data/lib/capybara/spec/session/has_table_spec.rb +51 -5
- data/lib/capybara/spec/session/has_text_spec.rb +31 -0
- data/lib/capybara/spec/session/node_spec.rb +15 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
- data/lib/capybara/spec/session/selectors_spec.rb +15 -2
- data/lib/capybara/spec/views/form.erb +5 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/dsl_spec.rb +2 -2
- data/spec/minitest_spec_spec.rb +46 -46
- data/spec/regexp_dissassembler_spec.rb +45 -37
- data/spec/result_spec.rb +3 -3
- data/spec/rspec/features_spec.rb +1 -0
- data/spec/rspec/shared_spec_matchers.rb +3 -3
- data/spec/rspec_spec.rb +4 -4
- data/spec/selenium_spec_chrome.rb +3 -3
- data/spec/selenium_spec_firefox.rb +7 -2
- data/spec/server_spec.rb +42 -0
- data/spec/session_spec.rb +1 -1
- data/spec/shared_selenium_node.rb +3 -3
- data/spec/shared_selenium_session.rb +8 -7
- metadata +3 -3
@@ -48,7 +48,12 @@ module Capybara
|
|
48
48
|
|
49
49
|
def apply(subject, name, value, skip_value, ctx)
|
50
50
|
return skip_value if skip?(value)
|
51
|
-
|
51
|
+
|
52
|
+
unless valid_value?(value)
|
53
|
+
raise ArgumentError,
|
54
|
+
"Invalid value #{value.inspect} passed to #{self.class.name.split('::').last} #{name}" \
|
55
|
+
"#{" : #{name}" if @name.is_a?(Regexp)}"
|
56
|
+
end
|
52
57
|
|
53
58
|
if @block.arity == 2
|
54
59
|
filter_context(ctx).instance_exec(subject, value, &@block)
|
@@ -56,12 +56,14 @@ module Capybara
|
|
56
56
|
if format
|
57
57
|
raise ArgumentError, "Selector #{@name} does not support #{format}" unless expressions.key?(format)
|
58
58
|
|
59
|
-
instance_exec(locator, options, &expressions[format])
|
59
|
+
instance_exec(locator, **options, &expressions[format])
|
60
60
|
else
|
61
61
|
warn 'Selector has no format'
|
62
62
|
end
|
63
63
|
ensure
|
64
|
-
|
64
|
+
unless locator_valid?(locator)
|
65
|
+
warn "Locator #{locator.class}:#{locator.inspect} for selector #{name.inspect} must #{locator_description}. This will raise an error in a future version of Capybara."
|
66
|
+
end
|
65
67
|
end
|
66
68
|
|
67
69
|
def add_error(error_msg)
|
@@ -20,7 +20,9 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
20
20
|
require 'capybara/selenium/logger_suppressor'
|
21
21
|
require 'capybara/selenium/patches/atoms'
|
22
22
|
require 'capybara/selenium/patches/is_displayed'
|
23
|
-
|
23
|
+
if Gem.loaded_specs['selenium-webdriver'].version < Gem::Version.new('3.5.0')
|
24
|
+
warn "Warning: You're using an unsupported version of selenium-webdriver, please upgrade."
|
25
|
+
end
|
24
26
|
rescue LoadError => e
|
25
27
|
raise e unless e.message.match?(/selenium-webdriver/)
|
26
28
|
|
@@ -143,7 +145,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
143
145
|
|
144
146
|
switch_to_frame(:parent)
|
145
147
|
begin
|
146
|
-
|
148
|
+
frame.base.obscured?(x: x, y: y)
|
147
149
|
ensure
|
148
150
|
switch_to_frame(frame)
|
149
151
|
end
|
@@ -219,7 +221,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
219
221
|
|
220
222
|
def accept_modal(_type, **options)
|
221
223
|
yield if block_given?
|
222
|
-
modal = find_modal(options)
|
224
|
+
modal = find_modal(**options)
|
223
225
|
|
224
226
|
modal.send_keys options[:with] if options[:with]
|
225
227
|
|
@@ -230,7 +232,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
230
232
|
|
231
233
|
def dismiss_modal(_type, **options)
|
232
234
|
yield if block_given?
|
233
|
-
modal = find_modal(options)
|
235
|
+
modal = find_modal(**options)
|
234
236
|
message = modal.text
|
235
237
|
modal.dismiss
|
236
238
|
message
|
@@ -238,7 +240,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
238
240
|
|
239
241
|
def quit
|
240
242
|
@browser&.quit
|
241
|
-
rescue Selenium::WebDriver::Error::SessionNotCreatedError, Errno::ECONNREFUSED # rubocop:disable Lint/
|
243
|
+
rescue Selenium::WebDriver::Error::SessionNotCreatedError, Errno::ECONNREFUSED # rubocop:disable Lint/SuppressedException
|
242
244
|
# Browser must have already gone
|
243
245
|
rescue Selenium::WebDriver::Error::UnknownError => e
|
244
246
|
unless silenced_unknown_error_message?(e.message) # Most likely already gone
|
@@ -290,7 +292,7 @@ private
|
|
290
292
|
def clear_browser_state
|
291
293
|
delete_all_cookies
|
292
294
|
clear_storage
|
293
|
-
rescue *clear_browser_state_errors # rubocop:disable Lint/
|
295
|
+
rescue *clear_browser_state_errors # rubocop:disable Lint/SuppressedException
|
294
296
|
# delete_all_cookies fails when we've previously gone
|
295
297
|
# to about:blank, so we rescue this error and do nothing
|
296
298
|
# instead.
|
@@ -314,7 +316,7 @@ private
|
|
314
316
|
def clear_storage
|
315
317
|
clear_session_storage unless options[:clear_session_storage] == false
|
316
318
|
clear_local_storage unless options[:clear_local_storage] == false
|
317
|
-
rescue Selenium::WebDriver::Error::JavascriptError # rubocop:disable Lint/
|
319
|
+
rescue Selenium::WebDriver::Error::JavascriptError # rubocop:disable Lint/SuppressedException
|
318
320
|
# session/local storage may not be available if on non-http pages (e.g. about:blank)
|
319
321
|
end
|
320
322
|
|
@@ -325,7 +327,9 @@ private
|
|
325
327
|
begin
|
326
328
|
@browser&.execute_script('window.sessionStorage.clear()')
|
327
329
|
rescue # rubocop:disable Style/RescueStandardError
|
328
|
-
|
330
|
+
unless options[:clear_session_storage].nil?
|
331
|
+
warn 'sessionStorage clear requested but is not supported by this driver'
|
332
|
+
end
|
329
333
|
end
|
330
334
|
end
|
331
335
|
end
|
@@ -337,7 +341,9 @@ private
|
|
337
341
|
begin
|
338
342
|
@browser&.execute_script('window.localStorage.clear()')
|
339
343
|
rescue # rubocop:disable Style/RescueStandardError
|
340
|
-
|
344
|
+
unless options[:clear_local_storage].nil?
|
345
|
+
warn 'localStorage clear requested but is not supported by this driver'
|
346
|
+
end
|
341
347
|
end
|
342
348
|
end
|
343
349
|
end
|
@@ -346,7 +352,7 @@ private
|
|
346
352
|
@browser.navigate.to(url)
|
347
353
|
sleep 0.1 # slight wait for alert
|
348
354
|
@browser.switch_to.alert.accept
|
349
|
-
rescue modal_error # rubocop:disable Lint/
|
355
|
+
rescue modal_error # rubocop:disable Lint/SuppressedException
|
350
356
|
# alert now gone, should mean navigation happened
|
351
357
|
end
|
352
358
|
|
@@ -378,7 +384,9 @@ private
|
|
378
384
|
alert = @browser.switch_to.alert
|
379
385
|
regexp = text.is_a?(Regexp) ? text : Regexp.new(Regexp.escape(text.to_s))
|
380
386
|
matched = alert.text.match?(regexp)
|
381
|
-
|
387
|
+
unless matched
|
388
|
+
raise Capybara::ModalNotFound, "Unable to find modal dialog with #{text} - found '#{alert.text}' instead."
|
389
|
+
end
|
382
390
|
|
383
391
|
alert
|
384
392
|
end
|
@@ -46,7 +46,7 @@ module Capybara::Selenium::Driver::W3CFirefoxDriver
|
|
46
46
|
begin
|
47
47
|
# Firefox 68 hangs if we try to switch windows while a modal is visible
|
48
48
|
browser.switch_to.alert&.dismiss
|
49
|
-
rescue Selenium::WebDriver::Error::NoSuchAlertError # rubocop:disable Lint/
|
49
|
+
rescue Selenium::WebDriver::Error::NoSuchAlertError # rubocop:disable Lint/SuppressedException
|
50
50
|
# Swallow
|
51
51
|
end
|
52
52
|
end
|
@@ -61,7 +61,7 @@ module Capybara::Selenium::Driver::W3CFirefoxDriver
|
|
61
61
|
accept_modal :confirm, wait: 0.1 do
|
62
62
|
super
|
63
63
|
end
|
64
|
-
rescue Capybara::ModalNotFound # rubocop:disable Lint/
|
64
|
+
rescue Capybara::ModalNotFound # rubocop:disable Lint/SuppressedException
|
65
65
|
# No modal was opened - page has refreshed - ignore
|
66
66
|
end
|
67
67
|
|
@@ -166,17 +166,18 @@ class Capybara::Selenium::Node
|
|
166
166
|
var dragOverOpts = Object.assign({clientX: targetCenter.x, clientY: targetCenter.y}, opts);
|
167
167
|
var dragOverEvent = new DragEvent('dragover', dragOverOpts);
|
168
168
|
target.dispatchEvent(dragOverEvent);
|
169
|
-
window.setTimeout(dragLeave, step_delay, dragOverEvent.defaultPrevented);
|
169
|
+
window.setTimeout(dragLeave, step_delay, dragOverEvent.defaultPrevented, dragOverOpts);
|
170
170
|
}
|
171
171
|
|
172
|
-
function dragLeave(drop) {
|
173
|
-
var
|
172
|
+
function dragLeave(drop, dragOverOpts) {
|
173
|
+
var dragLeaveOptions = Object.assign({}, opts, dragOverOpts);
|
174
|
+
var dragLeaveEvent = new DragEvent('dragleave', dragLeaveOptions);
|
174
175
|
target.dispatchEvent(dragLeaveEvent);
|
175
176
|
if (drop) {
|
176
|
-
var dropEvent = new DragEvent('drop',
|
177
|
+
var dropEvent = new DragEvent('drop', dragLeaveOptions);
|
177
178
|
target.dispatchEvent(dropEvent);
|
178
179
|
}
|
179
|
-
var dragEndEvent = new DragEvent('dragend',
|
180
|
+
var dragEndEvent = new DragEvent('dragend', dragLeaveOptions);
|
180
181
|
source.dispatchEvent(dragEndEvent);
|
181
182
|
callback.call(true);
|
182
183
|
}
|
@@ -54,7 +54,9 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|
54
54
|
# :backspace => send backspace keystrokes to clear the field <br/>
|
55
55
|
# Array => an array of keys to send before the value being set, e.g. [[:command, 'a'], :backspace]
|
56
56
|
def set(value, **options)
|
57
|
-
|
57
|
+
if value.is_a?(Array) && !multiple?
|
58
|
+
raise ArgumentError, "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
|
59
|
+
end
|
58
60
|
|
59
61
|
tag_name, type = attrs(:tagName, :type).map { |val| val&.downcase }
|
60
62
|
@tag_name ||= tag_name
|
@@ -77,10 +79,10 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
|
|
77
79
|
when 'color'
|
78
80
|
set_color(value)
|
79
81
|
else
|
80
|
-
set_text(value, options)
|
82
|
+
set_text(value, **options)
|
81
83
|
end
|
82
84
|
when 'textarea'
|
83
|
-
set_text(value, options)
|
85
|
+
set_text(value, **options)
|
84
86
|
else
|
85
87
|
set_content_editable(value)
|
86
88
|
end
|
@@ -202,7 +204,7 @@ protected
|
|
202
204
|
JS
|
203
205
|
begin
|
204
206
|
driver.execute_script(script, self)
|
205
|
-
rescue StandardError # rubocop:disable Lint/
|
207
|
+
rescue StandardError # rubocop:disable Lint/SuppressedException
|
206
208
|
# Swallow error if scrollIntoView with options isn't supported
|
207
209
|
end
|
208
210
|
end
|
@@ -25,7 +25,9 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
|
|
25
25
|
end
|
26
26
|
super
|
27
27
|
rescue *file_errors => e
|
28
|
-
|
28
|
+
if e.message.match?(/File not found : .+\n.+/m)
|
29
|
+
raise ArgumentError, "Selenium < 3.14 with remote Chrome doesn't support multiple file upload"
|
30
|
+
end
|
29
31
|
|
30
32
|
raise
|
31
33
|
end
|
@@ -34,13 +36,15 @@ class Capybara::Selenium::ChromeNode < Capybara::Selenium::Node
|
|
34
36
|
html5_drop(*args)
|
35
37
|
end
|
36
38
|
|
37
|
-
def click(
|
39
|
+
def click(*, **)
|
38
40
|
super
|
39
41
|
rescue ::Selenium::WebDriver::Error::ElementClickInterceptedError
|
40
42
|
raise
|
41
43
|
rescue ::Selenium::WebDriver::Error::WebDriverError => e
|
42
44
|
# chromedriver 74 (at least on mac) raises the wrong error for this
|
43
|
-
|
45
|
+
if e.message.match?(/element click intercepted/)
|
46
|
+
raise ::Selenium::WebDriver::Error::ElementClickInterceptedError, e.message
|
47
|
+
end
|
44
48
|
|
45
49
|
raise
|
46
50
|
end
|
@@ -25,7 +25,9 @@ class Capybara::Selenium::EdgeNode < Capybara::Selenium::Node
|
|
25
25
|
end
|
26
26
|
super
|
27
27
|
rescue *file_errors => e
|
28
|
-
|
28
|
+
if e.message.match?(/File not found : .+\n.+/m)
|
29
|
+
raise ArgumentError, "Selenium < 3.14 with remote Chrome doesn't support multiple file upload"
|
30
|
+
end
|
29
31
|
|
30
32
|
raise
|
31
33
|
end
|
@@ -14,7 +14,7 @@ class Capybara::Selenium::FirefoxNode < Capybara::Selenium::Node
|
|
14
14
|
warn 'You are attempting to click a table row which has issues in geckodriver/marionette - '\
|
15
15
|
'see https://github.com/mozilla/geckodriver/issues/1228. Your test should probably be '\
|
16
16
|
'clicking on a table cell like a user would. Clicking the first cell in the row instead.'
|
17
|
-
return find_css('th:first-child,td:first-child')[0].click(keys, options)
|
17
|
+
return find_css('th:first-child,td:first-child')[0].click(keys, **options)
|
18
18
|
end
|
19
19
|
raise
|
20
20
|
end
|
data/lib/capybara/server.rb
CHANGED
@@ -24,7 +24,9 @@ module Capybara
|
|
24
24
|
host: Capybara.server_host,
|
25
25
|
reportable_errors: Capybara.server_errors,
|
26
26
|
extra_middleware: [])
|
27
|
-
|
27
|
+
unless deprecated_options.empty?
|
28
|
+
warn 'Positional arguments, other than the application, to Server#new are deprecated, please use keyword arguments'
|
29
|
+
end
|
28
30
|
@app = app
|
29
31
|
@extra_middleware = extra_middleware
|
30
32
|
@server_thread = nil # suppress warnings
|
@@ -61,7 +63,7 @@ module Capybara
|
|
61
63
|
def wait_for_pending_requests
|
62
64
|
timer = Capybara::Helpers.timer(expire_in: 60)
|
63
65
|
while pending_requests?
|
64
|
-
raise
|
66
|
+
raise "Requests did not finish in 60 seconds: #{middleware.pending_requests}" if timer.expired?
|
65
67
|
|
66
68
|
sleep 0.01
|
67
69
|
end
|
@@ -106,7 +108,17 @@ module Capybara
|
|
106
108
|
|
107
109
|
def find_available_port(host)
|
108
110
|
server = TCPServer.new(host, 0)
|
109
|
-
server.addr[1]
|
111
|
+
port = server.addr[1]
|
112
|
+
server.close
|
113
|
+
|
114
|
+
# Workaround issue where some platforms (mac, ???) when passed a host
|
115
|
+
# of '0.0.0.0' will return a port that is only available on one of the
|
116
|
+
# ip addresses that resolves to, but the next binding to that port requires
|
117
|
+
# that port to be available on all ips
|
118
|
+
server = TCPServer.new(host, port)
|
119
|
+
port
|
120
|
+
rescue Errno::EADDRINUSE
|
121
|
+
retry
|
110
122
|
ensure
|
111
123
|
server&.close
|
112
124
|
end
|
@@ -4,19 +4,25 @@ module Capybara
|
|
4
4
|
class Server
|
5
5
|
class Middleware
|
6
6
|
class Counter
|
7
|
-
attr_reader :value
|
8
|
-
|
9
7
|
def initialize
|
10
|
-
@value =
|
8
|
+
@value = []
|
11
9
|
@mutex = Mutex.new
|
12
10
|
end
|
13
11
|
|
14
|
-
def increment
|
15
|
-
@mutex.synchronize { @value
|
12
|
+
def increment(uri)
|
13
|
+
@mutex.synchronize { @value.push(uri) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def decrement(uri)
|
17
|
+
@mutex.synchronize { @value.delete_at(@value.index(uri) || @value.length) }
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
@mutex.synchronize { @value
|
20
|
+
def positive?
|
21
|
+
@mutex.synchronize { @value.length.positive? }
|
22
|
+
end
|
23
|
+
|
24
|
+
def value
|
25
|
+
@mutex.synchronize { @value.dup }
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
@@ -31,8 +37,12 @@ module Capybara
|
|
31
37
|
@server_errors = server_errors
|
32
38
|
end
|
33
39
|
|
40
|
+
def pending_requests
|
41
|
+
@counter.value
|
42
|
+
end
|
43
|
+
|
34
44
|
def pending_requests?
|
35
|
-
@counter.
|
45
|
+
@counter.positive?
|
36
46
|
end
|
37
47
|
|
38
48
|
def clear_error
|
@@ -43,14 +53,14 @@ module Capybara
|
|
43
53
|
if env['PATH_INFO'] == '/__identify__'
|
44
54
|
[200, {}, [@app.object_id.to_s]]
|
45
55
|
else
|
46
|
-
@counter.increment
|
56
|
+
@counter.increment(env['REQUEST_URI'])
|
47
57
|
begin
|
48
58
|
@extended_app.call(env)
|
49
59
|
rescue *@server_errors => e
|
50
60
|
@error ||= e
|
51
61
|
raise e
|
52
62
|
ensure
|
53
|
-
@counter.decrement
|
63
|
+
@counter.decrement(env['REQUEST_URI'])
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
data/lib/capybara/session.rb
CHANGED
@@ -75,7 +75,9 @@ module Capybara
|
|
75
75
|
attr_accessor :synchronized
|
76
76
|
|
77
77
|
def initialize(mode, app = nil)
|
78
|
-
|
78
|
+
if app && !app.respond_to?(:call)
|
79
|
+
raise TypeError, 'The second parameter to Session::new should be a rack app if passed.'
|
80
|
+
end
|
79
81
|
|
80
82
|
@@instance_created = true # rubocop:disable Style/ClassVars
|
81
83
|
@mode = mode
|
@@ -88,7 +90,7 @@ module Capybara
|
|
88
90
|
@server = if config.run_server && @app && driver.needs_server?
|
89
91
|
server_options = { port: config.server_port, host: config.server_host, reportable_errors: config.server_errors }
|
90
92
|
server_options[:extra_middleware] = [Capybara::Server::AnimationDisabler] if config.disable_animation
|
91
|
-
Capybara::Server.new(@app, server_options).boot
|
93
|
+
Capybara::Server.new(@app, **server_options).boot
|
92
94
|
end
|
93
95
|
@touched = false
|
94
96
|
end
|
@@ -494,7 +496,7 @@ module Capybara
|
|
494
496
|
'`within` or `within_frame` blocks.'
|
495
497
|
end
|
496
498
|
|
497
|
-
_switch_to_window(window, options, &window_locator)
|
499
|
+
_switch_to_window(window, **options, &window_locator)
|
498
500
|
end
|
499
501
|
|
500
502
|
##
|
@@ -528,7 +530,7 @@ module Capybara
|
|
528
530
|
when Proc
|
529
531
|
_switch_to_window { window_or_proc.call }
|
530
532
|
else
|
531
|
-
raise ArgumentError
|
533
|
+
raise ArgumentError, '`#within_window` requires a `Capybara::Window` instance or a lambda'
|
532
534
|
end
|
533
535
|
|
534
536
|
begin
|
@@ -721,7 +723,7 @@ module Capybara
|
|
721
723
|
# @param [Hash] options a customizable set of options
|
722
724
|
# @return [String] the path to which the file was saved
|
723
725
|
def save_screenshot(path = nil, **options)
|
724
|
-
prepare_path(path, 'png').tap { |p_path| driver.save_screenshot(p_path, options) }
|
726
|
+
prepare_path(path, 'png').tap { |p_path| driver.save_screenshot(p_path, **options) }
|
725
727
|
end
|
726
728
|
|
727
729
|
##
|
@@ -736,7 +738,7 @@ module Capybara
|
|
736
738
|
# @param [Hash] options a customizable set of options
|
737
739
|
#
|
738
740
|
def save_and_open_screenshot(path = nil, **options)
|
739
|
-
save_screenshot(path, options).tap { |s_path| open_file(s_path) } # rubocop:disable Lint/Debugger
|
741
|
+
save_screenshot(path, **options).tap { |s_path| open_file(s_path) } # rubocop:disable Lint/Debugger
|
740
742
|
end
|
741
743
|
|
742
744
|
def document
|
@@ -819,11 +821,11 @@ module Capybara
|
|
819
821
|
end
|
820
822
|
|
821
823
|
def accept_modal(type, text_or_options, options, &blk)
|
822
|
-
driver.accept_modal(type, modal_options(text_or_options, options), &blk)
|
824
|
+
driver.accept_modal(type, **modal_options(text_or_options, **options), &blk)
|
823
825
|
end
|
824
826
|
|
825
827
|
def dismiss_modal(type, text_or_options, options, &blk)
|
826
|
-
driver.dismiss_modal(type, modal_options(text_or_options, options), &blk)
|
828
|
+
driver.dismiss_modal(type, **modal_options(text_or_options, **options), &blk)
|
827
829
|
end
|
828
830
|
|
829
831
|
def modal_options(text = nil, **options)
|