teamcapybara/capybara · error · Capybara::ExpectationNotMet

result.failure_message

Error message

result.failure_message

What it means

Node::Matchers#assert_selector raises ExpectationNotMet with Result#failure_message when, after waiting, the resolved element set neither matches the count options nor contains anything (unless the query expects zero). The message reads 'expected to find <description> <count expectation>' plus what was actually found and elements that matched the selector but failed filters ('Also found ... which matched the selector but not all filters').

Source

Thrown at lib/capybara/node/matchers.rb:112

      #
      # It also accepts all options that {Capybara::Node::Finders#all} accepts,
      # such as `:text` and `:visible`.
      #
      #     page.assert_selector('li', text: 'Horse', visible: true)
      #
      # {#assert_selector} can also accept XPath expressions generated by the
      # XPath gem:
      #
      #     page.assert_selector(:xpath, XPath.descendant(:p))
      #
      # @param (see Capybara::Node::Finders#all)
      # @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, &optional_filter_block)
        _verify_selector_result(args, optional_filter_block) do |result, query|
          unless result.matches_count? && (result.any? || query.expects_none?)
            raise Capybara::ExpectationNotMet, result.failure_message
          end
        end
      end

      ##
      #
      # Asserts that an element has the specified CSS styles.
      #
      #     element.assert_matches_style( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
      #
      # @param styles [Hash]
      # @raise [Capybara::ExpectationNotMet]    If the element doesn't have the specified styles
      #
      def assert_matches_style(styles = nil, **options)
        styles, options = options, {} if styles.nil?
        query_args, query_opts = _set_query_session_options(styles, options)
        query = Capybara::Queries::StyleQuery.new(*query_args, **query_opts)
        synchronize(query.wait) do

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Read the failure message: 'found N matches' tells you the real count; adjust the count option or the selector
  2. If 'Also found ... not all filters' appears, loosen the failing filter (:text/:visible/:exact)
  3. Increase wait: assert_selector('tr', count: 3, wait: 5)
  4. Prefer the predicate when you need a boolean: page.has_selector?('tr', count: 3)

Example fix

# before
page.assert_selector('table tbody tr', count: 5)

# after
page.assert_selector('table tbody tr', minimum: 1, wait: 5)
expect(page.all('table tbody tr').size).to eq(5)
Defensive patterns

Strategy: retry

Validate before calling

n = page.all('table tbody tr').size
page.assert_selector('table tbody tr', count: n) if n.positive?

Try / catch

begin
  page.assert_selector('tr', minimum: 1, wait: 5)
rescue Capybara::ExpectationNotMet => e
  puts e.message # lists actual matches and filter-excluded elements
  raise
end

Prevention

When it happens

Trigger: page.assert_selector('table tr', count: 3) with 4 rows; element.assert_selector('li', minimum: 2) on an empty list; assert_selector(:field, 'Email', disabled: true) when the field is enabled; assert_selector('a', text: 'Home', visible: true) when the link is display:none.

Common situations: Timing races on dynamic pages, wrong counts after pagination/filtering, filters that silently exclude the intended elements, porting RSpec matchers (have_selector) to bare assert_* calls in minitest and hitting the same count semantics.

Related errors


AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21). Data as JSON: /api/errors/c30e9dd1529cd14f. Report an issue: GitHub.