프록시
.mock.json Next.js / TanStack Start SSR → 프록시 → 실제 API
서버와 API 사이에 위치합니다. 서버 측 요청(SSR fetch, 라우트 핸들러, BFF(backend-for-frontend)가 호출하는 모든 것)을 기록합니다.
서버가 API를 호출하는 풀스택 앱용.
Next.js 예제 보기 → TanStack Start 예제 보기 →Playwright용 VCR
Playwright 스위트를 로컬에서 실행하는 동안 실제 API 응답을 캡처한 다음, CI에서 바이트 단위 그대로 재생합니다. 백엔드도, 네트워크도, 유지 관리할 직접 작성한 목(mock)도 없습니다.
npm i -D test-proxy-recorder GitHub에서 스타 MIT · TypeScript · Next.js 및 TanStack Start SSR, SPA, Chrome 확장 프로그램과 호환 · WebSocket 지원
REC
saved e2e/recordings/todos.GET.mock.json
REPLAY
200 OK · 3 ms · zero network
한 번의 Playwright 실행으로 실제 응답을 디스크에 기록합니다. 재생으로 전환하면 동일한 스위트가 백엔드를 끈 상태로 통과합니다. 네트워크 없이요.
요청은 두 곳에서 발생하므로 기록 메커니즘도 두 가지입니다. 둘 중 하나를 사용하거나 함께 사용하세요. 둘 다 한 번 기록하고 디스크에서 재생하므로, CI가 백엔드를 끈 상태로, 직접 작성한 목(mock) 없이 실행됩니다.
.mock.json Next.js / TanStack Start SSR → 프록시 → 실제 API
서버와 API 사이에 위치합니다. 서버 측 요청(SSR fetch, 라우트 핸들러, BFF(backend-for-frontend)가 호출하는 모든 것)을 기록합니다.
서버가 API를 호출하는 풀스택 앱용.
Next.js 예제 보기 → TanStack Start 예제 보기 →.har 브라우저 → HAR 가로채기 → 실제 API
브라우저 자체에서 가로챕니다. 클라이언트 측 fetch 호출, Chrome 확장 프로그램 API 트래픽, 분석, 서드파티 API를 기록합니다.
SPA, 확장 프로그램, 브라우저 전용 앱용.
Chrome 확장 프로그램 예제 보기 →목킹 도구들은 각자 다른 작업에 뛰어납니다. 아래 조합(직접 작성한 목(mock) 없이 SSR, 브라우저, WebSocket 전반에서 실제 트래픽을 기록)이 다른 도구들이 남겨 둔 공백입니다.
| 기능 | test-proxy-recorder | Playwright routeFromHAR | MSW | Polly.js | playwright-network-cache | Mocky Balboa |
|---|---|---|---|---|---|---|
| 실제 트래픽 기록 | 예 | 예 | 아니요 | 예 | 예 | 아니요 |
| 서버 측(SSR) | 예 | 아니요 | 예 | 부분 | 아니요 | 예 |
| 브라우저 측 | 예 | 예 | 예 | 예 | 예 | 예 |
| WebSocket | 예 | 아니요 | 예 | 아니요 | 아니요 | 아니요 |
| Playwright 네이티브 | 예 | 예 | 아니요 | 아니요 | 예 | 예 |
| 유지 관리됨 | 예 | 예 | 예 | 아니요 | 예 | 예 |
Polly.js는 Node HTTP를 가로채므로 앱 프로세스 내부에서 SSR 모킹이 가능하지만, Playwright 실행의 일부로는 불가능합니다. MSW와 Mocky Balboa도 실제 응답을 재생하지만, 직접 목(mock)을 작성해야 합니다. 다른 도구를 선택해야 하는 경우는 문서에서 다룹니다.
Cognito, Auth0, Clerk 또는 WorkOS를 통해 실제로, 매 실행마다 로그인하세요. 앱의 API만 기록되며, 인증은 계속 실시간으로 동작하고 데이터는 오프라인으로 재생됩니다.
// 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' });});AWS Cognito 예제 → TanStack Start의 Cognito → 목(mock) 인증(클라우드 계정 불필요) →
한 번의 명령으로 모든 것을 스캐폴딩하고, API를 프록시로 연결한 뒤 기록하고 커밋하세요. 브라우저 전용 앱인가요? init 이 SSR 단계를 대신 건너뜁니다.
이것을 복사하고 백엔드 URL을 바꾼 뒤 Claude Code, Cursor 또는 아무 코딩 에이전트에 붙여넣으세요. 그러면 init 을 실행하고, init 이 출력하는 프롬프트에 따라 나머지 연결 작업을 마무리합니다.
Set up test-proxy-recorder for end-to-end tests in this project, then follow theinstructions 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 — findit yourself from the app's env/config (the URL the app calls in dev); don'tassume 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 atthe proxy in dev/test only, tag server-side fetches (Next.js), add a smoke test,and verify record → replay.또는 직접 연결하기:
init 은 프록시 설정, Playwright 픽스처, 전역 티어다운, package.json 스크립트를 작성하고, (Next.js의 경우) SSR fetch 태깅을 루트 레이아웃에 연결합니다. 비파괴적으로 동작합니다.
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 init 이 추측할 수 없는 유일한 것은 바로 API 기본 URL을 담고 있는 환경 변수입니다. 레코더가 활성화되어 있으면 프록시를, 그렇지 않으면 실제 백엔드를 가리키세요. 프록시는 프로덕션에서 절대 실행되지 않습니다.
// 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`); Next.js의 경우 init 은 또한 루트 레이아웃에 registerProxyFetch() 를 추가하여 서버 측 fetch 호출에 태깅합니다. 프로덕션에서는 아무 동작도 하지 않습니다.
// app/layout.tsx — tag server-side fetches so SSR is recorded/replayedimport { registerProxyFetch } from 'test-proxy-recorder/nextjs';
registerProxyFetch(); // no-op in production unless TEST_PROXY_RECORDER_ENABLED=true MODE = 'record'로 설정하고 실제 API를 대상으로 한 번 실행한 뒤, 'replay' 로 전환하고 커밋하세요. 기록은 git에 보관됩니다. 그것이 CI를 결정적으로 만드는 이유입니다. gitignore에 넣지 마세요.
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();});# 1. Set MODE = 'record' in your test file, run against the real APInpx playwright test --ui # recordings written to e2e/recordings/
# 2. Flip MODE back to 'replay' and commit the recordingsgit add e2e/recordings/git commit -m "add e2e recordings"여러분의 API는 이미 올바른 답을 제공합니다. 기록하기만 하면 됩니다.
npm i -D test-proxy-recorder GitHub에서 스타 오후 시간을 아끼셨다면, 스타는 1초면 충분합니다. 다음 사람이 이 도구를 발견하는 방법이자, 1인 메인테이너에게 계속 만들라는 신호가 됩니다. 막히는 부분이나 아이디어가 있으신가요? 이슈를 열거나 또는 Discord에 참여하세요.