One of the main reasons behind Selenium's popularity is that it supports multiple element locators. And one of them is XPath. XPath is one of the most powerful and flexible element locators in Selenium Webdriver. It helps you to navigate through the HTML structures of a page to locate an element using XPath.
In this guide, we will learn about what is XPath, how it works, and when to use it in Selenium test scripts. It is necessary to learn about different ways to find XPath of the element and how to write XPath syntax easily using real world examples. By the end, you will know the difference between absolute vs. relative XPath, common XPath expressions, and how to handle dynamic and nested elements like a pro.
What is XPath in Selenium?
When to use XPath In Selenium WebDriver?
You can use XPath element locator:
- When dealing with dynamic elements that change frequently.
- When you need to navigate between elements (like finding a button inside a specific div).
- When other locators don’t work or aren’t stable.
- When working with complex web structures like SVG or Shadow DOM.
When not to use XPath in Selenium?
- When performance is important → XPath is the slowest option.
- When an element has a unique and stable ID or Name. → Use By.id() to By.name().
- When CSS Selectors can do the job → Use By.cssSelector()
- When dealing with Shadow DOM → It is better to use JavaScript instead of XPath.
- When working with SVG Elements → CSS Selectors is a better option.
Why Should You Use XPath?
XPath Can Find Any Element on the Page
Great for Dynamic and Complex Elements
You Can Move Around the DOM Like a Pro
Absolute vs. Relative XPath
Relative XPath (//input[@type='text']) is a more flexible way to locate an element based on its attributes, no matter where they are on the page.
Powerful Search Functions
Example:
- contains(): //button[contains(text(),'Login')]: Finds buttons with "Login" in the text.
- starts-with(): //input[starts-with(@id,'user')]: Finds input textbox elements where the ID starts with "user" text.
- text(): //h1[text()='Hello']: Finds an element with exact text "Hello".
Handles Shadow DOM & SVG Elements
Combine Multiple Conditions for Precision
What are the different types of XPath?
Mainly there are two types of XPath that you can use in Selenium. Absolute XPath and Relative XPath. Each type has its own use case, advantages, and limitations. As experts suggest, Relative XPath is more reliable than the Absolute XPath.
Let’s go through them step by step to learn how to build XPath with examples.
Absolute XPath (Avoid If Possible!)
Absolute XPath Provides exact path from the root <html> tag to your element. But it can break if page structure changes.
It is just like giving a direction to someone like "Go to the first building, enter the second room, then open the first drawer."
Example of Absolute XPath:
/html/body/div[1]/form/input
Pros and Cons of Absolute XPath
- Precise: Points directly to your targeted element.
- Easy to generate: You can easily copy it from your browser's dev tool.
- Easily breaks: It can break even if there is a small change in page structure.
- Hard to maintain: You need to update the XPath even a small update on the page.
- When to use?: Only as a last resort when nothing else works.
Relative XPath (The Smart Choice!)
Example of Relative XPath
//input[@id='username']
Pros of Relative XPath
- More flexible: It works even if the structure of the page changes.
- Easier to maintain: Doesn’t break with minor updates.
- More readable: You can locate elements by attributes, text, or relationships.
- When to use?: Always prefer relative XPath over Absolute XPath. It is the recommended method for XPath.
All Possible Ways to Write XPath in Selenium
We will use the below given sample login form for demonstration.
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<div class="container">
<form id="loginForm">
<label for="username">Username:</label>
<input type="text" class="input-field" id="uname" name="username" placeholder="Enter username">
<label for="password">Password:</label>
<input type="password" id="pass" name="password" placeholder="Enter password">
<button type="submit">Login</button>
</form>
</div>
</body>
</html>
1. XPath Using Different Attributes
Here are examples of building XPath using id, name, class, and type attributes.
Using ID attribute
If an element has an ID attribute, then you can use it to build XPath as below.
//input[@id='uname']
Using Name attribute
If an element does not have an ID but a name attribute is available, then you can utilize it to generate XPath. Here is an Example:
//input[@name='username']
This XPath will locate an element with attribute name=username.
Using Class attribute
Same as ID and Name attributes, you can use the class attribute as well.
//input[@class='input-field']
This
XPath will locate an element with attribute class=input-field.Using Type attribute
You can use
//input[@type='password']
This
XPath will locate an element with attribute type=password.2. XPath Using contains() Function
You can use the contains function in XPath as below when the element has a dynamic attribute value.
//input[contains(@name, 'user')]
It will find any input field where the name contains text "user" (e.g., user123, user_login).
//button[contains(text(), 'Login')]
It will find a button that contains the text "Login" in its text.
3. XPath Using starts-with() Function
You can use the starts-with() function when an element’s attribute starts with a fixed text pattern.
//input[starts-with(@name, 'user')]
It will locate elements with name="username", name="user123", etc.
4. XPath using text() Function
You can use the text() function to find elements by their exact text value.
//button[text()='Login']
5. XPath Using Logical Operators (and, or)
You can use multiple conditions to narrow down your selection.
//input[@type='text' and @name='username']
It will find an <input> field that is both text-type and has the name "username".
//button[@type='submit' or text()='Login']
It will locate a button with either type="submit" or text "Login".
6. Parent-Child & Descendant XPath
To find elements that are direct children of a parent, you can write XPath as below.
//form/input
One can use given XPath to find any input field inside a <div>, even if it is deeply nested.
//form/input
7. Navigating the DOM (Parent, Sibling, Ancestors)
Moving to Parent (..)
//input[@name='password']/..
It will find the parent element of the password input field.
Finding Siblings
Next Sibling (following-sibling)
//label[@for='username']/following-sibling::input
It will locate the input field immediately after the "Username" label.
//input[@id='pass']/preceding-sibling::label
8. XPath Using Position (first(), last(), [n])
Locate the first element
//input[1]
Locate the last element
//table/tbody/tr[last()]
Finds the last row in a table.
Specific Position (nth element)
//input[2]
You can refer to this xpath cheat sheet which covers almost all functions, axes, predicts, expressions, and selectors.
Where to practice XPath?
Using XPath Axes in Selenium WebDriver With Examples
When to Use XPath Axes?
- When elements do not have any unique attributes like id or name.
- When you need to locate an element relative to another.
- When you are dealing with complex, nested structures.
List of XPath Axes with example
- child:: -> Selects Direct Children
- Example: //form/child::input (It will select all input fields inside the <form>.)
- parent:: -> Selects Parent of an Element
- Example: //input[@id='password']/parent::form (Finds the form that contains the password field.)
- descendant:: -> Selects All Nested Elements
- Example: //div/descendant::input (Finds all input fields inside the <div>.)
- ancestor:: -> Selects All Ancestor Elements (Upwards Traversal)
- Example: //input[@id='username']/ancestor::div (Finds the div container of the username input field.)
- following:: -> Selects All Elements After the Current Element.
- Example: //label[@for='username']/following::input (Finds the first input field after the username label (i.e., the username input))
- following-sibling:: -> Selects Next Sibling Elements
- Example: //label[@for='username']/following-sibling::input (Finds the username input field, which is the next sibling of the label.)
- preceding:: -> Selects All Elements Before the Current Element.
- Example: //input[@id='password']/preceding::label (Finds the label for username, which comes before the password input.)
- preceding-sibling:: -> Selects Previous Sibling Elements.
- Example: //input[@id='password']/preceding-sibling::label (Finds the password label, which is the sibling before the password input field.)
- self:: -> Selects the Current Element Itself.
- Example: //input[@id='username']/self::input (Finds itself (username input field))
Handling Customized Dynamic XPath In Selenium WebDriver
- Using contains() for Partial Matching: //input[contains(@id, 'user_')]
- Using starts-with() for Matching Beginning Text: //input[starts-with(@id, 'user_')]
- Using text() for Text-Based Matching: //button[text()='Login']
- Using or and and for Multiple Conditions: //input[@type='text' or @placeholder='Enter username']
- Using following-sibling:: to Locate Elements Dynamically: //label[text()='Username:']/following-sibling::input
- Using ancestor:: to Find Parent Elements: //input[@id='pass_987']/ancestor::form
- Using last() to Get the Last Element in a List: //input[last()]
How to Use XPath in Java, Python, and C# With Selenium
Using XPath in Selenium With Java Example
WebElement username = driver.findElement(By.xpath("//input[@id='username']"));
WebElement password = driver.findElement(By.xpath("//input[@type='password']"));
WebElement loginButton = driver.findElement(By.xpath("//button[contains(text(), 'Login')]"));
Using XPath in Selenium With Python Example
IWebElement username = driver.FindElement(By.XPath("//input[@id='username']"));
IWebElement password = driver.FindElement(By.XPath("//input[@type='password']"));
IWebElement loginButton = driver.FindElement(By.XPath("//button[contains(text(), 'Login')]"));
Using XPath in Selenium With C# Example
username = driver.find_element(By.XPATH, "//input[@id='username']")
password = driver.find_element(By.XPATH, "//input[@type='password']")
login_button = driver.find_element(By.XPATH, "//button[contains(text(), 'Login')]")
Best XPath extensions and Plugins For Chrome Browser
Frequently Asked Selenium Interview Questions on XPath
1. What is XPath in Selenium, and why do we use it?
- Some elements have dynamic changing attributes. XPath works well in this scenario.
- It has built-in functions and methods to search elements by text, partial text, parent-child relationships, or even positions.
- It is super flexible compared to other locators.
2. What is the difference between Absolute XPath and Relative XPath?
Example: /html/body/div[1]/table/tbody/tr[2]/td[1]
Relative XPath is more flexible as it can search from anywhere in the document instead of the root. Less chances to break when the UI updates.
Example: //table[@id='userTable']//tr[2]/td[1]
3. How do you handle dynamic elements with XPath?
- contains(): We can use contains() function when a part of attributes remain same
- Example: //input[contains(@id, 'email')]
- starts-with(): If the attribute's initial part remains the same, we can use the starts-with() function.
- Example: //button[starts-with(@class, 'submit-btn')]
- ends-with(): One can match the end part of an attribute if it remains the same.
- Example: //input[ends-with(@class, 'txt')]
- text(): It is useful when you are looking to locate an element based on visible text.
- Example: //a[text()='Login']
- last(): You can match the last matching element in a group using this function.
- Example: (//input[@type='text'])[last()]
4. How do you find a parent or sibling element using XPath?
- To find the parent element, we can use parent::
- Example: //input[@id='username']/parent::div
- To find the next sibling element, we can use the following-sibling::
- Example: //label[text()='Username']/following-sibling::input
- To find the previous sibling element, we can use preceding-sibling::
- Example: //input[@id='password']/preceding-sibling::label
5. What are XPath operators, and how do they help?
- and Operator: You can use it to match both conditions.
- Example of and Operator: //input[@type='text' and @name='email']
- or Operator: Useful when looking to match either condition.
- Example or Operator: //button[@id='submit' or @class='btn']
- = Operator: Check for exact match.
- Example of = Operator: //a[@href='login.html']
- != Operator: Not equal to
- Example of != Operator: //input[@type!='password']
You can learn and read frequently asked Selenium Interview Questions and Answers if you are preparing for an interview.
No comments:
Post a Comment