Chapter{4}: Selenium Automation Testing: Mastering XPath: Advanced Techniques Made Simple

--

Image by freepik

Alright, so you’ve got the basics of XPath down — absolute vs. relative, contains(), starts-with(), and so on. But what if you're working on a real-world website like Myntra, where elements aren't always neatly structured? Let's level up your XPath skills so you can handle anything that comes your way!

1. When to Use Which XPath?

Not all XPaths are created equal. Some are better for stability, some for flexibility. Here’s a simple guide:

Use Absolute XPath (/) only if the page structure is static (rare).

  • Avoid it when dealing with dynamic elements (which is most of the time).

Use Relative XPath (//) for almost everything—it’s flexible and resistant to small changes in the page layout.

  • Use contains() when part of an attribute is stable but the full value changes (like IDs that have random numbers).
  • Use starts-with() when you know the beginning of an attribute but not the end.
  • Use text() when the visible text is the only reliable way to find an element.

2. Examples from a Web page(let’s say Myntra).

Finding a Search Bar

Let’s say the search bar has a class that looks like this:

<input type="text" class="desktop-searchBar">

You can locate it using:

driver.findElement(By.xpath("//input[@class='desktop-searchBar']")).sendKeys("Shoes");

Great! But what if tomorrow, the class name changes slightly?

Better way using contains():

driver.findElement(By.xpath("//input[contains(@class, 'searchBar')]")).sendKeys("Shoes");

This works even if they rename the class to myntra-searchBar or desktop-searchBar-new.

3. Handling Buttons with Dynamic Text

Imagine the “Add to Cart” button changes from “Add to Cart” to “Added!” after clicking.

<button class="cart-btn">Add to Cart</button>

Find the button using text():

driver.findElement(By.xpath("//button[text()='Add to Cart']")).click();

This will fail after clicking because the text changes.

Better approach: Use contains(text(), 'Add'), which works for both "Add to Cart" and "Added!":

driver.findElement(By.xpath("//button[contains(text(), 'Add')]")).click();

4. Traversing the DOM Like a Pro

Parent to Child Navigation

If you have this structure:

<div class="product">
<h2>Men's Shoes</h2>
<button class="buy-now">Buy Now</button>
</div>

You can select the “Buy Now” button based on its parent:

driver.findElement(By.xpath("//div[@class='product']/button")).click();

This selects the button inside .product.

Child to Parent Navigation (..)

Need to go up instead? Use .. to move to the parent. If you locate the button first but need to find the product name:

driver.findElement(By.xpath("//button[@class='buy-now']/..//h2")).getText();

This finds the parent div of the button and then locates the h2 inside it.

5. Working with Siblings

If you need to select a product price next to a title:

<div class="product">
<h2>Men's Shoes</h2>
<span class="price">₹1999</span>
</div>

You can use XPath to jump to the price:

driver.findElement(By.xpath("//h2[text()='Men's Shoes']/following-sibling::span")).getText();

This finds the h2 and then moves to its next sibling.

6. Using * When You're Unsure

Sometimes, the tag might change from <button> to <a>. Instead of guessing, use * to match any tag:

driver.findElement(By.xpath("//*[contains(text(), 'Add to Cart')]")).click();

This works for any element (<button>, <a>, <span>, etc.) as long as the text remains.

7. When to Avoid XPath?

  • If an element has a unique ID, prefer By.id() over XPath.
  • If it has a stable name, By.name() is usually faster.
  • XPath can be slower than CSS selectors. If performance is an issue, use:
driver.findElement(By.cssSelector("button.cart-btn")).click();
  • instead of
driver.findElement(By.xpath("//button[@class='cart-btn']")).click();

When dealing with dynamic elements on a webpage, some attributes stay the same, while others change frequently due to factors like session-based IDs, randomized class names, or dynamically generated content.

1. Attributes That Usually Change (Dynamic)

These attributes often get modified every time the page is loaded or interacted with:

  • ID (id) → Many modern websites generate unique IDs dynamically (e.g., button-12345 vs. button-67890 on the next load).
  • Class (class) → Sometimes classes have dynamically generated parts (e.g., btn-x345 today and btn-y678 tomorrow).
  • Name (name) → In rare cases, names can be generated dynamically, especially in form inputs.
  • Href (href) → URLs may have session tokens or timestamps (e.g., https://myntra.com/product/xyz?session=12345).
  • Data Attributes (data-*) → Some sites use data-id, data-product, or similar attributes that change dynamically.
  • Text Content (text()) → Button text might change after interaction (e.g., "Add to Cart" → "Added!").

2. Attributes That Usually Stay the Same (Stable)

These attributes tend to remain unchanged and are good candidates for XPath selection:

  • Tag Name (input, button, div, a) → A button will likely stay a button.
  • Aria Labels (aria-label) → Accessibility labels usually remain constant.
  • Placeholder (placeholder) → Input fields often retain the same placeholder text.
  • Role (role) → Elements with specific functions (like role="button") usually don't change.
  • Partial Class Names (class) → If only part of a class is dynamic, you can use contains() in XPath.

Final Thoughts

XPath is super powerful, but knowing when and how to use it is key. Use relative XPath as much as possible, mix in functions like contains() and starts-with(), and traverse the DOM smartly. Now go forth and automate like a pro!

You can now catch the podcast on YouTube too!

.

.

.

Happy Coding!

--

--

Automate This. By Mrigank Saxena
Automate This. By Mrigank Saxena

Written by Automate This. By Mrigank Saxena

Join me as I share insights, tips, and experiences from my journey in quality assurance, automation, and coding! https://www.linkedin.com/in/iammriganksaxena/

No responses yet