C.W.K.
Stream
Lesson 03 of 04 · published

Codegen, Headed 모드, page.pause

~15 min · playwright-setup, codegen, debug

Level 0테스트 호기심
0 XP0/32 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Codegen 은 draft. Headed 모드는 관찰. `page.pause` 는 테스트 안에 앉게 해줘."

Codegen — Draft 녹화

npx playwright codegen http://localhost:3000 가 윈도우 두 개 열어: URL 가리키는 실제 브라우저, 그리고 클릭하면 코드 뽑는 Inspector side panel. 흐름은: 테스트하고 싶은 사용자 여정 클릭; 생성된 코드를 spec 파일에 복사; 정리.

'정리' 는 필수. 생성된 코드는 장황하고, 괜찮지만 훌륭하진 않은 selector 골라 (role + name 이 더 잘 살아남는데 CSS 클래스 잡아), Inspector 의 'Assert visibility' / 'Assert text' 버튼으로 녹화하기 전엔 단언이 없어. Codegen 을 draft 생성기로 다뤄: 70% 가져다 주고, 마지막 30% 가 테스트를 유지 가능하게 만드는 부분이야.

Headed 모드 — 일어나는 거 관찰

Default 테스트 run 은 headless — 보이는 브라우저 없음. --headed 가 브라우저 윈도우 보여줘서 테스트가 운전하는 거 실시간으로 봐. 윈도우 셋 동시 피하려 --project=chromium 와 짝지어, 그리고 --slowMo=500 으로 각 액션을 500 밀리초로 느리게 해서 실제로 뭐 일어나는지 봐.

Headed 모드는 단일 테스트 디버깅용이지 routine run 용이 아냐. 느리지만 (병렬 없음, 수동 관찰), trace viewer 가 명확히 안 만드는 방식으로 테스트 실패할 때 무가치해.

--debug — 스텝 스루 모드

npx playwright test --debug 가 Playwright Inspector 열어 — 테스트 돌기 전에 일시 정지하고, 액션 하나씩 스텝 스루하게 하고, 커서 아래 locator 보여주고, REPL 에서 새 selector 실험하게 해주는 UI. Playwright 가 제공하는 가장 효율적 디버그 루프.

테스트 안에서 어느 라인에서든 await page.pause() 할 수도 있어. 테스트 일시 정지, Inspector 열림, 그 지점부터 스텝 스루. Pause-and-inspect 패턴이 console.log 의 현대적 대등물.

Codegen 은 첫 draft 용. Trace viewer 는 실패 조사용. `page.pause` 는 라이브 실험용. 도구 셋, 일 셋 — 하나로 다 하려 하지 마.

Inspector 의 숨겨진 힘

Inspector (codegen 과 --debug 로 열림) 에 툴바에서 안 명확한 기능 있어:

  • 'Pick locator' — 브라우저의 어느 element 든 hover, 그것의 가장 좋은 Playwright selector 봐.
  • 'Explore' — locator (page.getByRole('button')) 타이핑하고 실시간으로 어느 element 가 매칭되는지 브라우저에서 하이라이트로 봐.
  • 'Assert' 버튼 — Inspector 가 너의 인터랙션에서 expect(...).toBeVisible() / toHaveText() 생성.

Headed 모드 실패 패턴

테스트가 신비롭게 실패하면 headed 모드 + slowMo + page.pause 가 진단. 실패 라인 바로 전에 await page.pause() 추가, --debug 로 돌리고, 스텝 스루, 현실이 가정에서 어디서 발산했는지 봐. 이해되면 pause 제거하고 테스트 (또는 코드) 고쳐.

Code

Codegen — 인터랙션 녹화, 코드 얻기·bash
# Codegen — record a test by clicking
npx playwright codegen http://localhost:3000

# Codegen against a specific viewport (useful for mobile UI)
npx playwright codegen --device='Pixel 5' http://localhost:3000

# Codegen + save directly to a file
npx playwright codegen --target=playwright-test \
  --output=e2e/login.spec.ts \
  http://localhost:3000
전 vs 후 — codegen 출력과 정리·typescript
// Generated by codegen — what it actually looks like (before cleanup)
import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('http://localhost:3000/');
  await page.getByRole('link', { name: 'Sign in' }).click();
  await page.getByLabel('Email').click();
  await page.getByLabel('Email').fill('user@example.com');
  await page.getByLabel('Password').click();
  await page.getByLabel('Password').fill('password123');
  await page.getByRole('button', { name: 'Submit' }).click();
  await expect(page.getByText('Welcome back, user')).toBeVisible();
});

// Cleanup pass — name it, group it, remove redundant clicks
test('signs in with valid credentials', async ({ page }) => {
  await page.goto('/');

  await page.getByRole('link', { name: 'Sign in' }).click();
  await page.getByLabel('Email').fill('user@example.com');
  await page.getByLabel('Password').fill('password123');
  await page.getByRole('button', { name: 'Submit' }).click();

  await expect(page.getByText('Welcome back, user')).toBeVisible();
});
Headed + slowMo + --debug — 로컬 디버그 루프·bash
# Headed mode — watch the browser
npx playwright test --headed --project=chromium

# Slow it down so you can actually see
npx playwright test --headed --project=chromium --slowMo=500

# Debug mode — Inspector pauses before each action, step through
npx playwright test --debug

# Debug a single test
npx playwright test e2e/login.spec.ts -g 'signs in' --debug
page.pause — breakpoint 의 현대적 대등물·typescript
// page.pause() — drop a breakpoint inside a test
import { test, expect } from '@playwright/test';

test('something tricky', async ({ page }) => {
  await page.goto('/dashboard');
  await page.getByRole('button', { name: 'Open settings' }).click();

  await page.pause();   // ← pauses here when run with --debug
                        //   Inspector opens; you can step, try selectors,
                        //   inspect DOM state.

  await page.getByRole('switch', { name: 'Dark mode' }).check();
  await expect(page.locator('html')).toHaveClass(/dark/);
});

// Run with: npx playwright test --debug -g 'something tricky'
// Remember to remove page.pause() before commit.

External links

Exercise

앱에서 작은 흐름 골라 (로그인, 아이템 추가, 폼 submit). codegen 으로 녹화. 출력을 spec 파일에 복사. 이제 정리: 테스트에 진짜 이름, 중복 클릭 제거 (codegen 은 종종 fill 전에 클릭 — fill 만으로 충분), expect(...).toBeVisible() 로 최소 한 단언 추가. --headed --slowMo=300 으로 한 번 돌려 확인. 그 다음 정상 실행.
Hint
Codegen 이 brittle selector (자동 생성된 클래스명 가진 긴 CSS path) 고르면, Inspector 일시 정지, 같은 element hover, 'Pick locator' 로 role/name 버전 찾아. CSS selector 를 더 깔끔한 걸로 교체.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.