Skip to content

E2E Smoke Troubleshooting Checklist ​

이 체크리스트는 소비 포털의 GitHub Actions E2E smoke test가 실패했을 때 담당자가 처음부터 끝까지 따라가는 실행 절차다. 각 단계의 결과를 기록하면서 진행하고, 원인이 확인되기 전에는 timeout이나 assertion을 임의로 약화하지 않는다.

0. 실패 정보 기록 ​

  • [ ] GitHub Actions 실행 URL을 기록했다.
  • [ ] 실패한 commit SHA가 조사 대상 commit과 같은지 확인했다.
  • [ ] 실패한 job과 step을 확인했다.
    • [ ] Install dependencies
    • [ ] Install Playwright browser
    • [ ] Typecheck
    • [ ] Build production bundle
    • [ ] Run consumer portal E2E smoke
  • [ ] 실패한 테스트 이름과 assertion 문구를 기록했다.
  • [ ] 재시도 중 우연히 통과한 것이 아닌지 확인했다.

설치 단계에서 실패하면 E2E 테스트 문제가 아니다. private package 인증, Node/pnpm 버전, lockfile을 먼저 확인한다.

1. CI artifact 확보 ​

E2E step이 실패한 경우 GitHub Actions 실행 화면에서 다음 artifact를 다운로드한다.

  • [ ] playwright-report를 다운로드했다.
  • [ ] playwright-test-results를 다운로드했다.
  • [ ] 실패 screenshot을 확인했다.
  • [ ] video가 있으면 마지막 동작 전후 화면을 확인했다.
  • [ ] trace.zip을 확인했다.
  • [ ] build 결과가 필요하면 consumer-portal-dist를 다운로드했다.

Trace를 열 때:

bash
pnpm exec playwright show-trace path/to/trace.zip

Trace Viewer에서:

  • [ ] 실패한 action 직전의 DOM을 확인했다.
  • [ ] 실패 순간의 screenshot을 확인했다.
  • [ ] Console 탭에 React, hydration, Ant Design 오류가 없는지 확인했다.
  • [ ] Network 탭에 JS/CSS 404 또는 chunk loading failure가 없는지 확인했다.
  • [ ] 현재 URL과 viewport를 확인했다.

2. 로컬 재현 환경 준비 ​

bash
export NODE_AUTH_TOKEN="<GitHub Packages read token>"
pnpm install
pnpm exec playwright install chromium

CI와 같은 순서로 실행한다.

bash
CI=1 pnpm run check
CI=1 pnpm run build
CI=1 pnpm run e2e:smoke
  • [ ] NODE_AUTH_TOKEN이 설정되어 있다.
  • [ ] token에 GitHub Packages read 권한이 있다.
  • [ ] Node.js 버전이 CI와 같은 22인가?
  • [ ] pnpm 버전이 workflow와 같은 10.4.1인가?
  • [ ] Playwright Chromium이 설치되어 있는가?
  • [ ] 변경하지 않은 clean working tree에서 재현했는가?

특정 테스트만 재현할 때:

bash
pnpm exec playwright test e2e/portal-foundation.smoke.spec.ts -g "renders the shared shell"
pnpm exec playwright test e2e/portal-foundation.smoke.spec.ts -g "theme controls"
pnpm exec playwright test e2e/portal-foundation.smoke.spec.ts -g "direct navigation"

화면을 직접 보면서 조사할 때:

bash
pnpm exec playwright test --headed
PWDEBUG=1 pnpm exec playwright test e2e/portal-foundation.smoke.spec.ts

3. 실패 유형별 빠른 분류 ​

증상먼저 확인할 것다음 조치
401 UnauthorizedNODE_AUTH_TOKEN, packages: readpackage 인증 수정
TypeScript export 오류@hohyun94/portal-foundation version과 public exportpackage API 호환성 수정
Build 실패Vite output과 missing assetbuild 로그와 import 수정
heading이 hidden.pf-shell, .pf-shell-main geometryscreenshot과 computed style 확인
/admin URL 실패click, pushState, route fallbacknavigation과 hosting 설정 확인
dark mode 실패html.dark, data-portal-modePortalThemeProvider와 policy 확인
console/page errortrace Console 탭최초 runtime error부터 수정
간헐적 timeoutrace, animation, server readiness상태 기반 wait로 변경

4. 화면이 렌더링되지 않을 때 ​

  • [ ] page.goto("/") 이후 최종 URL을 확인했다.
  • [ ] 대상 heading이 DOM에 존재하는지 확인했다.
  • [ ] 대상 element의 display, visibility, opacity를 확인했다.
  • [ ] 대상 element의 width와 height가 0이 아닌지 확인했다.
  • [ ] 부모 .pf-shell, .pf-shell__body, .pf-shell-main, .pf-shell-main__inner의 geometry를 확인했다.
  • [ ] Ant Design runtime CSS가 Portal Foundation layout을 덮어쓰지 않는지 확인했다.
  • [ ] console error와 page error를 함께 수집했다.

임시 진단용 snippet:

ts
const details = await page.getByRole("heading", { name: /공통 기반이 준비되었습니다/ }).evaluate(element => {
  const style = getComputedStyle(element);
  const rect = element.getBoundingClientRect();
  return {
    display: style.display,
    visibility: style.visibility,
    opacity: style.opacity,
    width: rect.width,
    height: rect.height,
    parent: element.parentElement?.className,
  };
});
console.log(details);
  • [ ] 진단 후 임시 console.log를 제거했다.

5. 클릭과 navigation이 실패할 때 ​

  • [ ] locator가 semantic role과 accessible name을 사용하는지 확인했다.
  • [ ] locator가 실제 DOM에서 unique한지 확인했다.
  • [ ] 버튼이 visible하고 enabled인지 확인했다.
  • [ ] click 전후 URL을 기록했다.
  • [ ] window.history.pushState 이후 React state가 갱신되는지 확인했다.
  • [ ] /admin 직접 진입도 별도로 확인했다.
  • [ ] production hosting이 /admin을 index.html로 fallback하는지 확인했다.
  • [ ] browser back/forward가 필요한 앱이라면 해당 동작도 확인했다.

권장 assertion:

ts
await expect(page.getByRole("button", { name: "메뉴 관리 열기" })).toBeVisible();
await page.getByRole("button", { name: "메뉴 관리 열기" }).click();
await expect(page).toHaveURL(/\/admin$/);
await expect(page.getByRole("heading", { name: "메뉴 관리" })).toBeVisible();

6. Theme 전환이 실패할 때 ​

  • [ ] 사용자 설정 popup을 열었다.
  • [ ] 다크 control이 visible하고 enabled인지 확인했다.
  • [ ] html.dark class를 확인했다.
  • [ ] html[data-portal-mode="dark"]를 확인했다.
  • [ ] PortalThemeProvider가 PortalShell보다 상위에 있는지 확인했다.
  • [ ] applicationPolicy.allowDarkMode가 false가 아닌지 확인했다.
  • [ ] forced theme 정책이 dark 선택을 막고 있지 않은지 확인했다.
  • [ ] localStorage 또는 storage adapter가 이전 theme을 덮어쓰지 않는지 확인했다.
bash
pnpm exec playwright test e2e/portal-foundation.smoke.spec.ts -g "theme controls"

7. Console, hydration, Modal 오류가 있을 때 ​

  • [ ] 첫 번째 console error부터 조사했다.
  • [ ] 마지막에 표시된 연쇄 오류만 보고 원인을 판단하지 않았다.
  • [ ] React hydration mismatch가 있는지 확인했다.
  • [ ] SSR render에서 window, document, localStorage를 직접 참조하지 않는지 확인했다.
  • [ ] Modal portal이 SSR에서 열리지 않는지 확인했다.
  • [ ] client mount 후 Modal open 상태가 안정적인지 확인했다.
  • [ ] focus가 Modal input으로 이동하는지 확인했다.
  • [ ] cancel 또는 Escape 후 trigger로 focus가 돌아오는지 확인했다.

8. 실패를 수정한 뒤 ​

  • [ ] 실패한 단일 테스트가 통과한다.
  • [ ] 전체 pnpm run e2e:smoke가 통과한다.
  • [ ] pnpm run check가 통과한다.
  • [ ] pnpm run build가 통과한다.
  • [ ] browser console error가 없다.
  • [ ] page error가 없다.
  • [ ] desktop viewport에서 통과한다.
  • [ ] 필요 시 mobile viewport에서도 통과한다.
  • [ ] trace, screenshot, video가 실패 결과로 더 이상 생성되지 않는다.
  • [ ] 임시 page.pause(), console.log, broad timeout을 제거했다.
  • [ ] locator를 지나치게 넓히거나 assertion을 toBeAttached()로 약화하지 않았다.
  • [ ] 변경 이유와 검증 결과를 PR에 기록했다.

9. 최종 보고 템플릿 ​

문제 해결 후 PR 또는 Slack 보고에 다음 내용을 남긴다.

text
[ E2E smoke 장애 처리 결과 ]

- 실패 테스트:
- 실패 commit:
- 재현 명령:
- 원인:
- 수정 파일:
- 수정 내용:
- 로컬 check:
- 로컬 build:
- 전체 E2E:
- CI 실행 URL:
- 추가 확인 필요:

관련 문서 ​