How to Use Locator XPath in Playwright: Complete Guide

Featured image showing how to use XPath in Playwright for locating web elements with code and browser interface.

When it comes to web automation, finding the right way to locate elements on a page is crucial. Without accurate locators, your tests might fail unexpectedly or become difficult to maintain. That’s why many testers prefer using XPath in Playwright — it’s one of the most powerful and flexible locator strategies available today.

Unlike basic locators such as ID or class, XPath allows you to navigate the entire structure of a web page using tags, attributes, visible text, and more. As a result, it’s ideal for selecting dynamic or deeply nested elements that are hard to reach with simpler methods.

In this easy-to-follow tutorial, you’ll learn how to use XPath in Playwright with clear explanations and real HTML examples. We’ll also share practical tips for writing stronger XPath expressions. Whether you’re a beginner or looking to sharpen your skills, this step-by-step guide has everything you need to get started confidently.

What is XPath?

XPath, short for XML Path Language, is a special way to search and find elements inside an XML or HTML page. It helps you create strong and flexible expressions to locate elements based on their position, text content, or attribute values.

While CSS selectors are usually easier to read and write, XPath in Playwright gives you more control. This becomes especially helpful when working with complex page layouts or dynamic elements that change often. So, if you need advanced precision, XPath is a smart choice.

Why Use XPath in Playwright?

Playwright fully supports XPath, which comes in handy when CSS selectors or built-in locators like getByRole just aren’t enough.

So, why do many testers and developers still depend on XPath in Playwright?

  • It lets you find elements by their visible text
  • You can move up or down the DOM tree
  • It’s perfect for targeting complex or deeply nested HTML
  • It works well when there’s no reliable ID, class, or attribute to use

While it may not be your first option in every case, XPath becomes extremely useful when simpler selectors don’t work. It gives you the flexibility and power needed to handle tricky page layouts.

How to Locate Elements Using XPath in Playwright

In Playwright, you can use XPath in two main ways:

1. Using page.locator() with xpath= prefix

await page.locator('xpath=//button[@id="submit"]').click();

2. Using page.$x() (returns an array of elements)

const elements = await page.$x('//h2[text()="Welcome"]');
await elements[0].click();

Between the two options, it’s generally better to go with page.locator(). That’s because it not only waits intelligently for elements to appear but also retries automatically until the element is ready. As a result, your Playwright tests become more stable and much more reliable.

Real-World Example XPath in Playwright

Here’s a simple real-world example to show how XPath works in Playwright. First, we locate the input field using its name attribute and fill in a username. Then, we locate the Login button by matching part of its visible text and click it.

await page.locator("xpath=//input[@name='username']").fill('myUser');
await page.locator("xpath=//button[contains(text(), 'Login')]").click();

As you can see, using XPath makes it easy to target elements even if their IDs or classes are missing. This approach is helpful when automating login forms or dynamic pages.

Examples of XPath Locators in Playwright

To make things easier to understand, let’s look at some common XPath combinations paired with their matching HTML examples. These practical examples will help you see exactly how each XPath expression works in real-world scenarios.

1. By Element Tag

One easy and straightforward way to locate elements in Playwright is by using their HTML tag name. This XPath strategy is not only simple but also highly reliable. It works especially well for identifying common elements such as <div>, <input>, or <button> that are frequently used on web pages.

HTML:

<button>Click Me</button>
Example showing how to locate an HTML button using XPath with element tag in Playwright
  • XPath: //button
  • Playwright Syntax: const button = page.locator(‘//button’);

2. By Attribute Value

Another helpful XPath strategy in Playwright is to select elements based on specific attribute values like id, class, or type. This approach is especially effective when you need to target elements that have unique identifiers. In many cases, using attributes is the simplest way to locate elements reliably on a web page.

HTML:

<input type="text" id="search" />
Illustration of an HTML input field with XPath examples to locate it using the ID attribute in Playwright.
  • XPath: //input[@id=’search’]
  • Playwright Syntax: const searchInput = page.locator(“//input[@id=’search’]”);

3. By Text Content

You can also locate elements in Playwright by using their exact visible text. This XPath method is particularly helpful for selecting elements like buttons, headings, or links that show specific content. When the visible text is the most reliable identifier, this approach becomes a simple and effective choice.

HTML:

<button>Submit</button>
Infographic showing how to locate an HTML element by its visible text using XPath in Playwright.
  • XPath: //button[text()=’Submit’]
  • Playwright Syntax: const submitButton = page.locator(“//button[text()=’Submit’]”);

4. By Partial Attribute Match

Alternatively, you can choose elements by partially matching their attribute values. This approach offers great flexibility and works especially well in Playwright. It’s particularly helpful when dealing with dynamic elements, where full attribute values might change often. By using partial matches, you can create more reliable locators that adapt to changing content.

HTML:

<input name="username" />
Illustration demonstrating how to use XPath with partial attribute matching to locate dynamic elements in Playwright automation scripts.
  • XPath: //input[contains(@name, ‘user’)]
  • Playwright Syntax: const userInput = page.locator(“//input[contains(@name, ‘user’)]”);

5. By Position

In situations where several elements share the same tag or attributes, XPath indexing becomes especially helpful. With this method, you can tell Playwright to select a specific element based on its exact position in the DOM. As a result, you gain more control when dealing with repeated structures like lists, tables, or forms. This makes your tests more precise and reduces the chance of selecting the wrong element.

HTML:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
  • XPath: (//ul/li)[3]
  • Playwright Syntax: const thirdListItem = page.locator(“(//ul/li)[3]”);

6. By Parent-Child Relationship

To accurately locate structured or nested elements in Playwright, you can use XPath based on parent-child relationships. This method works especially well when elements are grouped inside specific containers. In other words, if you’re trying to pinpoint an element within a defined layout or section, this approach helps you navigate directly to it. As a result, your locators become more precise and reliable in complex DOM structures.

HTML:

<div class="form">
  <input type="text" />
</div>
  • XPath: //div[@class=’form’]//input[@type=’text’]
  • Playwright Syntax: const textInput = page.locator(“//div[@class=’form’]//input[@type=’text’]”);

7. Using and/or Conditions

You can also combine multiple conditions using and or or in XPath. This gives you the power to apply more complex logic when locating elements in your Playwright test scripts, making your selectors both precise and adaptable.

HTML:

<input type="text" name="email" />
  • XPath: //input[@type=’text’ and @name=’email’]
  • Playwright Syntax: const emailInput = page.locator(“//input[@type=’text’ and @name=’email’]”);

8. Using following-sibling and preceding-sibling

In many real-world scenarios, you might need to locate elements that are near each other in the HTML structure. In such cases, XPath axes like following-sibling and preceding-sibling become extremely helpful. With Playwright, you can easily use these axes to move across sibling elements, making your test scripts more flexible and accurate.

HTML:

<label>Email</label>
<input type="text" />
  • XPath: //label[text()=’Email’]/following-sibling::input
  • Playwright Syntax: const inputAfterLabel = page.locator(“//label[text()=’Email’]/following-sibling::input”);

9. XPath in Playwright using ancestor or descendant

Sometimes, to locate an element accurately, you need to move up or down the entire DOM tree. This is where XPath axes like ancestor and descendant come in handy. With Playwright, these powerful axes let you access deeply nested elements or trace back to parent containers. As a result, your locators become more precise and adaptable to complex HTML structures.

HTML:

<div class="product">
  <span>Price</span>
</div>
  • XPath: //span[text()=’Price’]/ancestor::div[@class=’product’]
  • Playwright Syntax: const productDiv = page.locator(“//span[text()=’Price’]/ancestor::div[@class=’product’]”);

10. Wildcard (*) Selectors

At times, you may not know the exact tag of an element you want to locate. In such cases, using * in XPath becomes very helpful. This wildcard matches any tag type, making it easier to target elements flexibly. In Playwright, this approach works well when dealing with dynamic or unpredictable HTML structures.

HTML:

<div id="header">Welcome</div>
  • XPath: //*[@id=’header’]
  • Playwright Syntax: const headerElement = page.locator(“//*[@id=’header’]”);

Common Use Cases for XPath in Playwright

You should consider using XPath in the following scenarios:

  • The element lacks a stable ID, name, or class attributes
  • You need to select based on visible text
  • Elements are deeply nested or generated dynamically
  • You want to move up the DOM (not possible with CSS)

For example, when automating dashboards, charts, or tables, XPath often simplifies complex element targeting.

XPath vs Other Playwright Locators

Here’s a quick comparison between XPath and other common Playwright locators to help you understand when and why to use each:

Locator TypeStrengthsWeaknesses
XPathVery flexible. Can locate elements by structure, text, or attributes.Slightly harder to read. Slower than CSS in some cases.
CSS SelectorEasy to read and fast. Great for simple attribute or class-based matches.Limited when dealing with text content or complex hierarchies.
ID SelectorFastest and most reliable if element has a unique ID.Not useful if ID is missing or dynamically generated.
Text SelectorPerfect for locating buttons or links with visible text.Breaks if text changes. Not ideal for non-unique text.
getByRole()Ideal for accessible web apps. Matches elements by ARIA roles.Requires proper ARIA attributes in the HTML structure.
getByTestId()Clean and stable for testing. Independent of styling or structure.Only works if data-testid is present in the HTML.

Each locator type has its own strengths. But when you need precision and flexibility, XPath is often the best option — especially for targeting dynamic or nested elements.

Best Practices for Using XPath in Playwright

To get the most out of XPath in Playwright, it’s important to follow a few best practices. These simple tips can help you write more reliable and flexible XPath expressions:

  • Use relative XPath: Instead of using long absolute paths like /html/body/div[2]/ul/li[3], try writing relative paths such as //ul/li[contains(text(), ‘Item’)]. This makes your XPath more stable, even if the page layout changes.
  • Avoid brittle selectors: Don’t rely on long chains of nested elements. If one element changes, your entire XPath might break. Aim for shorter, more meaningful expressions.
  • Use contains() for flexibility: Instead of matching full text exactly, use functions like contains(text(), ‘value’) or starts-with() to make your XPath handle dynamic content more gracefully.
  • Test XPath in browser DevTools first: Before adding XPath to your Playwright script, try it out in your browser’s DevTools (use $x(‘your-xpath’) in the console). This saves time and helps you confirm that the XPath actually works.
  • Use with waitForSelector() if needed: If the element takes time to load, combine your XPath with page.waitForSelector() or Playwright’s built-in auto-waiting to make your tests more stable.

Example of good practice:

await page.locator(‘xpath=//div[@id=”profile”]//button[contains(text(), “Edit”)]’).click();

Avoid:

await page.locator(‘xpath=/html/body/div[2]/div/div[1]/button[2]’).click(); // Too fragile

By following these tips, you’ll write smarter XPath that works better across different pages and test runs.

Conclusion

To sum it up, XPath in Playwright is a powerful and flexible way to locate elements—especially when simpler methods like ID or class selectors don’t work. Although you might not use XPath in every situation, it becomes incredibly helpful when you’re working with dynamic content, missing attributes, or deeply nested elements.

By learning how to use XPath properly, you’ll make your Playwright automation scripts not only more reliable but also easier to maintain in the long run. So, whenever basic locators aren’t enough, don’t hesitate to reach for XPath—it might just be the solution you need.

XPath in Playwright FAQs

Can I use XPath in Playwright?

Yes, absolutely! Playwright fully supports XPath. You can use it by writing page.locator(‘xpath=…’) or by using page.$x() for locating elements.

Which is better in Playwright: XPath or CSS selectors?

It depends on your use case. CSS selectors are usually faster and easier to read. However, XPath is a better choice when you’re dealing with complex DOM structures or need to find elements based on their text.

How do I test XPath before using it in Playwright?

To make sure your XPath works correctly, try it out in your browser’s DevTools console. Just type $x(‘//your/xpath’) and check if it returns the element you want.

Leave a Reply

Your email address will not be published. Required fields are marked *