capybara 2.18.0 → 3.0.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 +4 -4
- data/History.md +55 -1
- data/README.md +18 -17
- data/lib/capybara/config.rb +11 -58
- data/lib/capybara/cucumber.rb +2 -3
- data/lib/capybara/driver/base.rb +15 -16
- data/lib/capybara/driver/node.rb +5 -4
- data/lib/capybara/dsl.rb +1 -0
- data/lib/capybara/helpers.rb +19 -29
- data/lib/capybara/minitest/spec.rb +15 -14
- data/lib/capybara/minitest.rb +139 -138
- data/lib/capybara/node/actions.rb +60 -81
- data/lib/capybara/node/base.rb +11 -18
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +8 -8
- data/lib/capybara/node/element.rb +30 -40
- data/lib/capybara/node/finders.rb +62 -70
- data/lib/capybara/node/matchers.rb +50 -71
- data/lib/capybara/node/simple.rb +11 -17
- data/lib/capybara/queries/ancestor_query.rb +11 -7
- data/lib/capybara/queries/base_query.rb +22 -18
- data/lib/capybara/queries/current_path_query.rb +8 -24
- data/lib/capybara/queries/match_query.rb +3 -7
- data/lib/capybara/queries/selector_query.rb +92 -95
- data/lib/capybara/queries/sibling_query.rb +4 -4
- data/lib/capybara/queries/text_query.rb +35 -35
- data/lib/capybara/queries/title_query.rb +8 -11
- data/lib/capybara/rack_test/browser.rb +15 -18
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +6 -10
- data/lib/capybara/rack_test/form.rb +50 -40
- data/lib/capybara/rack_test/node.rb +93 -63
- data/lib/capybara/rails.rb +2 -6
- data/lib/capybara/result.rb +22 -22
- data/lib/capybara/rspec/compound.rb +5 -10
- data/lib/capybara/rspec/features.rb +17 -48
- data/lib/capybara/rspec/matcher_proxies.rb +31 -15
- data/lib/capybara/rspec/matchers.rb +70 -61
- data/lib/capybara/rspec.rb +5 -10
- data/lib/capybara/selector/css.rb +6 -11
- data/lib/capybara/selector/filter.rb +1 -17
- data/lib/capybara/selector/filter_set.rb +18 -15
- data/lib/capybara/selector/filters/base.rb +7 -6
- data/lib/capybara/selector/filters/expression_filter.rb +6 -23
- data/lib/capybara/selector/filters/node_filter.rb +2 -12
- data/lib/capybara/selector/selector.rb +28 -34
- data/lib/capybara/selector.rb +129 -117
- data/lib/capybara/selenium/driver.rb +131 -125
- data/lib/capybara/selenium/node.rb +197 -115
- data/lib/capybara/server.rb +3 -2
- data/lib/capybara/session/config.rb +47 -67
- data/lib/capybara/session/matchers.rb +8 -7
- data/lib/capybara/session.rb +138 -224
- data/lib/capybara/spec/public/test.js +25 -4
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -0
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -2
- data/lib/capybara/spec/session/accept_prompt_spec.rb +1 -0
- data/lib/capybara/spec/session/all_spec.rb +31 -18
- data/lib/capybara/spec/session/ancestor_spec.rb +6 -8
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +6 -5
- data/lib/capybara/spec/session/assert_current_path.rb +12 -11
- data/lib/capybara/spec/session/assert_selector.rb +1 -0
- data/lib/capybara/spec/session/assert_text.rb +23 -23
- data/lib/capybara/spec/session/assert_title.rb +13 -3
- data/lib/capybara/spec/session/attach_file_spec.rb +51 -30
- data/lib/capybara/spec/session/body_spec.rb +1 -0
- data/lib/capybara/spec/session/check_spec.rb +7 -6
- data/lib/capybara/spec/session/choose_spec.rb +5 -4
- data/lib/capybara/spec/session/click_button_spec.rb +24 -32
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -7
- data/lib/capybara/spec/session/click_link_spec.rb +8 -7
- data/lib/capybara/spec/session/current_scope_spec.rb +4 -3
- data/lib/capybara/spec/session/current_url_spec.rb +17 -6
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -0
- data/lib/capybara/spec/session/element/assert_match_selector.rb +1 -1
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +1 -1
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +5 -5
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +3 -2
- data/lib/capybara/spec/session/evaluate_script_spec.rb +4 -3
- data/lib/capybara/spec/session/execute_script_spec.rb +4 -3
- data/lib/capybara/spec/session/fill_in_spec.rb +30 -5
- data/lib/capybara/spec/session/find_button_spec.rb +4 -3
- data/lib/capybara/spec/session/find_by_id_spec.rb +2 -1
- data/lib/capybara/spec/session/find_field_spec.rb +9 -15
- data/lib/capybara/spec/session/find_link_spec.rb +6 -5
- data/lib/capybara/spec/session/find_spec.rb +37 -31
- data/lib/capybara/spec/session/first_spec.rb +60 -33
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +2 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +9 -16
- data/lib/capybara/spec/session/go_back_spec.rb +1 -0
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +15 -15
- data/lib/capybara/spec/session/has_button_spec.rb +2 -1
- data/lib/capybara/spec/session/has_css_spec.rb +3 -2
- data/lib/capybara/spec/session/has_current_path_spec.rb +12 -28
- data/lib/capybara/spec/session/has_field_spec.rb +4 -3
- data/lib/capybara/spec/session/has_link_spec.rb +1 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +17 -17
- data/lib/capybara/spec/session/has_select_spec.rb +30 -29
- data/lib/capybara/spec/session/has_selector_spec.rb +5 -4
- data/lib/capybara/spec/session/has_table_spec.rb +2 -1
- data/lib/capybara/spec/session/has_text_spec.rb +9 -13
- data/lib/capybara/spec/session/has_title_spec.rb +1 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
- data/lib/capybara/spec/session/headers.rb +2 -1
- data/lib/capybara/spec/session/html_spec.rb +1 -0
- data/lib/capybara/spec/session/node_spec.rb +91 -56
- data/lib/capybara/spec/session/node_wrapper_spec.rb +36 -0
- data/lib/capybara/spec/session/refresh_spec.rb +6 -2
- data/lib/capybara/spec/session/reset_session_spec.rb +19 -0
- data/lib/capybara/spec/session/response_code.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -11
- data/lib/capybara/spec/session/save_page_spec.rb +1 -17
- data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -3
- data/lib/capybara/spec/session/select_spec.rb +20 -20
- data/lib/capybara/spec/session/selectors_spec.rb +2 -2
- data/lib/capybara/spec/session/sibling_spec.rb +1 -1
- data/lib/capybara/spec/session/text_spec.rb +17 -3
- data/lib/capybara/spec/session/title_spec.rb +11 -1
- data/lib/capybara/spec/session/uncheck_spec.rb +4 -3
- data/lib/capybara/spec/session/unselect_spec.rb +6 -5
- data/lib/capybara/spec/session/visit_spec.rb +9 -3
- data/lib/capybara/spec/session/window/become_closed_spec.rb +2 -1
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +2 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -1
- data/lib/capybara/spec/session/window/window_spec.rb +12 -12
- data/lib/capybara/spec/session/window/windows_spec.rb +2 -3
- data/lib/capybara/spec/session/window/within_window_spec.rb +15 -71
- data/lib/capybara/spec/session/within_spec.rb +1 -0
- data/lib/capybara/spec/spec_helper.rb +34 -18
- data/lib/capybara/spec/test_app.rb +17 -9
- data/lib/capybara/spec/views/form.erb +7 -0
- data/lib/capybara/spec/views/with_html.erb +23 -1
- data/lib/capybara/spec/views/within_frames.erb +4 -1
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +6 -10
- data/lib/capybara.rb +28 -25
- data/spec/basic_node_spec.rb +1 -0
- data/spec/capybara_spec.rb +11 -50
- data/spec/dsl_spec.rb +5 -13
- data/spec/filter_set_spec.rb +5 -4
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +3 -2
- data/spec/minitest_spec.rb +4 -3
- data/spec/minitest_spec_spec.rb +3 -2
- data/spec/per_session_config_spec.rb +9 -8
- data/spec/rack_test_spec.rb +21 -20
- data/spec/result_spec.rb +17 -16
- data/spec/rspec/features_spec.rb +17 -14
- data/spec/rspec/scenarios_spec.rb +5 -7
- data/spec/rspec/shared_spec_matchers.rb +96 -99
- data/spec/rspec/views_spec.rb +2 -1
- data/spec/rspec_matchers_spec.rb +18 -2
- data/spec/rspec_spec.rb +11 -15
- data/spec/selector_spec.rb +5 -6
- data/spec/selenium_spec_chrome.rb +9 -4
- data/spec/selenium_spec_edge.rb +27 -0
- data/spec/selenium_spec_ie.rb +31 -0
- data/spec/selenium_spec_marionette.rb +28 -12
- data/spec/server_spec.rb +33 -33
- data/spec/session_spec.rb +2 -1
- data/spec/shared_selenium_session.rb +36 -22
- data/spec/spec_helper.rb +3 -6
- metadata +68 -85
- data/lib/capybara/query.rb +0 -7
- data/spec/selenium_spec_firefox.rb +0 -68
data/lib/capybara/session.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'capybara/session/matchers'
|
3
4
|
require 'addressable/uri'
|
4
5
|
|
5
6
|
module Capybara
|
6
|
-
|
7
7
|
##
|
8
8
|
#
|
9
9
|
# The Session class represents a single user's interaction with the system. The Session can use
|
@@ -38,64 +38,63 @@ module Capybara
|
|
38
38
|
class Session
|
39
39
|
include Capybara::SessionMatchers
|
40
40
|
|
41
|
-
NODE_METHODS = [
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
]
|
41
|
+
NODE_METHODS = %i[
|
42
|
+
all first attach_file text check choose
|
43
|
+
click_link_or_button click_button click_link
|
44
|
+
fill_in find find_all find_button find_by_id find_field find_link
|
45
|
+
has_content? has_text? has_css? has_no_content? has_no_text?
|
46
|
+
has_no_css? has_no_xpath? resolve has_xpath? select uncheck
|
47
|
+
has_link? has_no_link? has_button? has_no_button? has_field?
|
48
|
+
has_no_field? has_checked_field? has_unchecked_field?
|
49
|
+
has_no_table? has_table? unselect has_select? has_no_select?
|
50
|
+
has_selector? has_no_selector? click_on has_no_checked_field?
|
51
|
+
has_no_unchecked_field? query assert_selector assert_no_selector
|
52
|
+
assert_all_of_selectors assert_none_of_selectors
|
53
|
+
refute_selector assert_text assert_no_text
|
54
|
+
].freeze
|
55
55
|
# @api private
|
56
|
-
DOCUMENT_METHODS = [
|
57
|
-
|
58
|
-
]
|
59
|
-
SESSION_METHODS = [
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
] + DOCUMENT_METHODS
|
69
|
-
MODAL_METHODS = [
|
70
|
-
|
71
|
-
|
72
|
-
]
|
56
|
+
DOCUMENT_METHODS = %i[
|
57
|
+
title assert_title assert_no_title has_title? has_no_title?
|
58
|
+
].freeze
|
59
|
+
SESSION_METHODS = %i[
|
60
|
+
body html source current_url current_host current_path
|
61
|
+
execute_script evaluate_script visit refresh go_back go_forward
|
62
|
+
within within_element within_fieldset within_table within_frame switch_to_frame
|
63
|
+
current_window windows open_new_window switch_to_window within_window window_opened_by
|
64
|
+
save_page save_and_open_page save_screenshot
|
65
|
+
save_and_open_screenshot reset_session! response_headers
|
66
|
+
status_code current_scope
|
67
|
+
assert_current_path assert_no_current_path has_current_path? has_no_current_path?
|
68
|
+
].freeze + DOCUMENT_METHODS
|
69
|
+
MODAL_METHODS = %i[
|
70
|
+
accept_alert accept_confirm dismiss_confirm accept_prompt dismiss_prompt
|
71
|
+
].freeze
|
73
72
|
DSL_METHODS = NODE_METHODS + SESSION_METHODS + MODAL_METHODS
|
74
73
|
|
75
74
|
attr_reader :mode, :app, :server
|
76
75
|
attr_accessor :synchronized
|
77
76
|
|
78
|
-
def initialize(mode, app=nil)
|
77
|
+
def initialize(mode, app = nil)
|
79
78
|
raise TypeError, "The second parameter to Session::new should be a rack app if passed." if app && !app.respond_to?(:call)
|
80
79
|
@@instance_created = true
|
81
80
|
@mode = mode
|
82
81
|
@app = app
|
83
82
|
if block_given?
|
84
83
|
raise "A configuration block is only accepted when Capybara.threadsafe == true" unless Capybara.threadsafe
|
85
|
-
yield config
|
84
|
+
yield config
|
86
85
|
end
|
87
|
-
if config.run_server and @app and driver.needs_server?
|
88
|
-
|
86
|
+
@server = if config.run_server and @app and driver.needs_server?
|
87
|
+
Capybara::Server.new(@app, config.server_port, config.server_host, config.server_errors).boot
|
89
88
|
else
|
90
|
-
|
89
|
+
nil
|
91
90
|
end
|
92
91
|
@touched = false
|
93
92
|
end
|
94
93
|
|
95
94
|
def driver
|
96
95
|
@driver ||= begin
|
97
|
-
unless Capybara.drivers.
|
98
|
-
other_drivers = Capybara.drivers.keys.map
|
96
|
+
unless Capybara.drivers.key?(mode)
|
97
|
+
other_drivers = Capybara.drivers.keys.map(&:inspect)
|
99
98
|
raise Capybara::DriverNotFoundError, "no driver called #{mode.inspect} was found, available drivers: #{other_drivers.join(', ')}"
|
100
99
|
end
|
101
100
|
driver = Capybara.drivers[mode].call(app)
|
@@ -145,7 +144,7 @@ module Capybara
|
|
145
144
|
raise CapybaraError, "Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true"
|
146
145
|
end
|
147
146
|
rescue CapybaraError
|
148
|
-
#needed to get the cause set correctly in JRuby -- otherwise we could just do raise @server.error
|
147
|
+
# needed to get the cause set correctly in JRuby -- otherwise we could just do raise @server.error
|
149
148
|
raise @server.error, @server.error.message, @server.error.backtrace
|
150
149
|
ensure
|
151
150
|
@server.reset_error!
|
@@ -196,8 +195,9 @@ module Capybara
|
|
196
195
|
|
197
196
|
# Addressable doesn't support opaque URIs - we want nil here
|
198
197
|
return nil if uri.scheme == "about"
|
198
|
+
|
199
199
|
path = uri.path
|
200
|
-
path if path
|
200
|
+
path if path && !path.empty?
|
201
201
|
end
|
202
202
|
|
203
203
|
##
|
@@ -259,15 +259,15 @@ module Capybara
|
|
259
259
|
if visit_uri.relative?
|
260
260
|
uri_base.port ||= @server.port if @server && config.always_include_port
|
261
261
|
|
262
|
-
visit_uri_parts = visit_uri.to_hash.delete_if { |
|
262
|
+
visit_uri_parts = visit_uri.to_hash.delete_if { |_k, v| v.nil? }
|
263
263
|
|
264
264
|
# Useful to people deploying to a subdirectory
|
265
265
|
# and/or single page apps where only the url fragment changes
|
266
266
|
visit_uri_parts[:path] = uri_base.path + visit_uri.path
|
267
267
|
|
268
268
|
visit_uri = uri_base.merge(visit_uri_parts)
|
269
|
-
|
270
|
-
visit_uri.port ||= @server.port
|
269
|
+
elsif @server && config.always_include_port
|
270
|
+
visit_uri.port ||= @server.port
|
271
271
|
end
|
272
272
|
end
|
273
273
|
|
@@ -335,7 +335,7 @@ module Capybara
|
|
335
335
|
# @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
|
336
336
|
#
|
337
337
|
def within(*args)
|
338
|
-
new_scope =
|
338
|
+
new_scope = args.first.respond_to?(:to_capybara_node) ? args.first.to_capybara_node : find(*args)
|
339
339
|
begin
|
340
340
|
scopes.push(new_scope)
|
341
341
|
yield
|
@@ -352,9 +352,7 @@ module Capybara
|
|
352
352
|
# @param [String] locator Id or legend of the fieldset
|
353
353
|
#
|
354
354
|
def within_fieldset(locator)
|
355
|
-
within
|
356
|
-
yield
|
357
|
-
end
|
355
|
+
within(:fieldset, locator) { yield }
|
358
356
|
end
|
359
357
|
|
360
358
|
##
|
@@ -364,9 +362,7 @@ module Capybara
|
|
364
362
|
# @param [String] locator Id or caption of the table
|
365
363
|
#
|
366
364
|
def within_table(locator)
|
367
|
-
within
|
368
|
-
yield
|
369
|
-
end
|
365
|
+
within(:table, locator) { yield }
|
370
366
|
end
|
371
367
|
|
372
368
|
##
|
@@ -390,15 +386,19 @@ module Capybara
|
|
390
386
|
driver.switch_to_frame(frame)
|
391
387
|
scopes.push(:frame)
|
392
388
|
when :parent
|
393
|
-
|
394
|
-
|
389
|
+
if scopes.last != :frame
|
390
|
+
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's "\
|
391
|
+
"`within` block."
|
392
|
+
end
|
395
393
|
scopes.pop
|
396
394
|
driver.switch_to_frame(:parent)
|
397
395
|
when :top
|
398
396
|
idx = scopes.index(:frame)
|
399
397
|
if idx
|
400
|
-
|
401
|
-
|
398
|
+
if scopes.slice(idx..-1).any? { |scope| ![:frame, nil].include?(scope) }
|
399
|
+
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's "\
|
400
|
+
"`within` block."
|
401
|
+
end
|
402
402
|
scopes.slice!(idx..-1)
|
403
403
|
driver.switch_to_frame(:top)
|
404
404
|
end
|
@@ -413,34 +413,16 @@ module Capybara
|
|
413
413
|
# @overload within_frame(element)
|
414
414
|
# @param [Capybara::Node::Element] frame element
|
415
415
|
# @overload within_frame([kind = :frame], locator, options = {})
|
416
|
-
# @param [
|
416
|
+
# @param [Symbol] kind Optional selector type (:css, :xpath, :field, etc.) - Defaults to :frame
|
417
417
|
# @param [String] locator The locator for the given selector kind. For :frame this is the name/id of a frame/iframe element
|
418
418
|
# @overload within_frame(index)
|
419
419
|
# @param [Integer] index index of a frame (0 based)
|
420
420
|
def within_frame(*args)
|
421
|
-
|
422
|
-
|
421
|
+
switch_to_frame(_find_frame(*args))
|
423
422
|
begin
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
ensure
|
428
|
-
switch_to_frame(:parent)
|
429
|
-
end
|
430
|
-
rescue Capybara::NotSupportedByDriverError
|
431
|
-
# Support older driver frame API for now
|
432
|
-
if driver.respond_to?(:within_frame)
|
433
|
-
begin
|
434
|
-
scopes.push(:frame)
|
435
|
-
driver.within_frame(frame) do
|
436
|
-
yield
|
437
|
-
end
|
438
|
-
ensure
|
439
|
-
scopes.pop
|
440
|
-
end
|
441
|
-
else
|
442
|
-
raise
|
443
|
-
end
|
423
|
+
yield
|
424
|
+
ensure
|
425
|
+
switch_to_frame(:parent)
|
444
426
|
end
|
445
427
|
end
|
446
428
|
|
@@ -493,15 +475,11 @@ module Capybara
|
|
493
475
|
# `within_frame` methods
|
494
476
|
# @raise [ArgumentError] if both or neither arguments were provided
|
495
477
|
#
|
496
|
-
def switch_to_window(window = nil, options
|
497
|
-
options, window = window, nil if window.is_a? Hash
|
498
|
-
|
478
|
+
def switch_to_window(window = nil, **options, &window_locator)
|
499
479
|
block_given = block_given?
|
500
|
-
if window && block_given
|
501
|
-
|
502
|
-
|
503
|
-
raise ArgumentError, "`switch_to_window`: either window or block should be provided"
|
504
|
-
elsif !scopes.last.nil?
|
480
|
+
raise ArgumentError, "`switch_to_window` can take either a block or a window, not both" if window && block_given
|
481
|
+
raise ArgumentError, "`switch_to_window`: either window or block should be provided" if !window && !block_given
|
482
|
+
unless scopes.last.nil?
|
505
483
|
raise Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from "\
|
506
484
|
"`within` or `within_frame` blocks."
|
507
485
|
end
|
@@ -526,51 +504,30 @@ module Capybara
|
|
526
504
|
# @example
|
527
505
|
# within_window(->{ page.title == 'Page title' }) { click_button 'Submit' }
|
528
506
|
# @raise [Capybara::WindowError] if no window matching lambda was found
|
529
|
-
# @overload within_window(string) { do_something }
|
530
|
-
# @deprecated Pass window or lambda instead
|
531
|
-
# @param [String] handle, name, url or title of the window
|
532
507
|
#
|
533
508
|
# @raise [Capybara::ScopeError] if this method is invoked inside `within_frame` method
|
534
509
|
# @return value returned by the block
|
535
510
|
#
|
536
|
-
def within_window(
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
ensure
|
548
|
-
scopes.pop
|
549
|
-
end
|
550
|
-
elsif window_or_handle.is_a?(Proc)
|
551
|
-
original = current_window
|
552
|
-
scopes << nil
|
553
|
-
begin
|
554
|
-
_switch_to_window { window_or_handle.call }
|
555
|
-
begin
|
556
|
-
yield
|
557
|
-
ensure
|
558
|
-
_switch_to_window(original)
|
559
|
-
end
|
560
|
-
ensure
|
561
|
-
scopes.pop
|
511
|
+
def within_window(window_or_proc)
|
512
|
+
original = current_window
|
513
|
+
scopes << nil
|
514
|
+
begin
|
515
|
+
case window_or_proc
|
516
|
+
when Capybara::Window
|
517
|
+
_switch_to_window(window_or_proc) unless original == window_or_proc
|
518
|
+
when Proc
|
519
|
+
_switch_to_window { window_or_proc.call }
|
520
|
+
else
|
521
|
+
raise ArgumentError("`#within_window` requires a `Capybara::Window` instance or a lambda")
|
562
522
|
end
|
563
|
-
|
564
|
-
offending_line = caller.first
|
565
|
-
file_line = offending_line.match(/^(.+?):(\d+)/)[0]
|
566
|
-
warn "DEPRECATION WARNING: Passing string argument to #within_window is deprecated. "\
|
567
|
-
"Pass window object or lambda. (called from #{file_line})"
|
523
|
+
|
568
524
|
begin
|
569
|
-
|
570
|
-
driver.within_window(window_or_handle) { yield }
|
525
|
+
yield
|
571
526
|
ensure
|
572
|
-
|
527
|
+
_switch_to_window(original) unless original == window_or_proc
|
573
528
|
end
|
529
|
+
ensure
|
530
|
+
scopes.pop
|
574
531
|
end
|
575
532
|
end
|
576
533
|
|
@@ -580,15 +537,16 @@ module Capybara
|
|
580
537
|
# It's better to use this method than `windows.last`
|
581
538
|
# {https://dvcs.w3.org/hg/webdriver/raw-file/default/webdriver-spec.html#h_note_10 as order of windows isn't defined in some drivers}
|
582
539
|
#
|
583
|
-
# @
|
584
|
-
#
|
585
|
-
#
|
586
|
-
#
|
587
|
-
#
|
540
|
+
# @overload window_opened_by(**options, &block)
|
541
|
+
# @param options [Hash]
|
542
|
+
# @option options [Numeric] :wait (Capybara.default_max_wait_time) maximum wait time
|
543
|
+
# @return [Capybara::Window] the window that has been opened within a block
|
544
|
+
# @raise [Capybara::WindowError] if block passed to window hasn't opened window
|
545
|
+
# or opened more than one window
|
588
546
|
#
|
589
|
-
def window_opened_by(options
|
547
|
+
def window_opened_by(**options)
|
590
548
|
old_handles = driver.window_handles
|
591
|
-
|
549
|
+
yield
|
592
550
|
|
593
551
|
wait_time = Capybara::Queries::BaseQuery.wait(options, config.default_max_wait_time)
|
594
552
|
document.synchronize(wait_time, errors: [Capybara::WindowError]) do
|
@@ -612,12 +570,7 @@ module Capybara
|
|
612
570
|
#
|
613
571
|
def execute_script(script, *args)
|
614
572
|
@touched = true
|
615
|
-
|
616
|
-
driver.execute_script(script)
|
617
|
-
else
|
618
|
-
raise Capybara::NotSupportedByDriverError, "The current driver does not support execute_script arguments" if driver.method(:execute_script).arity == 1
|
619
|
-
driver.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
620
|
-
end
|
573
|
+
driver.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg })
|
621
574
|
end
|
622
575
|
|
623
576
|
##
|
@@ -631,12 +584,7 @@ module Capybara
|
|
631
584
|
#
|
632
585
|
def evaluate_script(script, *args)
|
633
586
|
@touched = true
|
634
|
-
result =
|
635
|
-
driver.evaluate_script(script)
|
636
|
-
else
|
637
|
-
raise Capybara::NotSupportedByDriverError, "The current driver does not support evaluate_script arguments" if driver.method(:evaluate_script).arity == 1
|
638
|
-
driver.evaluate_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
639
|
-
end
|
587
|
+
result = driver.evaluate_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg })
|
640
588
|
element_script_result(result)
|
641
589
|
end
|
642
590
|
|
@@ -649,12 +597,7 @@ module Capybara
|
|
649
597
|
#
|
650
598
|
def evaluate_async_script(script, *args)
|
651
599
|
@touched = true
|
652
|
-
result =
|
653
|
-
driver.evaluate_async_script(script)
|
654
|
-
else
|
655
|
-
raise Capybara::NotSupportedByDriverError, "The current driver does not support evaluate_async_script arguments" if driver.method(:evaluate_async_script).arity == 1
|
656
|
-
driver.evaluate_async_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg} )
|
657
|
-
end
|
600
|
+
result = driver.evaluate_async_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.base : arg })
|
658
601
|
element_script_result(result)
|
659
602
|
end
|
660
603
|
|
@@ -678,9 +621,8 @@ module Capybara
|
|
678
621
|
# @return [String] the message shown in the modal
|
679
622
|
# @raise [Capybara::ModalNotFound] if modal dialog hasn't been found
|
680
623
|
#
|
681
|
-
|
682
|
-
|
683
|
-
accept_modal(:alert, text_or_options, options, &blk)
|
624
|
+
def accept_alert(text = nil, **options, &blk)
|
625
|
+
accept_modal(:alert, text, options, &blk)
|
684
626
|
end
|
685
627
|
|
686
628
|
##
|
@@ -689,8 +631,8 @@ module Capybara
|
|
689
631
|
#
|
690
632
|
# @macro modal_params
|
691
633
|
#
|
692
|
-
def accept_confirm(
|
693
|
-
accept_modal(:confirm,
|
634
|
+
def accept_confirm(text = nil, **options, &blk)
|
635
|
+
accept_modal(:confirm, text, options, &blk)
|
694
636
|
end
|
695
637
|
|
696
638
|
##
|
@@ -699,8 +641,8 @@ module Capybara
|
|
699
641
|
#
|
700
642
|
# @macro modal_params
|
701
643
|
#
|
702
|
-
def dismiss_confirm(
|
703
|
-
dismiss_modal(:confirm,
|
644
|
+
def dismiss_confirm(text = nil, **options, &blk)
|
645
|
+
dismiss_modal(:confirm, text, options, &blk)
|
704
646
|
end
|
705
647
|
|
706
648
|
##
|
@@ -710,8 +652,8 @@ module Capybara
|
|
710
652
|
# @macro modal_params
|
711
653
|
# @option options [String] :with Response to provide to the prompt
|
712
654
|
#
|
713
|
-
def accept_prompt(
|
714
|
-
accept_modal(:prompt,
|
655
|
+
def accept_prompt(text = nil, **options, &blk)
|
656
|
+
accept_modal(:prompt, text, options, &blk)
|
715
657
|
end
|
716
658
|
|
717
659
|
##
|
@@ -720,8 +662,8 @@ module Capybara
|
|
720
662
|
#
|
721
663
|
# @macro modal_params
|
722
664
|
#
|
723
|
-
def dismiss_prompt(
|
724
|
-
dismiss_modal(:prompt,
|
665
|
+
def dismiss_prompt(text = nil, **options, &blk)
|
666
|
+
dismiss_modal(:prompt, text, options, &blk)
|
725
667
|
end
|
726
668
|
|
727
669
|
##
|
@@ -731,17 +673,15 @@ module Capybara
|
|
731
673
|
#
|
732
674
|
# If invoked without arguments it will save file to `Capybara.save_path`
|
733
675
|
# and file will be given randomly generated filename. If invoked with a relative path
|
734
|
-
# the path will be relative to `Capybara.save_path
|
735
|
-
# the previous behavior with `Capybara.save_and_open_page_path` where the relative path was
|
736
|
-
# relative to Dir.pwd
|
676
|
+
# the path will be relative to `Capybara.save_path`
|
737
677
|
#
|
738
678
|
# @param [String] path the path to where it should be saved
|
739
679
|
# @return [String] the path to which the file was saved
|
740
680
|
#
|
741
681
|
def save_page(path = nil)
|
742
|
-
|
743
|
-
|
744
|
-
|
682
|
+
prepare_path(path, 'html').tap do |p|
|
683
|
+
File.write(p, Capybara::Helpers.inject_asset_host(body, host: config.asset_host), mode: 'wb')
|
684
|
+
end
|
745
685
|
end
|
746
686
|
|
747
687
|
##
|
@@ -750,15 +690,12 @@ module Capybara
|
|
750
690
|
#
|
751
691
|
# If invoked without arguments it will save file to `Capybara.save_path`
|
752
692
|
# and file will be given randomly generated filename. If invoked with a relative path
|
753
|
-
# the path will be relative to `Capybara.save_path
|
754
|
-
# the previous behavior with `Capybara.save_and_open_page_path` where the relative path was
|
755
|
-
# relative to Dir.pwd
|
693
|
+
# the path will be relative to `Capybara.save_path`
|
756
694
|
#
|
757
695
|
# @param [String] path the path to where it should be saved
|
758
696
|
#
|
759
697
|
def save_and_open_page(path = nil)
|
760
|
-
path
|
761
|
-
open_file(path)
|
698
|
+
save_page(path).tap { |p| open_file(p) }
|
762
699
|
end
|
763
700
|
|
764
701
|
##
|
@@ -767,17 +704,13 @@ module Capybara
|
|
767
704
|
#
|
768
705
|
# If invoked without arguments it will save file to `Capybara.save_path`
|
769
706
|
# and file will be given randomly generated filename. If invoked with a relative path
|
770
|
-
# the path will be relative to `Capybara.save_path
|
771
|
-
# the previous behavior with `Capybara.save_and_open_page_path` where the relative path was
|
772
|
-
# relative to Dir.pwd
|
707
|
+
# the path will be relative to `Capybara.save_path`
|
773
708
|
#
|
774
709
|
# @param [String] path the path to where it should be saved
|
775
710
|
# @param [Hash] options a customizable set of options
|
776
711
|
# @return [String] the path to which the file was saved
|
777
|
-
def save_screenshot(path = nil, options
|
778
|
-
|
779
|
-
driver.save_screenshot(path, options)
|
780
|
-
path
|
712
|
+
def save_screenshot(path = nil, **options)
|
713
|
+
prepare_path(path, 'png').tap { |p| driver.save_screenshot(p, options) }
|
781
714
|
end
|
782
715
|
|
783
716
|
##
|
@@ -786,16 +719,15 @@ module Capybara
|
|
786
719
|
#
|
787
720
|
# If invoked without arguments it will save file to `Capybara.save_path`
|
788
721
|
# and file will be given randomly generated filename. If invoked with a relative path
|
789
|
-
# the path will be relative to `Capybara.save_path
|
790
|
-
# the previous behavior with `Capybara.save_and_open_page_path` where the relative path was
|
791
|
-
# relative to Dir.pwd
|
722
|
+
# the path will be relative to `Capybara.save_path`
|
792
723
|
#
|
793
724
|
# @param [String] path the path to where it should be saved
|
794
725
|
# @param [Hash] options a customizable set of options
|
795
726
|
#
|
796
|
-
def save_and_open_screenshot(path = nil, options
|
797
|
-
|
798
|
-
|
727
|
+
def save_and_open_screenshot(path = nil, **options)
|
728
|
+
# rubocop:disable Lint/Debugger
|
729
|
+
save_screenshot(path, options).tap { |p| open_file(p) }
|
730
|
+
# rubocop:enable Lint/Debugger
|
799
731
|
end
|
800
732
|
|
801
733
|
def document
|
@@ -821,8 +753,7 @@ module Capybara
|
|
821
753
|
|
822
754
|
def current_scope
|
823
755
|
scope = scopes.last
|
824
|
-
|
825
|
-
scope
|
756
|
+
[nil, :frame].include?(scope) ? document : scope
|
826
757
|
end
|
827
758
|
|
828
759
|
##
|
@@ -864,6 +795,7 @@ module Capybara
|
|
864
795
|
Capybara::ReadOnlySessionConfig.new(Capybara.session_options)
|
865
796
|
end
|
866
797
|
end
|
798
|
+
|
867
799
|
private
|
868
800
|
|
869
801
|
@@instance_created = false
|
@@ -876,32 +808,21 @@ module Capybara
|
|
876
808
|
driver.dismiss_modal(type, modal_options(text_or_options, options), &blk)
|
877
809
|
end
|
878
810
|
|
879
|
-
def modal_options(
|
880
|
-
|
881
|
-
options[:text] ||= text_or_options unless text_or_options.nil?
|
811
|
+
def modal_options(text = nil, **options)
|
812
|
+
options[:text] ||= text unless text.nil?
|
882
813
|
options[:wait] ||= config.default_max_wait_time
|
883
814
|
options
|
884
815
|
end
|
885
816
|
|
886
|
-
|
887
817
|
def open_file(path)
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
warn "File saved to #{path}."
|
893
|
-
warn "Please install the launchy gem to open the file automatically."
|
894
|
-
end
|
818
|
+
require "launchy"
|
819
|
+
Launchy.open(path)
|
820
|
+
rescue LoadError
|
821
|
+
warn "File saved to #{path}.\nPlease install the launchy gem to open the file automatically."
|
895
822
|
end
|
896
823
|
|
897
824
|
def prepare_path(path, extension)
|
898
|
-
|
899
|
-
path = File.expand_path(path || default_fn(extension), config.save_path)
|
900
|
-
else
|
901
|
-
path = File.expand_path(default_fn(extension), config.save_and_open_page_path) if path.nil?
|
902
|
-
end
|
903
|
-
FileUtils.mkdir_p(File.dirname(path))
|
904
|
-
path
|
825
|
+
File.expand_path(path || default_fn(extension), config.save_path).tap { |p| FileUtils.mkdir_p(File.dirname(p)) }
|
905
826
|
end
|
906
827
|
|
907
828
|
def default_fn(extension)
|
@@ -927,26 +848,22 @@ module Capybara
|
|
927
848
|
end
|
928
849
|
|
929
850
|
def _find_frame(*args)
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
raise TypeError
|
943
|
-
end
|
851
|
+
case args[0]
|
852
|
+
when Capybara::Node::Element
|
853
|
+
args[0]
|
854
|
+
when String, Hash
|
855
|
+
find(:frame, *args)
|
856
|
+
when Symbol
|
857
|
+
find(*args)
|
858
|
+
when Integer
|
859
|
+
idx = args[0]
|
860
|
+
all(:frame, minimum: idx + 1)[idx]
|
861
|
+
else
|
862
|
+
raise TypeError
|
944
863
|
end
|
945
864
|
end
|
946
865
|
|
947
|
-
def _switch_to_window(window = nil, options
|
948
|
-
options, window = window, nil if window.is_a? Hash
|
949
|
-
|
866
|
+
def _switch_to_window(window = nil, **options)
|
950
867
|
raise Capybara::ScopeError, "Window cannot be switched inside a `within_frame` block" if scopes.include?(:frame)
|
951
868
|
raise Capybara::ScopeError, "Window cannot be switch inside a `within` block" unless scopes.last.nil?
|
952
869
|
|
@@ -960,9 +877,7 @@ module Capybara
|
|
960
877
|
begin
|
961
878
|
driver.window_handles.each do |handle|
|
962
879
|
driver.switch_to_window handle
|
963
|
-
if yield
|
964
|
-
return Window.new(self, handle)
|
965
|
-
end
|
880
|
+
return Window.new(self, handle) if yield
|
966
881
|
end
|
967
882
|
rescue => e
|
968
883
|
driver.switch_to_window(original_window_handle)
|
@@ -974,6 +889,5 @@ module Capybara
|
|
974
889
|
end
|
975
890
|
end
|
976
891
|
end
|
977
|
-
|
978
892
|
end
|
979
893
|
end
|