Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The shortest working Playwright test imports test and expect, uses the supplied page fixture to open a URL, and asserts something a user can observe:

import { test, expect } from '@playwright/test';

test('homepage has the expected title', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await expect(page).toHaveTitle(/Playwright/);
});

test declares the case, page represents an isolated browser tab, and expect verifies the result. The example is runnable, but replace the URL and assertion with a stable page in your own application before relying on it.

1. Create a Playwright Test project

Use a project directory with Node.js and npm available. From that directory, run the official initializer:

npm init playwright@latest

The wizard creates a Playwright Test project, configuration, and starter test. It may ask whether to use TypeScript or JavaScript, where to place tests, and whether to add a continuous-integration workflow. Choose the language your team already maintains; the API is the same apart from type annotations and file extensions.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the generated files

A typical project contains a playwright.config file and a tests directory. The configuration defines browser projects, test location, timeouts, and reporters. Keep the generated configuration for a first run, then change one setting at a time so failures remain easy to diagnose.

Initializer screens and defaults can change between Playwright releases. If your installed version presents different questions, follow that version’s prompts rather than copying an older screenshot of the wizard.

2. Install the browser binaries

Playwright’s test package and its browser binaries are version-specific. Install the browsers required by your project with:

npx playwright install

If your operating system needs additional system libraries, install them with the documented browser-install option for your environment. After upgrading Playwright, run the install command again; a package update can require matching browser revisions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The standard projects cover Chromium, Firefox, and WebKit. A browser passing locally does not prove that every other engine renders your application correctly.

3. Write a small sample program

Create tests/homepage.spec.ts (or a .js file if you selected JavaScript) and add:

import { test, expect } from '@playwright/test';

test('homepage has the expected title', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await expect(page).toHaveTitle(/Playwright/);
});

What each line does

  • import { test, expect } loads Playwright Test’s declaration and assertion functions.
  • test('...', async ({ page }) => { ... }) gives the test a readable name and receives a fresh page fixture.
  • page.goto() navigates the page and waits for the navigation to reach the normal completion state.
  • expect(page).toHaveTitle() checks the browser title with a regular expression. Web-first assertions wait and retry while the page settles.

For an application test, prefer a meaningful user outcome:

test('user sees a confirmation after saving', async ({ page }) => {
  await page.goto('http://localhost:3000/settings');
  await page.getByRole('button', { name: 'Save' }).click();
  await expect(page.getByRole('status')).toHaveText('Saved');
});

Use accessible roles, labels, and visible text when possible. CSS selectors tied to implementation details are more likely to break during harmless refactoring.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Run the test

Run every test in the configured projects with:

npx playwright test

The default run is headless and can execute tests in parallel. A passing result appears in the terminal with the number of tests and duration; a failure includes the assertion message and a trace or artifact when configured.

See the browser

npx playwright test --headed

Headed mode opens browser windows while the test runs. For an interactive runner with test lists, steps, and inspection controls, use:

npx playwright test --ui

These modes are especially useful while learning selectors or diagnosing a navigation that behaves differently than expected.

Run one file or one test

npx playwright test tests/homepage.spec.ts
npx playwright test -g "homepage has the expected title"

The first command narrows by file path. The -g option filters test names by pattern, so quote names containing spaces.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Select one browser project

npx playwright test --project=webkit

The value must exactly match a project name in playwright.config. All configured projects run when no project is selected. Use a single project for a quick feedback loop, then run the full matrix before release.

5. Make assertions reliable

Prefer web-first assertions

Assertions such as toHaveText, toBeVisible, and toHaveURL poll browser state until it matches or the assertion timeout expires:

await expect(page.getByRole('status')).toHaveText('Submitted');

The documented default assertion timeout is five seconds. That is a configuration default, not a promise about test speed. Set a longer timeout only for a known slow operation:

await expect(page.getByRole('status')).toHaveText('Report ready', {
  timeout: 15000
});

Do not replace a web-first assertion with a fixed sleep unless you are investigating a timing issue. Sleeps make tests slower and still fail when the real condition takes longer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep tests isolated

Each test receives its own browser context, even when tests use the same browser process. Avoid storing mutable page state in module-level variables or depending on another test’s order. Repeated setup belongs in a hook:

import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }) => {
  await page.goto('http://localhost:3000');
});

test('navigation shows pricing', async ({ page }) => {
  await page.getByRole('link', { name: 'Pricing' }).click();
  await expect(page).toHaveURL(/pricing/);
});

If tests share a database or account, reset that state explicitly. Isolation prevents a retry or parallel worker from inheriting surprising data.

6. Choose browser and execution coverage

One project for fast feedback

A single Chromium project gives beginners the quickest first loop: edit, run, inspect. It is appropriate for a smoke test while an application is under active development.

Multiple projects for compatibility

Add Chromium, Firefox, and WebKit projects when browser-engine differences matter. Projects can also represent device profiles, viewport sizes, or authenticated configurations. Run all of them by default, or select one with --project while debugging.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Passing Chromium alone cannot establish compatibility in Firefox, WebKit, mobile layouts, or assistive-technology combinations that your configuration does not exercise.

Headless, headed, and UI mode

  • Headless: the normal automated run; efficient for local checks and CI.
  • Headed: visible browser windows for understanding interaction and timing.
  • UI mode: interactive test selection and step inspection during development.

7. Run Playwright in continuous integration

A CI job must install both npm packages and the matching browsers before running tests. The essential sequence is:

npm ci
npx playwright install --with-deps
npx playwright test

Use the dependency option when the CI image does not already contain the operating-system libraries required by the browsers. Keep the Playwright package and browser installation in the same job so revisions cannot drift.

Playwright recommends one worker in CI when stability and reproducibility are the priority. A capable self-hosted runner can increase workers or shard the suite, but do so only after the environment is reliable and the tests do not contend for shared state. Store traces, screenshots, and videos as CI artifacts when a failure needs investigation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

8. Troubleshoot common failures

“Executable doesn’t exist” or browser launch failure

Cause: the package is installed but its browser revision is not. Fix: run npx playwright install; in a Linux CI image, install required system dependencies as well.

Tests pass locally but fail in CI

Cause: missing browser libraries, different environment variables, slower services, or parallel tests sharing data. Fix: install browsers in the job, verify the base URL and secrets, use web-first assertions, and try one CI worker while you remove state coupling.

Timeout waiting for a locator

Cause: a wrong role or name, a hidden element, a page that never finished loading, or an application error. Fix: run with --headed or --ui, inspect the rendered accessible name, wait for a real state such as a status message, and check the browser console and network logs. Increase the assertion timeout only when the slow behavior is expected.

Navigation hangs or the URL is unstable

Cause: a third-party request, redirect loop, offline dependency, or a page that is not intended as a test fixture. Fix: choose a stable environment, wait for a specific locator instead of an arbitrary delay, and mock an external service when the test’s purpose does not include that service.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Only one browser fails

Cause: an engine-specific CSS, API, or timing difference. Fix: reproduce with --project, inspect the trace, and correct the application or isolate a documented browser limitation. Do not hide the failure by removing that project unless the product genuinely does not support it.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

9. Capture a page without maintaining browser setup

Or skip the browser setup

If your goal is a clean image or PDF rather than an interaction assertion, ScreenshotNeo provides a single HTTP request. Its capture process accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing result.

It also offers an MCP server for Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for authentication, output formats, and the complete option set. You can request full-page captures with lazy images loaded, a CSS-selected element, dark mode, device presets or custom viewports, retina scale, PDF paper and page ranges, custom CSS or JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage data, and the OpenAPI specification.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a free ScreenshotNeo account to get 1,000 screenshots each month without a card.

10. A repeatable first-run checklist

  1. Run npm init playwright@latest in the intended project directory.
  2. Install matching browsers with npx playwright install.
  3. Create a test that imports test and expect, navigates with page.goto, and checks a stable result.
  4. Run npx playwright test headlessly.
  5. Use --headed, --ui, a file path, -g, or --project to narrow investigation.
  6. Replace arbitrary sleeps with web-first assertions and keep test data isolated.
  7. Install browsers and required dependencies in CI before setting the worker strategy.
  8. Run the browser projects that represent the compatibility promises of your application.

Frequently Asked Questions

Can I use JavaScript instead of TypeScript?

Yes. Select JavaScript during initialization or create a .js test file; the test, page fixture, navigation, and expect APIs remain the same.

Where should the base URL be configured?

Put a shared application origin in the Playwright configuration and navigate with relative paths when the suite targets one environment. Keep environment-specific values outside test source so local and CI runs can select their own deployment.

How do I preserve a failed run for later diagnosis?

Configure traces, screenshots, or videos for failures and publish those files as CI artifacts. Re-run the smallest failing file or title filter locally before changing the test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.