UI Automation — Playwright
Design/own/defend a reliable CI-friendly Playwright framework; Selenium literacy (52% of JDs) + BDD/Cucumber. STOP before self-healing engines, custom runners, grid infra.
- Strict mode: what triggers it, how to resolve
Playwright errors when a locator resolves to more than one element, forcing you to disambiguate.
'What is a strict-mode violation and how do you fix it?' (flagged as a classic separator)
- Locator chaining, .filter(hasText), .and()/.or(), .first()/.last()/.nth(), count() + iteration over lists
Narrowing a locator by composing/filtering it and acting on N matching elements.
'How do you act on multiple elements?' / 'How do you click the row that contains a given text?'
- User-facing locators (getByRole/getByLabel/getByText/getByPlaceholder/getByTestId/getByTitle/getByAltText)
The role/label/testid family that Playwright recommends over CSS/XPath because it is resilient and accessibility-aligned.
'What is a locator?' / 'How and why do you use getByRole?' / 'When would you fall back to CSS or XPath?'
- Web-first assertions vs boolean assertions; expect.soft; auto-retrying expect
await expect(locator).toBeVisible()/toHaveText()/toHaveValue() auto-wait and retry until timeout; expect(await locator.isVisible()).toBe(true) does not.
'Why is expect(await ...).toBe(true) flaky?' / 'What are soft assertions and when do you use them?'
- Explicit event waits: waitForResponse/waitForRequest, waitForLoadState, waitForURL, waitForFunction — and never waitForTimeout
Deterministic waits keyed to a real signal (network, navigation, predicate) that replace hard sleeps.
'Why should you avoid waitForTimeout?' / 'What types of waits does Playwright support?' / 'How do you wait for an API before asserting?'
- Auto-wait actionability model + its limit (waits for element actionable, NOT for app/API state)
Before each action Playwright waits for visible/enabled/stable/receives-events/not-obscured, but it does not know about data your click triggers.
'What is auto-wait?' / 'toBeVisible vs manually checking visibility?' / trap: 'if auto-wait exists why are tests still flaky?'
- Auth reuse: global setup/teardown + storageState (log in once, reuse across tests/workers)
A one-time login in global setup saves session state to disk that every test/worker loads, avoiding per-test login.
'How do you handle authentication across tests?' / 'How do you avoid logging in for every test?'
- Page Object Model — design and defend (locators + action methods, return types, no assertions-in-page debate)
A class per page/component holding its locators and user-action methods so tests read as intent and maintenance is localized.
'Walk me through a framework you built' / 'How is your POM structured?' / 'Where do assertions go — in the page object or the test?'
- Fixtures (Playwright's DI): built-in page/context/request/browser + custom fixtures; scope & override; POM-vs-fixture decision
Fixtures provide the STATE a test needs (logged-in user, seeded data, API client) via dependency injection; POM provides what an ACTION looks like.
'POM vs fixtures — when do you use which?' / 'How do you create a custom fixture?' / 'How do fixtures differ from beforeEach hooks?'
- Framework design patterns: data-driven & keyword-driven; module/flow layer for business journeys; test isolation
Parametrized (data-driven) and abstracted-action (keyword-driven) designs layered above POM, with each test fully independent (own storage/data).
'What framework design patterns have you used?' / 'How do you make tests independent?' / 'Data-driven vs keyword-driven?'
- BDD with Cucumber/Gherkin on top of Playwright (feature files, step defs, scenario outlines); Jira Xray linkage
Human-readable Given/When/Then scenarios (Gherkin) bound to Playwright step definitions, often linked to test-management (Xray).
'Have you used BDD/Cucumber with Playwright?' / 'How do you structure feature files and step definitions?' / 'When is BDD worth it?'
- Cross-browser (Chromium/Firefox/WebKit) + device/mobile-web emulation, responsive validation
Same suite run across three engines via projects; devices dict emulates viewport/UA/touch for mobile-web.
'How do you run cross-browser?' / 'How do you test responsive/mobile-web?'
- playwright.config: projects, baseURL, the 4 timeouts (test/expect/action/navigation), use-block, reporters, outputDir, headed/headless
The single config that defines what runs where and how; projects define browser/device matrices and can chain (setup -> tests).
'What is in playwright.config?' / 'What are projects?' / 'Difference between test timeout and expect timeout?'
- Workers, fullyParallel, test.describe.configure({mode}); parallel vs serial
Files run in parallel across worker processes by default; fullyParallel parallelizes within files; serial/default modes control intra-describe behavior.
'How does parallel execution work?' / 'workers vs parallel mode?' / 'How do you run dependent tests serially?'
- Retries strategy + trace-on-first-retry (0 local / 1-2 CI); when retries help vs hide bugs
Retries re-run failures to absorb infra noise, but masking real flakiness with retries is an anti-pattern.
'When do retries hide bugs vs help?' / 'What is your retry strategy?' (separator question)
- Sharding across machines (--shard=x/y), CI matrix, blob report merge (merge-reports)
Splitting a run across independent machines (shards) — distinct from workers (parallel within one machine) — then merging blob reports into one.
'How does sharding work and when do you need it?' / 'Sharding vs workers?' / 'How do you merge reports from shards?'
- iframes, frames, and dialogs/popups handling
frameLocator() scopes actions inside an iframe; event handlers/expect handle native dialogs and new-tab popups.
'How do you handle iframes?' / 'How do you handle a new tab / dialog?'
- Network interception & mocking: page.route/context.route fulfill/continue(modify)/abort; register before goto; HAR record/replay
Intercept requests to return mock JSON (fulfill), alter them (continue), or block them (abort); routes must be set before navigation.
'How do you intercept and mock network calls with page.route?' / 'fulfill vs continue vs abort?' / 'How do you test the UI when the backend is unstable?'
- Hybrid API+UI in one framework: request fixture / APIRequestContext for seed/teardown, then assert via UI
Use Playwright's request context to set up/tear down state and to test at the right layer instead of driving everything through the slow UI.
'How do you do API testing with Playwright?' / 'How do you set up test data?' / 'When do you assert via API vs UI?'
- Trace Viewer: record modes (on / on-first-retry / retain-on-failure), reading DOM snapshots + network + console to root-cause
A time-travel recording of a run — per-action DOM snapshot, network, console, source — that makes CI-only failures diagnosable.
'What is Trace Viewer and when do you use it?' / 'A test fails in CI but passes locally — how do you debug it?' (top separator question)
- Debug toolbox: UI Mode (time-travel/watch), Inspector --debug, codegen, VS Code extension live-locator, screenshots/video config
The interactive tools for authoring and stepping through tests; codegen records actions into a script starting point.
'How do you generate tests with codegen/CLI?' / 'How do you debug a failing test locally?' / 'How do you capture screenshots/video on failure?'
- Reporters: built-in HTML, list, JUnit, blob; Allure integration + attachments; test.step for readable reports
Multiple reporters run at once — HTML for humans, JUnit/blob for CI — and Allure adds step-level breakdown with auto-attached trace/screenshot/video.
'How do you report results?' / 'How do you integrate Allure?' / 'How do you make CI consume results (JUnit)?'
- Accessibility testing: @axe-core/playwright scans; ARIA-snapshot testing (toMatchAriaSnapshot, YAML a11y-tree) [2026]
axe-core flags WCAG violations in-test; ARIA snapshots assert the accessibility-tree structure as YAML — a 2025-2026 Playwright addition.
'How do you test accessibility?' / 'What are ARIA snapshots?' (rising 2026 question)
- Visual regression: toHaveScreenshot()/toMatchSnapshot(), baseline mgmt, maxDiffPixels/threshold, OS/browser pinning
Built-in pixel-diff assertions against committed baselines, tuned by threshold and pinned to a stable OS/browser to avoid false diffs.
'How do you do visual regression?' / 'How do you keep visual baselines stable across machines?'
- Flaky root-cause taxonomy + trace-driven detect->fix->verify (auto-wait gap, race, order-dependence, selector, network, animation, shared state)
A named catalogue of why tests flake and a disciplined RCA loop that fixes the cause instead of cranking retries.
'What are the most common causes of flaky tests?' / 'A test is flaky — how do you diagnose and fix it?' (top-2 separator question)
- Selenium literacy: WebDriver arch, explicit/implicit/fluent waits (WebDriverWait/ExpectedConditions), Selenium 4/5 relative locators, CDP
Enough Selenium to work a legacy suite and contrast it with Playwright: client sends W3C HTTP commands to a driver (ChromeDriver) that drives the browser.
'Explain Selenium's architecture' / 'implicit vs explicit wait' / 'Why is Playwright faster/less flaky than Selenium?'
- CORRECTION — modern Selenium: WebDriver BiDi (WebSocket event-push) + Selenium Manager (auto driver setup); Selenium 5 (2026)
Selenium 4/5 added WebDriver BiDi (bidirectional WebSockets so the browser pushes console/network/JS-error events, no polling) and Selenium Manager (no more manual chromedriver downloads).
'What changed in Selenium 4/5?' / 'What is WebDriver BiDi?' / 'Does BiDi make Selenium equal to Playwright?'
- Selenium -> Playwright migration: 3-layer architecture, pattern translation (waits/locators/assertions), migrate-by-value in waves, dual-run
A staged migration keeping both suites running until Playwright coverage matches, translating explicit waits -> auto-wait/web-first assertions and CSS/XPath -> role locators.
'How would you migrate a Selenium suite to Playwright?' / 'How do you translate WebDriverWait to Playwright?'
- Cloud device/browser grids: BrowserStack / Sauce Labs / LambdaTest for cross-browser at scale; Dockerized runs; Grid concept
Hosted browser/device farms to run cross-browser/real-device coverage you can't hold locally; Docker gives reproducible CI containers.
'Have you used BrowserStack/Sauce Labs?' / 'How do you get real-device/OS coverage?' / 'How do you run tests in Docker/CI?'
- Run suite in CI: install browsers (--with-deps), Jenkins/GitHub Actions/GitLab/Azure DevOps, upload HTML report, tagging (@smoke/@regression) + --grep for selective runs
A pipeline that installs browsers, runs the suite (often a tag-filtered subset), and publishes the report as an artifact.
'How do you integrate Playwright into CI/CD?' / 'How do you run only smoke tests on a PR?' / 'How do you tag and select tests?'
- Self-healing / intent-based AI locators (concept + trade-offs); Clock API for deterministic time [2026]
Self-healing = store selector + fallback and swap on failure (Momentic-style intent locators); Clock API (page.clock) fakes time to test timeouts/dates deterministically.
'What do you think of self-healing locators?' / 'How would you test time-dependent UI?' (rising)
- Playwright MCP + official test agents; AI test generation & Selenium->Playwright conversion (the salary-premium skill)
Playwright's official MCP server exposes structured browser-control tools so an LLM can drive a live session; 2026 shipped AI test agents too.
'What is Playwright MCP and why does it matter?' / 'MCP vs CLI?' / 'How would you use AI in test automation?'
- Cypress / WebdriverIO / Robot Framework / Squish / Pywinauto / Appium (adjacency awareness)
Neighboring tools that appear in some JDs; Cypress is the settled runner-up, Appium is mobile-native (separate topic), Squish/Pywinauto are desktop-GUI niches.
'Playwright vs Cypress?' (answer in 2-3 sentences and move on)
- OVERKILL — custom self-healing engine, bespoke reporter/runner plugin, CDP-protocol hacking, Grid infra design at scale, Playwright-core contributions, component testing deep-dive
Staff/tooling-team or automation-architect work beyond a mid SDET-2 scope.
(rarely asked at mid level; name-drop awareness is enough)