@playwright-backend-mocks/playwright
v0.1.3
Published
Playwright fixtures for mocking Node.js backend HTTP
Readme
@playwright-backend-mocks/playwright
Playwright fixtures for mocking outbound Node.js HTTP (and WebSockets) from your tests — the test-side half of Playwright Backend Mocks.
Documentation · Getting started · API · GitHub
Run the real app. Mock only the outside world.
Good e2e tests cover your UI and your server — then fake Stripe, email, and every other third party at the boundary. Playwright can do the browser half. This library makes the server half just as easy.
Your UI and server stay real. backendMocks.route() targets the outbound HTTP your Node process makes — the calls that never show up in the browser Network tab.
test("declined card shows an error", async ({ page, backendMocks }) => {
await backendMocks.route("https://api.stripe.com/**", async (route) => {
await route.fulfill({
status: 402,
json: { error: "card_declined" },
});
});
await page.goto("/checkout");
await page.getByRole("button", { name: "Pay" }).click();
await expect(page.getByText("Your card was declined")).toBeVisible();
});If you know page.route(), you already know this shape: fulfill, fetch, continue, and abort — plus request spying for what your server actually called.
Role in the system
This package is what your Playwright tests import. It exposes the backendMocks fixture: live route handlers, matchers, waitForRequest / HAR helpers, and WebSocket routing. Handlers run in the Playwright worker; the proxy coordinates with the Node agent.
| Process | Package | Responsibility |
| --- | --- | --- |
| Playwright worker | @playwright-backend-mocks/playwright | backendMocks.route(), matching, settle (fulfill / continue / abort / …) |
| Proxy coordinator | @playwright-backend-mocks/proxy | Claims, decisions, history, REST |
| Node app | @playwright-backend-mocks/node | Intercepts outbound HTTP / WebSocket |
Install
npm install -D @playwright/[email protected] \
@playwright-backend-mocks/playwright \
@playwright-backend-mocks/node \
@playwright-backend-mocks/proxyKeep the @playwright-backend-mocks/* packages on the same version.
Compose the fixture
import { mergeTests } from "@playwright/test";
import { test as backendMocksTest } from "@playwright-backend-mocks/playwright";
import { test as appTest } from "./application-fixtures";
export const test = mergeTests(appTest, backendMocksTest);
export { expect } from "@playwright/test";Point Playwright at the proxy (usually via webServer) and set backendMocksProxyUrl — see the getting started guide.
How it works
- Start a proxy — a small local process between your Node app and Playwright.
- Route Node HTTP through it —
startBackendMocks()in the app catches outbound calls. - Control it from Playwright —
backendMocks.route(...)handlers decide fulfill / continue / abort.
When your app makes an outbound call:
@mswjs/interceptorspauses the request inside the Node process.- The Node agent forwards it to the proxy.
- The proxy matches it against the owning test’s
backendMocks.route()handlers. - Your handler settles with
fulfill,continue, orabort. - The decision returns to the app as a mocked or real response.
Unmatched requests pass through to the real network.
Related packages
| Package | Role |
| --- | --- |
| @playwright-backend-mocks/node | Agent that intercepts outbound traffic in the app |
| @playwright-backend-mocks/proxy | Coordinator + REST history API |
| @playwright-backend-mocks/dashboard | Optional read-only traffic UI |
| @playwright-backend-mocks/protocol | Shared wire types (usually a transitive dependency) |
License
MIT
