LogoSkills

/jaspr-web widgetbook-web — 웹 컴포넌트 카탈로그 자동 점검

Flutter Web 디버그 모드로 띄운 로컬 CoUI Widgetbook 을 한 칸씩 돌며 조작 전후 화면을 캡처하고 점검 목록·요약 보고서를 폴더로 남깁니다 (Playwright + Marionette VM Service 필요).

/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)를 동시에 부려서 각자 잘하는 일을 시킵니다.

  1. 브라우저 화면과 위젯 엔진에 모두 연결되는지 먼저 확인합니다.
  2. 카탈로그의 컴포넌트 목록을 읽어옵니다.
  3. 컴포넌트를 하나씩 돌면서: 해당 항목을 클릭 → 화면이 안정되길 기다림 → 캡처 → 실제로 눌러보거나 입력해 봄 → 다시 캡처 → 누르기 전후 화면을 비교합니다.
  4. 모든 결과를 모아 요약 보고서를 작성합니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Parameters#

ParameterRequiredDescriptionDefault
--portflutter run Chrome port (the URL Widgetbook is served at)8080
--marionette-uriDTD/VM Service URI; if omitted, derived from flutter run --print-dtd outputauto
--routesWidgetbook routes / UseCase paths to walkall visible
--limitCap on UseCasesunlimited
--outputOutput 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=true

Look 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/xyz

The first is for Marionette; the second is for cc-pixel-loop if you also want pixel-loop (rare for web).

The ENABLE_SEMANTICS=true flag is a cocode convention — guard SemanticsBinding.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 summary

Each layer does what it's best at:

StepPlaywrightMarionette
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/ws

Artifacts#

.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.md

When 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#

SymptomCauseRecovery
Marionette: not connectedflutter run printed a stale URI from a previous runRe-run flutter run --print-dtd; paste fresh URI
flt-semantics-host emptyENABLE_SEMANTICS was falseRestart with the dart-define; semantics must be enabled before main runs
Canvas screenshot is all-whitePlaywright clipped before the first frame paintedIncrease wait: --wait-for=flutter-view[data-flt-renderer]
Hot reload failsSame as nativeSwitch to hot_restart; re-navigate via Playwright