/jaspr-web widgetbook-web — 웹 컴포넌트 카탈로그 자동 점검#
| 항목 | 내용 |
|---|---|
| 실행 명령 | /cc-jaspr-web:widgetbook-web |
| 분류 | 웹 |
| 난이도 | ●●● 높음 |
| MCP 서버 | playwright, marionette |
한마디로#
웹 브라우저에 띄운 컴포넌트 견본 카탈로그(Widgetbook) 를 한 칸씩 자동으로 돌면서, 화면을 캡처하고 직접 눌러보며 이상이 없는지 점검해 주는 명령입니다. 마치 매장 직원이 진열된 모든 상품을 하나씩 꺼내 작동시켜 보고 사진으로 남겨 두는 것과 같아요.
누가·언제 쓰나요#
- 웹에서만 생기는 문제를 조사할 때 (예: 맥/모바일에서는 멀쩡한데 브라우저에서만 깨지는 화면)
- 페이지의 바깥 틀(브라우저 DOM) 과 안쪽 실제 컴포넌트(Flutter 캔버스) 를 한 번에 함께 확인하고 싶을 때
- 맥이 없고 브라우저만 쓸 수 있는 환경(예: CI 서버)에서 점검해야 할 때
👉 평소 일반 점검은 맥에서 도는 cc-marionette:sweep이 더 빠르고 안정적입니다. 이 명령은 위처럼 "웹이어야만 하는" 상황에 씁니다.
무엇을 해주나요#
점검이 끝나면 .claude/docs/jaspr-web/widgetbook-<시각>/ 폴더 안에 결과가 정리됩니다.
-
컴포넌트별 화면 캡처 — 가만히 있을 때(
00_idle.png)와 눌러본 뒤(01_after_action.png)를 비교 - 점검한 컴포넌트 목록 —
routes.json - 요약 보고서 —
summary.md - 컴포넌트마다 무엇을 확인했는지 메모(
notes.md)와 내부 동작 기록(interactive.json)
어떻게 쓰나요#
# 1) 터미널에서 Widgetbook을 브라우저에 띄웁니다
cd packages/coui_widgetbook
flutter run -d chrome --web-port=8080 --print-dtd --dart-define=ENABLE_SEMANTICS=true
# 2) Claude Code에서 점검 명령을 실행합니다
/jaspr-web widgetbook-web --port=8080 --marionette-uri=ws://127.0.0.1:54321/abc/ws
자주 쓰는 선택 항목:
--port— Widgetbook이 열린 브라우저 포트 (기본8080)--routes— 특정 컴포넌트 경로만 골라서 점검--limit— 점검할 컴포넌트 개수 제한--output— 결과 저장 폴더 지정
안에서 무슨 일이 벌어지나요#
이 명령은 두 도구(브라우저를 조종하는 Playwright, 실제 위젯을 조종하는 Marionette)를 동시에 부려서 각자 잘하는 일을 시킵니다.
- 브라우저 화면과 위젯 엔진에 모두 연결되는지 먼저 확인합니다.
- 카탈로그의 컴포넌트 목록을 읽어옵니다.
- 컴포넌트를 하나씩 돌면서: 해당 항목을 클릭 → 화면이 안정되길 기다림 → 캡처 → 실제로 눌러보거나 입력해 봄 → 다시 캡처 → 누르기 전후 화면을 비교합니다.
- 모든 결과를 모아 요약 보고서를 작성합니다.
⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)
Parameters#
| Parameter | Required | Description | Default |
|---|---|---|---|
--port | ❌ | flutter run Chrome port (the URL Widgetbook is served at) | 8080 |
--marionette-uri | ❌ | DTD/VM Service URI; if omitted, derived from flutter run --print-dtd output | auto |
--routes | ❌ | Widgetbook routes / UseCase paths to walk | all visible |
--limit | ❌ | Cap on UseCases | unlimited |
--output | ❌ | Output dir | .claude/docs/jaspr-web/widgetbook-<ts>/ |
Prerequisites#
# In the Widgetbook package
flutter run \
-d chrome \
--web-port=8080 \
--print-dtd \
--dart-define=ENABLE_SEMANTICS=trueLook for two lines:
A Dart VM Service ... is available at: http://127.0.0.1:54321/abc/
The Dart Tooling Daemon is listening on ws://127.0.0.1:54322/xyzThe first is for Marionette; the second is for cc-pixel-loop if you also want pixel-loop (rare for web).
The
ENABLE_SEMANTICS=trueflag is a cocode convention — guardSemanticsBinding.instance.ensureSemantics()behind it in the Widgetbook bootstrap so production sites stay unaffected.
Flow#
1. Confirm Playwright can reach http://localhost: < port >
2. Confirm Marionette can reach the VM Service URI
3. List Widgetbook UseCases by:
- Playwright: read the Widgetbook NavigationSidebar DOM
- OR Marionette: `get_interactive_elements` + filter sidebar entries
4. For each UseCase:
a. Playwright: click the sidebar entry (browser-level navigation)
b. Marionette: wait for hot reload to settle (`hot_reload` returns success)
c. Playwright: take a clipped screenshot of the canvas region
d. Marionette: `get_interactive_elements` inside the canvas; for each, run smoke action (tap / type)
e. Playwright: take post-action screenshot
f. Diff before/after at default tolerance
5. Write summaryEach layer does what it's best at:
| Step | Playwright | Marionette |
|---|---|---|
| Browser navigation | ✓ | — |
| Sidebar click | ✓ | (fallback) |
| Widget tap inside canvas | (only if Semantics on) | ✓ (better) |
| TextField controller assertion | — | ✓ (only Marionette can read it) |
| Screenshot | ✓ (DOM-aware clip) | ✓ (frame buffer) |
| Hot reload | — | ✓ |
Example#
# In one terminal
cd packages/coui_widgetbook
flutter run -d chrome --web-port=8080 --print-dtd --dart-define=ENABLE_SEMANTICS=true
# In Claude Code
/jaspr-web widgetbook-web --port=8080 --marionette-uri=ws://127.0.0.1:54321/abc/wsArtifacts#
.claude/docs/jaspr-web/widgetbook- < ts > /
├── usecases/ < usecase-id > /
│ ├── 00_idle.png
│ ├── 01_after_action.png
│ ├── interactive.json # what Marionette saw
│ └── notes.md
├── routes.json # list of UseCases walked
└── summary.mdWhen to prefer the native counterpart#
The native cc-marionette:sweep against a non-web Widgetbook (flutter run -d macos) is usually faster and less flaky. Use /jaspr-web widgetbook-web when:
- You're investigating a web-only regression.
- You want to verify both DOM (Jaspr Widgetbook chrome) and Canvas (Flutter UseCase) parts of the page.
- The browser is the only target you have available (e.g. on a CI agent without macOS).
Failure Modes#
| Symptom | Cause | Recovery |
|---|---|---|
Marionette: not connected | flutter run printed a stale URI from a previous run | Re-run flutter run --print-dtd; paste fresh URI |
flt-semantics-host empty | ENABLE_SEMANTICS was false | Restart with the dart-define; semantics must be enabled before main runs |
| Canvas screenshot is all-white | Playwright clipped before the first frame painted | Increase wait: --wait-for=flutter-view[data-flt-renderer] |
| Hot reload fails | Same as native | Switch to hot_restart; re-navigate via Playwright |