docs(sw): document storybook regression baseline maintenance
This commit is contained in:
1 parent
20ed2f2afb
commit
96f7a846cb
2 files changed
+180
No files matched your search
@@ -0,0 +1,169 @@
|
||||
# SW 테스트 정합성 개선 — Storybook 회귀 기준선 유지 (2026-10-20)
|
||||
|
||||
> 범위: 테스트 코드와 이 문서만 다룹니다. `@hm-design/sw` 제품 코드·공개 API·Storybook Story·디자인은 바꾸지 않았습니다.
|
||||
> 브랜치 `fix/test-home-menu-integration`, 기준 main `553e4df`(Merge `feature/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`)이며 이 문서 작성 시점에 변경하지 않았습니다.
|
||||
|
||||
1. 병합할 브랜치의 Story·제품 소스 변경이 Commit 단위로 모두 사용자 승인을 받았는지 확인합니다. 승인되지 않은 변경이 있으면 기준을 옮기지 않습니다.
|
||||
2. 병합 전 브랜치에서 §8의 승인 목록을 갱신하고, 테스트가 PASS인지 확인합니다.
|
||||
3. main에 병합합니다. Squash·Rebase 병합이면 SHA가 바뀌므로 `approvedHeaderDeclarations`·`movedHeaderDeclarations`의 Commit을 main에 실제로 들어간 SHA로 다시 맞춥니다.
|
||||
4. 병합 Commit의 전체 SHA로 `approvedMainCommit`을 바꾸는 **테스트 전용 Commit**을 만듭니다. 이 Commit은 보호 경로를 건드리지 않습니다.
|
||||
5. Node 22.23.2에서 `npm run build-storybook` 후 Home Menu, Overview(두 모드), 미사용 검사를 새 증거 폴더로 실행합니다. 하나라도 FAIL이면 기준을 옮기지 말고 원인(미승인 변경 또는 목록 누락)을 확인합니다.
|
||||
6. 실행 결과와 갱신 사유를 `docs/sw/`의 보고서에 남깁니다. 기존 보고서와 증거는 고치지 않습니다.
|
||||
|
||||
## 10. 남은 문제
|
||||
|
||||
- 이번 범위 밖 기존 테스트 4종은 같은 빌드에서 과거 기준으로 실패합니다(수정 전 측정, 이 Commit에서 고치지 않음): `dropdown-consolidation` 223/228(목록·선언·경로 5건), `storybook-cleanup-stage1` 29/34(목록·선언·경로 4건 + 삭제된 `sw-header--dynamic-controls`에서 중단), `detail-buttons verify`(삭제된 `sw-header--composition`에서 중단), `property-panel-comparison verify` 50/52(목록 2건) 후 삭제된 `sw-header--property-panel`에서 예외 종료. 별도 작업으로 다룹니다.
|
||||
- 통합 개선 파일 예외: Overview·미사용 검사는 `integratedChangedFiles`가 `approvedMainCommit`과 달라도 허용합니다(그 파일은 통합 개선 suite가 검증). 그 suite를 함께 실행하지 않으면 이 파일들의 미승인 변경은 두 검사로는 드러나지 않습니다.
|
||||
- 과거 QA 폴더를 기본 증거 경로로 쓰는 스크립트가 있습니다. 반드시 새 증거 폴더를 지정해야 합니다.
|
||||
|
||||
## 11. 재현
|
||||
|
||||
```bash
|
||||
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 제외 대상), 주요 수치는 위 표에 옮겼습니다.
|
||||
@@ -40,6 +40,17 @@ export const integratedChangedFiles = [
|
||||
]
|
||||
// 2026-10-20 (test alignment): approved SW Story changes after the unused-demo removal that the lists above do not name.
|
||||
// Each comes from a user-requested commit merged into main as 553e4df. Regressions accept exactly these changes.
|
||||
// approvedMainCommit is the reviewed main merge the regressions treat as the accepted source state. overview.browser.mjs
|
||||
// (both modes) and storybook-unused-removal.browser.mjs keep their old baselines (50bf5bd, c8e5fbe) for the Story
|
||||
// inventory and declarations, and accept only the changes named in this file. For the source paths they guard (overview:
|
||||
// packages/sw/src; unused-removal: also the SW ai/package files, the other packages, Overview, Dropdown CSF, assets and
|
||||
// .storybook) they require no difference from this commit (integratedChangedFiles excepted) and report the diff from the
|
||||
// old baseline as sinceBaseline only.
|
||||
// Update it only after a merge into main whose Story and product source changes were all approved, in the same change
|
||||
// that records that merge's approved Story additions, removals, moves and tag changes in the lists of this file.
|
||||
// Never move it to make a failing check pass, and never to a commit that carries unreviewed Story or source changes.
|
||||
// A new main HEAD alone is no reason to move it: no script or workflow updates it automatically; it changes only in a
|
||||
// reviewed test-only commit (docs/sw/sw-test-regression-baseline-2026-10-20.md §9).
|
||||
export const approvedMainCommit = '553e4df4a865aaf6514b1c2b86cb2e3e9a658e5f'
|
||||
// 170a5c2: the SW/Header sidebar page of the home menu (the moved verification Stories are movedHomeMenuIds).
|
||||
export const homeMenuSidebarIds = ['sw-header--home-menu']
|
||||
|
||||
Reference in new issue
Block a user