Assertions
Combine retrying Playwright assertions with Symfony response checks and ordinary PHPUnit assertions.
A Symfony browser test sees three kinds of facts: what the user can perceive, what the kernel returned, and what the application stored. Use the assertion layer that owns each fact.
Assert the rendered page with Playwright
Use expect() for visible, interactive state. These assertions re-read the browser until the expected state appears or the timeout is reached.
use function Playwright\Testing\expect;
$page = $this->visit('/account');
expect($page->getByRole('heading', ['name' => 'Your account']))
->toBeVisible();
expect($page->getByLabel('Email'))
->toHaveValue('ada@example.com');
This is the right layer for text, accessible names, visibility, enabled state, URLs, titles, and UI changes driven by JavaScript.
Assert the Symfony response
After an intercepted request, the normal Symfony response is available to the test. The bundle includes concise status helpers:
$this->visit('/account');
$this->assertResponseStatusCode(200);
$response = $this->getLastResponse();
self::assertNotNull($response);
self::assertSame('private', $response->headers->get('X-Page-Scope'));
PlaywrightTestCase extends Symfony's WebTestCase, so Symfony response assertions such as assertResponseIsSuccessful() are also available after visit():
$this->visit('/dashboard');
self::assertResponseIsSuccessful();
For a redirect that the client is configured not to follow, use the bundle helper and inspect the location directly:
static::getPlaywrightClient()->followRedirects(false);
$this->visit('/account');
$this->assertResponseIsRedirect();
self::assertSame('/login', $this->getLastResponse()?->headers->get('Location'));
Bundle assertion helpers
| Helper | Checks |
|---|---|
assertPageContains($text) |
The current page HTML contains text. |
assertPageNotContains($text) |
The current page HTML does not contain text. |
assertSelectorVisible($selector) |
A matching element is currently visible. |
assertSelectorHidden($selector) |
A matching element is currently hidden. |
assertResponseStatusCode($code) |
The last intercepted response has the expected status. |
assertResponseIsRedirect() |
The last intercepted response is a redirect. |
The page and selector helpers are convenient for stable states. For an interface that changes asynchronously, prefer expect() so the wait and the assertion describe the same condition.
Assert application state with PHPUnit
Use the test container for PHP-side facts, then keep the browser assertion focused on the visible outcome:
$page = $this->visit('/orders/42');
self::assertSame(200, $this->getLastResponse()?->getStatusCode());
expect($page->getByText('Order confirmed'))->toBeVisible();
A useful test can combine all three layers. The response proves the server contract, Playwright proves the rendered behavior, and PHPUnit remains available for plain PHP values.