Locators are the most asked topic in Playwright interviews. Every interviewer wants to know: how do you find elements, which locator do you prefer, and why. I have collected the most common questions from real interviews. Know these answers cold.
Q: What locator strategy do you prefer in Playwright and why?
A: I prefer getByRole as my primary locator. It finds elements by their ARIA role and accessible name -- the same way a screen reader identifies elements. This makes tests resilient to CSS and HTML changes, validates accessibility, and is highly readable. For form inputs I use getByLabel, for static text getByText. I use getByTestId as a fallback for elements without semantic meaning, and CSS/XPath only when user-facing locators are not possible.
Q: How is a Playwright locator different from a Selenium selector?
A: Three key differences. First, Playwright locators are lazy -- they do not query the DOM until you perform an action or assertion, so they never go stale. Selenium's findElement returns an element reference that can become a StaleElementReferenceException. Second, Playwright locators auto-wait for elements to be actionable before performing actions. Selenium needs explicit waits. Third, Playwright prioritizes user-facing locators (getByRole, getByText) while Selenium primarily uses CSS and XPath selectors.
Q: How do you handle dynamic elements that load after an API call?
A: Playwright locators auto-wait, so I do not need explicit waits in most cases. I use assertion-based waiting: expect(locator).toBeVisible() retries for up to 5 seconds. For slow operations, I increase the timeout: toBeVisible({ timeout: 15000 }). I never use hardcoded delays like page.waitForTimeout(3000). If I need to wait for a specific API response, I use page.waitForResponse() to wait for the network call to complete before proceeding.
Q: What is the difference between toBeVisible and toBeAttached?
A: toBeAttached checks if the element exists in the DOM -- it could be hidden with display:none or visibility:hidden and still pass. toBeVisible checks if the element is actually visible on screen -- it must be in the DOM AND have non-zero size AND not be hidden by CSS AND not be obscured by another element. In most tests, you want toBeVisible because you care about what the user sees. Use toBeAttached only when you specifically need to check DOM presence regardless of visibility.
Q: How do you handle elements inside iframes?
A: I use page.frameLocator() to get a reference to the iframe, then use normal locators on that frame. For example: page.frameLocator('iframe[name="payment"]').getByLabel('Card Number').fill('4111...'); The API is identical to page -- getByRole, getByLabel, getByText all work on the frame. For nested iframes, I chain frameLocator calls. The key rule: page.locator() cannot see inside iframes, you must use frameLocator first.
Q: How does Playwright handle shadow DOM?
A: Playwright pierces shadow DOM boundaries automatically. Unlike Selenium where you need to explicitly access element.shadowRoot, Playwright locators find elements inside shadow DOM as if the boundary does not exist. getByRole('button', { name: 'Save' }) finds the button whether it is in light DOM or shadow DOM. CSS selectors also pierce shadow DOM by default in Playwright. This is one of Playwright's biggest advantages for testing web components.
Q: What is the locator priority order in Playwright?
A: The recommended priority is: 1) getByRole -- buttons, links, headings, inputs by their ARIA role. 2) getByLabel -- form inputs by their associated label. 3) getByPlaceholder -- inputs with placeholder text. 4) getByText -- elements by visible text content. 5) getByTestId -- elements with data-testid attribute. 6) CSS selectors via page.locator(). 7) XPath as the last resort. The higher in the list, the more resilient and accessible the locator. I follow this order strictly.
| Question | One-Line Answer |
|---|---|
| Can locators go stale in Playwright? | No -- they re-query the DOM on every action |
| Default assertion timeout? | 5 seconds (configurable via expect.timeout) |
| How to find elements in shadow DOM? | Same locators -- Playwright pierces shadow DOM automatically |
| How to find elements in iframes? | page.frameLocator() then use normal locators on the frame |
| getByText exact match? | Pass { exact: true } or use regex with ^ and $ anchors |
| How to change test ID attribute? | Set testIdAttribute in playwright.config.ts use options |
| How to check element count? | expect(locator).toHaveCount(n) |
| nth() is 0-indexed or 1-indexed? | 0-indexed in Playwright, but 1-indexed in XPath |
Key Point: Locators, assertions, iframes, shadow DOM, and priority order -- these are the top interview topics. Know the answers, know the reasoning behind each choice.
Answer all 5 questions, then submit to see your score.
1. Which locator should be your FIRST choice when finding a clickable button in Playwright?
2. What happens when you create a locator like page.getByRole('button', { name: 'Login' }) in Playwright?
3. How does Playwright handle elements inside shadow DOM?
4. What is the correct way to find an input element inside an iframe?
5. Which assertion should you use instead of expect(await locator.textContent()).toBe("Hello")?