Support filter block with current_path assertions and expectations
This commit is contained in:
parent
f43b6499ec
commit
f98c699a4c
|
@ -50,10 +50,10 @@ module Capybara
|
|||
|
||||
%w[text no_text title no_title current_path no_current_path].each do |assertion_name|
|
||||
class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
|
||||
def assert_#{assertion_name}(*args, **kwargs)
|
||||
def assert_#{assertion_name}(*args, **kwargs, &optional_filter_block)
|
||||
self.assertions +=1
|
||||
subject, args = determine_subject(args)
|
||||
subject.assert_#{assertion_name}(*args, **kwargs)
|
||||
subject.assert_#{assertion_name}(*args, **kwargs, &optional_filter_block)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
|
|
|
@ -6,26 +6,30 @@ module Capybara
|
|||
# @api private
|
||||
module Queries
|
||||
class CurrentPathQuery < BaseQuery
|
||||
def initialize(expected_path, **options)
|
||||
def initialize(expected_path, **options, &optional_filter_block)
|
||||
super(options)
|
||||
@expected_path = expected_path
|
||||
@options = {
|
||||
url: !@expected_path.is_a?(Regexp) && !::Addressable::URI.parse(@expected_path || '').hostname.nil?,
|
||||
ignore_query: false
|
||||
}.merge(options)
|
||||
@filter_block = optional_filter_block
|
||||
assert_valid_keys
|
||||
end
|
||||
|
||||
def resolves_for?(session)
|
||||
uri = ::Addressable::URI.parse(session.current_url)
|
||||
uri&.query = nil if options[:ignore_query]
|
||||
@actual_path = options[:url] ? uri&.to_s : uri&.request_uri
|
||||
@actual_path = (options[:ignore_query] ? uri&.omit(:query) : uri).yield_self do |u|
|
||||
options[:url] ? u&.to_s : u&.request_uri
|
||||
end
|
||||
|
||||
if @expected_path.is_a? Regexp
|
||||
res = if @expected_path.is_a? Regexp
|
||||
@actual_path.to_s.match?(@expected_path)
|
||||
else
|
||||
::Addressable::URI.parse(@expected_path) == ::Addressable::URI.parse(@actual_path)
|
||||
end
|
||||
|
||||
res && matches_filter_block?(uri)
|
||||
end
|
||||
|
||||
def failure_message
|
||||
|
@ -38,6 +42,12 @@ module Capybara
|
|||
|
||||
private
|
||||
|
||||
def matches_filter_block?(url)
|
||||
return true unless @filter_block
|
||||
|
||||
@filter_block.call(url)
|
||||
end
|
||||
|
||||
def failure_message_helper(negated = '')
|
||||
verb = @expected_path.is_a?(Regexp) ? 'match' : 'equal'
|
||||
"expected #{@actual_path.inspect}#{negated} to #{verb} #{@expected_path.inspect}"
|
||||
|
|
|
@ -6,7 +6,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|||
# That check should be based solely on the form element's 'enctype' attribute value,
|
||||
# which should probably be provided to Rack::Test in its non-GET request methods.
|
||||
class NilUploadedFile < Rack::Test::UploadedFile
|
||||
def initialize # rubocop:disable Lint/MissingSuper
|
||||
def initialize
|
||||
@empty_file = Tempfile.new('nil_uploaded_file')
|
||||
@empty_file.close
|
||||
end
|
||||
|
|
|
@ -139,8 +139,8 @@ module Capybara
|
|||
# RSpec matcher for the current path.
|
||||
#
|
||||
# @see Capybara::SessionMatchers#assert_current_path
|
||||
def have_current_path(path, **options)
|
||||
Matchers::HaveCurrentPath.new(path, **options)
|
||||
def have_current_path(path, **options, &optional_filter_block)
|
||||
Matchers::HaveCurrentPath.new(path, **options, &optional_filter_block)
|
||||
end
|
||||
|
||||
# RSpec matcher for element style.
|
||||
|
|
|
@ -7,11 +7,11 @@ module Capybara
|
|||
module Matchers
|
||||
class HaveCurrentPath < WrappedElementMatcher
|
||||
def element_matches?(el)
|
||||
el.assert_current_path(current_path, **@kw_args)
|
||||
el.assert_current_path(current_path, **@kw_args, &@filter_block)
|
||||
end
|
||||
|
||||
def element_does_not_match?(el)
|
||||
el.assert_no_current_path(current_path, **@kw_args)
|
||||
el.assert_no_current_path(current_path, **@kw_args, &@filter_block)
|
||||
end
|
||||
|
||||
def description
|
||||
|
|
|
@ -19,8 +19,8 @@ module Capybara
|
|||
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
||||
# @return [true]
|
||||
#
|
||||
def assert_current_path(path, **options)
|
||||
_verify_current_path(path, **options) do |query|
|
||||
def assert_current_path(path, **options, &optional_filter_block)
|
||||
_verify_current_path(path, optional_filter_block, **options) do |query|
|
||||
raise Capybara::ExpectationNotMet, query.failure_message unless query.resolves_for?(self)
|
||||
end
|
||||
end
|
||||
|
@ -35,8 +35,8 @@ module Capybara
|
|||
# @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
|
||||
# @return [true]
|
||||
#
|
||||
def assert_no_current_path(path, **options)
|
||||
_verify_current_path(path, **options) do |query|
|
||||
def assert_no_current_path(path, **options, &optional_filter_block)
|
||||
_verify_current_path(path, optional_filter_block, **options) do |query|
|
||||
raise Capybara::ExpectationNotMet, query.negative_failure_message if query.resolves_for?(self)
|
||||
end
|
||||
end
|
||||
|
@ -50,8 +50,8 @@ module Capybara
|
|||
# @macro current_path_query_params
|
||||
# @return [Boolean]
|
||||
#
|
||||
def has_current_path?(path, **options)
|
||||
make_predicate(options) { assert_current_path(path, **options) }
|
||||
def has_current_path?(path, **options, &optional_filter_block)
|
||||
make_predicate(options) { assert_current_path(path, **options, &optional_filter_block) }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -63,14 +63,14 @@ module Capybara
|
|||
# @macro current_path_query_params
|
||||
# @return [Boolean]
|
||||
#
|
||||
def has_no_current_path?(path, **options)
|
||||
make_predicate(options) { assert_no_current_path(path, **options) }
|
||||
def has_no_current_path?(path, **options, &optional_filter_block)
|
||||
make_predicate(options) { assert_no_current_path(path, **options, &optional_filter_block) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _verify_current_path(path, **options)
|
||||
query = Capybara::Queries::CurrentPathQuery.new(path, **options)
|
||||
def _verify_current_path(path, filter_block, **options)
|
||||
query = Capybara::Queries::CurrentPathQuery.new(path, **options, &filter_block)
|
||||
document.synchronize(query.wait) do
|
||||
yield(query)
|
||||
end
|
||||
|
|
|
@ -94,6 +94,13 @@ Capybara::SpecHelper.spec '#has_current_path?' do
|
|||
expect(@session).to have_current_path(nil, ignore_query: true)
|
||||
end.not_to raise_exception
|
||||
end
|
||||
|
||||
it 'should accept a filter block that receives Addressable::URL' do
|
||||
@session.visit('/with_js?a=3&b=defgh')
|
||||
expect(@session).to have_current_path('/with_js', ignore_query: true) { |url|
|
||||
url.query_values.keys == ['a','b']
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
Capybara::SpecHelper.spec '#has_no_current_path?' do
|
||||
|
@ -135,4 +142,10 @@ Capybara::SpecHelper.spec '#has_no_current_path?' do
|
|||
expect(@session).not_to have_current_path('/with_js', ignore_query: true)
|
||||
end.not_to raise_exception
|
||||
end
|
||||
|
||||
it 'should accept a filter block that receives Addressable::URL' do
|
||||
expect(@session).to have_no_current_path('/with_js', ignore_query: true) { |url|
|
||||
!url.query.nil?
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@ class MinitestTest < Minitest::Test
|
|||
|
||||
def test_assert_current_path
|
||||
assert_current_path('/form')
|
||||
assert_current_path('/form') { |url| url.query.nil? }
|
||||
assert_no_current_path('/not_form')
|
||||
refute_current_path('/not_form')
|
||||
end
|
||||
|
@ -158,6 +159,6 @@ RSpec.describe 'capybara/minitest' do
|
|||
reporter.start
|
||||
MinitestTest.run reporter, {}
|
||||
reporter.report
|
||||
expect(output.string).to include('22 runs, 52 assertions, 0 failures, 0 errors, 1 skips')
|
||||
expect(output.string).to include('22 runs, 53 assertions, 0 failures, 0 errors, 1 skips')
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue