Mastering XPath in Selenium: A Complete Tutorial
Vipul Gupta
Posted On: July 31, 2025
723780 Views
19 Min Read
This article is a part of our Learning Hub. For more in-depth resources, check out our hub on Selenium Tutorial.
XPath is used to find and locate elements on a web page. Web pages are made up of HTML, which is like a tree structure. XPath helps you navigate that tree and pick out exactly what you want, whether it’s a button, a text field, a checkbox, or anything else.
Overview
XPath is a syntax used to navigate through elements and attributes in XML or HTML documents. It helps locate nodes for tasks like web scraping and test automation.
Types of XPath in Selenium
In Selenium, there are two types of XPath:
- Absolute XPath: Starts from the root node and follows a fixed path to the target element.
- Relative XPath: Starts from anywhere in the DOM and is more flexible and maintainable.
Steps to Write XPath in Selenium
Writing XPath in Selenium involves using XPath expressions to locate elements on a web page.
Syntax: //tagname[@attribute=’value’]
TABLE OF CONTENTS
- What Is XPath in Selenium?
- Types of XPath in Selenium
- How to Write XPath in Selenium?
- How to Write XPath Using Axes?
- How to Create a Dynamic XPath in Selenium?
- How to Capture the XPath of Loader Images?
- How LambaTest Online Selenium Grid Ensures Effective Test Automation?
- Best Practices for Using XPath in Selenium
- Common XPath Issues and How to Troubleshoot?
- Frequently Asked Questions (FAQs)
What Is XPath in Selenium?
XPath or XML Path Language is a query language to navigate through elements and attributes in XML and HTML documents. Since HTML pages are structured as a Document Object Model (DOM), XPath lets you define a path to any element or node based on its position, attributes, or relationships to other nodes.
Syntax:
1 |
XPath = //tagname[@Attribute=’Value’] |
In test automation, XPath is often used when other Selenium locators, like tags or CSS class names are not enough to select all elements in the DOM. That’s why XPath is often used, especially when elements lack unique IDs, require navigating parent-child relationships, or are deeply nested or dynamic.
Types of XPath in Selenium
There are two types of XPath in Selenium:
- Absolute XPath
- Relative XPath
Absolute XPath
Absolute XPath gives the complete path from the root element all the way down to your target element.
Syntax:
1 |
/html/body/div[1]/form/input[2] |
Features:
- Starts with a single slash /.
- Follows the exact structure of the page.
- Breaks easily if any part of the layout changes.
Relative XPath
Relative XPath starts from anywhere in the DOM, not necessarily from the root.
Syntax:
1 |
//input[@type='email'] |
Features:
- Starts with double slashes //, which means “anywhere on the page”.
- Lets you use attributes, text, and partial matches.
- Works even if the structure around the element changes.

Run your automation tests using various browsers and platforms. Try LambdaTest Today!
How to Write XPath in Selenium?
Let’s see how to write XPath in Selenium with various methods using real-world examples:
Basic Attribute Matching
XPath is used to locate elements in a web page by combining the HTML tag and an attribute-value pair.
Syntax:
1 |
//tagname[@attribute='value'] |
Example:
1 |
//div[@aria-labelledby='sign_up_with_google_label'] |
contains()
contains() is useful when attribute values are partially known or change dynamically.
Syntax:
1 |
//tagname[contains(@attribute,'partialValue')] |
Example:
1 |
//button[contains(@class,'justify-center')] |
Logical Operators (and/or)
Logical operators let you combine multiple conditions in a single XPath.
Syntax (or):
1 |
//tagname[@attr1='value1' or @attr2='value2'] |
Syntax (and):
1 |
//tagname[@attr1='value1' and @attr2='value2'] |
Example (or):
1 |
//input[@name="email" or contains(@placeholder,'abc')] |
Example (and):
1 |
//input[@name="email" and contains(@placeholder,'Email')] |
Note: Always use lowercase and and or as XPath is case-sensitive.
text()
Use text() to find elements based on the visible text between tags.
Syntax:
1 |
//tagname[text()='Exact Text'] |
Example:
1 |
//span[text()='Sign up with Google'] |
starts-with()
starts-with() helps when an attribute’s value begins with a consistent prefix.
Syntax:
1 |
//tagname[starts-with(@attribute,'startValue')] |
Example:
1 |
//input[starts-with(@placeholder,'Desired')] |
Index
Use index when multiple elements match the same XPath, and you want to target a specific one.
Syntax:
1 |
(//tagname[contains(@attribute,'value')])[index] |
Example:
1 |
(//input[contains(@class,'customPlaceholder')])[2] |
Chained XPath in Selenium
Chained XPath helps navigate through nested elements.
Syntax:
1 |
//parentTag[@attribute='value']//childTag[@attribute='value'] |
Example:
1 |
//div[contains(@class,'signUpWithEmail')]//input[@id='email'] |
Pro Tip: Use contains(), starts-with(), text(), and logical operators to handle dynamic or complex elements. Always test your XPath in browser DevTools before using it in Selenium.
How to Write XPath Using Axes?
XPath axes come in handy when the exact element TagName or its attribute value is dynamic and cannot be used to locate an element. In such cases, locating elements by traversing through child/sibling or parent elements becomes easy.
Some of the widely used XPath axes are:
following
It can be used when you have a unique attribute of the tag before your actual WebElement. For example, using the following axis, you can have all the elements that follow the current node, and you can simply use Index or another chained XPath to locate your actual WebElement.
Syntax:
1 |
//tagname[@attribute=’value’]//following::tagname |
Example:
1 |
//form[contains(@class,'form')]//following::div//input[@id='userpassword'] |
following-sibling
Siblings are those nodes that share the same parent or are at the same level. Hence, the following-sibling axis will return you to the node at the same level and after the current node.
Syntax:
1 |
//tagname[@attribute=’value’]//following-sibiling::tagname |
Example:
1 |
(//div[contains(@class,'custom__border')]//following-sibling::div)[1] |
preceding
The preceding axis locate all the elements before the current node. You can retrieve all the elements preceding the current node, and with an index or another chained XPath expression, you can pinpoint the specific WebElement you are looking for.
Syntax:
1 |
//tagname[@attribute=’value’]//preceding::tagname |
Example:
1 |
//button[@data-testid='signup-button']//preceding::input[@type='password'] |
preceding-sibling
The preceding-sibling axis retrieves all nodes that are siblings or at the same level but appear before the current node.
Syntax:
1 |
//tagname[@attribute=’value’]//preceding-sibling::tagname |
Example:
1 |
//div[contains(@class,'custom__border')]//preceding-sibling::div |
child
It is used to locate child elements of a particular node. A common use case for this approach is to iterate through the data in a table by navigating through its rows.
Syntax:
1 |
//tagname[@attribute=’value’]//child::tagname |
Example:
1 |
//div[@aria-labelledby='sign_up_with_google_label']//child::span |
parent
It is used to select the parent node of the current node in an XML or HTML document. This axis allows you to navigate from a specific element to its immediate parent.
Syntax:
1 |
//tagname[@attribute=’value’]/parent::tagname |
Example:
1 |
//button[@data-testid='signup-button']//parent::div//preceding-sibling::div//input[@type='password'] |
descendant
It is used to select all the descendants of the current node in an XML or HTML document. In this context, descendants encompass not only immediate child nodes but also include grandchild nodes, great-grandchild nodes, and so forth.
Syntax:
1 |
//tagname[@attribute=’value’]//descendant::tagname |
Example:
1 |
//div[contains(@class,'overflow-hidden')]//descendant::span |
ancestor
It is used for selecting the ancestors of the current node. In this context, ancestors refer to the parent nodes, grandparent nodes, and so forth.
Syntax:
1 |
//tagname[@attribute=’value’]//ancestors::tagname |
Example:
1 |
//input[@type='password']//ancestor::div//input[@id='email'] |
How to Create a Dynamic XPath in Selenium?
A dynamic XPath helps you locate such elements without rewriting the locator each time something changes. These XPath expressions are flexible and adapt to shifting attributes, positions, or DOM structures.
You can build dynamic XPath expressions using the following techniques:
Functions
Functions such as contains(), starts-with(), and text() help match elements based on partial attribute values or visible text.
Example – contains():
1 |
//input[contains(@id, 'user')] |
Example – starts-with():
1 |
//button[starts-with(@class, 'submit')] |
Example – text():
1 |
//label[text()='Email'] |
Logical Operators
You can combine multiple conditions (and/or) to make your XPath more robust.
Example:
1 |
//input[@type='email' or @name='userEmail'] |
XPath Axes
You can use DOM relationships to find elements based on their position relative to other known elements.
Example:
1 |
//label[text()='Password']//following::input[1] |
Other useful axes:
- following / following-sibling
- preceding / preceding-sibling
- child, parent, ancestor, descendant
Indexing for Repeating Elements
You can use position to differentiate when multiple elements match the same XPath.
Example:
1 |
//div[@class='field-wrapper']//input[2] |
Wildcards (*) for Flexible Tag Selection
If you’re unsure about the tag name, use an asterisk * to match any element type.
Syntax:
1 |
//*[@attribute='value'] |
Example:
1 |
//*[@id='email'] |
How to Capture the XPath of Loader Images?
While performing automation testing with Selenium, you may encounter WebElements that appear only for a short time. Writing XPath for such transient or dynamic elements, like loading images can be challenging.
Below is a screen capture from X (Formerly Twitter) illustrating a loader image. Let us demonstrate how to capture the XPath for this image:
- As soon as the page opens, press F12 to be ready to inspect the element. Switch to the Sources tab, as highlighted in the below image.
- When the loading symbol appears on your screen, press F8 or click on the image highlighted below.
- Now, you can return to the Elements tab and start identifying and writing the locator.
- Go back to the Sources tab and click on the resume icon as shown below.
This will pause the execution, and you will see a notification badge like below on top of your screen.
1 |
//div[@aria-label='Loading'] |
This way, you can simply pause the execution and let the element be on your screen till you identify the locator.
Pro-Tip: To learn more about XPath, follow this XPath locator cheat sheet to learn and use all the various ways of locating WebElement efficiently, making your automation testing process faster.
How LambaTest Online Selenium Grid Ensures Effective Test Automation?
LambdaTest is a GenAI-native test execution platform that offers scalable online Selenium Grid to execute Selenium automation tests across thousands of real browser and operating system combinations on demand.
You can run Selenium tests without maintaining any local infrastructure. This approach significantly streamlines setup, accelerates cross‑browser coverage, and reduces overall test execution time.
To get started, check out this guide on Selenium testing with LambdaTest.
Features:
- Parallel Test Execution at Scale: Execute hundreds of Selenium tests concurrently across multiple browsers and operating systems to drastically reduce testing time. Ideal for large test suites.
- Comprehensive Debugging with Logs & Video Playback: Capture full execution details – Selenium logs, network logs, step-by-step screenshots, and video recordings to debug faster and build reliable bug reports.
- Test Insights: Leverage GenAI-native test insights to gain visibility into test trends with an interactive dashboard that shows execution timelines, pass/fail rates, environment breakdowns, and more.
- CI/CD Integration: Integrate effortlessly with tools like Jenkins, GitHub Actions, Azure DevOps for seamless test automation.
Best Practices for Using XPath in Selenium
To write stable and efficient Selenium scripts, using XPath the right way is crucial.
Below are key best practices that you can follow to handle XPath efficiently.
- Prefer Relative XPath Over Absolute XPath: Use relative XPath (//) instead of absolute paths (/html/body/…) to make your locators more resilient to UI changes.
- Use Unique Attributes: Target attributes like id, name, or custom data-* when available to create stable and specific locators.
- Use contains() for Partial Matching: When dealing with dynamic attribute values, use the contains() function to match partial values.
- Use text() to Match Visible Text: If the element’s visible text is consistent and unique, use the text() function to locate it.
- Combine Multiple Conditions: Make your XPath more specific by combining conditions using and or or.
- Use starts-with() for Matching Dynamic Prefixes: For attributes that begin with a consistent prefix, use the starts-with() function.
- Avoid Index-Based XPath When Possible: Using indexes like (//div[@class=’item’])[3] is fragile. DOM changes can break your test.
- Use XPath Axes When Necessary: Axes like following-sibling::, parent::, or ancestor:: help target elements in complex DOMs.
- Keep XPath Short and Readable: Write concise expressions that are easy to read and maintain. Avoid deeply nested or overly complex paths.
- Validate XPath Using Browser DevTools: Use tools like XPath tester or Chrome DevTools with $x(“your_xpath”) to test and validate XPath expressions before using them in scripts.
- Leverage Custom Data Attributes: Prefer data-testid, data-role, or other data-* attributes as they are designed for automation.
- Write Contextual Locators: Use nearby stable elements, like labels, to anchor your XPath reliably.
Common XPath Issues and How to Troubleshoot?
Here are some common XPath issues in Selenium and how to troubleshoot them.
-
Invalid or Malformed XPath: Syntax errors like missing brackets, unclosed quotes, wrong axes, or stray characters.
-
XPath Matches Nothing: The element may not be present in the live DOM (e.g., inside iFrame, Shadow DOM, or is loaded dynamically).
-
XPath Returns Multiple Elements: The XPath is too broad or lacks specific filters.
-
Dynamic Attributes (IDs, Classes): Attributes change between sessions or page loads.
-
Element Inside Shadow DOM or Custom Elements: Standard XPath can’t access elements inside shadow DOM.
-
XPath Works in Browser but Not in Code: Possible timing issue or unhandled frame context.
-
Case Sensitivity and Typos: XPath is case-sensitive; even small mismatches can break it.
Fix: Use browser DevTools or tools like SelectorsHub to validate and correct your XPath.
Fix: Check for iframes using browser DevTools. Use JavaScript like document.querySelector or $x() in console. Add proper waits using WebDriverWait.
Fix: Use indexes like (//div[@class=’item’])[1] or add more conditions such as //div[@class=’item’ and @data-id=’123′].
Fix: Use partial match functions like contains() or starts-with(). Example: //div[contains(@class, ‘btn’)].
Fix: Use JavaScript like element.shadowRoot.querySelector(). Consider tools like Playwright which handle shadow DOM better.
Fix: Wait for elements using explicit waits. Make sure to switch to the correct iframe using driver.switchTo().frame(…).
Fix: Double-check tag names and attributes. Test XPath directly using $x(‘your_xpath’) in browser console.
Conclusion
You’ve now seen how XPath works in Selenium, from the basics to advanced techniques like axes and dynamic locators. We also looked at how to handle specific elements like loaders and how to follow best practices for writing reliable XPath expressions.
To scale your automation, you can use LambdaTest online Selenium Grid. It helps you run tests in parallel, debug faster, and cover multiple browser-OS combinations without managing infrastructure.
Now that you’ve seen how XPath works, you might also want to explore how it differs from CSS selectors. You can this comparison guide on XPath vs CSS Selectors to know more.
Frequently Asked Questions (FAQs)
What is XPath?
XPath helps you locate elements in XML or HTML using structure. You use it with tags, attributes, or text to target nodes. It’s commonly used in automation, like Selenium. Think of it as a precise way to find things on a web page.
Why use XPath?
Use XPath when elements don’t have unique IDs or are nested. It gives you flexibility to locate based on attributes or text. XPath works even when the structure is complex or dynamic. It’s powerful for advanced test automation.
How to find XPath in Chrome?
Right-click the element and choose Inspect to open DevTools. Then right-click the HTML code and select Copy > Copy XPath. Paste it into your test or script to use it. This gives you a full path to that element.
How to write XPath?
Use the format //tagname[@attribute=’value’] to create basic paths. You can also use contains(), text(), or logical conditions. Combine multiple filters to get accurate matches. Always test your XPath in DevTools.
How to find XPath?
Inspect the element in Chrome DevTools and right-click its HTML. Choose Copy XPath to grab its locator. You can also refine it for stability. Use $x(‘your_xpath’) in Console to verify.
How to find XPath of an element?
Open DevTools and inspect the element. Right-click its HTML and choose Copy XPath. You can paste it in your script or validate it with $x(). This helps in writing reliable test cases.
What is XPath syntax in Selenium?
XPath in Selenium uses expressions like //tag[@attr=’value’]. You can use functions like contains() or axes like following. Double slashes (//) mean relative path. It’s powerful for locating dynamic elements.
How to use XPath?
Use XPath to find elements based on structure, text, or attributes. Start with //tagname[@attr=’value’] and build from there. It helps when IDs or class names aren’t unique. It’s widely used in testing and web scraping.
What is XPath in HTML?
XPath helps you select HTML elements using tag names, attributes, or position. It’s useful when IDs aren’t available or consistent. XPath works well in test scripts and scraping. Think of it as a flexible way to find HTML nodes.
How to use contains() method in XPath?
Use contains() to match partial values inside an attribute or text. Example: //input[contains(@placeholder, ‘Email’)]. It’s useful when values change dynamically. This adds flexibility to your locators.
How to write XPath for text?
Use //tagname[text()=’Exact Text’] for exact match. For partial matches, use contains(text(), ‘keyword’). It helps when text is visible but elements lack good attributes. Text-based XPath is useful in many UIs.
What is XPath injection?
XPath injection is a security flaw caused by unvalidated user input in queries. Attackers can manipulate XPath to access data. Always sanitize input in XPath expressions. It’s similar to SQL injection but for XML or HTML.
What is XPath axes in Selenium?
Axes let you navigate from one node to another like parent, sibling, or child. Examples include following, preceding, and ancestor. Use them when direct attributes don’t help. They give you powerful navigation control.
What is XPath in XML?
XPath helps you query and locate elements in XML documents. You can filter by tag, attribute, or node structure. It’s used in parsing, validation, and configuration files. XPath works the same in HTML and XML.
What is the difference between static and dynamic XPath?
Static XPath uses fixed paths and exact values, like //div[@id=’menu’]. Dynamic XPath uses functions like contains() or wildcards. Use dynamic XPath when elements or attributes change. It’s more robust for modern web apps.
Citations
- XPath Wikipedia: https://en.wikipedia.org/wiki/XPath
Got Questions? Drop them on LambdaTest Community. Visit now