🎭 Playwright β˜… End-to-End Testing β˜… Aayush Mishra Β· SDET β˜… page.click() Β· page.fill() Β· page.goto() β˜… Auto-Wait Β· Screenshots Β· Trace Viewer β˜… Multi-Browser Β· Parallel Β· API Testing β˜… 🎭 Playwright β˜… End-to-End Testing β˜… Aayush Mishra Β· SDET β˜… page.click() Β· page.fill() Β· page.goto() β˜… Auto-Wait Β· Screenshots Β· Trace Viewer β˜… Multi-Browser Β· Parallel Β· API Testing β˜…
🎭Microsoft Open Source · 2020

NEXT-GENBROWSERTESTING.

Playwright by Microsoft β€” the most powerful E2E framework ever made. Auto-waits, 3 browsers, screenshots, trace viewer & API testing. All built-in. Zero drama.

3Browsers
0msManual Waits
AutoScreenshots
∞Parallel
login.spec.ts
TypeScript
import { test, expect } from '@playwright/test';

test('user logs in successfully',
  async ({ page }) => {
  // navigate β€” auto waits for page load
  await page.goto('https://app.example.com');
  // fill β€” no explicit waits needed!
  await page.fill('#email', 'admin@co.com');
  await page.fill('#password', 'secret!');
  await page.click('[type="submit"]');
  // web-first assertion β€” retries automatically
  await expect(page).toHaveURL('/dashboard');
});
2 passed · 0 failed⏱ 1.18s
⏳
Auto-Waits
Playwright checks visibility, stability and actionability before every single action. No Thread.sleep(). Ever.
Zero Flakiness
🌐
3 Engines
Chromium, Firefox and WebKit from one script. Real cross-browser coverage with zero extra configuration.
Chrome+FF+Safari
🎬
Trace Viewer
Time-travel debugging. See every step β€” screenshots, DOM, network, console β€” all captured automatically.
Time-Travel Debug
πŸ”Œ
API + UI Tests
Test REST endpoints with request.get() alongside UI flows in the same spec file. No Postman needed.
All-In-One
✦ 01 · What is Playwright

The framework
that actually
gets it.

Built by Microsoft's Puppeteer team. They knew every Selenium pain point and fixed them all. Playwright is what modern E2E testing looks like.

Selenium needs WebDriverManager, explicit waits everywhere, a test runner, an assertion library, a screenshot plugin and a reporting tool. That's 6 dependencies to do 1 job.

Playwright ships with everything built-in: auto-waiting, web-first assertions, screenshot/video on failure, code generation via playwright codegen, network interception and the iconic Trace Viewer. One install, everything included.

search.spec.ts
TypeScript
import { test, expect } from '@playwright/test';

test('search for products', async ({ page }) => {
  await page.goto('https://amazon.in');
  // Semantic locator β€” survives CSS refactors
  await page.getByPlaceholder('Search Amazon').fill('laptop');
  await page.keyboard.press('Enter');
  // Smart assertion β€” auto-retries until true
  await expect(page.getByRole('heading')).toContainText('laptop');
  await page.screenshot({ path: 'results.png', fullPage: true });
});
⚑
Auto-Waiting Engine
6 actionability checks before any action: attached? visible? enabled? stable? not animating? not obscured? All automatic β€” zero flakiness.
🌐
Network Interception
Intercept, mock or modify any request with page.route(). Build fully isolated UI tests that don't need a real backend.
πŸŽ₯
Trace + Video Recording
Set trace: 'on-first-retry' β€” every CI failure gets a full trace. Open in Trace Viewer like DevTools for your tests.
πŸ€–
Codegen β€” Click to Write Tests
Run playwright codegen url.com and Playwright records your clicks as working test code in real time.
πŸ”Œ
API Testing Built-In
Use request.get()/post() alongside page.click() in the same test. Seed DB via API, verify result via UI β€” one framework.
✦ 02 · Core API Methods

Every command
you'll actually use.

Clean, async-first, intuitive. These are the Playwright API methods every SDET reaches for daily.

page.goto()
Navigate to URL
Navigate and wait for load state. Supports domcontentloaded, load, and networkidle. Zero manual waits.
await page.goto('/login', { waitUntil: 'networkidle' });
page.click()
Click an Element
Auto-waits for visible, enabled, stable before clicking. Handles retries internally. Never flakes.
await page.click('button[type="submit"]');
page.fill()
Type into Input
Fills input fields after clearing them. Use page.type() for character-by-character keyboard simulation.
await page.fill('#search', 'playwright');
getByRole()
Semantic Locator
Find by ARIA role β€” recommended over CSS selectors. Resilient to HTML changes and refactors.
page.getByRole('button', { name: 'Login' })
expect().toBeVisible()
Web-First Assertions
Smart assertions that auto-retry until true or timeout. No external assertion library needed at all.
await expect(page.getByText('Welcome')).toBeVisible();
page.route()
Network Mocking
Intercept any request and return custom responses. Mock 3rd party APIs, loading states, and error flows.
await page.route('**/api/users', r => r.fulfill({ body: '[]' }));
page.screenshot()
Capture Screenshots
Full-page or element screenshots. Auto-capture on failure with screenshot: 'only-on-failure' config.
await page.screenshot({ path: 'fail.png', fullPage: true });
waitForResponse()
Wait for Network
Wait for a specific API response before asserting. Essential for SPAs loading data after navigation.
await page.waitForResponse('**/api/products');
test.describe()
Group Tests
Organize into suites with scoped beforeEach/afterEach setup and teardown. Clean and maintainable.
test.describe('Login Suite', () => { ... });
✦ playwright.config.ts
playwright.config.ts
Config
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir:   './tests',
  workers:   process.env.CI ? 2 : undefined,
  retries:   process.env.CI ? 2 : 0,
  use: {
    baseURL:    'https://staging.myapp.com',
    trace:     'on-first-retry',
    screenshot:'only-on-failure',
    video:     'retain-on-failure',
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox',  use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit',   use: { ...devices['Desktop Safari'] } },
    { name: 'mobile',   use: { ...devices['iPhone 13'] } },
  ],
});
✦ 03 · Playwright vs Selenium

The honest
comparison.

Legacy
Selenium WebDriver
  • βœ—Manual WebDriver version management (ChromeDriver hell)
  • βœ—No built-in auto-wait β€” Thread.sleep() everywhere
  • βœ—No built-in test runner β€” needs TestNG/JUnit externally
  • βœ—No network interception in standard API
  • βœ—No built-in screenshot on failure
  • βœ—No built-in parallelism β€” complex ThreadLocal setup needed
  • βœ—Slow WebDriver JSON Wire Protocol
  • βœ—No Trace Viewer β€” debugging is painful
VS
✨ Modern Choice
🎭 Playwright
  • βœ“npx playwright install β€” downloads everything automatically
  • βœ“Auto-waits on every single action β€” zero flakiness default
  • βœ“Built-in test runner with gorgeous HTML reports
  • βœ“page.route() β€” full request/response mocking built-in
  • βœ“Auto screenshot + video + trace on every failure
  • βœ“workers: 4 β€” parallel execution out of the box
  • βœ“Native CDP protocol β€” blazing fast execution speed
  • βœ“Trace Viewer β€” time-travel debug any failed test
✦ 04 · Live Test Runner

🎭 Run Playwright Now.

Pick a test scenario and watch Playwright execute it β€” real console output, auto-wait logs, traces, pass/fail β€” just like your local terminal.

Test Configuration
Quick Presets
playwright Β· v1.44.0
idle
00:00:00INFORunner ready β€” select a scenario and click β–Ά Run Test
0 / 0 tests0%
✦ 05 · Setup Guide

Zero to testing
in 60 seconds.

One command installs everything β€” browsers included. No WebDriver, no version matching. It just works.

01
Create Project
Scaffold a new Playwright project with runner, config, sample tests and GitHub Actions CI workflow.
npm init playwright@latest
02
Install Browsers
Download Chromium, Firefox and WebKit browser binaries. One command, all three browsers done.
npx playwright install
03
Write First Test
Create tests/login.spec.ts and add your first test block with page.goto, fill, click and expect.
tests/login.spec.ts
04
Use Codegen
Open a URL and click around β€” Playwright records your interactions as working TypeScript code.
npx playwright codegen url.com
05
Configure Config
Set baseURL, browsers, retries, screenshot, trace and video settings in playwright.config.ts.
defineConfig({ use: { baseURL } })
06
Run All Tests
Execute the full suite across all configured browsers in parallel with one single command.
npx playwright test
07
View HTML Report
Open the built-in HTML report β€” test timings, screenshots, videos and status at a glance.
npx playwright show-report
08
Debug with Traces
Open any trace file to time-travel through a failed test β€” every step, screenshot and network call.
npx playwright show-trace trace.zip
✦ 06 · Best Practices

Tests that never
break.

The exact patterns senior SDETs use to write Playwright suites that are reliable, fast and maintainable forever.

POM
πŸ—οΈ
Page Object Model
One class per page with locators and actions as methods. Tests call loginPage.login(user,pass) β€” not page.fill everywhere. One selector change β†’ fix one file, not 50 tests.
Architecture
LOC
🎯
getByRole() First
Always try ARIA-based locators first: getByRole(), getByLabel(), getByText(), getByPlaceholder(). They mirror how users interact with your app and survive any CSS refactor.
Locators
AUTH
πŸ”’
storageState for Auth
Login once, save to storageState.json, reuse across all tests. Cuts suite time 30–50% by skipping the login flow for every test that isn't actually testing login.
Performance
NET
🌐
Mock External APIs
Use page.route() to mock payment gateways and slow 3rd-party services. Tests must be deterministic β€” don't let Stripe's uptime affect your CI pipeline results.
Reliability
TRC
🎬
Always Trace in CI
Set trace: 'on-first-retry'. Every CI failure gets a complete trace. Debugging remote failures becomes trivial β€” no more "works on my machine" ever again.
Debugging
PAR
⚑
Maximize Parallelism
Tests run parallel per file by default. Keep tests independent, set workers: 'auto'. A 200-test suite finishing in under 3 minutes is completely achievable with Playwright.
Speed