teamcapybara/capybara · warning

Boolean 'exact_text' option is not supported when 'text' opt

Error message

Boolean 'exact_text' option is not supported when 'text' option is a Regexp - ignoring

What it means

The exact_text option (true/false) controls exact versus substring matching only when the text option is a String. When text is a Regexp, exactness has no meaning, so SelectorQuery's initializer warns and ignores the boolean. The regexp itself is still applied unchanged.

Source

Thrown at lib/capybara/queries/selector_query.rb:31

      VALID_MATCH = %i[first smart prefer_exact one].freeze

      def initialize(*args,
                     session_options:,
                     enable_aria_label: session_options.enable_aria_label,
                     enable_aria_role: session_options.enable_aria_role,
                     test_id: session_options.test_id,
                     selector_format: nil,
                     order: nil,
                     **options,
                     &filter_block)
        @resolved_node = nil
        @resolved_count = 0
        @options = options.dup
        @order = order
        @filter_cache = Hash.new { |hsh, key| hsh[key] = {} }

        if @options[:text].is_a?(Regexp) && [true, false].include?(@options[:exact_text])
          Capybara::Helpers.warn(
            "Boolean 'exact_text' option is not supported when 'text' option is a Regexp - ignoring"
          )
        end

        super(@options)
        self.session_options = session_options

        @selector = Selector.new(
          find_selector(args[0].is_a?(Symbol) ? args.shift : args[0]),
          config: {
            enable_aria_label: enable_aria_label,
            enable_aria_role: enable_aria_role,
            test_id: test_id
          },
          format: selector_format
        )

        @locator = args.shift

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Remove exact_text whenever text is a Regexp.
  2. If you meant fully anchored matching, encode it in the regexp: text: /\ATotal\z/.
  3. If you want exact matching, pass a String with exact_text: true: find('div', text: 'Total', exact_text: true).

Example fix

# before
page.find('div', text: /Total/, exact_text: true) # warns; exact_text ignored

# after
page.find('div', text: /\ATotal\z/)
Defensive patterns

Strategy: validation

Validate before calling

# Strip exact_text before any finder/matcher when text is a Regexp
query_opts = opts.dup
query_opts.delete(:exact_text) if query_opts[:text].is_a?(Regexp)
page.find(selector, **query_opts)

Type guard

def consistent_text_options?(opts)
  !(opts[:text].is_a?(Regexp) && [true, false].include?(opts[:exact_text]))
end

Prevention

When it happens

Trigger: page.find('div', text: /Total/, exact_text: true); a shared options hash like { text: /#{term}/i, exact_text: true } reused across find/match calls; expect(page).to have_selector('p', text: /foo/, exact_text: false).

Common situations: Option hashes written for String text lookups later reused with Regexp text; developers trying to anchor a regex match through exact_text instead of regex anchors.

Related errors


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