Principle:Microsoft Playwright Implement Response Fixtures
| Knowledge Sources | |
|---|---|
| Domains | Network_Testing, Mocking, HAR_Fixtures |
| Last Updated | 2026-02-11 00:00 GMT |
Overview
Recording and replaying HTTP responses from HAR (HTTP Archive) files to create deterministic, network-independent test fixtures.
Description
Manually writing mock responses for every API endpoint is tedious and error-prone, especially for applications with many network dependencies. Implement Response Fixtures is the principle of capturing real HTTP traffic into a structured archive format and then replaying those recorded responses during test execution.
The industry-standard format for this is HAR (HTTP Archive), a JSON-based format defined by the W3C Web Performance Working Group. A HAR file contains a complete log of HTTP transactions, including:
- Request data: URL, method, headers, query parameters, POST body, cookies.
- Response data: Status code, status text, headers, body content (text or base64-encoded binary), content size and MIME type.
- Timing data: DNS lookup, connection, SSL handshake, send, wait, and receive timings.
- Page and entry relationships: Which page load triggered each request.
The fixture workflow has two phases:
Recording phase: The test runs against a real server, and all HTTP traffic is captured into a HAR file. This produces an authoritative snapshot of server responses at a point in time.
Replay phase: The test runs with the HAR file as the source of responses. When a request matches an entry in the HAR file, the recorded response is served. When no match is found, the test can either abort the request, fall back to the real network, or report an error.
The matching algorithm for HAR replay must handle:
- URL matching: Exact or pattern-based URL comparison.
- Method matching: Ensuring GET vs. POST responses are not confused.
- Header matching: Some responses vary by Accept, Content-Type, or custom headers.
- Body matching: POST requests with different bodies should receive different responses.
- Order sensitivity: Some APIs return different responses on repeated calls.
Benefits of HAR-based fixtures:
- Determinism: Tests always see the same responses regardless of server state.
- Speed: No network roundtrip latency.
- Isolation: Tests do not require a running backend.
- Reproducibility: Fixtures can be version-controlled and shared across teams.
- Low maintenance: Fixtures can be re-recorded when the API changes.
This principle is library-agnostic. HAR recording and replay can be implemented with any HTTP proxy, browser automation tool, or custom middleware.
Usage
Apply this principle when:
- Your application makes many API calls and manually mocking each one is impractical.
- You want to capture a baseline of server responses and replay them for regression testing.
- You need to test against a complex API that is expensive, slow, or unreliable to call during CI.
- You want to create snapshot-based tests where the entire network layer is recorded and replayed.
- You are migrating from integration tests (with a real backend) to isolated frontend tests.
- You need to version-control API response fixtures alongside your test code.
Theoretical Basis
The HAR fixture workflow follows the record-replay pattern commonly used in test doubles:
RECORDING PHASE:
Test Runner -> Browser -> Real Server
|
v
HAR Recorder (captures request/response pairs)
|
v
HAR File (persisted to disk)
REPLAY PHASE:
Test Runner -> Browser -> HAR Router (intercepts requests)
|
v
HAR Backend (matches against recorded entries)
|
+------+------+
| |
Match found No match
| |
Fulfill with Abort, fallback,
recorded or error
response
The HAR file format structure:
{
"log": {
"version": "1.2",
"entries": [
{
"request": {
"method": "GET",
"url": "https://api.example.com/users",
"headers": [...],
"postData": { ... }
},
"response": {
"status": 200,
"statusText": "OK",
"headers": [...],
"content": {
"size": 1234,
"mimeType": "application/json",
"text": "{\"users\": [...]}"
}
}
}
]
}
}
The matching algorithm (simplified pseudocode):
function findMatchingEntry(request, harEntries):
for entry in harEntries:
if entry.request.url != request.url: continue
if entry.request.method != request.method: continue
if hasPostData(request) and entry.request.postData != request.postData: continue
if headersMismatch(entry.request.headers, request.headers): continue
return entry.response
return NOT_FOUND
HAR files can be stored as plain JSON or compressed into ZIP archives with response bodies stored as separate files (the "attach" content mode). This reduces file size for large fixtures with binary content (images, fonts, etc.).