teamcapybara/capybara · error · ArgumentError

The match_style matcher does not support use with not_to/sho

Error message

The match_style matcher does not support use with not_to/should_not

What it means

MatchStyle#does_not_match? raises ArgumentError: negating match_style would mean 'the styles are not exactly this set', which mixes many unrelated failures (wrong value, missing property, extra properties) into one opaque assertion. Capybara only supports the positive form, which asserts the element's computed styles match all given key/value pairs exactly.

Source

Thrown at lib/capybara/rspec/matchers/match_style.rb:19

# frozen_string_literal: true

require 'capybara/rspec/matchers/base'

module Capybara
  module RSpecMatchers
    module Matchers
      class MatchStyle < WrappedElementMatcher
        def initialize(styles = nil, **kw_args, &filter_block)
          styles, kw_args = kw_args, {} if styles.nil?
          super(styles, **kw_args, &filter_block)
        end

        def element_matches?(el)
          el.assert_matches_style(*@args, **@kw_args)
        end

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

        def description
          'match style'
        end
      end
    end
  end
end

module Capybara
  module RSpecMatchers
    module Matchers
      ##
      # @deprecated
      class HaveStyle < MatchStyle
        def initialize(*args, **kw_args, &filter_block)
          warn 'HaveStyle matcher is deprecated, please use the MatchStyle matcher instead'

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Restate positively with the style set you do expect: expect(find('.modal')).to match_style(display: 'block', opacity: '1').
  2. To assert a single style is absent/different, read it and compare directly: expect(find('.modal').style('display')['display']).to eq('none').
  3. For 'element no longer has style X', assert the state change instead (e.g. hidden class or :visible option), not the negated style set.
  4. Remember style queries need a real browser driver - keep these specs tagged js: true.

Example fix

# before
expect(find('.modal')).not_to match_style(display: 'none')

# after
expect(find('.modal').style('display')['display']).to eq('block')
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: expect(page).not_to match_style(display: 'none'); expect(find('.modal')).not_to match_style({ 'opacity' => '0' }) - plus the underlying style lookup itself requires a JS-capable driver (see the rack_test NotImplementedError), so this matcher is selenium/cuprite-only territory.

Common situations: RSpec style guides pushing negative one-liners; mechanically flipping have_style/match_style assertions during refactors; teams moving from asserting classes to computed styles and keeping the not_to habits.

Related errors


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