Playwright Mastery
Playwright has revolutionized browser automation by fixing the “flakiness” inherent in older tools like Selenium. It communicates directly with the browser engine (via Chrome DevTools Protocol), bypassing the slow WebDriver HTTP layer.Goal: Build a test suite that runs reliably in CI, executes in parallel, and handles complex authentication flows.
1. Core Concepts & Architecture
Browser, Context, Page
Understanding this hierarchy is key to speed and isolation.- Browser: The heavy OS process (e.g., Chromium.exe). Expensive to start.
- Context: An “Incognito Window”. Cheap to create (milliseconds). Stores cookies/storage. Tests usually run here.
- Page: A single tab within a context.
Auto-Waiting (The “Flake Killer”)
Playwright performs “Actionability Checks” before actions. Beforeawait page.click('#submit'), it ensures:
- Element is attached to DOM.
- Element is visible.
- Element is stable (not animating).
- Element receives events (not covered by a modal).
- Element is enabled.
2. Advanced Selectors & Locators
Stop using XPath. Playwright’s locator engine is powerful.User-Facing Locators (ARIA)
Always prefer these. They withstand refactors.Layout Selectors
Find elements relative to others.Shadow DOM
Playwright pierces Shadow DOM by default.page.locator('my-custom-element button') works automatically, even if button is in #shadow-root.
3. The Page Object Model (POM)
For any suite larger than 5 tests, you need POM. Avoid spaghetti code.Base Page Pattern
Feature Page
Usage in Test
4. Network Control & API Testing
Playwright is a full HTTP client.Interception (Mocking)
Don’t wait for your slow backend. Mock it.API Testing (No Browser)
You can use Playwright as a replacement for Postman/Axios.5. Global Setup & Authentication
Don’t log in before every test. Log in once, save the state, and reuse.1. Global Setup (global-setup.ts)
2. Config (playwright.config.ts)
6. Visual Regression Testing
Detect pixel-perfect changes.npx playwright test --update-snapshots
7. Scaling with CI/CD
Parallelism & Sharding
A suite taking 1 hour can take 10 minutes with sharding. GitHub Actions Sharding Example:npx playwright merge-reports.
8. Common Pitfalls & Debugging
Hydration Errors (React/Next.js)
Hydration Errors (React/Next.js)
Symptom: Test fails immediately because button “is not stable” or clicks do nothing.
Cause: Playwright is too fast. It clicks before React attaches event listeners (Hydration).
Fix:
- Use
await expect(locator).toBeEnabled()to wait for hydration. - Check for a specific hydration indicator (e.g.,
data-hydrated="true").
Multiple Tabs / New Windows
Multiple Tabs / New Windows
Symptom:
await page.click('#open-new-tab') works, but subsequent commands fail.
Cause: Playwright stays on the old page. It does not automatically switch focus.
Fix:Element Not Visible
Element Not Visible
Symptom:
Timeout 30000ms waiting for locator(...)
Cause: Element is technically in DOM but hidden by CSS display:none or behind a sticky header.
Fix: Use .scrollIntoViewIfNeeded() or check force: true (use sparingly).9. Interview Questions
How does Playwright differ from Selenium architecture?
How does Playwright differ from Selenium architecture?
Selenium uses the WebDriver protocol (HTTP JSON wire protocol). Commands are sent via HTTP, which is slower and flaky.
Playwright uses the Chrome DevTools Protocol (CDP) (and similar for FF/WebKit) over a WebSocket. This allows bi-directional communication, enabling features like Auto-waiting, Network Interception, and capturing Console logs directly.
Explain the difference between Browser, Context, and Page.
Explain the difference between Browser, Context, and Page.
- Browser: The OS process (Expensive). Launched once.
- Context: An isolation layer (Incognito profile). Stores cookies/storage. Created for each test.
- Page: A single tab/window within a context. Running tests in new Contexts (instead of new Browsers) allows Playwright to run hundreds of tests in parallel efficiently.
How do you handle flaky tests in Playwright?
How do you handle flaky tests in Playwright?
- Auto-waiting: Ensure I’m avoiding manual sleeps.
- Web-First Assertions: Use
await expect(loc).toBeVisible()instead ofloc.isVisible(). - Tracing: Enable Trace Viewer on CI to see the snapshot exactly when it failed.
- Retries: Configure
retries: 2in config for known unstable environments.