VCR for Playwright

Ghi lại một lần.
Phát lại mãi mãi.

Ghi lại các response API thật trong khi bộ Playwright của bạn chạy cục bộ, rồi phát lại chúng từng byte trên CI. Không cần backend, không cần mạng, không có mock viết tay để bảo trì.

npm i -D test-proxy-recorder Star trên GitHub Số star trên GitHub

MIT · TypeScript · hoạt động với SSR của Next.js & TanStack Start, SPA & extension Chrome · hỗ trợ WebSocket

REC · MODE=record · local run

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

REPLAY · MODE=replay · CI

200 OK · 3 ms · zero network

Xem nó ghi lại, rồi phát lại

Một lần chạy Playwright ghi các response thật ra đĩa; lật sang phát lại và cùng bộ test đó pass với backend đã tắt — không cần mạng.

Hai bộ ghi lại, một proxy

Request xuất phát từ hai nơi, nên có hai cơ chế ghi lại. Dùng một trong hai — hoặc cả hai cùng lúc. Cả hai đều ghi lại một lần và phát lại từ đĩa, nên CI chạy với backend đã tắt và không cần mock viết tay.

Proxy

.mock.json

SSR của Next.js / TanStack Start → proxy → API thật

Nằm giữa máy chủ của bạn và API. Ghi lại các request phía máy chủ — fetch SSR, route handler, bất cứ thứ gì backend-for-frontend của bạn gọi.

Cho các ứng dụng full-stack nơi máy chủ gọi API.

Xem ví dụ Next.js → Xem ví dụ TanStack Start →

HAR

.har

trình duyệt → HAR intercept → API thật

Chặn ngay trong trình duyệt. Ghi lại các lời gọi fetch phía client, traffic API của extension Chrome, analytics, API bên thứ ba.

Cho SPA, extension, và các ứng dụng chỉ chạy trên trình duyệt.

Xem ví dụ extension Chrome →

Vị trí của nó

Các công cụ mocking giỏi ở những việc khác nhau. Sự kết hợp bên dưới — ghi lại traffic thật trên cả SSR, trình duyệt, và WebSockets, không cần mock viết tay — chính là khoảng trống các công cụ khác để lại.

So sánh tính năng giữa test-proxy-recorder với Playwright routeFromHAR, MSW, Polly.js, playwright-network-cache, và Mocky Balboa.
Tính năng test-proxy-recorder Playwright routeFromHAR MSW Polly.js playwright-network-cache Mocky Balboa
Ghi lại traffic thật Không Không
Phía máy chủ (SSR) Không Một phần Không
Phía trình duyệt
WebSocket Không Không Không Không
Thuần Playwright Không Không
Được bảo trì Không

Polly.js chặn HTTP của Node, nên việc mock SSR có thể thực hiện bên trong tiến trình ứng dụng, nhưng không phải như một phần của lần chạy Playwright. MSW và Mocky Balboa cũng phát lại các response thật — nhưng bạn phải viết mock bằng tay. Khi nào nên chọn thứ khác được trình bày trong tài liệu.

Hoạt động với auth provider thật của bạn

Đăng nhập qua Cognito, Auth0, Clerk, hoặc WorkOS — thật sự, trong mỗi lần chạy. Chỉ API của ứng dụng bạn được ghi lại; auth vẫn trực tiếp, dữ liệu của bạn chuyển sang offline.

// 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' });
});

Thiết lập trong ba bước

Dựng mọi thứ bằng một lệnh, trỏ API của bạn về proxy, rồi ghi lại và commit. Ứng dụng chỉ chạy trên trình duyệt? init sẽ bỏ qua bước SSR giúp bạn.

Đường nhanh nhất: giao cho AI agent của bạn

Sao chép đoạn này, thay URL backend của bạn vào, và dán vào Claude Code, Cursor, hoặc bất kỳ coding agent nào — nó chạy init và hoàn tất việc kết nối từ prompt init in ra.

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.

Hoặc tự kết nối bằng tay:

  1. Cài đặt & dựng khung

    init viết cấu hình proxy, một Playwright fixture, một global teardown, package.json script, và (trên Next.js) kết nối việc gắn thẻ fetch SSR vào root layout của bạn — một cách không phá hoại.

    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. Trỏ API của ứng dụng bạn về proxy

    Điều duy nhất init không thể đoán: biến env nào chứa base URL API của bạn. Trỏ nó về proxy khi recorder được bật, về backend thật trong trường hợp còn lại — proxy không bao giờ chạy trong 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`);

    Trên Next.js, init cũng thêm registerProxyFetch() vào root layout của bạn để gắn thẻ cho các lời gọi fetch phía máy chủ — một no-op trong 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. Ghi lại, commit, phát lại

    Đặt MODE = 'record', chạy một lần dựa trên API thật, rồi lật sang 'replay' và commit. Các bản ghi nằm trong git — đó là điều làm CI tất định. Đừng gitignore chúng.

    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"

Ngừng viết mock bằng tay

API của bạn đã cho sẵn câu trả lời đúng. Hãy ghi lại chúng.

npm i -D test-proxy-recorder Star trên GitHub

Nếu nó giúp bạn tiết kiệm một buổi chiều, một star chỉ mất một giây — đó là cách người tiếp theo tìm thấy nó, và nó báo cho một maintainer độc lập rằng hãy tiếp tục xây dựng. Gặp trục trặc hay có ý tưởng? Mở một issue hoặc tham gia Discord.