MSW transport
The same in-process Hono mock, exposed as MSW handlers. Use this transport when your tests need MSW's request interception: React Testing Library component tests, Playwright component runner, browser-mode vitest. One mock, two transports.
When to use MSW
| Test shape | Reach for |
|---|---|
| Pure SDK calls | createTestClient |
React component test that mounts CataloguePage / CartDrawer and lets the SDK's built-in client fetch normally | createMswHandlers |
| Browser-mode vitest or Playwright component tests | createMswHandlers |
Production storefront in bun dev | cimplify mock CLI |
Install
msw is an optional peer dependency; install it only if you reach for this transport.
bun add -d mswSetup (Node, vitest)
import { setupServer } from "msw/node";
import { beforeAll, afterAll, afterEach } from "vitest";
import { createMswHandlers } from "@cimplify/sdk/testing/msw";
const { handlers, deps } = await createMswHandlers({ seed: "retail" });
const server = setupServer(...handlers);
beforeAll(() => server.listen({ onUnhandledRequest: "bypass" }));
afterEach(() => deps.resetAll());
afterAll(() => server.close());Setup (browser)
import { setupWorker } from "msw/browser";
import { createMswHandlers } from "@cimplify/sdk/testing/msw";
const { handlers } = await createMswHandlers({ seed: "fashion" });
export const worker = setupWorker(...handlers);
if (typeof window !== "undefined") {
await worker.start({ onUnhandledRequest: "bypass" });
}Component test example
import { render, screen, waitFor } from "@testing-library/react";
import { CimplifyProvider } from "@cimplify/sdk/react";
import { createCimplifyClient } from "@cimplify/sdk";
import { CataloguePage } from "@cimplify/sdk/react";
const client = createCimplifyClient({
baseUrl: "http://localhost:8787",
publicKey: "pk_test_msw",
});
it("renders products from the seed", async () => {
render(
<CimplifyProvider client={client}>
<CataloguePage />
</CimplifyProvider>,
);
await waitFor(() => {
expect(screen.getAllByRole("article").length).toBeGreaterThan(0);
});
});Options
createMswHandlers accepts every CreateAppOptions the in-process mock does (seed, authMode, frozenAt, rngSeed, defaultOtp), plus a baseUrl override for the URL handlers register against.
const { handlers, deps } = await createMswHandlers({
seed: "retail",
baseUrl: "http://localhost:8787", // default
frozenAt: new Date("2026-05-07T10:00:00Z"),
rngSeed: 42,
authMode: "permissive",
defaultOtp: "123456",
});Resetting between tests
deps.resetAll() drops every in-memory cart, order, session, and event queue. Call it from afterEach; server.resetHandlers() from MSW is a separate thing and not needed when you don't mutate the handler set per test.
Next
-
Test client The lighter-weight transport for pure SDK tests
-
Contracts Pinning the mock to the production lens
Schemas
Every shape the SDK, mock, and storefronts must agree on lives as a zod schema in `@cimplify/sdk/testing`. Schemas are registered with metadata, paired with typed `assertX` helpers, and exported as JSON Schema for downstream tooling.
Contracts
The SDK and the backend agree on shapes by snapshotting both sides as JSON Schema and diffing on every CI run. The pipeline runs on every PR; drift breaks the build before it can reach a storefront.