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:
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();
});
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();
});
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.
If you still have questions, please ask a question and I will try to answer it.
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 [email protected].