Observing traffic
Observe requests and responses without making the test depend on every background call.
Network evidence is useful when a user action depends on one backend exchange. It is less useful when the test records every request and then tries to infer whether the product worked.
Keep two questions separate:
- What did the browser send? Inspect the request.
- What did the application return? Inspect the response.
The final assertion should normally still describe what the user sees.
Observe without changing behaviour
Events are read-only. Register them before the action that emits the traffic:
$page->events()->onRequest(static function ($request): void {
printf('> %s %s'.PHP_EOL, $request->method(), $request->url());
});
$page->goto('https://app.example.test/dashboard');
Use broad listeners for temporary diagnostics. For a test assertion, wait for the one exchange that belongs to the scenario.
Tie a response to an action
The PHP process cannot click while waitForResponse() is blocking. Pass the small browser-side action as a JavaScript expression so the listener is armed before the click:
$response = $page->waitForResponse('**/api/orders', [
'action' => 'document.querySelector("[data-testid=refresh-orders]").click()',
]);
self::assertSame(200, $response->status());
expect($page->getByRole('heading', ['name' => 'Orders']))
->toBeVisible();
The status explains the backend exchange. The locator assertion proves that the page reached the user-visible result.
Keep this exception narrow. When the response itself is not part of the requirement, click through a locator and assert the visible result instead.
Choose the right signal
| Need | Use |
|---|---|
| Print temporary diagnostics | request or response events |
| Prove an action sent one call | wait for the matching request |
| Tie an action to a backend result | wait for the matching response |
| Change, block, or replace traffic | Routing |
| Test an endpoint without rendering | API requests |
Match narrowly enough to identify the call: URL, method, and meaningful query parameters when needed. Avoid assertions on analytics, preloads, polling, or third-party noise unless they are the product contract.
Common mistakes
- Registering the listener after navigation or the click.
- Treating a
200response as proof that the UI updated. - Asserting every request made during page load.
- Matching only a broad URL fragment when several calls share it.
- Forgetting that a request can fail before any response exists.
Go next
- Control an endpoint: Routing
- Configure headers and proxies: Network configuration
- Copy a task: Wait for a network response
- Look up exact objects: Request, Response