VCR pour Playwright

Enregistrez une fois.
Rejouez pour toujours.

Capture les vraies réponses d'API pendant que votre suite Playwright s'exécute en local, puis les rejoue octet par octet en CI. Sans backend, sans réseau, sans mocks écrits à la main à maintenir.

npm i -D test-proxy-recorder Mettre une étoile sur GitHub Nombre d'étoiles GitHub

MIT · TypeScript · fonctionne avec le SSR Next.js & TanStack Start, les SPA et les extensions Chrome · prise en charge WebSocket

REC · MODE=record · local run

saved e2e/recordings/todos.GET.mock.json

REPLAY · MODE=replay · CI

200 OK · 3 ms · zero network

Voyez-le enregistrer, puis rejouer

Une exécution Playwright enregistre de vraies réponses sur le disque ; basculez en rejeu et la même suite passe avec le backend éteint — sans réseau.

Deux enregistreurs, un proxy

Les requêtes ont leur origine à deux endroits, donc il y a deux mécanismes d'enregistrement. Utilisez l'un ou l'autre — ou les deux ensemble. Les deux enregistrent une fois et rejouent depuis le disque, donc la CI tourne avec le backend éteint et sans mocks écrits à la main.

Proxy

.mock.json

SSR Next.js / TanStack Start → proxy → vraie API

Se place entre votre serveur et l'API. Enregistre les requêtes côté serveur — fetches SSR, route handlers, tout ce que votre backend-for-frontend appelle.

Pour les apps full-stack où le serveur appelle l'API.

Voir l'exemple Next.js → Voir l'exemple TanStack Start →

HAR

.har

navigateur → interception HAR → vraie API

Intercepte dans le navigateur lui-même. Enregistre les appels fetch côté client, le trafic des API d'extensions Chrome, l'analytics, les API tierces.

Pour les SPA, les extensions et les apps uniquement navigateur.

Voir l'exemple d'extension Chrome →

Où il se situe

Les outils de mocking excellent à des tâches différentes. La combinaison ci-dessous — enregistrer du trafic réel à travers le SSR, le navigateur et les WebSockets, sans mocks écrits à la main — est le vide que les autres laissent ouvert.

Comparaison des fonctionnalités de test-proxy-recorder avec Playwright routeFromHAR, MSW, Polly.js, playwright-network-cache et Mocky Balboa.
Fonctionnalité test-proxy-recorder Playwright routeFromHAR MSW Polly.js playwright-network-cache Mocky Balboa
Enregistre le trafic réel Oui Oui Non Oui Oui Non
Côté serveur (SSR) Oui Non Oui Partiel Non Oui
Côté navigateur Oui Oui Oui Oui Oui Oui
WebSocket Oui Non Oui Non Non Non
Natif Playwright Oui Oui Non Non Oui Oui
Maintenu Oui Oui Oui Non Oui Oui

Polly.js intercepte le HTTP de Node, donc le mock SSR est possible dans le processus de l'app, mais pas dans le cadre d'une exécution Playwright. MSW et Mocky Balboa rejouent aussi de vraies réponses — mais vous écrivez les mocks à la main. Quand choisir autre chose est couvert dans les docs.

Fonctionne avec votre vrai fournisseur d'authentification

Connectez-vous via Cognito, Auth0, Clerk ou WorkOS — pour de vrai, à chaque exécution. Seule l'API de votre app est enregistrée ; l'authentification reste en direct, vos données passent hors ligne.

// e2e/auth.setup.ts — log in for real, once. Never recorded.
import { test as setup } from '@playwright/test';
import { setProxyMode } from 'test-proxy-recorder';
setup('authenticate', async ({ page }) => {
await setProxyMode('transparent'); // login bypasses the recorder
await page.goto('/login');
await page.getByTestId('email').fill(process.env.TEST_EMAIL!);
await page.getByTestId('password').fill(process.env.TEST_PASSWORD!);
await page.getByTestId('signinButton').click();
await page.waitForURL('/dashboard');
// Reused by every test — they start already signed in.
await page.context().storageState({ path: 'e2e/.auth/state.json' });
});

Configuration en trois étapes

Scaffoldez tout avec une commande, pointez votre API vers le proxy, puis enregistrez et committez. App uniquement navigateur ? init saute l'étape SSR pour vous.

Chemin le plus rapide : confiez-le à votre agent IA

Copiez ceci, remplacez votre URL de backend et collez-le dans Claude Code, Cursor ou n'importe quel agent de codage — il exécute init et termine le branchement à partir du prompt init affiche.

Set up test-proxy-recorder for end-to-end tests in this project, then follow the
instructions that `init` prints. Run these commands:
npx @tanstack/intent@latest install
npm install --save-dev test-proxy-recorder
Then run init, passing this project's backend API base URL as the target — find
it yourself from the app's env/config (the URL the app calls in dev); don't
assume the default:
npx test-proxy-recorder init <your-backend-api-url> --port 8100 --dir ./e2e/recordings
Then complete the app-specific steps init prints: point the app's API base URL at
the proxy in dev/test only, tag server-side fetches (Next.js), add a smoke test,
and verify record → replay.

Ou branchez-le à la main :

  1. Installer et scaffolder

    init écrit la config du proxy, une fixture Playwright, un teardown global, des scripts package.json , et (sur Next.js) branche le marquage des fetches SSR dans votre root layout — sans rien écraser.

    Terminal window
    npm install --save-dev test-proxy-recorder
    # http://localhost:3002 is your API endpoint; 8100 is the proxy. Flags are optional.
    npx test-proxy-recorder init http://localhost:3002 --port 8100 --dir ./e2e/recordings
  2. Pointez l'API de votre app vers le proxy

    La seule chose init ne peut pas deviner : quelle variable d'environnement contient l'URL de base de votre API. Pointez-la vers le proxy lorsque le recorder est activé, vers le vrai backend sinon — le proxy ne tourne jamais en production.

    // Point your app at the proxy when the recorder is enabled, at the real backend otherwise.
    // The proxy never runs in production — TEST_PROXY_RECORDER_ENABLED is set only for e2e.
    const API_BASE =
    process.env.NODE_ENV === 'production' && !process.env.TEST_PROXY_RECORDER_ENABLED
    ? 'https://api.example.com'
    : 'http://localhost:8100'; // proxy address from `init`
    const res = await fetch(`${API_BASE}/todos`);

    Sur Next.js, init ajoute aussi registerProxyFetch() à votre root layout pour tagger les fetch côté serveur — un no-op en production :

    // app/layout.tsx — tag server-side fetches so SSR is recorded/replayed
    import { registerProxyFetch } from 'test-proxy-recorder/nextjs';
    registerProxyFetch(); // no-op in production unless TEST_PROXY_RECORDER_ENABLED=true
  3. Enregistrer, committer, rejouer

    Définissez MODE = 'record', exécutez une fois contre la vraie API, puis basculez sur 'replay' et committez. Les enregistrements vivent dans git — c'est ce qui rend la CI déterministe. Ne les gitignorez pas.

    e2e/my.test.ts
    import { test, expect } from '@playwright/test';
    import { playwrightProxy } from 'test-proxy-recorder';
    // Full-stack: the browser also talks to the proxy, so match its URL.
    // (Browser-only app? Match your real API domain instead, e.g. /api\.example\.com/.)
    const CLIENT_SIDE_URL = /localhost:8100/;
    // 'record' hits the real API and saves responses.
    // 'replay' serves them from disk — no network needed.
    const MODE = 'replay' as const;
    test.beforeEach(async ({ page }, testInfo) => {
    await playwrightProxy.before(page, testInfo, MODE, { url: CLIENT_SIDE_URL });
    });
    test('homepage loads', async ({ page }) => {
    await page.goto('/');
    await expect(page.getByText('Welcome')).toBeVisible();
    });
    Terminal window
    # 1. Set MODE = 'record' in your test file, run against the real API
    npx playwright test --ui # recordings written to e2e/recordings/
    # 2. Flip MODE back to 'replay' and commit the recordings
    git add e2e/recordings/
    git commit -m "add e2e recordings"

Arrêtez d'écrire des mocks à la main

Votre API donne déjà les bonnes réponses. Enregistrez-les.

npm i -D test-proxy-recorder Mettre une étoile sur GitHub

Si ça vous a épargné un après-midi, une étoile prend une seconde — c'est ainsi que la prochaine personne le trouve, et cela dit à un mainteneur solo de continuer à construire. Vous avez un souci ou une idée ? Ouvrir une issue ou rejoindre Discord.