feat: harden test and registry evidence

This commit is contained in:
donghyeon-ka
2026-07-26 17:15:26 +09:00
parent 3f634eb655
commit 98d4fd4960
68 changed files with 6167 additions and 250 deletions
@@ -0,0 +1,71 @@
# VD-08: 개발용 Storybook과 로컬 시각 회귀 증적
- 상태: Accepted
- 결정일: 2026-07-26
- 적용 브랜치: `feature-frontend-test-registry-evidence-hardening`
- 재검토: 제품이 cloud visual review, 다중 OS baseline 또는 별도 디자인 시스템
배포를 요구할 때
## 배경
`/examples/ui``/examples/states`는 실제 application composition 안에서 공통
UI와 상태 표면을 보여 주지만, primitive를 격리해 interaction과 접근성을 검증하는
workshop은 아니었다. 실패 시 screenshot도 디버깅 증거일 뿐 의도된 UI 기준선과
현재 렌더의 차이를 차단하지 못했다.
외부 visual review 서비스, 별도 Storybook 배포와 브랜드별 baseline은 아직
선정되지 않았다. 이 결정을 기다리며 UI 회귀 검증을 비워 두거나 production
application bundle에 workshop runtime을 포함하는 것 모두 적절하지 않다.
## 결정
1. Storybook은 development dependency와 별도 static artifact로만 사용한다.
production entry와 application `dist`에는 Storybook runtime, story 또는
테스트 selector를 포함하지 않는다.
2. story는 public design-system entry를 소비하고 실제 locale, theme, session,
router와 query provider 계약으로 렌더한다. production component를 복제한
story 전용 구현을 만들지 않는다.
3. interaction과 story-level axe는 Playwright가 정적 Storybook을 대상으로
실행한다. unexpected console, page error와 request failure는 테스트 실패다.
4. 시각 회귀는 production `build``preview`를 대상으로 pinned Chromium,
locale, color scheme과 viewport에서 `toHaveScreenshot()`으로 실행한다.
5. 최초 기준선은 wide shell, compact pseudo-locale drawer, dark design-system
gallery, loading/empty/error/access 상태 표면을 포함한다.
6. animation과 caret만 결정적으로 비활성화한다. `html`, `body`, `main` 또는
application 전체를 mask해 false PASS를 만드는 설정은 gate가 거절한다.
7. snapshot 갱신은 `test:visual:update`라는 명시적 명령으로 분리하고 PNG diff를
review한다. 일반 `test:visual`은 승인 기준선을 변경하지 않는다.
8. local visual threshold는 작은 rasterization 차이만 허용하며 실제 layout,
copy, theme 또는 상태 변화가 숨겨지도록 확대하지 않는다.
9. `/examples/*`는 production composition smoke로 유지하고 Storybook story의
대체물로 취급하지 않는다. 반대로 Storybook만 통과해 application shell
integration을 완료 처리하지 않는다.
10. cloud service가 선정되지 않아도 repository-local workshop, interaction,
a11y와 visual baseline gate는 완전하게 실행 가능해야 한다.
## 실행과 증적
- workshop config: `.storybook/main.ts`, `.storybook/preview.tsx`
- story: `src/presentation/design-system/design-system.stories.tsx`
- interaction/a11y: `tests/storybook/workshop.spec.ts`
- visual: `tests/visual/platform.visual.spec.ts`
- baseline: `tests/visual/__snapshots__/`
- production E2E: `playwright.config.js`
- local dev E2E: `playwright.dev.config.js`
- evidence policy: `scripts/check-test-evidence.mjs`
CI는 JUnit, HTML report, failure trace/screenshot, visual baseline 존재 여부와
금지된 full-screen mask/무소유 skip fixture를 함께 검사한다.
## 한계와 재검토 조건
로컬 기준선은 실제 iOS/Android 기기, 여러 운영체제의 font rasterization,
디자인 승인 workflow와 다중 브랜드를 증명하지 않는다. 이를 요구하면 동일
public component와 story를 입력으로 사용하는 외부 review adapter를 추가하되,
provider 결과가 없을 때 임의 PASS로 대체하지 않는다.
## Rollback
Storybook dependency/config, workshop test와 visual config/baseline은 production
runtime 변경 없이 독립적으로 제거할 수 있다. rollback 후에도 `/examples/*`,
component behavior, automated accessibility와 built-dist E2E는 유지한다.