17 KiB
SW 테스트 정합성 개선 — Storybook 회귀 기준선 유지 (2026-10-20)
범위: 테스트 코드와 이 문서만 다룹니다.
@hm-design/sw제품 코드·공개 API·Storybook Story·디자인은 바꾸지 않았습니다. 브랜치fix/test-home-menu-integration, 기준 main553e4df(Mergefeature/sw-package). 과거 QA 증거 폴더는 수정하지 않았습니다. 실행 환경: Node.js 22.23.2 / npm 10.9.8, Chrome 155.0.8059.85(headless), Playwright 1.62.1(Codex 런타임,playwright-runtime.mjs탐색 순서 5번).
1. 결과 요약
같은 storybook-static(Node 22.23.2로 npm run build-storybook, 패키지 build 포함)에서 수정 전 테스트(553e4df 버전)와 현재 테스트를 각각 실행했습니다.
| 테스트 | 수정 전 (553e4df) |
수정 후 (20ed2f2) |
관련 Commit |
|---|---|---|---|
home-menu-integration.browser.mjs |
22/23 (FAIL 1) | 23/23 | 7fd7342 |
overview.browser.mjs |
51/54 (FAIL 3) | 54/54 | 522ecbd, 20ed2f2 |
overview.browser.mjs … overlays |
17/20 (같은 FAIL 3) | 20/20 | 522ecbd, 20ed2f2 |
storybook-unused-removal.browser.mjs |
88/93 (FAIL 5) | 93/93 | 20ed2f2 |
모든 FAIL은 과거 시점 값에 고정된 단언이었고, 기능(브라우저 동작) 실패는 없었습니다. 수정은 단언을 지우거나 건너뛰지 않고, 기준선은 그대로 둔 채 승인된 이후 변경만 명시적으로 허용하는 방식입니다.
2. Home Menu 기존 실패 1건 (7fd7342)
- 실패 항목:
without homeMenu: logo click calls onHomeClick, renders no menu, no aria-expanded - 실제 오류:
sw-header--overview의 로고를 누르자[SWHeader Overview] homeMenuOpen(true, home)이 기록되고 홈 메뉴가 열림. - 원인:
170a5c2(홈 메뉴 Header 통합, 사용자 요청)부터 Overview가homeMenu를 전달합니다(docs/sw/sw-header-usage.md"Overview의 로고도 같은 홈 메뉴"). 테스트가 "homeMenu 없는 Header"의 대상으로 Overview를 계속 열고 있었습니다. - 해결: 대상만
sw-header--logo-slot의 첫 Header(figmaArgs+callbacks,homeMenu없음)로 바꾸고, Callback 판정 문자열을 그 Header의 로그([SWHeader] home)로 맞췄습니다. "메뉴 없음 ·aria-expanded없음 ·onHomeClick만 호출" 단언은 그대로입니다.
3. Overview 기존 실패 3건 (522ecbd, 20ed2f2)
기준선은 50bf5bd와 그 시점의 before-index.json으로 유지합니다.
| 실패 항목(수정 전) | 원인 | 해결 |
|---|---|---|
24 retained Story IDs, names and tags; only approved Dropdown retirements |
이후 승인된 삭제(속성창 5개, 미사용 9개), Popup 이동, verification 태그, 홈 메뉴·통합 개선 Story 추가로 SW/Header가 20개가 됨 |
24개에서 승인된 삭제·이동을 빼고 승인된 태그를 적용한 뒤 승인된 추가 ID를 더한 20개와 ID·이름·태그가 정확히 같아야 PASS. 이동한 Story는 title이 SW/Popup인지 확인 |
retained non-Overview declarations byte-identical |
ResponsiveMore(170a5c2), WindowMoveMotion·KGuide(2b0e1a2) 변경, 미사용 Story 선언 삭제, PropertyPanelCompare의 sw-property-panel.stories.tsx 이동 |
변경 선언은 승인 Commit의 내용과 byte 단위로 같을 때만 허용, 삭제는 승인된 삭제 ID일 때만, 이동 선언은 새 파일에서 승인 Commit 내용과 비교. 그 밖의 선언은 계속 50bf5bd와 동일해야 함 |
package production source untouched except the integrated-improvement files |
50bf5bd 이후 승인되어 main에 병합된 packages/sw/src 변경 |
approvedMainCommit(553e4df)과 비교해 통합 개선 파일 외 차이가 없어야 PASS. 50bf5bd 이후 차이 개수는 sinceBaseline으로 기록만 함 |
20ed2f2에서는 위 목록(태그·추가 ID·승인 선언·이동 선언)을 storybook-inventory.mjs로 옮겨 Overview와 미사용 검사가 같은 목록을 쓰게 했습니다. Overlays 모드는 같은 앞부분 검사를 공유하므로 같은 3건이 함께 해결됩니다.
4. Storybook 미사용 검사 기존 실패 5건 (20ed2f2)
기준선은 c8e5fbe의 full-index-before.json으로 유지합니다.
| 실패 항목(수정 전) | 해결 |
|---|---|
19 -> 10 retained SW/Header Stories, 338 -> 329 total plus only the integrated-improvement Stories |
338 → 329와 19 → 10은 그대로 단언. 이후 추가는 approvedAddedStoryIds(통합 개선·홈 메뉴·Footer·Viewer·Theme)와 정확히 같은 집합일 때만 PASS. 승인되지 않은 추가(unapproved)·누락(missing)을 결과에 기록 |
retained SW IDs, names, titles, tags and order unchanged |
유지 10개의 ID·이름·title·tags·순서를 비교하되, 승인된 verification 태그와 Popup 이동만 반영 |
every non-removed index entry identical (docs and other packages included) |
SW 밖 항목은 값·순서 모두 동일, 유지 SW 항목은 승인 변경만 반영해 동일, SW 블록은 Center Graphic 바로 뒤에 연속(2b0e1a2 storySort) |
retained exports (Stories and ComposedDemo) byte-identical |
변경·추가 Export는 승인 Commit 내용과 같을 때만, 이동 Export는 새 파일에서 비교, 나머지는 c8e5fbe와 동일 |
other packages, Overview, Dropdown CSF, assets and Storybook config untouched |
같은 경로가 approvedMainCommit과 달라서는 안 됨(통합 개선 파일 제외). c8e5fbe 이후 차이는 sinceBaseline으로 기록 |
5. 관련 Commit
| Commit | 내용 | 파일 |
|---|---|---|
7fd7342 |
test(sw): align home menu integration with current stories | home-menu-integration.browser.mjs |
522ecbd |
test(sw): align overview regression checks with approved changes | overview.browser.mjs |
20ed2f2 |
test(sw): align storybook inventory checks with approved changes | storybook-inventory.mjs, overview.browser.mjs, storybook-unused-removal.browser.mjs |
5.1 승인 목록에 반영된 Story 변경 이력
모두 사용자 요청으로 진행되어 main 553e4df에 포함된 Commit입니다(git merge-base --is-ancestor로 확인).
| Commit | 변경 | storybook-inventory.mjs 항목 |
|---|---|---|
50bf5bd |
정리 1단계: Story 5개 삭제 | retiredStage1Ids |
9482d45, c705a1f |
Dropdown 4개 통합, composed-controls → Dropdown(SW/Header 바로 아래) |
retiredDropdownIds, retainedInventory |
c8e5fbe |
속성창 중복 5개 삭제, 4개 비교로 통합 | retiredPropertyPanelIds |
5faa1f1 |
미사용 SW Header 시연 9개 삭제 | retiredUnusedDemoIds |
55179b4, e8409ef |
통합 개선 0.2.0 Story 추가, Options를 SW/Header로 통합 | integratedStoryIds |
170a5c2 등 홈 메뉴 병합 |
SW/Home Menu → SW/Header(home-menu, home-menu-*), Overview·ResponsiveMore 변경 |
homeMenuSidebarIds, movedHomeMenuIds, approvedHeaderDeclarations |
6cf8854, 7f42923, 41e963a |
SW Footer, Viewer, Theme Story 추가 | footerStoryIds, viewerStoryIds, themeStoryIds |
7f42923 |
SW/Tool Story 메뉴 삭제(SWToolButton·SWToolGroup은 공개 유지) |
retiredToolIds |
126a35d |
Footer 기본 Footer·States Story 삭제(전체 Footer 섹션으로 통합) |
retiredFooterIds |
2b0e1a2 |
사이드바 단순화: verification 태그 2개, Property Panel 비교 SW/Popup 이동, 홈 메뉴 Figma 비교·중복 Variant 6개 삭제 |
verificationTaggedIds, movedToPopupIds, movedHeaderDeclarations, retiredHomeMenuCompareIds |
6. 변조 검증
수정한 단언이 "무조건 PASS"가 아닌지 확인하려고 현재 테스트(20ed2f2)에 일부러 승인되지 않은 변경을 넣고 실행한 뒤 원상 복구했습니다. 복구는 백업 파일로 했고 매번 git diff가 비어 있음(소스) 또는 index.json SHA-256 일치(빌드 산출물)를 확인했습니다.
6.1 Story 목록 변조 (storybook-static/index.json, 재빌드 없음)
| 시나리오 | Overview | Overlays | 미사용 검사 | Home Menu |
|---|---|---|---|---|
| 승인되지 않은 SW/Header Story 추가 | 53/54 — 목록 검사 FAIL | 19/20 — 목록 FAIL | 31/34 — 개수·전체 항목 FAIL, 가짜 Story 렌더 중단 | 23/23 (목록 비검사) |
유지 Story(logo-slot) 삭제 |
53/54 — 목록 FAIL | 19/20 — 목록 FAIL | 89/92 — 개수·유지 항목·전체 항목 FAIL | 중단(Logo Slot Header 대기 시간 초과) |
유지 Story에 verification 태그 추가 |
53/54 | 19/20 | 91/93 — 유지 항목·전체 항목 FAIL | 23/23 |
유지 Story(document-dropdown) title 이동 |
53/54 | 19/20 | 90/92 — 유지 항목·전체 항목 FAIL | 23/23 |
유지 Story(responsive-more) 이름 변경 |
53/54 | 19/20 | 91/93 — 유지 항목·전체 항목 FAIL | 23/23 |
6.2 소스 변조 (작업 트리, 재빌드 없음, 한 번에 4건)
| 변조 | 검출 |
|---|---|
유지 선언 LogoSlot의 섹션 제목 변경 |
Overview·Overlays 선언 검사 FAIL(LogoSlot), 미사용 검사 Export 검사 FAIL(changed: LogoSlot) |
승인 선언 ResponsiveMore(170a5c2)를 승인 내용과 다르게 변경 |
같은 두 검사에서 ResponsiveMore FAIL — 승인 목록은 Commit 내용에 고정되며 와일드카드가 아님 |
통합 개선 목록 밖 패키지 파일(sw-footer/SWFooterParts.tsx) 변경 |
Overview·Overlays 소스 검사 FAIL(unapproved), 미사용 검사 경로 검사 FAIL |
.storybook/main.ts 변경 |
미사용 검사 경로 검사 FAIL(unexpected). Overview는 이 경로를 원래 검사하지 않음 |
결과: Overview 52/54, Overlays 18/20, 미사용 검사 91/93, Home Menu 23/23. 다른 검사는 그대로 PASS였습니다.
6.3 동작 변조 (Story 수정 후 재빌드)
sw-header--logo-slot 첫 Header에 homeMenu={{ sections: OVERVIEW_HOME_MENU }}를 임시로 넣고 Storybook을 다시 build했습니다. Home Menu는 22/23으로 without homeMenu: logo click calls onHomeClick, renders no menu, no aria-expanded만 FAIL(로고 클릭 시 onHomeClick 기록 없음)이었습니다. 원본으로 되돌린 뒤 다시 build했고, 그 빌드에서 §7을 실행했습니다.
7. 회귀 테스트 결과 (Node 22.23.2, 수정 후)
| 테스트 | 결과 |
|---|---|
npm run build-storybook(prebuild: theme defaults 확인, 5개 패키지 build) |
PASS |
home-menu-integration |
23/23 |
overview |
54/54 |
overview … overlays |
20/20 |
storybook-unused-removal |
93/93 |
npm run check:ai-docs |
PASS (2 shared files × 4 packages, catalog·링크 일치) |
node packages/sw/tests/ai-docs.check.mjs |
46/46 |
같은 빌드에서 이번 범위 밖의 기존 테스트 4종은 아직 과거 기준으로 실패합니다(§10).
8. Story 추가·삭제·이동 시 승인 목록 관리
승인 목록은 packages/sw/tests/storybook-inventory.mjs 하나에서 관리합니다. Story 변경을 사용자가 승인한 같은 변경(또는 바로 뒤 테스트 정렬 변경)에서 아래 목록을 갱신하고, 각 항목 옆 주석에 승인 Commit과 사유를 적습니다. 값은 실제 Story ID·선언 이름·Commit SHA(전체 40자)만 씁니다.
| 변경 | 갱신할 항목 |
|---|---|
| SW Story 추가 | 해당 영역 목록(footerStoryIds, viewerStoryIds, themeStoryIds, homeMenuSidebarIds, integratedStoryIds 등)에 ID 추가 → approvedAddedStoryIds에 자동 포함. 새 영역이면 새 목록을 만들고 approvedAddedStoryIds에 연결 |
| SW Story 삭제 | retired…Ids 목록에 ID 추가(예: retiredFooterIds, retiredHomeMenuCompareIds), 추가 목록에서 제외되는지 확인. sw-header.stories.tsx의 Story를 지우면 Overview 선언 검사는 retiredPropertyPanelIds·retiredUnusedDemoIds의 삭제만, 미사용 검사의 Export 검사는 그 스크립트의 removedExports 9개만 허용하므로 새 삭제는 두 검사도 함께 갱신해야 함 |
| Story 이동(title 변경, ID 유지) | movedToPopupIds 같은 이동 목록과 withApprovedEntryChanges의 변환(title·importPath), 선언이 다른 파일로 가면 movedHeaderDeclarations(새 파일, 승인 Commit) |
태그 변경(verification 등) |
verificationTaggedIds(또는 해당 변환을 withApprovedEntryChanges에 추가) |
sw-header.stories.tsx 선언 변경·추가 |
approvedHeaderDeclarations에 선언 이름: 승인 Commit. 검사는 현재 선언이 그 Commit의 내용과 byte 단위로 같은지 봄 |
| Story ID 변경 | ID 변경은 삭제 + 추가로 다룸(이전 ID는 retired…, 새 ID는 추가 목록). 승인 없이 ID를 바꾸지 않음 |
원칙:
- 승인되지 않은 Story·제품 소스 변경을 목록에 넣어 테스트를 통과시키지 않습니다. 목록은 사용자 승인 기록입니다.
- 기준선 파일(
before-index.json,full-index-before.json)과 과거 QA 폴더는 고치지 않습니다. 새 실행은 항상 새 증거 폴더에 저장합니다(기본 경로로 실행하면 일부 스크립트가 과거 증거를 덮어씀). - 목록을 바꾼 뒤에는 Storybook을 다시 build하고 Overview(두 모드)·미사용 검사를 실행해 PASS를 확인합니다. 가능하면 §6.1처럼 가짜 Story 하나를 넣어 FAIL이 나는지도 확인합니다.
9. 향후 main 병합 시 기준 갱신 절차
approvedMainCommit은 "Story와 제품 소스 변경이 모두 승인된 main 병합"을 가리키며, Overview·미사용 검사는 보호 경로(Overview: packages/sw/src, 미사용 검사: SW ai/package 파일, 다른 패키지, Overview, Dropdown CSF, assets, .storybook)가 이 Commit과 같아야 PASS입니다(통합 개선 파일 제외). 역할과 갱신 조건은 같은 파일의 주석에도 적었습니다.
자동 변경 금지: main에 새 HEAD가 생겼다는 이유만으로
approvedMainCommit을 바꾸지 않습니다. 이 값을 자동으로 갱신하는 스크립트·Workflow는 없으며, 아래 절차를 거친 검토된 테스트 전용 Commit에서만 바뀝니다. 현재 값은553e4df(553e4df4a865aaf6514b1c2b86cb2e3e9a658e5f)이며 이 문서 작성 시점에 변경하지 않았습니다.
- 병합할 브랜치의 Story·제품 소스 변경이 Commit 단위로 모두 사용자 승인을 받았는지 확인합니다. 승인되지 않은 변경이 있으면 기준을 옮기지 않습니다.
- 병합 전 브랜치에서 §8의 승인 목록을 갱신하고, 테스트가 PASS인지 확인합니다.
- main에 병합합니다. Squash·Rebase 병합이면 SHA가 바뀌므로
approvedHeaderDeclarations·movedHeaderDeclarations의 Commit을 main에 실제로 들어간 SHA로 다시 맞춥니다. - 병합 Commit의 전체 SHA로
approvedMainCommit을 바꾸는 테스트 전용 Commit을 만듭니다. 이 Commit은 보호 경로를 건드리지 않습니다. - Node 22.23.2에서
npm run build-storybook후 Home Menu, Overview(두 모드), 미사용 검사를 새 증거 폴더로 실행합니다. 하나라도 FAIL이면 기준을 옮기지 말고 원인(미승인 변경 또는 목록 누락)을 확인합니다. - 실행 결과와 갱신 사유를
docs/sw/의 보고서에 남깁니다. 기존 보고서와 증거는 고치지 않습니다.
10. 남은 문제
- 이번 범위 밖 기존 테스트 4종은 같은 빌드에서 과거 기준으로 실패합니다(수정 전 측정, 이 Commit에서 고치지 않음):
dropdown-consolidation223/228(목록·선언·경로 5건),storybook-cleanup-stage129/34(목록·선언·경로 4건 + 삭제된sw-header--dynamic-controls에서 중단),detail-buttons verify(삭제된sw-header--composition에서 중단),property-panel-comparison verify50/52(목록 2건) 후 삭제된sw-header--property-panel에서 예외 종료. 별도 작업으로 다룹니다. - 통합 개선 파일 예외: Overview·미사용 검사는
integratedChangedFiles가approvedMainCommit과 달라도 허용합니다(그 파일은 통합 개선 suite가 검증). 그 suite를 함께 실행하지 않으면 이 파일들의 미승인 변경은 두 검사로는 드러나지 않습니다. - 과거 QA 폴더를 기본 증거 경로로 쓰는 스크립트가 있습니다. 반드시 새 증거 폴더를 지정해야 합니다.
11. 재현
npm run build-storybook
node packages/sw/tests/home-menu-integration.browser.mjs <새 폴더>/home
node packages/sw/tests/overview.browser.mjs <before-index.json을 복사한 새 폴더>
node packages/sw/tests/overview.browser.mjs <before-index.json을 복사한 새 폴더> overlays
node packages/sw/tests/storybook-unused-removal.browser.mjs <새 폴더>/unused
npm run check:ai-docs
node packages/sw/tests/ai-docs.check.mjs
Overview는 증거 폴더의 before-index.json을 읽으므로 docs/sw/storybook-overview-qa/before-index.json을 새 폴더에 복사한 뒤 실행합니다. 이번 실행의 결과 JSON·로그는 저장소 밖 임시 폴더에 두었고(*.log는 Git 제외 대상), 주요 수치는 위 표에 옮겼습니다.