Without showing your document structure, we can only guess what'd be better. The structural context matters greatly. Often, a parent container is necessary to disambiguate similar children.

If the buttons have different text, aria labels or titles, you can select on that. If they have different parent containers, you could filter on those first using chained locators.

You can also let Playwright can choose the best locator with its test generator.

The reason XPath and CSS selectors are considered "last resort" is because they tend to be too closely coupled to implementation details like document structure and styling-oriented classes that don't reflect how the user engages with the app.

This warning applies as much to CSS selectors as XPath, but XPath in particular tends to result in highly brittle tests due to its tendency to be very precise about structure and properties.

Other discouraged patterns include over-reliance on nth and test ids. As a rule of thumb, you want to be the right kind of precise ("button with text 'Learn more'"), but not precise in the wrong way ("4th child of the first child of the 6th child of the 2nd paragraph nested within...."). Try to determine what characteristics make an element unique in a way that isn't likely to change other than due to a meaningful adjustment, preferably something that a user might notice.

See the docs for further details:

XPath and CSS selectors can be tied to the DOM structure or implementation. These selectors can break when the DOM structure changes. Long CSS or XPath chains below are an example of a bad practice that leads to unstable tests:

await page.locator(
    '#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > > input'
).click();
await page
   .locator('//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input')
   .click();

I also caution against the "long selector chains" pattern in my Puppeteer antipatterns blog post (similar framework). If you do use CSS or XPath, try to avoid >, n-th and [class="something-too-specific"] and only use the bare number of ancestor containers necessary to disambiguate the element.

React Testing Library follows a similar "don't test implementation details" philosophy which has swept through the React world in the past few years and surely influenced Playwright.

Answer from ggorlen on Stack Overflow
๐ŸŒ
Software-testing-tutorials-automation
software-testing-tutorials-automation.com โ€บ home โ€บ playwright tutorial โ€บ playwright java โ€บ playwright java xpath locator tutorial: complete guide
Playwright Java XPath Locator Tutorial: Complete Guide
November 8, 2025 - When to Use XPath vs. Other Locator Strategies ... In Playwright Java, XPath is a powerful locator strategy used to identify elements within the Document Object Model (DOM). The Playwright Java XPath Locator works by navigating the pageโ€™s ...
๐ŸŒ
Medium
medium.com โ€บ @kbalaji.kks โ€บ playwright-locators-and-selectors-5a0882f8c801
Playwright| Locators and Selectors | by balaji k | Medium
October 7, 2023 - Playwright supports many selectors including Text Selector, CSS Selector, XPath Selector, React Selector, Vue Selector etc.
๐ŸŒ
Playwright
playwright.dev โ€บ locators
Locators | Playwright
Playwright supports CSS and XPath selectors, and auto-detects them if you omit css= or xpath= prefix.
Top answer
1 of 2
2

Without showing your document structure, we can only guess what'd be better. The structural context matters greatly. Often, a parent container is necessary to disambiguate similar children.

If the buttons have different text, aria labels or titles, you can select on that. If they have different parent containers, you could filter on those first using chained locators.

You can also let Playwright can choose the best locator with its test generator.

The reason XPath and CSS selectors are considered "last resort" is because they tend to be too closely coupled to implementation details like document structure and styling-oriented classes that don't reflect how the user engages with the app.

This warning applies as much to CSS selectors as XPath, but XPath in particular tends to result in highly brittle tests due to its tendency to be very precise about structure and properties.

Other discouraged patterns include over-reliance on nth and test ids. As a rule of thumb, you want to be the right kind of precise ("button with text 'Learn more'"), but not precise in the wrong way ("4th child of the first child of the 6th child of the 2nd paragraph nested within...."). Try to determine what characteristics make an element unique in a way that isn't likely to change other than due to a meaningful adjustment, preferably something that a user might notice.

See the docs for further details:

XPath and CSS selectors can be tied to the DOM structure or implementation. These selectors can break when the DOM structure changes. Long CSS or XPath chains below are an example of a bad practice that leads to unstable tests:

await page.locator(
    '#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > > input'
).click();
await page
   .locator('//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input')
   .click();

I also caution against the "long selector chains" pattern in my Puppeteer antipatterns blog post (similar framework). If you do use CSS or XPath, try to avoid >, n-th and [class="something-too-specific"] and only use the bare number of ancestor containers necessary to disambiguate the element.

React Testing Library follows a similar "don't test implementation details" philosophy which has swept through the React world in the past few years and surely influenced Playwright.

2 of 2
0

XPath are not recommended as the DOM can often change leading to non resilient tests. You can get those buttons by their class

await page.locator("//div[@class='mui-primary']")

If you have no option then you can use xpath.

๐ŸŒ
Playwright
playwright.dev โ€บ selectors
Selectors | Playwright
const { selectors, firefox } = require('@playwright/test'); // Or 'chromium' or 'webkit'. (async () => { // Must be a function that evaluates to a selector engine instance. const createTagNameEngine = () => ({ // Returns the first element matching ...
๐ŸŒ
Playwright
playwright.dev โ€บ other locators
Other locators | Playwright
Any selector string starting with // or .. are assumed to be an xpath selector. For example, Playwright converts '//html/body' to 'xpath=//html/body'.
Find elsewhere
๐ŸŒ
BrowserStack
browserstack.com โ€บ home โ€บ guide โ€บ how to find elements by xpath in playwright
How To Find Elements by XPath in Playwright | BrowserStack
November 18, 2025 - The locator method in Playwright allows you to define an XPath selector to find elements on the page. To use XPath with Playwright, you can simply pass the XPath expression as a string to the locator() function.
๐ŸŒ
SKPTRICKS
skptricks.com โ€บ 2025 โ€บ 04 โ€บ how-to-use-playwright-locators-detailed-guide.html
How to Use Playwright Locators: A Detailed Guide | SKPTRICKS
April 6, 2025 - XPath locators enable you to select elements based on their XML path expressions, providing a flexible method for element identification.
๐ŸŒ
ScrapeOps
scrapeops.io โ€บ home โ€บ playwright web scraping playbook โ€บ nodejs playwright find elements xpath
Playwright Guide - How To Find Elements by XPath | ScrapeOps
May 16, 2024 - Learn to find elements with XPath selectors in Playwright - master XPath syntax, locate elements by text, attributes, position, and handle dynamic content for web scraping.
๐ŸŒ
ScrapingBee
scrapingbee.com โ€บ webscraping-questions โ€บ playwright โ€บ how-to-find-elements-by-xpath-in-playwright
How to find elements by XPath selectors in Playwright? | ScrapingBee
You can find elements by XPath selectors in Playwright by using the locator method of the Page object. Playwright can automatically detect that an XPath is being passed as an argument.
๐ŸŒ
Playwright
playwright.dev โ€บ locator
Locator | Playwright
Matches elements that do not contain an element that matches an inner locator. Inner locator is queried against the outer one. For example, article that does not have div matches <article><span>Playwright</span></article>.
๐ŸŒ
Medium
medium.com โ€บ @dinusha-s โ€บ playwright-selectors-locators-find-anything-on-a-page-like-a-pro-2576ac218b89
Playwright Selectors & Locators: Find Anything on a Page Like a Pro ๐Ÿ” | by Dinusha Somarathne | Medium
September 30, 2025 - const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://example.com'); // Find element by text const heading = page.locator('text=Example Domain'); console.log(await heading.textContent()); await browser.close(); })();
๐ŸŒ
Momentic
momentic.ai โ€บ blog โ€บ playwright-locators-guide
Playwright Locators Guide: getByRole, getByText, getByLabel, CSS & XPath | Momentic
October 22, 2025 - Playwright locators address these ... brittle CSS selectors and XPath queries, Playwright encourages you to find elements the way users do, by their role, text, and labels....