At 1–2 years, Playwright interview questions move from "what is" to "how do you": structuring tests with page objects and fixtures, configuring projects, testing APIs, reusing login with storageState, debugging failures and running suites in parallel and in CI.
78 questions with concise answers. Focus: POM, waits/sync, fixtures/hooks, API testing, interactions, Git, basic CI.
Waits & Synchronization
How does auto-waiting work?
Every action/web-first assertion waits for actionability/truth before proceeding.
Why avoid waitForTimeout?
Fixed sleeps are flaky (too short) or slow (too long); they don’t track the real ready signal.
How to wait for an API response?
page.waitForResponse(predicate) set up before triggering the call.
How to wait for navigation?
await page.waitForURL(/pattern/).
Load states?
domcontentloaded (HTML parsed), load (all resources), networkidle (no network 500ms).
How to wait for an element state?
locator.waitFor({ state: 'visible'|'hidden'|'attached'|'detached' }).
How to sync on a spinner disappearing?
await expect(spinner).toBeHidden().
Why is networkidle risky as a default?
Fragile with polling/websockets that never go idle.
Interactions
How to handle a native dropdown?
selectOption(value|label|index).
Custom dropdown?
Click to open, click the option element.
Checkboxes/radios?
check()/uncheck() (idempotent) + toBeChecked().
File upload?
setInputFiles(path) on the input; filechooser event for custom triggers.
File download?
waitForEvent('download') + suggestedFilename()/saveAs()/path().
Alerts/confirms?
page.on('dialog', d => d.accept()/d.dismiss()) before the trigger.
iframes?
page.frameLocator(sel) then chain locators; nest for nested frames.
New tabs/windows?
waitForEvent('popup')/context.waitForEvent('page') paired with the trigger.
Hover menus?
locator.hover() then click the revealed item.
Drag and drop?
source.dragTo(target); custom drag via mouse.down/move/up.
Keyboard shortcuts?
locator.press('Control+S') / page.keyboard.press(...).
Reading table data?
Locate rows by unique text, scope cells; read columns with allTextContents.
Date pickers?
Native: fill('YYYY-MM-DD'); custom: open, navigate months, click day cell.
Shadow DOM?
Semantic locators pierce open shadow roots automatically.
Page Object Model
What is POM?
A pattern where each page is a class encapsulating locators + actions; tests call methods.
Why POM?
Centralizes locators, reduces duplication, survives UI changes, improves readability.
Should assertions go in page objects?
No — page objects act; tests assert.
POM disadvantages?
Boilerplate; risk of over-abstraction if methods are too coarse/fine.
How does POM reduce maintenance?
A UI change touches one class, not every test.
What is a BasePage?
A base class with shared helpers (goto/title) that pages extend.
What is a component object?
A class for a repeated widget (header, card) composed into pages.
Inheritance vs composition in POM?
Prefer composition (components); keep BasePage thin.
How to locate a list item by name?
getByRole('listitem').filter({ hasText }) — not .nth().
Where do locators live in POM?
Defined once, privately, in the constructor.
Fixtures & Hooks
What is a fixture?
A managed resource with setup/teardown injected into tests (e.g., page).
How to create a custom fixture?
base.extend<T>({ name: async ({deps}, use) => { /* setup */ await use(value) } }).
Test vs worker fixture?
Test-scoped runs per test (isolated); worker-scoped once per worker (expensive setup).
Fixtures vs hooks?
Fixtures inject values and compose with dependencies; hooks run side-effect setup/teardown.
Hook order?
beforeAll → (beforeEach → test → afterEach)* → afterAll.
Do afterEach hooks run on failure?
Yes — ideal for cleanup/evidence.
Why fixtures over beforeEach?
Reusable across files, dependency-aware, provide values.
How to inject a page object?
A fixture that constructs and use()s it.
How to reduce login overhead?
storageState from a setup step, injected via fixture/config.
Test Runner & Organization
What does describe do?
Groups related tests and scopes hooks.
What is test.step?
Labels sub-steps for readable reports/traces.
skip vs fixme vs fail?
skip = don’t run (conditionally); fixme = known broken; fail = expected to fail.
Danger of test.only?
If committed, CI runs only that test, hiding failures.
What are tags?
Labels (@smoke) to filter runs via --grep.
How to run a subset?
--grep @smoke, --project, or by file/title.
How to link a test to a ticket?
test.info().annotations.push({type:'jira',description:'...'}).
Configuration
What’s in playwright.config.ts?
testDir, timeout, retries, workers, reporters, projects, use defaults.
timeout vs expect.timeout?
Whole-test limit vs per-assertion limit.
What is baseURL?
A default URL base enabling page.goto('/path').
What are projects?
Named configs for browsers/devices or dependency ordering.
When to set retries?
In CI to absorb infra flakiness — not to hide bugs.
What is webServer config?
Auto-starts the app before the suite.
API Testing
How does Playwright do API testing?
Via the request fixture / APIRequestContext — real HTTP.
Why test APIs separately?
Faster, more stable, better backend/edge coverage.
How to send GET/POST?
request.get(url,{params}) / request.post(url,{data,headers}).
How to assert a response?
Check status()/ok() and the parsed json() body.
What is API chaining?
Using output (an id) from one request as input to the next.
How to validate a response schema?
JSON-schema validation (e.g., Ajv) on the body.
How to use API for setup?
Seed data via API in beforeAll/fixtures instead of slow UI steps.
How to combine UI + API in a test?
Both page and request fixtures are available; seed/verify via API, act via UI.
Screenshots, Trace, Reports
How to capture on failure only?
screenshot: 'only-on-failure', video: 'retain-on-failure'.
What is the trace viewer?
A time-travel debugger showing DOM/network/console per step.
Best trace setting for CI?
on-first-retry or retain-on-failure.
Which reporters for CI?
JUnit/JSON (machine) + HTML (human, as an artifact).
How to attach evidence to the report?
testInfo.attach(name, {body, contentType}).
Git & CI
merge vs rebase?
Merge preserves history with a merge commit; rebase replays for a linear history.
What belongs in .gitignore?
node_modules, test-results, playwright-report, .env, auth/.
How do you resolve a conflict?
Edit conflicted regions, remove markers, stage, commit/continue.
What is a PR workflow?
Feature branch → commit → push → PR → review + CI → merge.
How to run Playwright in CI?
checkout → setup-node → npm ci → playwright install --with-deps → playwright test → publish report.
Why npm ci over npm install?
Deterministic, lockfile-based, faster in CI.
Why --with-deps?
Installs OS libraries browsers need on fresh runners.
Data & Reliability
How to avoid data collisions in parallel?
Generate unique data (Faker/UUID/timestamp).
JSON vs factory data?
JSON for static reference; factories for dynamic, unique, typed data.
How to run one test over many inputs?
Loop over a typed array creating one test per case.
First step when a test is flaky?
Reproduce with --repeat-each, read the trace, fix the root cause (usually waits/data).
FAQs
What Playwright topics matter most at 2 years experience?
Page Object Model, fixtures, playwright.config, API testing with the request fixture, storageState authentication, tracing and parallel execution in CI.