Skip to content
>_devvkit
$devvkit learn --librarie playwright-guide

Playwright Guide

[testing][e2e][browser]
JavaScript / TypeScript
Install
npm install -D @playwright/test
npx playwright install

Playwright speaks browser native protocols — faster and more reliable than Selenium.

Auto-waiting eliminates flaky waitForTimeout calls. Elements must be visible and stable.

Supports Chromium, Firefox, WebKit. Trace Viewer shows frame-by-frame test replay.

Setup

Basic testNavigate and check title.
import { test, expect } from '@playwright/test';
test('has title', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example/);
});

Locators & Actions

Click buttonFind and click.
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByTestId('submit-btn').click();
Type into inputFill a text input.
await page.getByLabel('Email').fill('alice@example.com');
await page.getByPlaceholder('Name').fill('Alice');

Assertions

Visible assertionCheck visibility.
await expect(page.getByText('Success')).toBeVisible();
await expect(page.getByText('Loading')).toBeHidden();
Wait for URLWait for navigation.
await page.getByText('Continue').click();
await page.waitForURL('**/dashboard');

Network

Intercept APIMock a response.
await page.route('**/api/users', async route => {
  await route.fulfill({ json: [{ id: 1, name: 'Mocked' }] });
});
Wait for responseWait for API call.
const res = page.waitForResponse('**/api/submit');
await page.getByRole('button').click();
const response = await res;
expect(response.ok()).toBeTruthy();

Fixtures

Custom fixtureReusable auth fixture.
export const test = base.extend<{ loggedInPage: Page }>({
  loggedInPage: async ({ page }, use) => {
    await page.goto('/login');
    await page.getByLabel('Email').fill('admin@example.com');
    await page.getByRole('button').click();
    await use(page);
  },
});