9. 검증
시작 상태
섹션 제목: “시작 상태”test -s docs/review.md && git status --shortnpm test && npm run e2e; echo "exit=$?"8단계 리뷰 기록 docs/review.md가 있고 커밋되어 있어야 합니다. 첫 줄은 아무것도 찍히지
않아야 하고, exit=0이어야 합니다. 아니면 8. 코드 리뷰로 돌아갑니다.
이 단계에서 하는 것
섹션 제목: “이 단계에서 하는 것”요구 하나(“긴 텍스트를 붙여도 카운터가 화면 밖으로 밀리지 않는다”)를 jsdom 테스트와 Playwright 두 방식으로 각각 검증해 무엇이 잠기고 무엇이 잠기지 않는지 봅니다. 그다음 준비에서 등록한 Playwright MCP로 같은 화면을 열어 설명에 쓸 스크린샷과 좌표 값을 따로 만듭니다. jsdom이 원리적으로 잠글 수 없는 것은 Test가, 실제 픽셀을 재는 방법은 E2E와 Visual Verification이 다룹니다.
따라하기
섹션 제목: “따라하기”- jsdom으로 먼저 시켜 봅니다.
"긴 텍스트(5000자)를 입력해도 카운터가 뷰포트 밖으로 밀리지 않는다"를 Vitest(jsdom) 테스트로 써 주세요. 구현은 바꾸지 마세요.-
나온 테스트 코드를 읽고 무엇을 assert하는지 봅니다. assert 대상이 요소 존재나 클래스 여부에 머무는 경우가 많습니다. 실제 픽셀 위치를 확인하는 assertion이 있는지 봅니다. jsdom이 그것을 잠글 수 없는 이유는 Test가 다룹니다. 이 테스트를 지우거나, 이름을 실제로 잠근 것으로 바꿉니다. 예를 들어 요소 존재만 확인하는 테스트라면 이름을 “카운터 요소가 DOM에 존재한다”처럼 정직하게 고칩니다.
-
Playwright로 실제 값을 잽니다.
e2e/count-visible.spec.ts:
import { test, expect } from '@playwright/test';
test('5000자 입력 후 카운터 전체가 뷰포트 안에 있다', async ({ page }) => { await page.goto('/'); await page.locator('textarea').fill('가'.repeat(5000)); await expect(page.getByTestId('count')).toBeVisible(); const box = await page.getByTestId('count').boundingBox(); const viewport = page.viewportSize(); expect(box).not.toBeNull(); expect(viewport).not.toBeNull(); expect(box!.x).toBeGreaterThanOrEqual(0); expect(box!.y).toBeGreaterThanOrEqual(0); expect(box!.x + box!.width).toBeLessThanOrEqual(viewport!.width); expect(box!.y + box!.height).toBeLessThanOrEqual(viewport!.height); await page.screenshot({ path: 'e2e/long-text.png', fullPage: true });});npm run e2e- 이 테스트의 탐지 능력도 확인합니다.
fill직후에 아래 코드를 임시로 넣어 실행합니다.position을 left/right/top/bottom으로 바꿔 가며 네 번 실행하면 모두 실패해야 합니다. 이 코드를 지우면 다시 통과해야 합니다. 테스트 전용 주입은 커밋하지 않습니다.
const position = 'bottom'; // left, right, top, bottom 각각 실행const displacement: Record<string, string> = { left: 'left:-10000px;top:0', right: 'left:10000px;top:0', top: 'left:0;top:-10000px', bottom: 'left:0;top:10000px',};await page.addStyleTag({ content: `[data-testid="count"] { position:fixed !important; ${displacement[position]} }`,});- 설명에 쓸 스크린샷과 좌표 값은 Playwright MCP로 따로 만듭니다. 준비에서 등록한 그
서버입니다.
npm run dev를 띄워 둔 채로 시킵니다.
Playwright로 http://localhost:5173 을 열고 textarea에 5000자를 입력해 주세요.그 상태에서 전체 페이지 스크린샷을 long-text-mcp.png 로 저장하고 저장된 절대 경로를 알려 주세요.그리고 data-testid="count" 요소의 getBoundingClientRect() 값을 읽어 그대로 보여 주세요.저장 경로는 세션 cwd이거나 서버의 출력 디렉터리일 수 있습니다.
준비: 브라우저 도구에서 확인한 그
동작입니다. 알려 준 경로에서 파일을 찾아 e2e/long-text-mcp.png로 옮깁니다. 이미지를
프롬프트에 올리는 세 가지 방법은 활용 팁의
이미지 첨부 절에 있습니다.
판단은 여전히 3번 e2e 테스트의 boundingBox assertion이 합니다. MCP가 돌려준 사각형
값과 스크린샷은 결과를 사람에게 설명할 때 붙이는 자료입니다. 두 값이 어긋나면
뷰포트 크기 가정부터 봅니다. MCP 브라우저와 Playwright 러너의 뷰포트는 같지
않습니다.
-
끝 비용과 컨텍스트 사용률을 읽어
docs/tutorial-log.md의 “9. 검증” 행에 적습니다. 메모 열에는 2번에서 읽은 “jsdom 테스트가 원래 무엇을 assert했는가”를 한 줄로 적습니다. -
테스트와 기록표를 함께 커밋합니다.
git add -A가 기록표와 스크린샷 두 장(e2e/long-text.png,e2e/long-text-mcp.png)을 함께 담습니다. 이 튜토리얼은 스크린샷을 저장소에 남기는 쪽을 택합니다. 스크린샷이 커밋에 붙어 있으면 11단계 핸드오프에서 다시 열어 볼 수 있기 때문입니다.
git add -A && git commit -m "test: 카운터 위치 e2e 검증"완료 확인
섹션 제목: “완료 확인”npm run e2e; echo "e2e exit=$?"고정 뷰포트에서 네 방향 결함 주입이 각각 실패하는 것은 4번에서 확인한 사실입니다. 이
블록은 주입을 제거한 상태를 확인하는 것이므로 e2e exit=0이어야 합니다. jsdom 테스트의
이름은 2번에서 확인한 실제 assertion과 일치해야 합니다.
계측 기록
섹션 제목: “계측 기록”값은 6번에서 이미 적었습니다. 시작 상태를 확인한 직후 시작 비용을, 커밋 직전에 끝 비용과 컨텍스트 사용률을 각각 적고 차액으로 읽습니다. 세션 수는 이 단계에서 연 세션 개수입니다. 5번의 MCP 호출이 사용률을 얼마나 움직였는지도 함께 보십시오.
어긋났을 때
섹션 제목: “어긋났을 때”- e2e가 통과하는데 실제로는 밀리면 뷰포트 크기 가정을 확인합니다. 측정값을 믿을 수 없을 때가 이 경우를 다룹니다.
- 스크린샷 파일이 비어 있으면 브라우저 자동화가 어긋날 때를 확인합니다.
- jsdom 테스트가 구현 전부터 초록이었으면 검사는 통과하는데 실제로는 깨져 있을 때를 확인합니다.