# Locator Strategies ## Table of Contents 1. [Priority Order](#priority-order) 2. [User-Facing Locators](#user-facing-locators) 3. [Filtering & Chaining](#filtering--chaining) 4. [Dynamic Content](#dynamic-content) 5. [Shadow DOM](#shadow-dom) 6. [Iframes](#iframes) ## Priority Order Use locators in this order of preference: 1. **Role-based** (most resilient): `getByRole` 2. **Label-based**: `getByLabel`, `getByPlaceholder` 3. **Text-based**: `getByText`, `getByTitle` 4. **Test IDs** (when semantic locators aren't possible): `getByTestId` 5. **CSS/XPath** (last resort): `locator('css=...')`, `locator('xpath=...')` ## User-Facing Locators ### getByRole Most robust approach - matches how users and assistive technology perceive the page. ```typescript // Buttons page.getByRole("button", { name: "Submit", exact: true }); // exact accessible name page.getByRole("button", { name: /submit/i }); // flexible case-insensitive match // Links page.getByRole("link", { name: "Home" }); // Form elements page.getByRole("textbox", { name: "Email" }); page.getByRole("checkbox", { name: "Remember me" }); page.getByRole("combobox", { name: "Country" }); page.getByRole("radio", { name: "Option A" }); // Headings page.getByRole("heading", { name: "Welcome", level: 1 }); // Lists & items page.getByRole("list").getByRole("listitem"); // Navigation & regions page.getByRole("navigation"); page.getByRole("main"); page.getByRole("dialog"); page.getByRole("alert"); ``` ### getByLabel For form elements with associated labels. ```typescript // Input with