|
| 1 | +# Playwright Advanced Selectors Guide |
| 2 | + |
| 3 | +This guide demonstrates advanced selector strategies in Playwright using the Locators Lab page. These examples help you robustly target elements in complex UIs, including shadow DOM and iframes. |
| 4 | + |
| 5 | +## Covered Selector Strategies |
| 6 | +- **Text and Partial Text**: Locate elements by their visible text or a substring. |
| 7 | +- **CSS and XPath**: Use CSS selectors and XPath expressions for precise targeting. |
| 8 | +- **Nth Element and Attribute**: Select elements by index or filter by attributes. |
| 9 | +- **Role and Label**: Use ARIA roles and accessible names for robust, semantic selection. |
| 10 | +- **Shadow DOM**: Target elements inside open shadow roots. |
| 11 | +- **Iframe**: Interact with elements inside embedded iframes. |
| 12 | + |
| 13 | +## Example Test Cases |
| 14 | + |
| 15 | +```js |
| 16 | +const { test, expect } = require('@playwright/test'); |
| 17 | +const LocatorsLabPage = require('../../pages/LocatorsLabPage'); |
| 18 | + |
| 19 | +test.describe('Selectors Advanced (Locators Lab)', () => { |
| 20 | + test('should select element by text and partial text', async ({ page }) => { |
| 21 | + const lab = new LocatorsLabPage(page); |
| 22 | + await lab.goto(); |
| 23 | + await expect(page.getByText('Sandbox Area')).toBeVisible(); |
| 24 | + await expect(page.locator('text=Practice Lab')).toBeVisible(); |
| 25 | + await expect(lab.title).toBeVisible(); |
| 26 | + }); |
| 27 | + |
| 28 | + test('should select element by CSS and XPath', async ({ page }) => { |
| 29 | + const lab = new LocatorsLabPage(page); |
| 30 | + await lab.goto(); |
| 31 | + await expect(lab.title).toBeVisible(); |
| 32 | + await expect(page.locator('//h2[contains(text(),"Sandbox Area")]')).toBeVisible(); |
| 33 | + }); |
| 34 | + |
| 35 | + test('should select nth element and filter by attribute', async ({ page }) => { |
| 36 | + const lab = new LocatorsLabPage(page); |
| 37 | + await lab.goto(); |
| 38 | + const actionButtons = lab.actionButtons.locator('button'); |
| 39 | + await expect(actionButtons.nth(0)).toBeVisible(); |
| 40 | + await expect(page.locator('input[id*="user"]').first()).toBeVisible(); |
| 41 | + }); |
| 42 | + |
| 43 | + test('should select element inside shadow DOM', async ({ page }) => { |
| 44 | + const lab = new LocatorsLabPage(page); |
| 45 | + await lab.goto(); |
| 46 | + await expect(lab.sandboxShadowSection).toBeVisible(); |
| 47 | + // Example: page.locator('k11-shadow-root >>> .shadow-element') |
| 48 | + }); |
| 49 | + |
| 50 | + test('should select element by role and label', async ({ page }) => { |
| 51 | + const lab = new LocatorsLabPage(page); |
| 52 | + await lab.goto(); |
| 53 | + await expect(page.getByRole('button', { name: /run/i })).toBeVisible(); |
| 54 | + await expect(page.getByRole('button', { name: /clear/i })).toBeVisible(); |
| 55 | + }); |
| 56 | + |
| 57 | + test('should select element inside iframe', async ({ page }) => { |
| 58 | + const lab = new LocatorsLabPage(page); |
| 59 | + await lab.goto(); |
| 60 | + await expect(lab.sandboxIframeSection).toBeVisible(); |
| 61 | + await expect(lab.iframe.locator('h3', { hasText: 'Iframe Lab' })).toBeVisible(); |
| 62 | + await expect(lab.iframe.locator('div > p')).toBeVisible(); |
| 63 | + await expect(lab.iframe.locator('input#ifEmail')).toBeVisible(); |
| 64 | + await expect(lab.iframe.locator('table[aria-label="Orders"]')).toBeVisible(); |
| 65 | + await expect(lab.iframe.locator('td', { hasText: '#A-101' })).toBeVisible(); |
| 66 | + }); |
| 67 | +}); |
| 68 | +``` |
| 69 | + |
| 70 | +## Best Practices |
| 71 | +- Prefer role and label selectors for accessibility and resilience. |
| 72 | +- Use page objects (like `LocatorsLabPage`) to centralize and maintain selectors. |
| 73 | +- For shadow DOM, use the `>>>` combinator. |
| 74 | +- For iframes, use `frameLocator` and assert on elements inside the frame. |
| 75 | +- Always validate selectors against the current DOM structure. |
| 76 | + |
| 77 | +--- |
| 78 | +For more, see the Playwright [Selectors documentation](https://playwright.dev/docs/selectors). |
0 commit comments