teamcapybara/capybara · error · ArgumentError

The have_all_selectors matcher does not support use with not

Error message

The have_all_selectors matcher does not support use with not_to/should_not

What it means

The RSpec matcher HaveAllSelectors implements does_not_match? by raising ArgumentError. 'Not all selectors present' is ambiguous (how many? which ones?), so Capybara forbids negating have_all_selectors with not_to/should_not. The positive form asserts every given selector is present via assert_all_of_selectors.

Source

Thrown at lib/capybara/rspec/matchers/have_selector.rb:40

        def element_does_not_match?(el)
          el.assert_no_selector(*@args, **session_query_options, &@filter_block)
        end

        def description = "have #{query.description}"

        def query
          @query ||= Capybara::Queries::SelectorQuery.new(*session_query_args, **session_query_options, &@filter_block)
        end
      end

      class HaveAllSelectors < WrappedElementMatcher
        def element_matches?(el)
          el.assert_all_of_selectors(*@args, **session_query_options, &@filter_block)
        end

        def does_not_match?(_actual)
          raise ArgumentError, 'The have_all_selectors matcher does not support use with not_to/should_not'
        end

        def description = 'have all selectors'
      end

      class HaveNoSelectors < WrappedElementMatcher
        def element_matches?(el)
          el.assert_none_of_selectors(*@args, **session_query_options, &@filter_block)
        end

        def does_not_match?(_actual)
          raise ArgumentError, 'The have_none_of_selectors matcher does not support use with not_to/should_not'
        end

        def description = 'have no selectors'
      end

      class HaveAnySelectors < WrappedElementMatcher

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. State the real expectation positively: expect(page).to have_selector('.header') and a separate expectation for whatever absence you meant.
  2. If you meant 'none of these exist', use the positive form of the none matcher: expect(page).to have_none_of_selectors('.header', '.footer').
  3. If you meant 'at least one exists', assert that single selector with have_selector instead of negating the all-form.
  4. Audit auto-generated negations (RuboCop RSpec/NotToNot rewrites or matcher wrappers) that flip to to not_to mechanically.

Example fix

# before
expect(page).not_to have_all_selectors('.header', '.footer')

# after
expect(page).to have_none_of_selectors('.header', '.footer')
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: expect(page).not_to have_all_selectors('.header', '.footer'); should_not have_all_selectors(:field, 'Email') - RSpec calls does_not_match? and the matcher raises immediately.

Common situations: RSpec cops or shared examples mechanically rewriting to to not_to; developers writing 'the page should not show all of these sections' one-liners; copy-pasting a negated have_selector pattern onto the aggregate matcher without rethinking the intent.

Related errors


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