What is the best practice for locating deeply nested elements in Playwright when '.' is not sufficient?


Locating Deeply Nested Elements in Playwright

When using '.' to extend a locator, it only looks for direct children. If you need to locate a deeply nested element, you can try the following workarounds:

Chaining and Filtering Locators

Combine locators and filter them based on attributes or text content. For example, use getByRole and filter methods:

import { test, expect } from '@playwright/test';

test('locate nested element', async ({ page }) => {
  await page.goto('https://ray.run/');
  const parentLocator = page.locator('.parent');
  const nestedElement = parentLocator.locator('.child').filter('[data-testid="nested-element"]');
  await expect(nestedElement).toBeVisible();

Using Resilient Selectors

Avoid selectors that depend on specific CSS classes or XPath expressions. Instead, use user-facing attributes like role and name:

import { test, expect } from '@playwright/test';

test('locate element using role', async ({ page }) => {
  await page.goto('https://ray.run/');
  const button = page.locator('[role="button"][name="submit"]');
  await expect(button).toBeVisible();

Leveraging Codegen Tool

Playwright's codegen tool automatically generates tests and picks locators based on your page's structure. It prioritizes role, text, and test id locators for robust tests:

npx playwright codegen https://ray.run/

In summary, use chaining and filtering, resilient selectors, and the codegen tool to locate deeply nested elements in Playwright.

Thank you!
Was this helpful?
Still have questions?

If you still have questions, please ask a question and I will try to answer it.

AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.