teamcapybara/capybara · error · ArgumentError

This driver doesn't support case insensitive attribute match

Error message

This driver doesn't support case insensitive attribute matching when using CSS base selectors

What it means

The rack_test driver translates CSS selectors via Nokogiri's CSS parser, which does not accept the CSS4 case-insensitivity flag (the trailing ' i' inside an attribute selector) in all positions Capybara generates it. find_css rescues Nokogiri::CSS::SyntaxError and, if the selector contains the ' i]' marker, re-raises ArgumentError explaining the limitation. So a case-insensitive attribute selector works in a real browser driver but not under rack_test.

Source

Thrown at lib/capybara/rack_test/driver.rb:81

  def response_headers
    response.headers
  end

  def status_code
    response.status
  end

  def find_xpath(selector)
    browser.find(:xpath, selector)
  end

  def find_css(selector)
    browser.find(:css, selector)
  rescue Nokogiri::CSS::SyntaxError
    raise unless selector.include?(' i]')

    raise ArgumentError, "This driver doesn't support case insensitive attribute matching when using CSS base selectors"
  end

  def html
    browser.html
  end

  def dom
    browser.dom
  end

  def title
    browser.title
  end

  def reset!
    @browser = nil
  end

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Rewrite the query as XPath with case-insensitive matching (XPath translate() or the xpath gem's case-insensitive helpers).
  2. Drop case-insensitivity under rack_test and match the literal casing in the selector string.
  3. Move the affected spec to a JS-capable driver (selenium, cuprite) whose engine supports the flag - tag it js: true.
  4. Gate the assertion by driver so the case-insensitive path only runs where supported.

Example fix

# before
find(:css, "input[placeholder='email' i]")

# after
find(:xpath, "//input[translate(@placeholder,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='email']")
Defensive patterns

Strategy: fallback

Validate before calling

def css_supported?(selector)
  return true if Capybara.current_driver != :rack_test
  !selector.include?(' i]')
end

selector = "input[placeholder='email' i]"
raise ArgumentError, 'case-insensitive CSS unsupported under rack_test' unless css_supported?(selector)

Type guard

def case_insensitive_css?(sel)
  sel.include?(' i]')
end

Try / catch

begin
  find(:css, "input[placeholder='email' i]")
rescue ArgumentError
  find(:xpath, "//input[translate(@placeholder,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='email']")
end

Prevention

When it happens

Trigger: find(:css, "input[placeholder='email' i]"); or a casefold regexp filter that makes the CSS builder emit [attr*='...' i], e.g. find(:css, '.menu', class: /nav-item/i) - under the rack_test driver the resulting selector hits Nokogiri and fails.

Common situations: Copying selectors from DevTools or browser-only specs (where ' i]' is valid CSS4) into rack_test feature specs; using case-insensitive regexp filters with CSS-format selectors while running the default :rack_test driver.

Related errors


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