Made in JS. Unleashed in PHP.

Real browsers.From PHP.

A synchronous, typed PHP API for Chromium, Firefox, and WebKit, with web-first assertions and trace-based debugging.

Three real engines Chromium, Firefox, and WebKit, driven through a local Playwright bridge.
Retrying assertions Re-read the page until the expected state appears or the timeout is reached.
Trace artifacts Keep DOM snapshots, network activity, console output, and screenshots together.
A PHPUnit workflow Use the test runner, assertions, and failure output your PHP suite already uses.
Symfony Bundle Run end-to-end tests with application fixtures and profiler access when you need them.
Browsers ready in CI A GitHub Action installs the Playwright runtime and selected browser binaries.
PHP≥ 8.2
Releasev1.4.0
PHPStanlevel 10
TestsPHPUnit
LicenseMIT
$ composer require playwright-php/playwright
Smart locators

Target what users see.

Use roles and labels instead of coupling tests to DOM structure. Each action resolves the current page and waits for its own preconditions.

Read the locators guide →
<?php
$page->getByRole('button', ['name' => 'Sign in'])->click();
$page->getByLabel('Email')->fill('ada@example.com');
$page->getByText('Welcome back')->waitFor();
Retrying assertions

Assert the outcome.

Web-first assertions re-read the page until the expected state appears or the timeout is reached.

Read the assertions guide →
<?php
expect($locator)->toBeVisible();      // retries
expect($locator)->toContainText('Saved');
expect($page)->toHaveTitle('Dashboard');
Trace-based debugging

Bring the failure home.

Save DOM snapshots, network activity, console output, and screenshots in one trace archive from the failed run.

Read the debugging guide →
$context->tracing()->start([
    'snapshots' => true,
    'screenshots' => true,
]);

// ... the test ...

$context->tracing()->stop([
    'path' => 'trace.zip',
]);
Symfony

Real browsers, inside Symfony.

Route browser requests through the test kernel. Prepare state with application services, then combine Playwright assertions with Symfony responses and profiler data.

$page = $this->visit('/account');

$this->assertResponseIsSuccessful();

expect($page->getByRole('heading', [
    'name' => 'Account',
]))->toBeVisible();
Integrations

Fits existing PHP workflows.

Run browser tests in PHPUnit, keep valuable Mink suites moving, and prepare GitHub Actions runners with a focused setup step.

PHPUnit Fresh browser contexts, web-first assertions, and failure artifacts in the test runner you already use.
Mink Move an existing Mink or Behat suite onto Playwright browsers while keeping the familiar Session API.
GitHub Actions Install the Playwright runtime, browser binaries, and Linux dependencies in one explicit CI step.
All integrations →
Extensions

Add focused capabilities.

Bring device profiles, accessibility audits, and performance budgets into the same browser runs.

Device profiles Named phone and tablet presets with viewport, touch, user agent, and pixel ratio.
Accessibility Run axe-core audits against the rendered state and assert violations from PHP.
Performance Collect Core Web Vitals and browser timings from controlled page loads.

PHP tests. Real browsers.