Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Teamcapybara Capybara XPathBuilder

From Leeroopedia
Knowledge Sources
Domains Testing, Selector Building
Last Updated 2026-02-12 06:00 GMT

Overview

Builds XPath expressions by appending attribute conditions with support for regular expressions, boolean attributes, XPath sub-expressions, and class-based filtering.

Description

XPathBuilder takes an initial XPath expression (either a String or XPath::Expression) and provides add_attribute_conditions to append predicate filters. For :class attributes, it generates contains_word predicates for positive classes and negated contains_word for classes prefixed with !, with double-bang (!!) escaping. Regexp values are handled by the regexp_to_xpath_conditions method, which uses RegexpDisassembler to extract alternated substrings and builds contains predicates, applying uppercase transformation for case-insensitive regexps. Boolean values produce XPath.attr(name) for true and !XPath.attr(name) for false/nil. XPath::Expression values are used directly as sub-predicates via XPath.attr(name)[value]. String values produce equality checks. When the base expression is itself an XPath::Expression, conditions are appended via the [] predicate operator; otherwise, string expressions are wrapped in parentheses with the predicate appended.

Usage

Use XPathBuilder internally when defining XPath-based selectors in Capybara to translate high-level attribute filters into valid XPath predicate expressions. It is the XPath counterpart to CSSBuilder and is used by Capybara's selector infrastructure.

Code Reference

Source Location

Signature

class Capybara::Selector::XPathBuilder
  def initialize(expression)
  attr_reader :expression
  def add_attribute_conditions(**conditions)
end

Import

require 'capybara/selector/builders/xpath_builder'

I/O Contract

XPathBuilder#initialize

Parameter Type Description
expression String, XPath::Expression, or nil The initial XPath expression; nil defaults to an empty string
Returns Type Description
Instance XPathBuilder A new builder initialized with the given XPath expression

XPathBuilder#add_attribute_conditions

Parameter Type Description
**conditions Hash{Symbol => String, Regexp, Boolean, XPath::Expression, nil} Attribute name-value pairs to append as XPath predicates
Returns Type Description
expression String or XPath::Expression The updated XPath expression with all predicate conditions appended

Special attribute handling:

Attribute Value Type Generated XPath Predicate
:class String contains_word('classname') (positive) or not(contains_word('classname')) (negated with ! prefix)
:class Regexp Delegates to attribute_conditions(class: regexp)
:class XPath::Expression Delegates to attribute_conditions(class: expr)
any XPath::Expression @attr[value] -- sub-expression used as predicate directly
any Regexp contains('substring') predicates joined with AND/OR from regexp disassembly
any true @attr -- attribute presence check
any false or nil not(@attr) -- attribute absence check
any String @attr = 'value' -- equality check

Usage Examples

Basic attribute conditions

builder = Capybara::Selector::XPathBuilder.new('.//div')
builder.add_attribute_conditions(id: 'main', disabled: true)
builder.expression
# => "(.//div)[@id = 'main'][@disabled]"

Class conditions with negation

builder = Capybara::Selector::XPathBuilder.new('.//span')
builder.add_attribute_conditions(class: ['active', '!hidden'])
builder.expression
# => "(.//span)[contains_word(@class, 'active') and not(contains_word(@class, 'hidden'))]"

Regexp attribute matching

builder = Capybara::Selector::XPathBuilder.new('.//input')
builder.add_attribute_conditions(name: /user.*name/i)
builder.expression
# => XPath expression with: contains(uppercase(@name), 'USER') and contains(uppercase(@name), 'NAME')

XPath::Expression as base

base_xpath = XPath.descendant(:div)
builder = Capybara::Selector::XPathBuilder.new(base_xpath)
builder.add_attribute_conditions(role: 'button')
builder.expression
# => XPath::Expression with [@role = 'button'] predicate appended via [] operator

Boolean attribute absence

builder = Capybara::Selector::XPathBuilder.new('.//input')
builder.add_attribute_conditions(disabled: false, readonly: nil)
builder.expression
# => "(.//input)[not(@disabled) and not(@readonly)]"

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment