Merge pull request #1763 from jnicklas/custom_filter_block

support custom filter block in finders/matchers/assertions
This commit is contained in:
Thomas Walpole 2016-10-02 17:58:28 -07:00 committed by GitHub
commit 6000e0d332
7 changed files with 232 additions and 203 deletions

View File

@ -28,8 +28,8 @@ module Capybara
# @return [Capybara::Node::Element] The found element
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
#
def find(*args)
query = Capybara::Queries::SelectorQuery.new(*args)
def find(*args, &optional_filter_block)
query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
synchronize(query.wait) do
if (query.match == :smart or query.match == :prefer_exact) and query.supports_exact?
result = query.resolve_for(self, true)
@ -74,9 +74,9 @@ module Capybara
# @return [Capybara::Node::Element] The found element
#
def find_field(locator=nil, options={})
def find_field(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
find(:field, locator, options)
find(:field, locator, options, &optional_filter_block)
end
alias_method :field_labeled, :find_field
@ -96,9 +96,9 @@ module Capybara
# @option options [String, Array<String>] class Match links that match the class(es) provided
# @return [Capybara::Node::Element] The found element
#
def find_link(locator=nil, options={})
def find_link(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
find(:link, locator, options)
find(:link, locator, options, &optional_filter_block)
end
##
@ -125,9 +125,9 @@ module Capybara
# @option options [String, Array<String>] class Match links that match the class(es) provided
# @return [Capybara::Node::Element] The found element
#
def find_button(locator=nil, options={})
def find_button(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
find(:button, locator, options)
find(:button, locator, options, &optional_filter_block)
end
##
@ -140,11 +140,12 @@ module Capybara
#
# @return [Capybara::Node::Element] The found element
#
def find_by_id(id, options={})
find(:id, id, options)
def find_by_id(id, options={}, &optional_filter_block)
find(:id, id, options, &optional_filter_block)
end
##
# @!method all([kind = Capybara.default_selector], locator = nil, options = {})
#
# Find all elements on the page matching the given selector
# and options.
@ -184,26 +185,29 @@ module Capybara
# See {Capybara::Helpers#matches_count?} for additional information about
# count matching.
#
# @overload all([kind], locator, options)
# @param [:css, :xpath] kind The type of selector
# @param [String] locator The selector
# @option options [String, Regexp] text Only find elements which contain this text or match this regexp
# @option options [Boolean, Symbol] visible Only find elements with the specified visibility:
# @param [Symbol] kind Optional selector type (:css, :xpath, :field, etc.) - Defaults to Capybara.default_selector
# @param [String] locator The selector
# @option options [String, Regexp] text Only find elements which contain this text or match this regexp
# @option options [Boolean, Symbol] visible Only find elements with the specified visibility:
# * true - only finds visible elements.
# * false - finds invisible _and_ visible elements.
# * :all - same as false; finds visible and invisible elements.
# * :hidden - only finds invisible elements.
# * :visible - same as true; only finds visible elements.
# @option options [Integer] count Exact number of matches that are expected to be found
# @option options [Integer] maximum Maximum number of matches that are expected to be found
# @option options [Integer] minimum Minimum number of matches that are expected to be found
# @option options [Range] between Number of matches found must be within the given range
# @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially
# @option options [Integer] wait (Capybara.default_max_wait_time) The time to wait for element count expectations to become true
# @option options [Integer] count Exact number of matches that are expected to be found
# @option options [Integer] maximum Maximum number of matches that are expected to be found
# @option options [Integer] minimum Minimum number of matches that are expected to be found
# @option options [Range] between Number of matches found must be within the given range
# @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially
# @option options [Integer] wait (Capybara.default_max_wait_time) The time to wait for element count expectations to become true
# @overload all([kind = Capybara.default_selector], locator = nil, options = {})
# @overload all([kind = Capybara.default_selector], locator = nil, options = {}, &filter_block)
# @yieldparam element [Capybara::Node::Element] The element being considered for inclusion in the results
# @yieldreturn [Boolean] Should the element be considered in the results?
# @return [Capybara::Result] A collection of found elements
#
def all(*args)
query = Capybara::Queries::SelectorQuery.new(*args)
def all(*args, &optional_filter_block)
query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
synchronize(query.wait) do
result = query.resolve_for(self)
raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count?
@ -227,15 +231,16 @@ module Capybara
# @param [Hash] options Additional options; see {#all}
# @return [Capybara::Node::Element] The found element or nil
#
def first(*args)
def first(*args, &optional_filter_block)
if Capybara.wait_on_first_by_default
options = if args.last.is_a?(Hash) then args.pop.dup else {} end
args.push({minimum: 1}.merge(options))
end
all(*args).first
all(*args, &optional_filter_block).first
rescue Capybara::ExpectationNotMet
nil
end
end
end
end

View File

@ -36,8 +36,8 @@ module Capybara
# @option args [Range] :between (nil) Range of times that should contain number of times text occurs
# @return [Boolean] If the expression exists
#
def has_selector?(*args)
assert_selector(*args)
def has_selector?(*args, &optional_filter_block)
assert_selector(*args, &optional_filter_block)
rescue Capybara::ExpectationNotMet
return false
end
@ -50,83 +50,12 @@ module Capybara
# @param (see Capybara::Node::Finders#has_selector?)
# @return [Boolean]
#
def has_no_selector?(*args)
assert_no_selector(*args)
def has_no_selector?(*args, &optional_filter_block)
assert_no_selector(*args, &optional_filter_block)
rescue Capybara::ExpectationNotMet
return false
end
##
#
# Checks if the current node matches given selector
#
# @param (see Capybara::Node::Finders#has_selector?)
# @return [Boolean]
#
def matches_selector?(*args)
assert_matches_selector(*args)
rescue Capybara::ExpectationNotMet
return false
end
##
#
# Checks if the current node matches given XPath expression
#
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
# @return [Boolean]
#
def matches_xpath?(xpath, options={})
matches_selector?(:xpath, xpath, options)
end
##
#
# Checks if the current node matches given CSS selector
#
# @param [String] css The CSS selector to match against the current code
# @return [Boolean]
#
def matches_css?(css, options={})
matches_selector?(:css, css, options)
end
##
#
# Checks if the current node does not match given selector
# Usage is identical to Capybara::Node::Matchers#has_selector?
#
# @param (see Capybara::Node::Finders#has_selector?)
# @return [Boolean]
#
def not_matches_selector?(*args)
assert_not_matches_selector(*args)
rescue Capybara::ExpectationNotMet
return false
end
##
#
# Checks if the current node does not match given XPath expression
#
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
# @return [Boolean]
#
def not_matches_xpath?(xpath, options={})
not_matches_selector?(:xpath, xpath, options)
end
##
#
# Checks if the current node does not match given CSS selector
#
# @param [String] css The CSS selector to match against the current code
# @return [Boolean]
#
def not_matches_css?(css, options={})
not_matches_selector?(:css, css, options)
end
##
#
# Asserts that a given selector is on the page or a descendant of the current node.
@ -160,8 +89,8 @@ module Capybara
# @option options [Integer] :count (nil) Number of times the expression should occur
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
#
def assert_selector(*args)
query = Capybara::Queries::SelectorQuery.new(*args)
def assert_selector(*args, &optional_filter_block)
query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
synchronize(query.wait) do
result = query.resolve_for(self)
unless result.matches_count? && ((!result.empty?) || query.expects_none?)
@ -187,8 +116,8 @@ module Capybara
# @param (see Capybara::Node::Finders#assert_selector)
# @raise [Capybara::ExpectationNotMet] If the selector exists
#
def assert_no_selector(*args)
query = Capybara::Queries::SelectorQuery.new(*args)
def assert_no_selector(*args, &optional_filter_block)
query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
synchronize(query.wait) do
result = query.resolve_for(self)
if result.matches_count? && ((!result.empty?) || query.expects_none?)
@ -199,45 +128,6 @@ module Capybara
end
alias_method :refute_selector, :assert_no_selector
##
#
# Asserts that the current_node matches a given selector
#
# node.assert_matches_selector('p#foo')
# node.assert_matches_selector(:xpath, '//p[@id="foo"]')
# node.assert_matches_selector(:foo)
#
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
# such as :text and :visible.
#
# node.assert_matches_selector('li', :text => 'Horse', :visible => true)
#
# @param (see Capybara::Node::Finders#all)
# @raise [Capybara::ExpectationNotMet] If the selector does not match
#
def assert_matches_selector(*args)
query = Capybara::Queries::MatchQuery.new(*args)
synchronize(query.wait) do
result = query.resolve_for(self.query_scope)
unless result.include? self
raise Capybara::ExpectationNotMet, "Item does not match the provided selector"
end
end
return true
end
def assert_not_matches_selector(*args)
query = Capybara::Queries::MatchQuery.new(*args)
synchronize(query.wait) do
result = query.resolve_for(self.query_scope)
if result.include? self
raise Capybara::ExpectationNotMet, 'Item matched the provided selector'
end
end
return true
end
alias_method :refute_matches_selector, :assert_not_matches_selector
##
#
# Checks if a given XPath expression is on the page or a descendant of the current node.
@ -267,8 +157,8 @@ module Capybara
# @option options [Integer] :count (nil) Number of times the expression should occur
# @return [Boolean] If the expression exists
#
def has_xpath?(path, options={})
has_selector?(:xpath, path, options)
def has_xpath?(path, options={}, &optional_filter_block)
has_selector?(:xpath, path, options, &optional_filter_block)
end
##
@ -279,8 +169,8 @@ module Capybara
# @param (see Capybara::Node::Finders#has_xpath?)
# @return [Boolean]
#
def has_no_xpath?(path, options={})
has_no_selector?(:xpath, path, options)
def has_no_xpath?(path, options={}, &optional_filter_block)
has_no_selector?(:xpath, path, options, &optional_filter_block)
end
##
@ -306,8 +196,8 @@ module Capybara
# @option options [Integer] :count (nil) Number of times the selector should occur
# @return [Boolean] If the selector exists
#
def has_css?(path, options={})
has_selector?(:css, path, options)
def has_css?(path, options={}, &optional_filter_block)
has_selector?(:css, path, options, &optional_filter_block)
end
##
@ -318,8 +208,8 @@ module Capybara
# @param (see Capybara::Node::Finders#has_css?)
# @return [Boolean]
#
def has_no_css?(path, options={})
has_no_selector?(:css, path, options)
def has_no_css?(path, options={}, &optional_filter_block)
has_no_selector?(:css, path, options, &optional_filter_block)
end
##
@ -332,9 +222,9 @@ module Capybara
# @option options [String, Regexp] :href The value the href attribute must be
# @return [Boolean] Whether it exists
#
def has_link?(locator=nil, options={})
def has_link?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:link, locator, options)
has_selector?(:link, locator, options, &optional_filter_block)
end
##
@ -345,9 +235,9 @@ module Capybara
# @param (see Capybara::Node::Finders#has_link?)
# @return [Boolean] Whether it doesn't exist
#
def has_no_link?(locator=nil, options={})
def has_no_link?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:link, locator, options)
has_no_selector?(:link, locator, options, &optional_filter_block)
end
##
@ -358,9 +248,9 @@ module Capybara
# @param [String] locator The text, value or id of a button to check for
# @return [Boolean] Whether it exists
#
def has_button?(locator=nil, options={})
def has_button?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:button, locator, options)
has_selector?(:button, locator, options, &optional_filter_block)
end
##
@ -371,9 +261,9 @@ module Capybara
# @param [String] locator The text, value or id of a button to check for
# @return [Boolean] Whether it doesn't exist
#
def has_no_button?(locator=nil, options={})
def has_no_button?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:button, locator, options)
has_no_selector?(:button, locator, options, &optional_filter_block)
end
##
@ -398,9 +288,9 @@ module Capybara
# @option options [String] :type The type attribute of the field
# @return [Boolean] Whether it exists
#
def has_field?(locator=nil, options={})
def has_field?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:field, locator, options)
has_selector?(:field, locator, options, &optional_filter_block)
end
##
@ -413,9 +303,9 @@ module Capybara
# @option options [String] :type The type attribute of the field
# @return [Boolean] Whether it doesn't exist
#
def has_no_field?(locator=nil, options={})
def has_no_field?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:field, locator, options)
has_no_selector?(:field, locator, options, &optional_filter_block)
end
##
@ -427,9 +317,9 @@ module Capybara
# @param [String] locator The label, name or id of a checked field
# @return [Boolean] Whether it exists
#
def has_checked_field?(locator=nil, options={})
def has_checked_field?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:field, locator, options.merge(:checked => true))
has_selector?(:field, locator, options.merge(:checked => true), &optional_filter_block)
end
##
@ -441,7 +331,7 @@ module Capybara
# @param [String] locator The label, name or id of a checked field
# @return [Boolean] Whether it doesn't exist
#
def has_no_checked_field?(locator=nil, options={})
def has_no_checked_field?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:field, locator, options.merge(:checked => true))
end
@ -455,9 +345,9 @@ module Capybara
# @param [String] locator The label, name or id of an unchecked field
# @return [Boolean] Whether it exists
#
def has_unchecked_field?(locator=nil, options={})
def has_unchecked_field?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:field, locator, options.merge(:unchecked => true))
has_selector?(:field, locator, options.merge(:unchecked => true), &optional_filter_block)
end
##
@ -469,9 +359,9 @@ module Capybara
# @param [String] locator The label, name or id of an unchecked field
# @return [Boolean] Whether it doesn't exist
#
def has_no_unchecked_field?(locator=nil, options={})
def has_no_unchecked_field?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:field, locator, options.merge(:unchecked => true))
has_no_selector?(:field, locator, options.merge(:unchecked => true), &optional_filter_block)
end
##
@ -502,9 +392,9 @@ module Capybara
# @option options [String, Array] :selected Options which should be selected
# @return [Boolean] Whether it exists
#
def has_select?(locator=nil, options={})
def has_select?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:select, locator, options)
has_selector?(:select, locator, options, &optional_filter_block)
end
##
@ -515,9 +405,9 @@ module Capybara
# @param (see Capybara::Node::Matchers#has_select?)
# @return [Boolean] Whether it doesn't exist
#
def has_no_select?(locator=nil, options={})
def has_no_select?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:select, locator, options)
has_no_selector?(:select, locator, options, &optional_filter_block)
end
##
@ -530,9 +420,9 @@ module Capybara
# @param [String] locator The id or caption of a table
# @return [Boolean] Whether it exist
#
def has_table?(locator=nil, options={})
def has_table?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_selector?(:table, locator, options)
has_selector?(:table, locator, options, &optional_filter_block)
end
##
@ -543,11 +433,122 @@ module Capybara
# @param (see Capybara::Node::Matchers#has_table?)
# @return [Boolean] Whether it doesn't exist
#
def has_no_table?(locator=nil, options={})
def has_no_table?(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
has_no_selector?(:table, locator, options)
has_no_selector?(:table, locator, options, &optional_filter_block)
end
##
#
# Asserts that the current_node matches a given selector
#
# node.assert_matches_selector('p#foo')
# node.assert_matches_selector(:xpath, '//p[@id="foo"]')
# node.assert_matches_selector(:foo)
#
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
# such as :text and :visible.
#
# node.assert_matches_selector('li', :text => 'Horse', :visible => true)
#
# @param (see Capybara::Node::Finders#all)
# @raise [Capybara::ExpectationNotMet] If the selector does not match
#
def assert_matches_selector(*args, &optional_filter_block)
query = Capybara::Queries::MatchQuery.new(*args, &optional_filter_block)
synchronize(query.wait) do
result = query.resolve_for(self.query_scope)
unless result.include? self
raise Capybara::ExpectationNotMet, "Item does not match the provided selector"
end
end
return true
end
def assert_not_matches_selector(*args, &optional_filter_block)
query = Capybara::Queries::MatchQuery.new(*args)
synchronize(query.wait) do
result = query.resolve_for(self.query_scope)
if result.include? self
raise Capybara::ExpectationNotMet, 'Item matched the provided selector'
end
end
return true
end
alias_method :refute_matches_selector, :assert_not_matches_selector
##
#
# Checks if the current node matches given selector
#
# @param (see Capybara::Node::Finders#has_selector?)
# @return [Boolean]
#
def matches_selector?(*args, &optional_filter_block)
assert_matches_selector(*args, &optional_filter_block)
rescue Capybara::ExpectationNotMet
return false
end
##
#
# Checks if the current node matches given XPath expression
#
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
# @return [Boolean]
#
def matches_xpath?(xpath, options={}, &optional_filter_block)
matches_selector?(:xpath, xpath, options, &optional_filter_block)
end
##
#
# Checks if the current node matches given CSS selector
#
# @param [String] css The CSS selector to match against the current code
# @return [Boolean]
#
def matches_css?(css, options={}, &optional_filter_block)
matches_selector?(:css, css, options)
end
##
#
# Checks if the current node does not match given selector
# Usage is identical to Capybara::Node::Matchers#has_selector?
#
# @param (see Capybara::Node::Finders#has_selector?)
# @return [Boolean]
#
def not_matches_selector?(*args, &optional_filter_block)
assert_not_matches_selector(*args, &optional_filter_block)
rescue Capybara::ExpectationNotMet
return false
end
##
#
# Checks if the current node does not match given XPath expression
#
# @param [String, XPath::Expression] xpath The XPath expression to match against the current code
# @return [Boolean]
#
def not_matches_xpath?(xpath, options={}, &optional_filter_block)
not_matches_selector?(:xpath, xpath, options, &optional_filter_block)
end
##
#
# Checks if the current node does not match given CSS selector
#
# @param [String] css The CSS selector to match against the current code
# @return [Boolean]
#
def not_matches_css?(css, options={}, &optional_filter_block)
not_matches_selector?(:css, css, options, &optional_filter_block)
end
##
# Asserts that the page or current node has the given text content,
# ignoring any HTML tags.
@ -643,6 +644,7 @@ module Capybara
def ==(other)
self.eql?(other) || (other.respond_to?(:base) && base == other.base)
end
end
end
end

View File

@ -7,8 +7,9 @@ module Capybara
VALID_KEYS = COUNT_KEYS + [:text, :id, :class, :visible, :exact, :match, :wait, :filter_set]
VALID_MATCH = [:first, :smart, :prefer_exact, :one]
def initialize(*args)
def initialize(*args, &filter_block)
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end
@filter_block = filter_block
if args[0].is_a?(Symbol)
@selector = Selector.all.fetch(args.shift) do |selector_type|
@ -45,6 +46,7 @@ module Capybara
@description << " with id #{options[:id]}" if options[:id]
@description << " with classes #{Array(options[:class]).join(',')}]" if options[:class]
@description << selector.description(options)
@description << " that also matches the custom filter block" if @filter_block
@description
end
@ -59,7 +61,7 @@ module Capybara
when :hidden then return false if node.visible?
end
query_filters.all? do |name, filter|
res = query_filters.all? do |name, filter|
if options.has_key?(name)
filter.matches?(node, options[name])
elsif filter.default?
@ -68,6 +70,9 @@ module Capybara
true
end
end
res &&= @filter_block.call(node) unless @filter_block.nil?
res
end
def visible

View File

@ -16,8 +16,9 @@ module Capybara
class HaveSelector < Matcher
attr_reader :failure_message, :failure_message_when_negated
def initialize(*args)
def initialize(*args, &filter_block)
@args = args
@filter_block = filter_block
end
def matches?(actual)
@ -39,7 +40,7 @@ module Capybara
end
def query
@query ||= Capybara::Queries::SelectorQuery.new(*@args)
@query ||= Capybara::Queries::SelectorQuery.new(*@args, &@filter_block)
end
# RSpec 2 compatibility:
@ -221,8 +222,8 @@ module Capybara
alias_method :failure_message_for_should_not, :failure_message_when_negated
end
def have_selector(*args)
HaveSelector.new(*args)
def have_selector(*args, &optional_filter_block)
HaveSelector.new(*args, &optional_filter_block)
end
def match_selector(*args)
@ -233,16 +234,16 @@ module Capybara
::RSpec::Matchers.define_negated_matcher :not_match_selector, :match_selector if defined?(::RSpec::Expectations::Version) && (Gem::Version.new(RSpec::Expectations::Version::STRING) >= Gem::Version.new('3.1'))
def have_xpath(xpath, options={})
HaveSelector.new(:xpath, xpath, options)
def have_xpath(xpath, options={}, &optional_filter_block)
HaveSelector.new(:xpath, xpath, options, &optional_filter_block)
end
def match_xpath(xpath, options={})
MatchSelector.new(:xpath, xpath, options)
end
def have_css(css, options={})
HaveSelector.new(:css, css, options)
def have_css(css, options={}, &optional_filter_block)
HaveSelector.new(:css, css, options, &optional_filter_block)
end
def match_css(css, options={})
@ -262,39 +263,39 @@ module Capybara
HaveCurrentPath.new(path, options)
end
def have_link(locator=nil, options={})
def have_link(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:link, locator, options)
HaveSelector.new(:link, locator, options, &optional_filter_block)
end
def have_button(locator=nil, options={})
def have_button(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:button, locator, options)
HaveSelector.new(:button, locator, options, &optional_filter_block)
end
def have_field(locator=nil, options={})
def have_field(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:field, locator, options)
HaveSelector.new(:field, locator, options, &optional_filter_block)
end
def have_checked_field(locator=nil, options={})
def have_checked_field(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:field, locator, options.merge(:checked => true))
HaveSelector.new(:field, locator, options.merge(:checked => true), &optional_filter_block)
end
def have_unchecked_field(locator=nil, options={})
def have_unchecked_field(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:field, locator, options.merge(:unchecked => true))
HaveSelector.new(:field, locator, options.merge(:unchecked => true), &optional_filter_block)
end
def have_select(locator=nil, options={})
def have_select(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:select, locator, options)
HaveSelector.new(:select, locator, options, &optional_filter_block)
end
def have_table(locator=nil, options={})
def have_table(locator=nil, options={}, &optional_filter_block)
locator, options = nil, locator if locator.is_a? Hash
HaveSelector.new(:table, locator, options)
HaveSelector.new(:table, locator, options, &optional_filter_block)
end
##
@ -306,5 +307,6 @@ module Capybara
def become_closed(options = {})
BecomeClosed.new(options)
end
end
end

View File

@ -48,6 +48,13 @@ Capybara::SpecHelper.spec '#match_selector?' do
cbox = @session.find(:css, '#form_pets_dog')
expect(cbox.matches_selector?(:checkbox, id: 'form_pets_dog', option: 'dog', name: 'form[pets][]', checked: true)).to be true
end
it 'should accept a custom filter block' do
@session.visit('/form')
cbox = @session.find(:css, '#form_pets_dog')
expect(cbox.matches_selector?(:checkbox){ |node| node[:id] == "form_pets_dog"}).to be true
expect(cbox.matches_selector?(:checkbox){ |node| node[:id] != "form_pets_dog"}).to be false
end
end
Capybara::SpecHelper.spec '#not_matches_selector?' do

View File

@ -8,7 +8,6 @@ Capybara::SpecHelper.spec '#find_field' do
expect(@session.find_field('Dog').value).to eq('dog')
expect(@session.find_field('form_description').text).to eq('Descriptive text goes here')
expect(@session.find_field('Region')[:name]).to eq('form[region]')
end
context "aria_label attribute with Capybara.enable_aria_label" do
@ -107,4 +106,9 @@ Capybara::SpecHelper.spec '#find_field' do
expect(@session.find_field(with: 'dog')['id']).to eq "form_pets_dog"
end
end
it "should accept an optional filter block" do
# this would be better done with the :with option but this is just a test
expect(@session.find_field('form[pets][]'){ |node| node.value == 'dog' }[:id]).to eq "form_pets_dog"
end
end

View File

@ -399,6 +399,10 @@ Capybara::SpecHelper.spec '#find' do
end
end
it "supports a custom filter block" do
expect(@session.find(:css, 'input'){|node| node.disabled? }[:name]).to eq('disabled_text')
end
context "within a scope" do
before do
@session.visit('/with_scope')