Run real-browser Symfony tests while routing application requests through the kernel in the same PHP process.
Important
This package is in active development. Its public API may change before 1.0.
composer require --dev playwright-php/playwright-symfony
vendor/bin/playwright-install --browsersRequirements:
- PHP 8.2+
- Symfony 6.4, 7.x, or 8.x
- Node.js 20+
Register the bundle for the test environment:
// config/bundles.php
return [
// ...
Playwright\Symfony\PlaywrightSymfonyBundle::class => ['test' => true],
];The bundle works without additional configuration. To change the base URL or intercepted hosts:
# config/packages/test/playwright.yaml
playwright:
base_url: 'http://localhost'
intercepted_hosts: ['localhost', '127.0.0.1']Extend PlaywrightTestCase, visit an application route, and use the regular Playwright page API:
<?php
namespace App\Tests\E2E;
use Playwright\Symfony\Test\PlaywrightTestCase;
final class HomepageTest extends PlaywrightTestCase
{
public function testNavigation(): void
{
$page = $this->visit('/');
self::assertResponseIsSuccessful();
$page->getByRole('link', ['name' => 'About'])->click();
$this->assertPageContains('About');
}
}Run the test with PHPUnit:
vendor/bin/phpunit tests/E2ESet PLAYWRIGHT_HEADLESS=false to see the browser, or PLAYWRIGHT_BROWSER=firefox to use another engine.
For requests to an intercepted host, the package:
- Intercepts the browser request through Playwright.
- Converts it to a Symfony request.
- Handles it with the application kernel.
- Returns the Symfony response to the browser.
This keeps JavaScript, CSS, navigation, cookies, and browser storage in a real browser while preserving access to the Symfony test container, request, response, and profiler.
The kernel and browser start lazily when a browser helper or client is first used.
$this->visit('/admin');
self::assertSame(200, $this->getLastResponse()?->getStatusCode());
$service = static::getContainer()->get(App\Service\AuditLog::class);Static files and AssetMapper output can be served directly by the asset bridge without passing through the kernel.
Use the primary client alongside fresh clients when a test needs isolated browser contexts:
$alice = static::getPlaywrightClient();
$bob = static::createPlaywrightClient();The clients share the browser process and Symfony kernel, but not cookies or browser storage.
Use loginUser() when login itself is not under test:
$this->loginUser($user);
$page = $this->visit('/account');
$this->assertPageContains($user->getUserIdentifier());The package also provides cookie helpers and access to the last intercepted request and response.
PlaywrightTestCaseis for browser navigation. Prefervisit()and the Playwright page API over direct BrowserKit requests.- Only configured hosts are routed through the Symfony kernel. Other requests use the browser network normally.
- Browser tests are slower than unit and functional tests. Keep them in a dedicated PHPUnit suite or group.
- Getting started
- Configuration
- Test helpers
- Asset development server
- Continuous integration
- Architecture
Contributions are welcome. Before submitting a pull request, run:
composer install
vendor/bin/playwright-install --browsers
composer cs-check
vendor/bin/phpstan analyse
composer testChanges to public behavior should include tests and documentation.
Playwright PHP for Symfony is released under the MIT License.
