E2E 준비는 API로 하고, 화면은 흐름마다 한 번만 지난다
가입·만들기처럼 앞 단계에 필요한 사정은 화면을 열기 전에 API로 깔고 쿠키를 브라우저 맥락에 옮긴다.
E2E 시험이 저마다 가입 화면부터 지나가면 느리고, 앞 화면의 작은 변화에 시험 전체가 같이 깨진다. 화면을 연 다음에 데이터를 깔면 새로고침도 한 번 더 든다.
화면 흐름마다 시험을 하나 두고, 그 흐름 앞까지는 API로 준비한다. 가입·만들기 화면은 그 화면을 덮는 시험 하나에서만 화면으로 지난다. 준비 요청은 Node fetch로 보내고, 받은 쿠키를 Playwright 맥락에 옮긴 뒤에 화면을 연다.
import { test } from '@playwright/test';
test('첫 화면에서 캐릭터를 고른다', async ({ browser, baseURL }) => {
const res = await fetch(`${baseURL}/api/signup`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ name: `user-${Date.now()}` }),
});
const [pair] = res.headers.getSetCookie()[0].split(';');
const [name, value] = pair.split('=');
const context = await browser.newContext();
await context.addCookies([{ name, value, url: baseURL! }]);
const page = await context.newPage();
await page.goto('/home');
// ... 이 흐름에서 확인할 것만
await context.close();
});
같이 챙길 것:
globalSetup에서 시험과 같은 길(가입 → 첫 화면)을 한 번 지나 서버를 데운다. 안 하면 첫 시험이 첫 호출 비용을 혼자 진다(가입이 첫 번째에 0.5초, 그 뒤로 0.15초).- 화면은 개발 서버가 아니라 빌드본(
vite preview등)으로 띄워 모듈 변환을 기다리지 않는다. - 외부 글꼴·분석 스크립트는
context.route(...)에서abort()하고, 연출 애니메이션은reducedMotion: 'reduce'로 끈다. workers를 CI와 같은 비율로 정해 둔다. 정하지 않으면 호스트 코어 수만큼 띄워 시험마다 20~30초로 부푼다.- 여럿이 같이 쓰는 서버에서 「목록 전체 개수」를 단언하면 흔들린다. 고유 이름을 붙여 내 것만 센다.