Contents

    Guides

    Cypress XPath: Usage and Best Practices

    Published on

    February 17, 2026
    Cypress XPath: Usage and Best Practices

    Ever struggled to select a deeply nested element in Cypress when CSS selectors just don’t seem flexible enough?

    While Cypress primarily promotes CSS-based selectors, there are scenarios where navigating complex DOM relationships or selecting elements by text becomes easier with XPath.

    This is where Cypress XPath comes into play. By adding XPath support through a plugin, you can write more expressive queries for specific use cases without changing your core Cypress workflow.

    This article explores what Cypress XPath is, when to use it, and how to implement it effectively in your test automation strategy.

    What is XPath in Cypress?

    XPath (XML Path Language) is a query language used to navigate and select elements from an XML or HTML document. In the context of Cypress, XPath allows testers to locate elements using structured path expressions instead of traditional CSS selectors.

    By default, Cypress does not support XPath. It is designed to work primarily with CSS-based selectors through commands like cy.get(). However, XPath support can be added using a plugin (such as cypress-xpath), which introduces the cy.xpath() command for locating elements.

    Once enabled, XPath allows you to:

    For example:

    cy.xpath("//button[text()='Submit']").click()

    Here, the XPath expression selects a button element based on its visible text.

    In short, XPath in Cypress is an optional selector strategy that expands how you can locate elements, particularly in complex DOM structures, while still leveraging Cypress’s built-in test execution and retry capabilities.

    Why use XPath in Cypress?

    While Cypress primarily encourages CSS selectors, there are situations where XPath offers more flexibility, especially when dealing with complex or dynamic DOM structures. XPath can be a practical alternative when CSS selectors become difficult to maintain or overly verbose.

    That said, XPath should be used thoughtfully. While powerful, it can become harder to read and maintain if overused. In most cases, CSS selectors remain the preferred approach in Cypress, with XPath serving as a complementary option for specific scenarios.

    Installing and Configuring Cypress XPath

    Cypress does not support XPath out of the box, so you need to install a plugin to enable it. Once configured, you can use the cy.xpath() command alongside standard Cypress commands.

    1. Install the Cypress XPath plugin: Add the cypress-xpath package as a development dependency.

    npm install --save-dev cypress-xpath

    2. Import the plugin in the Cypress support file: Register the XPath command so it’s available in all your tests.

    // cypress/support/e2e.js
    require('cypress-xpath')

    3. Verify the installation: After setup, you can use the cy.xpath() command in your test files.

    cy.xpath("//button[text()='Submit']").click()

    If Cypress runs without errors and recognizes the cy.xpath() command, the configuration is successful. You can now use XPath expressions in combination with Cypress’s built-in commands, retries, and assertions.

    Basic Syntax of XPath in Cypress

    Once the cypress-xpath plugin is installed, you can use the cy.xpath() command to locate elements using XPath expressions. The syntax is straightforward and works similarly to cy.get(), except it accepts XPath instead of CSS selectors.

    1. Basic usage

    cy.xpath('xpath-expression')

    2. Selecting an element by tag name

    cy.xpath('//input')

    3. Selecting by attribute

    cy.xpath("//input[@type='email']")

    4. Using relative XPath (recommended)

    cy.xpath("//div[@class='form-container']//button")

    Common XPath Expressions in Cypress

    When using XPath in Cypress, certain expressions appear frequently because they help handle dynamic elements, relationships, and text-based selection. Below are the most commonly used XPath patterns in test automation.

    1. Selecting by attribute

    Use @attribute to target elements with specific attribute values.

    cy.xpath("//input[@name='email']").type('user@example.com')

    2. Selecting by text content

    The text() function allows you to match elements by their exact visible text.

    cy.xpath("//button[text()='Submit']").click()

    3. Using contains() for partial matches

    Helpful when attributes or text are dynamic.

    cy.xpath("//div[contains(@class, 'alert')]")
    cy.xpath("//button[contains(text(), 'Sign')]")

    4. Using logical operators

    Combine multiple conditions using and or or.

    cy.xpath("//input[@type='text' and @required]")
    cy.xpath("//button[@type='submit' or @type='button']")

    5. Navigating parent elements

    Select a parent node using .. or the parent:: axis.

    cy.xpath("//label[text()='Email']/parent::div")

    6. Selecting child elements

    Use / for direct children or // for descendants.

    cy.xpath("//form//input")

    7. Selecting following or preceding siblings

    Useful for elements that don’t have unique attributes.

    cy.xpath("//label[text()='Password']/following-sibling::input")

    8. Index-based selection

    Target a specific element using positional indexing (XPath indexes start at 1).

    cy.xpath("(//button[@type='button'])[2]").click()

    These expressions make XPath powerful for handling complex relationships and dynamic UI elements, especially when CSS selectors become limiting.

    XPath vs CSS Selectors in Cypress

    Both XPath and CSS selectors can locate elements in Cypress, but they differ in readability, maintainability, and the kinds of queries they handle best. Cypress is designed around CSS selectors, so XPath is typically a fallback option for specific situations.

    1. Native support

    2. Readability and team adoption

    3. Strengths

    4. Maintainability

    5. Performance

    // CSS selector (preferred when possible)
    cy.get('[data-testid="submit"]').click()
    // XPath selector (useful for text or relationships)
    cy.xpath("//button[text()='Submit']").click()

    Use CSS selectors by default, especially stable data-* attributes. Reach for XPath only when it clearly simplifies the selector, such as selecting by visible text or navigating tricky DOM relationships.

    Handling Dynamic Elements with XPath

    Modern web applications often generate dynamic IDs, classes, or nested structures that make element selection challenging. XPath provides flexible functions and relationship-based navigation that can help handle these dynamic scenarios more effectively.

    1. Use contains() for dynamic attributes: When attributes change partially (e.g., auto-generated IDs), match only the stable portion.

    cy.xpath("//div[contains(@id, 'user-card-')]")

    2. Match partial text content: If button labels or messages include dynamic values, use contains(text(), ...).

    cy.xpath("//button[contains(text(), 'Order')]")

    3. Avoid absolute XPath paths: Absolute paths break easily when the DOM structure changes. Always prefer relative expressions.

    // Fragile - absolute XPath
    cy.xpath("/html/body/div[3]/div/button")
    // Flexible - relative XPath
    cy.xpath("//div[@class='modal']//button")

    4. Leverage parent-child relationships instead of dynamic classes: If classes are unstable, target the element based on its relationship to a stable label or heading.

    cy.xpath("//label[text()='Email']/following-sibling::input")

    5. Combine conditions for precision: Narrow down matches using multiple conditions to avoid false positives.

    cy.xpath("//input[contains(@class, 'form') and @type='text']")

    When working with dynamic elements, the key is to rely on stable attributes, partial matching, and structural relationships rather than brittle, deeply nested paths. Used thoughtfully, XPath can make dynamic element handling more resilient within Cypress tests.

    Read More: Software Regression Testing: Complete Guide

    Common Mistakes when Using XPath in Cypress

    While XPath can be powerful, improper usage can make Cypress tests fragile and difficult to maintain. Below are common mistakes teams should avoid when using XPath in test automation.

    To use XPath effectively in Cypress, treat it as a specialized tool for specific scenarios, not as a default element selection strategy.

    Best Practices for Using XPath in Cypress

    When using XPath in Cypress, the goal should be to keep selectors clear, stable, and maintainable. Since XPath is not natively supported and requires a plugin, it should be applied thoughtfully rather than used as a default strategy.

    By following these best practices, teams can use XPath in Cypress in a way that enhances flexibility without compromising test stability or maintainability.

    Read More: Mastering File Upload Automation in Selenium

    Conclusion

    XPath can be a useful addition to your Cypress toolkit, especially when dealing with complex DOM structures, dynamic elements, or text-based selection scenarios where CSS selectors become limiting.

    By enabling XPath through a plugin, teams gain more flexibility in how they locate and interact with elements during test execution.

    However, XPath should be used thoughtfully. Since Cypress is designed around CSS selectors, those should remain the default choice for stability and simplicity.

    XPath works best as a complementary strategy, applied only when it clearly improves selector clarity or solves a specific challenge.

    Ultimately, writing maintainable Cypress tests is less about the selector type and more about choosing stable, readable, and resilient approaches. When used strategically, XPath can help strengthen your test automation without introducing unnecessary complexity.

    Try BrowserStack Now

    Updated from Google Doc:

    What is XPath in Cypress?

    XPath (XML Path Language) is a query language used to navigate and select elements from an XML or HTML document. In the context of Cypress, XPath allows testers to locate elements using structured path expressions instead of traditional CSS selectors.

    By default, Cypress does not support XPath. It is designed to work primarily with CSS-based selectors through commands like cy.get(). However, XPath support can be added using a plugin (such as cypress-xpath), which introduces the cy.xpath() command for locating elements.

    Once enabled, XPath allows you to:

    For example:

    cy.xpath("//button[text()='Submit']").click()

    Here, the XPath expression selects a button element based on its visible text.

    In short, XPath in Cypress is an optional selector strategy that expands how you can locate elements, particularly in complex DOM structures, while still leveraging Cypress’s built-in test execution and retry capabilities.

    Why use XPath in Cypress?

    While Cypress primarily encourages CSS selectors, there are situations where XPath offers more flexibility, especially when dealing with complex or dynamic DOM structures. XPath can be a practical alternative when CSS selectors become difficult to maintain or overly verbose.

    That said, XPath should be used thoughtfully. While powerful, it can become harder to read and maintain if overused. In most cases, CSS selectors remain the preferred approach in Cypress, with XPath serving as a complementary option for specific scenarios.

    Installing and Configuring Cypress XPath

    Cypress does not support XPath out of the box, so you need to install a plugin to enable it. Once configured, you can use the cy.xpath() command alongside standard Cypress commands.

    1. Install the Cypress XPath plugin: Add the cypress-xpath package as a development dependency.

    npm install --save-dev cypress-xpath

    2. Import the plugin in the Cypress support file: Register the XPath command so it’s available in all your tests.

    // cypress/support/e2e.js
    require('cypress-xpath')

    3. Verify the installation: After setup, you can use the cy.xpath() command in your test files.

    cy.xpath("//button[text()='Submit']").click()

    If Cypress runs without errors and recognizes the cy.xpath() command, the configuration is successful. You can now use XPath expressions in combination with Cypress’s built-in commands, retries, and assertions.

    Basic Syntax of XPath in Cypress

    Once the cypress-xpath plugin is installed, you can use the cy.xpath() command to locate elements using XPath expressions. The syntax is straightforward and works similarly to cy.get(), except it accepts XPath instead of CSS selectors.

    1. Basic usage

    cy.xpath('xpath-expression')

    2. Selecting an element by tag name

    cy.xpath('//input')

    3. Selecting by attribute

    cy.xpath("//input[@type='email']")

    4. Using relative XPath (recommended)

    cy.xpath("//div[@class='form-container']//button")

    Common XPath Expressions in Cypress

    When using XPath in Cypress, certain expressions appear frequently because they help handle dynamic elements, relationships, and text-based selection. Below are the most commonly used XPath patterns in test automation.

    1. Selecting by attribute

    Use @attribute to target elements with specific attribute values.

    cy.xpath("//input[@name='email']").type('user@example.com')

    2. Selecting by text content

    The text() function allows you to match elements by their exact visible text.

    cy.xpath("//button[text()='Submit']").click()

    3. Using contains() for partial matches

    Helpful when attributes or text are dynamic.

    cy.xpath("//div[contains(@class, 'alert')]")
    cy.xpath("//button[contains(text(), 'Sign')]")

    4. Using logical operators

    Combine multiple conditions using and or or.

    cy.xpath("//input[@type='text' and @required]")
    cy.xpath("//button[@type='submit' or @type='button']")

    5. Navigating parent elements

    Select a parent node using .. or the parent:: axis.

    cy.xpath("//label[text()='Email']/parent::div")

    6. Selecting child elements

    Use / for direct children or // for descendants.

    cy.xpath("//form//input")

    7. Selecting following or preceding siblings

    Useful for elements that don’t have unique attributes.

    cy.xpath("//label[text()='Password']/following-sibling::input")

    8. Index-based selection

    Target a specific element using positional indexing (XPath indexes start at 1).

    cy.xpath("(//button[@type='button'])[2]").click()

    These expressions make XPath powerful for handling complex relationships and dynamic UI elements, especially when CSS selectors become limiting.

    XPath vs CSS Selectors in Cypress

    Both XPath and CSS selectors can locate elements in Cypress, but they differ in readability, maintainability, and the kinds of queries they handle best. Cypress is designed around CSS selectors, so XPath is typically a fallback option for specific situations.

    1. Native support

    2. Readability and team adoption

    3. Strengths

    4. Maintainability

    5. Performance

    // CSS selector (preferred when possible)
    cy.get('[data-testid="submit"]').click()
    // XPath selector (useful for text or relationships)
    cy.xpath("//button[text()='Submit']").click()

    Use CSS selectors by default, especially stable data-* attributes. Reach for XPath only when it clearly simplifies the selector, such as selecting by visible text or navigating tricky DOM relationships.

    Handling Dynamic Elements with XPath

    Modern web applications often generate dynamic IDs, classes, or nested structures that make element selection challenging. XPath provides flexible functions and relationship-based navigation that can help handle these dynamic scenarios more effectively.

    1. Use contains() for dynamic attributes: When attributes change partially (e.g., auto-generated IDs), match only the stable portion.

    cy.xpath("//div[contains(@id, 'user-card-')]")

    2. Match partial text content: If button labels or messages include dynamic values, use contains(text(), ...).

    cy.xpath("//button[contains(text(), 'Order')]")

    3. Avoid absolute XPath paths: Absolute paths break easily when the DOM structure changes. Always prefer relative expressions.

    // Fragile - absolute XPath
    cy.xpath("/html/body/div[3]/div/button")
    // Flexible - relative XPath
    cy.xpath("//div[@class='modal']//button")

    4. Leverage parent-child relationships instead of dynamic classes: If classes are unstable, target the element based on its relationship to a stable label or heading.

    cy.xpath("//label[text()='Email']/following-sibling::input")

    5. Combine conditions for precision: Narrow down matches using multiple conditions to avoid false positives.

    cy.xpath("//input[contains(@class, 'form') and @type='text']")

    When working with dynamic elements, the key is to rely on stable attributes, partial matching, and structural relationships rather than brittle, deeply nested paths. Used thoughtfully, XPath can make dynamic element handling more resilient within Cypress tests.

    Read More: Software Regression Testing: Complete Guide

    Common Mistakes when Using XPath in Cypress

    While XPath can be powerful, improper usage can make Cypress tests fragile and difficult to maintain. Below are common mistakes teams should avoid when using XPath in test automation.

    To use XPath effectively in Cypress, treat it as a specialized tool for specific scenarios, not as a default element selection strategy.

    Best Practices for Using XPath in Cypress

    When using XPath in Cypress, the goal should be to keep selectors clear, stable, and maintainable. Since XPath is not natively supported and requires a plugin, it should be applied thoughtfully rather than used as a default strategy.

    By following these best practices, teams can use XPath in Cypress in a way that enhances flexibility without compromising test stability or maintainability.

    Read More: Mastering File Upload Automation in Selenium

    Conclusion

    XPath can be a useful addition to your Cypress toolkit, especially when dealing with complex DOM structures, dynamic elements, or text-based selection scenarios where CSS selectors become limiting.

    By enabling XPath through a plugin, teams gain more flexibility in how they locate and interact with elements during test execution.

    However, XPath should be used thoughtfully. Since Cypress is designed around CSS selectors, those should remain the default choice for stability and simplicity.

    XPath works best as a complementary strategy, applied only when it clearly improves selector clarity or solves a specific challenge.

    Adding some additional text for testinnggg

    Ultimately, writing maintainable Cypress tests is less about the selector type and more about choosing stable, readable, and resilient approaches. When used strategically, XPath can help strengthen your test automation without introducing unnecessary complexity.

    Try BrowserStack Now

    Data-rich bug reports loved by everyone

    Get visual proof, steps to reproduce and technical logs with one click

    Make bug reporting 50% faster and 100% less painful

    Rating LogosStars
    4.6
    |
    Category leader

    Liked the article? Spread the word

    Continue reading

    No items found.

    Put your knowledge to practice

    Try Bird on your next bug - you’ll love it

    “Game changer”

    Julie, Head of QA

    star-ratingstar-ratingstar-ratingstar-ratingstar-rating

    Overall rating: 4.7/5

    Try Bird later, from your desktop