Overview
Defines the base classes for all Capybara RSpec matchers, providing session handling, element wrapping, negation support, and a countable/spatial mixin hierarchy.
Description
The Base class stores matcher arguments (*args, **kw_args, &filter_block) and resolves session options from the matched context element, falling back to Capybara.session_options. WrappedElementMatcher extends Base with matches? and does_not_match? methods that automatically wrap the actual value into a Capybara node (via to_capybara_node or Capybara.string) and delegate to abstract element_matches? / element_does_not_match? hooks. CountableWrappedElementMatcher mixes in CountSugar and SpatialSugar for count-based and spatial assertions. NegatedMatcher is a decorator that swaps matches? and does_not_match? on any existing matcher, inverting its logic and failure messages.
Usage
Use these base classes when building custom RSpec matchers for Capybara. Subclass WrappedElementMatcher for simple presence/absence matchers, CountableWrappedElementMatcher when you need count or spatial constraints, and wrap any matcher in NegatedMatcher to invert its assertion semantics.
Code Reference
Source Location
Signature
# Base
class Capybara::RSpecMatchers::Matchers::Base
def initialize(*args, **kw_args, &filter_block)
end
# WrappedElementMatcher
class Capybara::RSpecMatchers::Matchers::WrappedElementMatcher < Base
def matches?(actual, &filter_block)
def does_not_match?(actual, &filter_block)
end
# CountableWrappedElementMatcher
class Capybara::RSpecMatchers::Matchers::CountableWrappedElementMatcher < WrappedElementMatcher
include CountSugar
include SpatialSugar
end
# NegatedMatcher
class Capybara::RSpecMatchers::Matchers::NegatedMatcher
def initialize(matcher)
def matches?(actual, &filter_block)
def does_not_match?(actual, &filter_block)
def description
def failure_message
def failure_message_when_negated
end
Import
require 'capybara/rspec/matchers/base'
I/O Contract
Base#initialize
| Parameter |
Type |
Description
|
*args |
Array |
Positional arguments forwarded to underlying Capybara queries
|
**kw_args |
Hash |
Keyword arguments forwarded to underlying Capybara queries
|
&filter_block |
Proc |
Optional block used to filter matched elements
|
| Returns |
Type |
Description
|
| Instance |
Base |
A new matcher base instance storing the provided arguments
|
WrappedElementMatcher#matches?
| Parameter |
Type |
Description
|
actual |
Object |
The page, node, or string to match against; auto-wrapped into a Capybara node
|
&filter_block |
Proc |
Optional filter block (used if none was provided at initialization)
|
| Returns |
Type |
Description
|
| result |
Boolean |
true if element matches, false if Capybara::ExpectationNotMet is raised
|
NegatedMatcher#initialize
| Parameter |
Type |
Description
|
matcher |
Base |
The original matcher whose logic will be inverted
|
| Returns |
Type |
Description
|
| Instance |
NegatedMatcher |
A decorator that swaps match/no-match semantics
|
Usage Examples
Subclassing WrappedElementMatcher
class HaveWidget < Capybara::RSpecMatchers::Matchers::WrappedElementMatcher
def element_matches?(el)
el.assert_selector('.widget', **session_query_options, &@filter_block)
end
def element_does_not_match?(el)
el.assert_no_selector('.widget', **session_query_options, &@filter_block)
end
def description
"have widget"
end
end
expect(page).to HaveWidget.new
Using NegatedMatcher
matcher = HaveSelector.new(:css, '.active')
negated = Capybara::RSpecMatchers::Matchers::NegatedMatcher.new(matcher)
negated.matches?(page) # delegates to matcher.does_not_match?(page)
negated.description # => "not have css \".active\""
CountableWrappedElementMatcher with count sugar
# CountSugar and SpatialSugar are mixed in automatically
expect(page).to have_selector('.item', count: 3)
expect(page).to have_selector('.item', minimum: 1, maximum: 5)
Related Pages