← Back to library
Playwrightselectorsadvancedv1.20+

XPath selector — when to use it

Use XPath as a last resort for legacy HTML with no accessible attributes or test IDs.

1test('targets a table row by cell text using XPath', async ({ page }) => {
2  await page.goto('/invoices');
3
4  // XPath is a last resort — only reach for it when getByRole, getByTestId,
5  // and CSS selectors all fail (e.g. old server-rendered HTML with no hooks).
6  // Here: find the <tr> whose first <td> contains "Invoice #1042"
7  const row = page.locator('//tr[td[normalize-space()="Invoice #1042"]]');
8  await expect(row).toBeVisible();
9
10  // Relative XPath from the matched element — get the third cell
11  const statusCell = row.locator('xpath=td[3]');
12  await expect(statusCell).toHaveText('Paid');
13});
#XPath#xpath#legacy#normalize-space