teamcapybara/capybara · error · NotImplementedError

The rack_test driver does not process CSS

Error message

The rack_test driver does not process CSS

What it means

rack_test renders the page through Nokogiri without executing JavaScript or a styling engine, so it cannot compute CSS styles. Node#style therefore raises NotImplementedError. Every style API funnels here under rack_test: node.style(...), assert_style, the have_style matcher, and match_style.

Source

Thrown at lib/capybara/rack_test/node.rb:24

class Capybara::RackTest::Node < Capybara::Driver::Node
  include Capybara::Node::WhitespaceNormalizer

  BLOCK_ELEMENTS = %w[p h1 h2 h3 h4 h5 h6 ol ul pre address blockquote dl div fieldset form hr noscript table].freeze

  def all_text
    normalize_spacing(native.text)
  end

  def visible_text
    normalize_visible_spacing(displayed_text)
  end

  def [](name)
    string_node[name]
  end

  def style(_styles)
    raise NotImplementedError, 'The rack_test driver does not process CSS'
  end

  def value
    string_node.value
  end

  def set(value, **options)
    return if disabled? || readonly?

    warn "Options passed to Node#set but the RackTest driver doesn't support any - ignoring" unless options.empty?

    if value.is_a?(Array) && !multiple?
      raise TypeError, "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}"
    end

    if radio? then set_radio(value)
    elsif checkbox? then set_checkbox(value)
    elsif range? then set_range(value)

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Run style specs under a JS-capable driver (selenium/cuprite) via a js: true tag or a dedicated driver-tagged describe block.
  2. For statically present inline styles, assert on the attribute instead: expect(node[:style]).to include('color: red') or match a CSS attribute substring.
  3. Guard the assertion by driver so it is skipped (or swapped) under rack_test.
  4. Prefer asserting the classes/animations that produce styling, which rack_test can observe in the DOM.

Example fix

# before
expect(page).to have_css('.modal', style: { 'opacity' => '1' }) # rack_test

# after
expect(page).to have_css('.modal[style*=\"opacity: 1\"]')
Defensive patterns

Strategy: fallback

Validate before calling

def style_checks_supported?
  Capybara.current_driver != :rack_test
end

Type guard

def style_capable_driver?
  %i[selenium_chrome_headless selenium_chrome cuprite].include?(Capybara.current_driver)
end

Try / catch

begin
  expect(find('.modal')).to match_style(display: 'block')
rescue NotImplementedError
  expect(find('.modal')[:style]).to include('display: block') # static attribute fallback
end

Prevention

When it happens

Trigger: find('.modal').style('opacity'); expect(page).to have_style(opacity: '1'); expect(el).to match_style(display: 'block') - any of these while Capybara.current_driver is :rack_test.

Common situations: Speeding a suite up by moving specs from selenium to rack_test without removing style assertions; shared step definitions used under both drivers; asserting on classes/inline styles that only a real browser can resolve after JS runs.

Related errors


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