playwright-php / playwright-behat
Behat extension powered by Playwright PHP (Chromium/Firefox/WebKit).
Package info
github.com/playwright-php/playwright-behat
pkg:composer/playwright-php/playwright-behat
Fund package maintenance!
Requires
- php: ^8.2
- behat/behat: ^3.23
- playwright-php/playwright: ^1.4
- symfony/config: ^5.4 || ^6.4 || ^7.0 || ^8.0
- symfony/dependency-injection: ^5.4 || ^6.4 || ^7.0 || ^8.0
- symfony/event-dispatcher: ^5.4 || ^6.4 || ^7.0 || ^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.40
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5 || ^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-08 19:42:34 UTC
README
Playwright PHP for Behat
A Behat extension that runs your scenarios in a real browser through Playwright PHP.
Use it when feature files are the contract with your product owners and the steps need a browser: Chromium, Firefox, or WebKit. The extension launches the browser once per run and gives every scenario its own browser context, so cookies and storage never leak between scenarios and no browser is relaunched.
If your suite already relies on Mink, use playwright-mink instead: it keeps the Mink API and swaps the driver.
Installation
The extension requires PHP 8.2 or later, Behat 3.23 or later, and Playwright PHP 1.4 or later.
composer require --dev playwright-php/playwright-behat vendor/bin/playwright-install --browsers
Configuration
Enable the extension and add the built-in context to a suite. With Behat 3.x,
in behat.yml:
default: extensions: Playwright\Behat\ServiceContainer\PlaywrightExtension: base_url: 'http://localhost:8000' suites: web: paths: ['%paths.base%/features'] contexts: - Playwright\Behat\Context\PlaywrightContext
Behat 4 drops YAML configuration. The PHP form below works on Behat 3.x and 4.x:
<?php // behat.php use Behat\Config\Config; use Behat\Config\Extension; use Behat\Config\Profile; use Behat\Config\Suite; use Playwright\Behat\Context\PlaywrightContext; use Playwright\Behat\ServiceContainer\PlaywrightExtension; return (new Config()) ->withProfile((new Profile('default')) ->withExtension(new Extension(PlaywrightExtension::class, [ 'base_url' => 'http://localhost:8000', ])) ->withSuite((new Suite('web')) ->withPaths('%paths.base%/features') ->withContexts(PlaywrightContext::class)));
All options and their defaults:
| Option | Default | Meaning |
|---|---|---|
browser |
chromium |
chromium, firefox, or webkit |
headless |
true |
Run without a visible window |
base_url |
null |
Prefix for relative URLs passed to goto() |
timeout |
30000 |
Default timeout for actions and navigations, in ms |
slow_mo |
0 |
Delay between browser operations, in ms |
viewport |
{width: 1280, height: 720} |
Viewport of every scenario page |
screenshot_dir |
%paths.base%/var/screenshots |
Where named and failure screenshots go |
auto_screenshot_on_failure |
true |
Save failed-<scenario>-<line>.png when a scenario fails |
Usage
The built-in PlaywrightContext provides these steps. Selectors are Playwright
selectors: CSS by default, plus text=, role= and the other engines.
Feature: Login Scenario: Sign in with valid credentials Given I am on "/login" When I fill "#email" with "user@example.com" And I fill "#password" with "secret" And I click on "button[type=submit]" Then I should see "Dashboard" And I take a screenshot named "after login"
| Step | Effect |
|---|---|
Given I am on :url, When I go to :url |
Navigates; relative URLs resolve against base_url |
When I click on :selector |
Waits for the element, then clicks it |
When I fill :selector with :value |
Waits for the field, then fills it |
Then I should see :text |
Fails unless the page HTML contains the text |
When I take a screenshot named :name |
Saves <slug>.png under screenshot_dir |
A failing step throws Playwright\Behat\Exception\ExpectationFailedException,
or the Playwright PHP exception for a timeout.
Custom steps
Extend RawPlaywrightContext to write your own steps against the Playwright
PHP Page. The page is opened on first use and closed after the scenario:
<?php use Behat\Step\When; use Playwright\Behat\Context\RawPlaywrightContext; final class AdminContext extends RawPlaywrightContext { #[When('I sign in as an administrator')] public function signInAsAdministrator(): void { $page = $this->getPage(); $page->goto('/admin/login'); $page->locator('#username')->fill('admin'); $page->locator('#password')->fill('secret'); $page->locator('[type="submit"]')->click(); } }
A context that cannot extend RawPlaywrightContext can implement
Playwright\Behat\Context\PlaywrightAwareContext instead: the extension calls
setPlaywrightManager() on it before the run, and
PlaywrightManager::getPage() returns the page of the current scenario.
Testing
composer install vendor/bin/playwright-install --browsers vendor/bin/phpunit
The suite includes a real behat run against tests/Fixtures, including a
failing scenario that must leave a screenshot. Repository CI runs it on PHP
8.2, 8.3 and 8.4 against the latest Behat 3.x, plus one job on the lowest
supported dependencies and one on Behat 4.0.0-alpha1.
License
Playwright PHP for Behat is released under the MIT License.