ScreenshotNeo

BlogHow-to

How to Run Playwright Tests

Run Playwright tests from install to CI, debug failures, select browsers, filter tests, and read HTML reports with practical commands.

By the ScreenshotNeo team1 October 20268 min read

Use npx playwright test to run the configured Playwright test suite. It runs tests headlessly and in parallel by default. Before the first run, install the Playwright test package and the browser binaries:

npm init playwright@latest
npx playwright install
npx playwright test

Playwright’s generated configuration controls browsers, projects, timeouts, retries, reporters, and other execution settings. Playwright supports Windows, macOS, and Linux, both locally and in CI. The official installation guide describes the package as including the test runner, assertions, isolation, parallelization, and tooling.

Sources: installation and introduction, running and debugging tests.

1. Install Playwright and its browsers

Start a new project

npm init playwright@latest

The setup wizard creates example tests, a Playwright configuration file, and the required package scripts. Accept the TypeScript or JavaScript choice that matches your project.

Add Playwright to an existing project

npm install --save-dev @playwright/test
npx playwright install

Run npx playwright install after upgrading Playwright as well. Each Playwright version requires specific browser binary versions.

Install browsers selectively

npx playwright install chromium
npx playwright install firefox webkit

On Linux CI machines, install operating-system dependencies with:

npx playwright install-deps
npx playwright install --with-deps chromium

The second command installs Chromium and its required system packages together. A headless-shell-only installation can reduce CI downloads when a full browser channel is unnecessary. See the browser installation guide.

2. Write a runnable test

A minimal TypeScript test uses a page fixture, navigates to a URL, and asserts a user-visible result:

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

test('has title', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example Domain/);
});

Save it as tests/example.spec.ts, then run:

npx playwright test tests/example.spec.ts

Prefer role- and label-based locators and web-first assertions. They wait for the expected condition and express what a user can observe:

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

test('user can add a todo', async ({ page }) => {
  await page.goto('https://example.com/todos');
  await page.getByRole('textbox', { name: 'New todo' }).fill('Buy milk');
  await page.getByRole('button', { name: 'Add' }).click();
  await expect(page.getByRole('listitem')).toContainText('Buy milk');
});

Each test receives an isolated BrowserContext, so cookies, local storage, and other browser state do not leak between tests.

3. Run all tests

npx playwright test

With no file or filter arguments, Playwright runs every test matched by the configuration. Tests run in parallel by default and in headless mode, so no browser window opens and results are printed in the terminal.

Useful execution controls include:

# Run serially
npx playwright test --workers=1

# Retry failed tests (for example, twice)
npx playwright test --retries=2

# Stop after a failure limit
npx playwright test --max-failures=1

# Run a shard in CI
npx playwright test --shard=3/5

Retries and sharding change execution; they do not repair a flaky test. Review the report and failure artifacts before increasing retries.

4. Run a subset of tests

Use the narrowest filter that answers your question:

# One file
npx playwright test tests/example.spec.ts

# Multiple files or directories
npx playwright test tests/todo-page/ tests/landing-page/

# Filename keywords
npx playwright test landing login

# Test title or regular expression
npx playwright test -g "add a todo item"

# Tests that failed in the previous run
npx playwright test --last-failed

# A test at a source line
npx playwright test my-spec.ts:42

Path filters are resolved against the test files selected by the project configuration. If a title pattern contains shell metacharacters, quote it.

5. Choose a browser, device, or project

Projects let one test body run against different engines, branded browsers, or device profiles. A typical configuration looks like this:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  timeout: 30_000,
  retries: process.env.CI ? 2 : 0,
  reporter: [['html', { open: 'never' }]],
  use: {
    baseURL: 'http://127.0.0.1:3000',
    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-chrome', use: { ...devices['Pixel 5'] } }
  ]
});

Run every configured project with:

npx playwright test

Select one or more projects with:

npx playwright test --project=chromium
npx playwright test --project=firefox --project=webkit
npx playwright test --project=mobile-chrome tests/example.spec.ts

Playwright documents Chromium, Firefox, WebKit, branded Chrome and Edge channels, and emulated mobile devices. Keep assertions the same across projects so browser differences remain visible.

6. Run headed, UI, and debug modes

Headed mode

npx playwright test --headed

Headed mode opens the browser while retaining normal test execution.

UI Mode

npx playwright test --ui

UI Mode provides an interactive test list, step timeline, trace details, and a way to rerun individual tests. It is useful when you need to see what happened before, during, and after each action.

Inspector debugging

npx playwright test example.spec.ts:10 --debug

The Inspector pauses execution, shows debug logs, and helps explore locators. You can also add a breakpoint in code:

await page.pause();

Remove pauses before committing a test. For repeatable failure analysis, enable traces, screenshots, and videos in the project configuration rather than leaving every run in debug mode.

7. Read the HTML report

npx playwright show-report

The HTML Reporter lets you filter and search by browser, passed or failed state, skipped tests, flaky tests, errors, and individual steps. If the report is on a different port:

npx playwright show-report --port 9324

In CI, publish the report and trace artifacts from the configured output directory. A failure should be investigated with its error, trace, screenshot, network context, and browser project together.

8. Run tests against a local web server

Use the webServer setting so Playwright starts your application before tests and stops it afterward:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  webServer: {
    command: 'npm run dev',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI
  },
  use: {
    baseURL: 'http://127.0.0.1:3000'
  }
});

Then navigate with a relative path:

await page.goto('/login');

Make the server command deterministic and ensure the URL is reachable from the same environment that runs the browser.

9. CI execution

A reliable CI run normally installs exact dependencies, installs browser binaries, runs headless tests, and stores reports and artifacts:

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

Use multiple projects when browser coverage matters. Use --workers=1 when a shared test environment cannot safely handle parallel sessions. Use retries sparingly and inspect flaky results instead of treating retries as a pass condition.

10. Troubleshooting common failures

Symptom Cause Fix
Executable doesn’t exist Browser binaries are missing or belong to another Playwright version. Run npx playwright install after installing or upgrading @playwright/test.
Linux launch or shared-library error CI image lacks browser system dependencies. Run npx playwright install --with-deps chromium or install dependencies with npx playwright install-deps.
No tests found File naming, directory, project, or grep filters exclude the test. Check testDir, use a *.spec.ts or *.test.ts filename, and remove filters temporarily.
Test times out waiting for a locator The locator is wrong, the page is not ready, or a navigation failed. Use a role or label locator, inspect the trace, verify the URL, and wait for a meaningful web-first assertion instead of a fixed sleep.
Works headed but fails headless Timing, viewport, missing dependency, or headless-only environment differences. Reproduce with --headed, inspect trace and console output, then fix synchronization or environment setup.
Flaky test passes on retry Race condition, unstable data, shared state, or external dependency. Use isolated fixtures, deterministic test data, locator-based waits, and trace-on-first-retry; keep the test visible as flaky.
Web server never becomes ready The command exits, binds another host, or the configured URL is wrong. Run the command locally, bind to 127.0.0.1, and make webServer.url match the actual address.
Report is empty or unavailable The reporter was not enabled, artifacts were discarded, or the wrong directory was opened. Configure the HTML reporter, preserve the output directory in CI, and run npx playwright show-report.

11. Reliability and performance practices

  • Keep tests independent so parallel workers can run safely.
  • Use locators and web-first assertions rather than arbitrary sleeps.
  • Control data and external services with fixtures or mocks where appropriate.
  • Set explicit timeouts for genuinely slow operations, but fix synchronization before raising global timeouts.
  • Run Chromium, Firefox, and WebKit in separate projects when cross-engine coverage is required.
  • Use sharding to distribute large suites across CI jobs, and keep each shard’s artifacts.
  • Capture traces on the first retry, screenshots only on failure, and videos only when needed to limit storage and runtime.
  • Pin dependency versions with a lockfile and reinstall matching browser binaries after upgrades.

12. Or skip the browser setup

If your goal is to capture a page image during a test or build workflow, ScreenshotNeo provides a website screenshot API without managing Playwright browsers. Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.

See the ScreenshotNeo API documentation for all options.

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}`);
const data = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));

ScreenshotNeo supports full-page and element captures, dark mode, device presets, custom viewports, retina scale, PDF output, custom CSS and JavaScript, clicks, waits, blocked requests, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous jobs, webhooks, bulk capture, usage reporting, and an OpenAPI specification. Parameter names used by other screenshot APIs also work.

Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

13. Cost and resource planning

Playwright itself is an open-source test framework, but your costs come from CI minutes, browser workers, artifact storage, and any hosted test infrastructure. Parallel workers reduce wall-clock time while increasing CPU and memory use. Sharding reduces time for large suites but requires more CI jobs and artifact management. Retaining videos and traces for every test can grow storage quickly, so keep them for failures or selected retries.

For page snapshots where browser installation and CI maintenance are unnecessary, ScreenshotNeo charges only for clean shots. Its plans are Free: 1,000 shots/month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; and Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is included on every plan.

FAQ

What command runs all Playwright tests?

npx playwright test runs all tests selected by the configuration.

How do I run only Chromium?

Use npx playwright test --project=chromium when the configuration defines a project named chromium.

How can I see the browser?

Run npx playwright test --headed, or use --ui for an interactive runner.

How do I rerun only failures?

Run npx playwright test --last-failed.

Why must I install browsers after upgrading Playwright?

Each Playwright version needs specific browser binary versions, so rerun npx playwright install.

Where do I inspect a failed test?

Open the HTML report with npx playwright show-report, then inspect the error, steps, trace, screenshot, and project details.