Popular Searches
Popular Course Categories
Popular Courses

XPath

Selenium Locators

XPath in Selenium

XPath stands for XML Path Language. In Selenium WebDriver, XPath is a powerful locator strategy used to identify and interact with web elements in an HTML DOM. XPath can locate elements using attributes, text, relationships between elements, indexes, and different axes.

XPath is especially useful when an element does not have a unique ID, Name, or Class Name, or when the tester needs to create a more flexible locator for dynamic web applications. Selenium WebDriver supports XPath through the By.xpath() method.

XPath is included among the locator strategies covered in Selenium training, along with ID and CSS selectors, and is used for locating web elements in practical browser automation. JustAcademy's Selenium Training Course also covers Selenium WebDriver, locators, web elements, forms, browser interactions, waits, and automation frameworks.

For course demonstration and registration information, visit the Register for Course Demo page.


1. What is XPath?

XPath is a query language used to navigate through elements and attributes in an XML or HTML document. Selenium uses XPath expressions to locate elements in the DOM.

For example, consider:

<input id="username" name="username" type="text">

An XPath locator for this element can be:

//input[@id='username']

Selenium code:

driver.findElement(

    By.xpath("//input[@id='username']")

);


2. Why XPath is Important in Selenium

XPath is important because modern web applications often contain complex and dynamic DOM structures. Simple locators may not always be sufficient to identify the required element.

  • XPath can locate elements using attributes.
  • XPath can locate elements using visible text.
  • XPath can locate elements using partial attribute values.
  • XPath can navigate parent-child relationships.
  • XPath can navigate sibling relationships.
  • XPath can locate elements based on surrounding elements.
  • XPath can handle many dynamic element scenarios.
  • XPath can use indexes when necessary.
  • XPath can locate elements inside complex DOM structures.
  • XPath is useful when unique IDs or names are unavailable.


3. Basic XPath Syntax

The most common XPath syntax is:

//tagname[@attribute='value']

Example:

//input[@name='username']

Another example:

//button[@type='submit']


4. XPath in Selenium

Selenium uses the By.xpath() method to locate an element.

driver.findElement(

    By.xpath("//input[@id='username']")

);

The general structure is:

driver.findElement(By.xpath("XPATH_EXPRESSION"));


5. Required Selenium Imports

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;


6. Basic XPath Example

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

 

public class XPathExample {

    public static void main(String[] args) {

 

        WebDriver driver = new ChromeDriver();

 

        driver.manage().window().maximize();

        driver.get("https://example.com");

 

        driver.findElement(

            By.xpath("//input[@id='username']")

        ).sendKeys("admin");

 

        driver.quit();

    }

}


7. Understanding the DOM

XPath works with the DOM structure of a web page. The browser converts HTML into a tree-like structure containing elements, attributes, text nodes, and relationships.

HTML

 |

 +-- BODY

      |

      +-- FORM

           |

           +-- INPUT

           |

           +-- INPUT

           |

           +-- BUTTON

XPath allows Selenium to navigate this structure and identify a specific element.


8. Absolute XPath

An Absolute XPath starts from the root of the HTML document and specifies the complete path to an element.

/html/body/div/form/input

Absolute XPath can become fragile because even a small change in the DOM structure can make the locator invalid.


9. Relative XPath

A Relative XPath usually starts with // and searches for an element based on its characteristics rather than describing the complete path from the root.

//input[@id='username']

Relative XPath is generally easier to maintain because it does not depend on the complete DOM hierarchy.


10. Absolute XPath vs Relative XPath

FeatureAbsolute XPathRelative XPath
Starts with///
DOM dependencyHighLower
MaintenanceCan be difficultGenerally easier
FlexibilityLimitedHigh
Typical usageSpecific full pathPractical automation locators


11. XPath Using ID

Suppose the HTML is:

<input id="username" type="text">

XPath:

//input[@id='username']

Selenium:

driver.findElement(

    By.xpath("//input[@id='username']")

).sendKeys("admin");


12. XPath Using Name

<input name="email" type="email">

XPath:

//input[@name='email']

Selenium:

driver.findElement(

    By.xpath("//input[@name='email']")

).sendKeys("[email protected]");


13. XPath Using Class

<button class="login-button">Login</button>

XPath:

//button[@class='login-button']


14. XPath Using Type Attribute

<input type="password">

XPath:

//input[@type='password']


15. XPath Using Value Attribute

<input type="submit" value="Login">

XPath:

//input[@value='Login']


16. XPath Using Placeholder

<input placeholder="Enter Username" type="text">

XPath:

//input[@placeholder='Enter Username']


17. XPath Using Multiple Attributes

Multiple attributes can be combined using the and operator.

//input[@type='text' and @name='username']

Another example:

//input[@type='text' and @name='username' and @placeholder='Enter Username']


18. XPath Using OR Condition

The or operator can be used when either of multiple conditions can identify the element.

//input[@id='username' or @name='username']

This XPath matches an input whose ID is username or whose name is username.


19. XPath Using Text

The text() function is useful for locating elements based on their exact visible text.

<button>Login</button>

XPath:

//button[text()='Login']

Selenium:

driver.findElement(

    By.xpath("//button[text()='Login']")

).click();


20. XPath Using Partial Text with contains()

The contains() function is useful when only part of the text is stable.

<button>Login to Account</button>

XPath:

//button[contains(text(),'Login')]


21. XPath contains() Function

The contains() function can be used with attributes as well as text.

Attribute example:

//input[contains(@id,'user')]

Text example:

//button[contains(text(),'Login')]

Class example:

//div[contains(@class,'container')]


22. XPath starts-with() Function

The starts-with() function identifies elements whose attribute value or text starts with a specified value.

//input[starts-with(@id,'user_')]

This is useful for dynamic IDs such as:

user_12345

user_93842

user_84729


23. XPath normalize-space()

The normalize-space() function removes leading and trailing whitespace and normalizes consecutive whitespace characters.

//button[normalize-space()='Login']

This can be useful when HTML contains unexpected spaces around visible text.


24. normalize-space() with Partial Text

//button[contains(normalize-space(),'Login')]


25. XPath with and

//input[@type='text' and @name='username']

Both conditions must match.


26. XPath with or

//input[@id='username' or @name='username']

At least one condition must match.


27. XPath with not()

The not() function can exclude elements matching a particular condition.

//input[not(@type='hidden')]

This selects input elements that do not have type equal to hidden.


28. XPath Using Multiple Conditions with contains()

//button[contains(@class,'btn') and contains(@class,'login')]


29. XPath Indexing

XPath supports indexes for selecting a particular matching element.

(//input[@type='text'])[1]

Second matching element:

(//input[@type='text'])[2]


30. XPath Indexing Example

<input type="text" name="first">

<input type="text" name="second">

<input type="text" name="third">

First input:

(//input[@type='text'])[1]

Second input:

(//input[@type='text'])[2]


31. XPath Position()

The position() function can be used to identify an element based on its position.

//input[@type='text'][position()=1]

Second element:

//input[@type='text'][position()=2]


32. XPath last()

The last() function identifies the last matching element.

//input[@type='text'][last()]


33. XPath Parent Axis

The parent axis selects the parent of the current element.

//input[@id='username']/parent::div


34. XPath Parent Using ..

The .. notation can be used to move to the parent element.

//input[@id='username']/..


35. XPath Child Axis

The child axis selects child elements.

//div[@id='login']/child::input

Equivalent shorter form:

//div[@id='login']/input


36. XPath Descendant Axis

The descendant axis selects elements located anywhere below the current element.

//div[@id='login']/descendant::input

Shorter form:

//div[@id='login']//input


37. XPath Ancestor Axis

The ancestor axis selects ancestor elements of the current element.

//input[@id='username']/ancestor::form


38. XPath Following-Sibling

The following-sibling axis selects siblings that appear after the current element.

//label[text()='Username']/following-sibling::input


39. XPath Preceding-Sibling

The preceding-sibling axis selects siblings that appear before the current element.

//input[@id='username']/preceding-sibling::label


40. XPath Following Axis

The following axis selects elements appearing later in the document, excluding descendants.

//label[text()='Username']/following::input


41. XPath Preceding Axis

The preceding axis selects elements appearing before the current element.

//input[@id='password']/preceding::label


42. XPath Self Axis

The self axis refers to the current node.

//input[@id='username']/self::input


43. XPath Descendant-or-Self

//div[@id='container']/descendant-or-self::div


44. XPath Ancestor-or-Self

//input[@id='username']/ancestor-or-self::input


45. XPath Axes Reference

AxisPurpose
ancestorSelects ancestors
ancestor-or-selfSelects ancestors and current node
attributeSelects attributes
childSelects direct children
descendantSelects descendants
descendant-or-selfSelects descendants and current node
followingSelects nodes later in the document
following-siblingSelects following siblings
parentSelects parent
precedingSelects preceding nodes
preceding-siblingSelects preceding siblings
selfSelects current node


46. XPath Using Parent-Child Relationship

<div class="login-form">

    <input name="username">

</div>

XPath:

//div[@class='login-form']/input[@name='username']


47. XPath Using Nested Elements

<div class="container">

    <div class="form">

        <input name="email">

    </div>

</div>

XPath:

//div[@class='container']//input[@name='email']


48. XPath Using Label Relationship

<label>Username</label>

<input type="text" name="username">

XPath:

//label[text()='Username']/following-sibling::input


49. XPath for Form Elements

//form[@id='registration']//input[@name='email']

This identifies an email field within a specific registration form.


50. XPath for Buttons

//button[@type='submit']

Using text:

//button[text()='Submit']

Using partial text:

//button[contains(text(),'Submit')]


51. XPath for Links

//a[@href='/login']

Using text:

//a[text()='Login']

Using partial text:

//a[contains(text(),'Login')]


52. XPath for Checkboxes

//input[@type='checkbox' and @name='terms']

Selenium:

WebElement checkbox = driver.findElement(

    By.xpath("//input[@type='checkbox' and @name='terms']")

);

 

if (!checkbox.isSelected()) {

    checkbox.click();

}


53. XPath for Radio Buttons

//input[@type='radio' and @value='male']

Selenium:

driver.findElement(

    By.xpath("//input[@type='radio' and @value='male']")

).click();


54. XPath for Dropdown

<select id="country">

    <option value="india">India</option>

    <option value="usa">USA</option>

</select>

Select element:

//select[@id='country']

India option:

//select[@id='country']/option[@value='india']


55. XPath for Images

<img src="/images/logo.png" alt="Company Logo">

XPath:

//img[@alt='Company Logo']


56. XPath for Tables

<table id="users">

    <tr>

        <td>John</td>

        <td>[email protected]</td>

    </tr>

</table>

Table:

//table[@id='users']

Rows:

//table[@id='users']//tr

Cells:

//table[@id='users']//tr//td


57. XPath for Specific Table Row

Suppose a table contains product names:

<table id="products">

    <tr>

        <td>Laptop</td>

        <td>1000</td>

    </tr>

    <tr>

        <td>Phone</td>

        <td>700</td>

    </tr>

</table>

Row containing Laptop:

//table[@id='products']//tr[td[text()='Laptop']]


58. XPath for Button in Specific Table Row

//table[@id='products']//tr[td[text()='Laptop']]//button

This is useful for actions such as Edit, Delete, View, or Add to Cart for a specific table row.


59. XPath for Dynamic IDs

Suppose an application generates:

<input id="user_847392">

If the stable portion is user_, use:

//input[starts-with(@id,'user_')]

Or:

//input[contains(@id,'user_')]


60. XPath for Dynamic Class

<button class="btn-submit-8392">Submit</button>

XPath:

//button[contains(@class,'btn-submit')]


61. XPath Using Multiple Stable Attributes

//input[contains(@class,'form-control') and @name='email']

Combining stable attributes can reduce the chance of matching the wrong element.


62. XPath for Dynamic Text

Suppose the text is:

Welcome, John

A partial text XPath can be:

//div[contains(text(),'Welcome')]

For whitespace variations:

//div[contains(normalize-space(),'Welcome')]


63. XPath for Text with Extra Spaces

<button>  Login  </button>

Instead of depending on the exact whitespace:

//button[normalize-space()='Login']


64. XPath for Partial Attribute Value

//input[contains(@placeholder,'Username')]


65. XPath Using Starts-With for URLs

//a[starts-with(@href,'/products')]

This can identify links whose href starts with a known path.


66. XPath for Multiple Matching Elements

When several elements match the same XPath, Selenium's findElement() returns the first matching element according to the WebDriver element search.

driver.findElement(

    By.xpath("//button[@class='btn']")

);

If you need all matching elements, use findElements().


67. XPath with findElements()

List<WebElement> buttons = driver.findElements(

    By.xpath("//button")

);


68. Count Elements Using XPath

List<WebElement> links = driver.findElements(

    By.xpath("//a")

);

 

System.out.println(

    "Number of links: " + links.size()

);


69. Loop Through XPath Results

List<WebElement> links = driver.findElements(

    By.xpath("//nav//a")

);

 

for (WebElement link : links) {

    System.out.println(link.getText());

}


70. XPath with Explicit Wait

WebDriverWait wait =

    new WebDriverWait(driver, Duration.ofSeconds(10));

 

WebElement loginButton = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.xpath("//button[@type='submit']")

    )

);

 

loginButton.click();


71. Required Imports for Explicit Wait

import java.time.Duration;

import org.openqa.selenium.By;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.support.ui.ExpectedConditions;

import org.openqa.selenium.support.ui.WebDriverWait;


72. XPath with Visibility Wait

WebElement dashboard = wait.until(

    ExpectedConditions.visibilityOfElementLocated(

        By.xpath("//div[@id='dashboard']")

    )

);


73. XPath with Presence Wait

WebElement element = wait.until(

    ExpectedConditions.presenceOfElementLocated(

        By.xpath("//input[@name='username']")

    )

);


74. XPath with Clickable Wait

WebElement button = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.xpath("//button[contains(text(),'Login')]")

    )

);

 

button.click();


75. XPath and Implicit Wait

driver.manage().timeouts().implicitlyWait(

    Duration.ofSeconds(10)

);

After configuring the wait, XPath can be used normally with findElement().


76. XPath and Dynamic Web Applications

Dynamic applications may generate changing IDs, classes, text, and DOM structures. XPath functions such as contains(), starts-with(), and normalize-space() can help create more flexible locators.

//input[contains(@id,'user')]

//button[contains(@class,'submit')]

//div[normalize-space()='Login']


77. XPath for Login Form

<form id="loginForm">

    <input name="username" type="text">

    <input name="password" type="password">

    <button type="submit">Login</button>

</form>

Username:

//form[@id='loginForm']//input[@name='username']

Password:

//form[@id='loginForm']//input[@name='password']

Login button:

//form[@id='loginForm']//button[@type='submit']


78. Complete Login Automation Using XPath

driver.findElement(

    By.xpath("//input[@name='username']")

).sendKeys("admin");

 

driver.findElement(

    By.xpath("//input[@name='password']")

).sendKeys("admin123");

 

driver.findElement(

    By.xpath("//button[@type='submit']")

).click();


79. XPath for Registration Form

driver.findElement(

    By.xpath("//input[@name='firstName']")

).sendKeys("John");

 

driver.findElement(

    By.xpath("//input[@name='lastName']")

).sendKeys("Smith");

 

driver.findElement(

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

).sendKeys("[email protected]");

 

driver.findElement(

    By.xpath("//input[@type='password']")

).sendKeys("Password123");

 

driver.findElement(

    By.xpath("//button[@type='submit']")

).click();


80. XPath for E-Commerce Product

<div class="product-card">

    <h3>Laptop</h3>

    <button>Add to Cart</button>

</div>

Product:

//div[contains(@class,'product-card')][.//h3[text()='Laptop']]

Add to Cart button for Laptop:

//div[contains(@class,'product-card')][.//h3[text()='Laptop']]//button[contains(text(),'Add to Cart')]


81. XPath for Navigation Links

//nav//a[@href='/courses']

Using text:

//nav//a[normalize-space()='Courses']


82. XPath for Modal

<div id="loginModal" class="modal">

    <input name="username">

</div>

Username inside modal:

//div[@id='loginModal']//input[@name='username']


83. XPath for Alert Message

<div class="alert-success">Login successful</div>

XPath:

//div[contains(@class,'alert-success')]

Using text:

//div[contains(text(),'Login successful')]


84. XPath for Error Message

//div[contains(@class,'error-message')]

Or:

//div[contains(normalize-space(),'Invalid password')]


85. XPath for Checkbox State

XPath can locate a checkbox using its attributes. Selenium's isSelected() method is normally used to verify its current state.

WebElement checkbox = driver.findElement(

    By.xpath("//input[@type='checkbox' and @name='terms']")

);

 

if (checkbox.isSelected()) {

    System.out.println("Checkbox is selected");

}


86. XPath for Radio Button State

WebElement radio = driver.findElement(

    By.xpath("//input[@type='radio' and @value='male']")

);

 

if (radio.isSelected()) {

    System.out.println("Male radio button is selected");

}


87. XPath for Selected Radio Button

For HTML form controls, XPath can sometimes be used with attributes such as @checked, but the presence of the attribute and the current DOM state are not always interchangeable. Selenium's isSelected() method is the preferred way to verify the current selected state.


88. XPath for Disabled Element

//button[@disabled]

Selenium can then verify whether the element is enabled:

WebElement button = driver.findElement(

    By.xpath("//button[@disabled]")

);

 

System.out.println(button.isEnabled());


89. XPath for Required Elements

//input[@required]


90. XPath for Elements with Specific Data Attributes

//button[@data-testid='login-button']

Data attributes can provide stable locator values when they are intentionally designed for automation or testing.


91. XPath with data-testid

<button data-testid="submit-button">Submit</button>

XPath:

//button[@data-testid='submit-button']


92. XPath with aria-label

<button aria-label="Search">🔍</button>

XPath:

//button[@aria-label='Search']


93. XPath for Angular Form Controls

Angular applications may expose attributes such as formcontrolname.

//input[@formcontrolname='email']


94. XPath for React Applications

React applications may contain dynamically generated class names. Stable attributes such as data-testid, aria-label, or application-specific attributes can sometimes provide more maintainable XPath expressions.

//button[@data-testid='login-button']


95. XPath for Specific Table Row

Suppose the table contains:

John

Smith

[email protected]

Active

A row containing the email can be located using:

//table[@id='users']//tr[td[contains(text(),'[email protected]')]]


96. XPath for Action Button in Specific Row

//table[@id='users']//tr[td[contains(text(),'[email protected]')]]//button[contains(text(),'Edit')]

This technique is useful when every row contains similar Edit or Delete buttons.


97. XPath Using Dot for Current Context

The dot . represents the current context node in XPath expressions.

//div[contains(@class,'product')][.//h3[text()='Laptop']]

Here the dot refers to the current product element while checking its descendant heading.


98. XPath Using Descendant Text

//div[.//span[normalize-space()='Laptop']]

This locates a div containing a descendant span with the specified text.


99. XPath with contains() and Multiple Conditions

//div[contains(@class,'product') and .//h3[contains(text(),'Laptop')]]


100. XPath for Nested Buttons

//div[@class='card']//div[@class='actions']//button


101. XPath for Parent Based on Child

Sometimes an element can be identified through a unique child.

//div[.//input[@name='username']]

This selects a div containing the username input.


102. XPath for Ancestor Based on Child

//input[@name='username']/ancestor::form

This locates the form containing the username field.


103. XPath for Sibling-Based Location

//label[normalize-space()='Password']/following-sibling::input

This is useful when the label text is stable but the input does not have a useful unique attribute.


104. XPath with following-sibling and Index

//label[normalize-space()='Username']/following-sibling::input[1]


105. XPath for Elements Based on Parent Attributes

//div[@id='loginForm']//input[@name='username']

This restricts the search to a particular parent container.


106. XPath for Multiple Forms

//form[@id='loginForm']//input[@name='username']

This is safer than using a generic selector such as:

//input[@name='username']

when multiple username fields may exist on the page.


107. XPath with Position in a Parent

//ul[@id='menu']/li[2]

This selects the second direct li child.


108. XPath for First Matching Element

(//button[contains(@class,'submit')])[1]


109. XPath for Last Matching Element

(//button[contains(@class,'submit')])[last()]


110. XPath with not() for Exclusion

//button[not(@disabled)]

This identifies buttons that do not contain a disabled attribute.


111. XPath and findElement()

WebElement username = driver.findElement(

    By.xpath("//input[@name='username']")

);

 

username.sendKeys("admin");


112. XPath and findElements()

List<WebElement> buttons = driver.findElements(

    By.xpath("//button")

);

 

for (WebElement button : buttons) {

    System.out.println(button.getText());

}


113. XPath and Page Object Model

XPath locators can be stored inside Page Object classes for better organization and maintainability.

public class LoginPage {

 

    private WebDriver driver;

 

    private By username =

        By.xpath("//input[@name='username']");

 

    private By password =

        By.xpath("//input[@name='password']");

 

    private By loginButton =

        By.xpath("//button[@type='submit']");

 

    public LoginPage(WebDriver driver) {

        this.driver = driver;

    }

 

    public void login(String user, String pass) {

        driver.findElement(username).sendKeys(user);

        driver.findElement(password).sendKeys(pass);

        driver.findElement(loginButton).click();

    }

}


114. Reusable XPath Utility

public WebElement findByXPath(String xpath) {

    return driver.findElement(

        By.xpath(xpath)

    );

}

Usage:

findByXPath("//input[@name='username']")

    .sendKeys("admin");


115. Reusable XPath Click Method

public void clickByXPath(String xpath) {

    driver.findElement(

        By.xpath(xpath)

    ).click();

}


116. Reusable XPath Type Method

public void typeByXPath(String xpath, String text) {

    driver.findElement(

        By.xpath(xpath)

    ).sendKeys(text);

}


117. XPath with TestNG

import org.testng.Assert;

import org.testng.annotations.Test;

 

@Test

public void verifyLoginButton() {

 

    WebElement button = driver.findElement(

        By.xpath("//button[@type='submit']")

    );

 

    Assert.assertTrue(button.isDisplayed());

}


118. XPath Validation Example

WebElement message = driver.findElement(

    By.xpath("//div[contains(@class,'success-message')]")

);

 

Assert.assertTrue(message.isDisplayed());


119. XPath and NoSuchElementException

If Selenium cannot find an element using the supplied XPath, NoSuchElementException may occur.

Common reasons include:

  • Incorrect XPath syntax.
  • Wrong attribute value.
  • Element is not present.
  • Element has not loaded yet.
  • Wrong iframe context.
  • Incorrect page or URL.
  • DOM changed after navigation.


120. XPath and InvalidSelectorException

If the XPath expression is syntactically invalid, Selenium may throw an InvalidSelectorException.

Example of a valid XPath:

//input[@id='username']

Always verify complex XPath expressions in browser developer tools before adding them to automation code.


121. XPath and StaleElementReferenceException

A previously located element can become stale if the page refreshes or the DOM element is replaced.

A common solution is to locate the element again rather than continuing to use an outdated WebElement reference.


122. XPath and ElementClickInterceptedException

If another element overlays the target, Selenium may not be able to click it even when the XPath is correct.

Possible solutions include:

  • Wait for the overlay to disappear.
  • Wait until the target becomes clickable.
  • Scroll appropriately.
  • Handle popups or modal windows.


123. XPath with iframe

If an element is inside an iframe, Selenium must first switch into the iframe.

driver.switchTo().frame("loginFrame");

 

driver.findElement(

    By.xpath("//input[@name='username']")

).sendKeys("admin");

 

driver.switchTo().defaultContent();


124. XPath with Nested iframe

driver.switchTo().frame("outerFrame");

driver.switchTo().frame("innerFrame");

 

driver.findElement(

    By.xpath("//input[@id='username']")

).sendKeys("admin");

 

driver.switchTo().defaultContent();


125. XPath and Shadow DOM

XPath does not automatically cross a Shadow DOM boundary. If the target element exists inside a shadow root, Selenium must first access the shadow root and then locate the element within that context using supported Shadow DOM APIs.


126. XPath and SVG Elements

SVG elements can require special attention because their namespace and DOM structure can differ from ordinary HTML elements.

For example:

//*[name()='svg']

For a specific SVG element, inspect the actual DOM structure and create a locator based on stable attributes.


127. XPath vs CSS Selector

FeatureXPathCSS Selector
MethodBy.xpath()By.cssSelector()
ID matchingSupportedSupported
Class matchingSupportedSupported
Attribute matchingSupportedSupported
Text matchingStrongMore limited
Parent navigationStrongDifferent model
Sibling navigationStrongSupported
Complex DOM relationshipsHighly expressiveExpressive but different
Partial attribute matchingcontains(), starts-with()*, ^=, $=


128. XPath vs ID Locator

FeatureIDXPath
MethodBy.id()By.xpath()
SyntaxSimpleMore expressive
AttributesID onlyMultiple attributes
RelationshipsNoYes
TextNoYes


129. XPath Best Practices

  • Prefer relative XPath over unnecessarily long absolute XPath.
  • Use stable attributes whenever possible.
  • Prefer unique and meaningful attributes.
  • Use data-testid or similar test attributes when intentionally provided by the application.
  • Use contains() for stable portions of dynamic attributes.
  • Use starts-with() when the beginning of an attribute is stable.
  • Use normalize-space() when whitespace can vary.
  • Avoid unnecessary indexes.
  • Avoid very long DOM paths.
  • Avoid depending on dynamically generated values unless there is a stable pattern.
  • Use explicit waits for dynamically loaded elements.
  • Store XPath locators in Page Object classes.
  • Validate complex XPath expressions before using them in tests.


130. Avoid Fragile Absolute XPath

Avoid locators such as:

/html/body/div[2]/div[1]/form/div[3]/input

A more maintainable locator may be:

//form[@id='loginForm']//input[@name='username']


131. Avoid Unnecessary Indexes

Instead of:

(//button)[7]

Prefer a stable locator:

//button[@type='submit' and normalize-space()='Login']

Indexes can be useful when the DOM genuinely requires positional selection, but they should not be the first choice when a stable attribute is available.


132. Validate XPath in Browser Developer Tools

Browsers provide developer tools that can be used to inspect the DOM and test XPath expressions.

Open Web Page

      ↓

Right Click Element

      ↓

Select Inspect

      ↓

Understand DOM Structure

      ↓

Identify Stable Attributes

      ↓

Create XPath

      ↓

Test XPath

      ↓

Use XPath in Selenium

      ↓

Validate Automation


133. Testing XPath in Browser Console

XPath can be tested in browser developer tools using document.evaluate().

document.evaluate(

    "//input[@id='username']",

    document,

    null,

    XPathResult.FIRST_ORDERED_NODE_TYPE,

    null

).singleNodeValue;

This helps verify whether an XPath identifies the intended element before implementing it in Selenium.


134. Practical Project: Login Automation

driver.get("https://example.com/login");

 

driver.findElement(

    By.xpath("//input[@name='username']")

).sendKeys("admin");

 

driver.findElement(

    By.xpath("//input[@name='password']")

).sendKeys("admin123");

 

driver.findElement(

    By.xpath("//button[@type='submit']")

).click();


135. Practical Project: Registration Automation

driver.findElement(

    By.xpath("//input[@name='firstName']")

).sendKeys("John");

 

driver.findElement(

    By.xpath("//input[@name='lastName']")

).sendKeys("Smith");

 

driver.findElement(

    By.xpath("//input[@name='email']")

).sendKeys("[email protected]");

 

driver.findElement(

    By.xpath("//input[@name='password']")

).sendKeys("Password123");

 

driver.findElement(

    By.xpath("//button[contains(normalize-space(),'Register')]")

).click();


136. Practical Project: E-Commerce Product Selection

driver.findElement(

    By.xpath("//h3[normalize-space()='Laptop']")

);

 

driver.findElement(

    By.xpath("//div[contains(@class,'product-card')][.//h3[normalize-space()='Laptop']]//button[contains(normalize-space(),'Add to Cart')]")

).click();


137. Practical Project: Table Data Extraction

List<WebElement> rows = driver.findElements(

    By.xpath("//table[@id='users']//tbody//tr")

);

 

for (WebElement row : rows) {

    System.out.println(row.getText());

}


138. Practical Project: Table Row Action

WebElement editButton = driver.findElement(

    By.xpath(

        "//table[@id='users']//tr[td[normalize-space()='[email protected]']]//button[contains(normalize-space(),'Edit')]"

    )

);

 

editButton.click();


139. Practical Project: Navigation Automation

driver.findElement(

    By.xpath("//nav//a[normalize-space()='Courses']")

).click();


140. Practical Project: Checkbox Selection

WebElement terms = driver.findElement(

    By.xpath("//input[@type='checkbox' and @name='terms']")

);

 

if (!terms.isSelected()) {

    terms.click();

}


141. Practical Project: Radio Button Selection

WebElement male = driver.findElement(

    By.xpath("//input[@type='radio' and @value='male']")

);

 

if (!male.isSelected()) {

    male.click();

}


142. Practical Project: Dropdown Option

driver.findElement(

    By.xpath("//select[@id='country']")

);

 

driver.findElement(

    By.xpath("//select[@id='country']/option[@value='india']")

).click();


143. XPath Automation Flow

Launch Browser

      ↓

Open Application

      ↓

Inspect DOM

      ↓

Identify Stable Attributes

      ↓

Create XPath

      ↓

Validate XPath

      ↓

Use By.xpath()

      ↓

Locate WebElement

      ↓

Perform Action

      ↓

Validate Result

      ↓

Continue Test

      ↓

Close Browser


144. XPath Quick Reference

RequirementXPath
ID//input[@id='username']
Name//input[@name='username']
Class//button[@class='login-button']
Attribute//input[@type='text']
Multiple Attributes//input[@type='text' and @name='username']
Exact Text//button[text()='Login']
Partial Text//button[contains(text(),'Login')]
Contains Attribute//input[contains(@id,'user')]
Starts With//input[starts-with(@id,'user_')]
Normalized Text//button[normalize-space()='Login']
Parent//input[@id='username']/parent::div
Child//div[@id='login']/child::input
Descendant//div[@id='login']//input
Ancestor//input[@id='username']/ancestor::form
Following Sibling//label/following-sibling::input
Preceding Sibling//input/preceding-sibling::label
First Match(//button)[1]
Last Match(//button)[last()]
Not//input[not(@type='hidden')]


145. XPath Interview Questions

Q1. What is XPath?

XPath is a language used to navigate XML and HTML DOM structures and identify specific nodes. Selenium uses XPath expressions to locate web elements.

Q2. What is the difference between absolute and relative XPath?

Absolute XPath starts from the root and describes the complete path, while relative XPath generally starts with // and identifies elements using attributes, text, relationships, or other conditions.

Q3. Which Selenium method is used for XPath?

By.xpath()

Q4. How do you locate an element by ID using XPath?

driver.findElement(

    By.xpath("//input[@id='username']")

);

Q5. How do you locate an element using text?

driver.findElement(

    By.xpath("//button[text()='Login']")

);

Q6. How do you locate an element using partial text?

driver.findElement(

    By.xpath("//button[contains(text(),'Login')]")

);

Q7. What is contains() used for?

contains() is used to match a substring within an attribute value or text.

Q8. What is starts-with() used for?

starts-with() identifies elements whose selected attribute or text starts with a specified value.

Q9. What is normalize-space()?

It normalizes whitespace and is useful when text contains unwanted leading, trailing, or repeated spaces.

Q10. How do you select a parent element?

//input[@id='username']/parent::div

Q11. How do you select a child element?

//div[@id='login']/child::input

Q12. How do you select a sibling?

//label/following-sibling::input

Q13. How do you select the last matching element?

(//button)[last()]

Q14. How do you handle dynamic IDs?

//input[starts-with(@id,'user_')]

Q15. Can XPath be used with findElements()?

Yes.

driver.findElements(

    By.xpath("//button")

);

Q16. Can XPath locate elements based on visible text?

Yes. Functions such as text() and normalize-space() can be used.

Q17. What is the difference between // and /?

A single slash is used for a direct path step, while // is commonly used to search through descendants from the current context or document.

Q18. Can XPath work with dynamic web pages?

Yes. Functions such as contains(), starts-with(), and stable attribute combinations can help identify dynamic elements.

Q19. Can XPath cross an iframe?

No. Selenium must first switch into the iframe context before locating elements inside it.

Q20. Can XPath automatically cross Shadow DOM boundaries?

No. The appropriate shadow root context must be accessed before locating elements inside it.


146. XPath Best-Practice Checklist

  • Use relative XPath where appropriate.
  • Prefer stable attributes.
  • Use unique identifiers whenever available.
  • Use multiple attributes when necessary.
  • Use text-based XPath when visible text is stable.
  • Use contains() for stable partial values.
  • Use starts-with() for predictable dynamic prefixes.
  • Use normalize-space() when whitespace varies.
  • Avoid unnecessary indexes.
  • Avoid long absolute XPath expressions.
  • Avoid dynamically generated values when a stable attribute is available.
  • Use explicit waits for dynamic elements.
  • Switch into iframes before locating elements inside them.
  • Handle Shadow DOM through its proper context.
  • Keep XPath locators inside Page Object classes.
  • Test XPath expressions before using them in large automation suites.


147. Final Conclusion

XPath is one of the most powerful locator strategies available in Selenium WebDriver. It allows automation testers to identify elements using IDs, names, classes, attributes, visible text, partial values, indexes, parent-child relationships, sibling relationships, and advanced XPath axes.

A maintainable XPath should generally rely on stable attributes and meaningful relationships rather than fragile absolute DOM paths or unnecessary indexes. Functions such as contains(), starts-with(), and normalize-space() are especially useful when working with dynamic web applications.

XPath becomes even more useful when combined with Selenium concepts such as WebElement methods, explicit waits, Page Object Model, TestNG, dynamic element handling, frames, forms, tables, and real-world automation projects.

For structured learning of Selenium WebDriver, XPath, CSS Selectors, Web Elements, browser automation, waits, TestNG, Page Object Model, and practical automation testing, explore the JustAcademy's Selenium Training Course.

To explore the available course demonstration and registration options, visit the Register for Course Demo page.

whatsapp