Debugging guides
MSW record and replay: when API mocks are not the whole setup
A stock-conflict response is easy to put in a mock. The checkout that produced it is less convenient: two items, one edited quantity, a saved delivery choice and a failed first submission.
MSW can help turn recorded traffic into request handlers. The checkout still needs its cart, delivery choice and first submission. Decide where that preparation will live: in the test, in a development fixture or in a saved browser case.
The distinction matters most when someone other than the fixture author has to reproduce the bug.
HAR-to-MSW is an existing path
The MSW project maintains @msw/source, a library for generating request handlers from sources including HAR files and OpenAPI documents. Do not choose another tool on the assumption that every MSW handler must be handwritten. 1
For a Node-based test setup, load a reviewed HAR as JSON and generate the handlers:
import { readFileSync } from 'node:fs';
import { fromTraffic } from '@msw/source/traffic';
const archive = JSON.parse(
readFileSync('./fixtures/checkout.har', 'utf8'),
);
export const handlers = [...fromTraffic(archive)];
Use these in your existing MSW setup. This snippet generates handlers; it does not start interception or prepare the checkout. A browser bundle needs its own HAR-loading method instead of node:fs. The Source getting-started guide shows the integration step. 5, 6
That setup belongs in the suite when it will be reused as a test. For a one-off investigation, weigh the setup work against capturing the browser case you already have.
A stock-conflict fixture needs a checkout to fail in
Consider an invented checkout response with HTTP 409:
{
"code": "STOCK_CONFLICT",
"items": [
{ "sku": "mug-blue", "requested": 2, "available": 1 }
],
"retryable": true
}
The hypothetical bug is not that checkout fails. It is that the UI resets the delivery selection after the conflict, then submits a retry without the original choice.
A handler that returns this response lets you exercise the error path. To test the reported failure, also prepare the edited quantity and delivery choice, submit once, correct the quantity, and inspect the next submission. A page opened straight at the final checkout route may never reach the same transition.
The handler describes the response. The test or development setup must still put those inputs into the checkout and submit them.
Give repeated requests a defined meaning
For the checkout, decide whether every submission should fail, only the first should fail, or the result should depend on the revised quantity. Those are three different tests.
Source already preserves response order for repeated matching requests and respects recorded response timings. After that sequence is exhausted, its documented behaviour is to reuse the final response. Check whether this is the behaviour your recovery test needs; it is not a missing record-and-replay feature. 6
Make the initial state explicit and reset any stateful handlers between tests. Keep the success criterion close to the fixture: the revised quantity is submitted, the delivery choice is preserved, and the user sees the correct outcome. This is test design rather than a limitation unique to MSW.
Mock drift is a separate problem
A fixture can faithfully preserve yesterday’s response and still disagree with today’s backend. That may be exactly what you need to reproduce a historical frontend bug. It is not what you need to prove compatibility with the current API.
MSW documents strategies for preventing mock drift. For a long-lived fixture, record where it came from and how you will detect a contract change. For a historical bug, retaining the old response can be intentional. 2
For the checkout example, preserve the conflict response while fixing the reset logic. Separately test the current API contract. If retryable has been removed or the request body has changed, record that difference rather than quietly rewriting the historical fixture and losing the failing case.
Where a State Card fits
StatePort offers a capture-and-reopen workflow for supported browser cases. Reproduce the checkout failure in the managed browser, review what was retained and save a Card. Reopen it on the running local application before assuming the setup is reusable. 3, 4
The saved case can bring supported actions, checkpoints, browser/form state and retained responses together. With Local app, the frontend code comes from the developer’s target while exact retained responses provide the captured dependencies. That is useful when reproducing the UI setup is the repeated work. 4
It does not remove the need to define the expected result. It also does not promise correct replay of every mutable backend workflow. If the case needs unsupported behaviour or missing material, use a controlled fixture or test environment rather than treating a partial capture as a complete reproduction.
Which artifact should go into the repository?
Use MSW handlers when the scenario belongs in test or development code. Check whether a component test can cover the delivery-selection bug with the same error response; a full browser capture may be unnecessary.
Use a State Card when a person has reached a supported state that is expensive to prepare again, particularly when someone else needs to inspect it on changed code. The Card is a debugging artifact; the regression test may still be written with MSW or another test tool afterward.
This guide does not describe a direct import of MSW handlers or arbitrary HAR files into StatePort. To evaluate the Card workflow, use StatePort capture rather than assuming format interchange. Review supported scope and the Developer access model first.
For rule-based response changes without maintaining handlers in source, see the Requestly comparison.
Sources
Written by StatePort; checked on 13 October 2026. Payloads and checkout behaviour are synthetic examples, not measured results or a claim of MSW interoperability.