Events
Use the normal HttpKernel event lifecycle and the bundle's before-request and after-response hooks.
An intercepted application request runs through the normal Symfony HttpKernel. Controllers, subscribers, security listeners, response listeners, and termination listeners participate in the request just as they do in a functional test.
Request lifecycle
For each request routed into the kernel, the bundle follows this order:
- Convert the Playwright request into a Symfony
Request. - Call the test case
beforeRequest()hook. - Handle the main request through HttpKernel.
- Call
kernel.terminatewhen the kernel is terminable. - Persist an enabled profiler profile.
- Call the test case
afterResponse()hook. - Fulfill the browser request with the Symfony response.
This means normal listeners for kernel.request, kernel.controller, kernel.response, and kernel.terminate continue to work for application requests.
Add a request hook
Override beforeRequest() when a test needs to add controlled request context before the kernel handles it:
use Symfony\Component\HttpFoundation\Request;
public function beforeRequest(Request $request): void
{
$request->headers->set('X-Test-Tenant', 'acme');
}
The hook runs for every request routed through the kernel, including browser subresources that are not handled by the asset bridge. Keep the condition explicit when only one path should change:
public function beforeRequest(Request $request): void
{
if ('/account' === $request->getPathInfo()) {
$request->attributes->set('test_locale', 'fr');
}
}
Inspect the response hook
afterResponse() runs after kernel termination and receives the Symfony response:
use Symfony\Component\HttpFoundation\Response;
public function afterResponse(Response $response): void
{
self::assertTrue($response->headers->has('Content-Security-Policy'));
}
Use this hook for a rule that genuinely applies to every intercepted response. For a single scenario, getLastResponse() keeps the assertion closer to the behavior being tested.
Test application events
Application subscribers remain ordinary Symfony services. Prepare or retrieve a recording service from the test container, perform the browser action, then assert the recorded domain event or kernel event:
$events = static::getContainer()->get('app.test_event_recorder');
$page = $this->visit('/checkout');
$page->getByRole('button', ['name' => 'Confirm order'])->click();
self::assertSame(['order.confirmed'], iterator_to_array($events));
kernel.terminate listeners complete before afterResponse() and before the browser request is fulfilled. This also allows the profiler to load the profile written during termination.
Know the boundary
Requests served directly by the asset bridge do not enter HttpKernel, so they do not dispatch kernel events or invoke the request hooks. Requests to hosts outside intercepted_hosts remain normal browser network traffic. The boundary is visible and configurable: application URLs use Symfony, direct assets use the asset bridge, and external URLs use the network.