← ClaudeAtlas

ui-visual-reviewlisted

Captures screenshots of key UI flows after E2E tests pass, runs an agent-side first-pass diff (regressions, console errors, layout shifts), then surfaces a checklist for the user's final approval. Also owns the browser-launch procedure the `playwright-launch` rule delegates here: use it whenever a browser must be opened for a human to drive or for automated capture — manual E2E checks, UX/fidelity comparison against a reference product, or a one-time OAuth login. Use after E2E tests pass on a UI track (csr-*, ssr-*, full).
uzysjung/uzys-agent-harness · ★ 3 · Code & Development · score 69
Install: claude install-skill uzysjung/uzys-agent-harness
# UI Visual Review ## Purpose E2E 테스트가 PASS 했어도 시각적 회귀(layout shift, 색상/간격 변화, 빈 화면, 잘림)는 functional test가 못 잡는다. 본 skill은: 1. 핵심 사용자 화면을 자동 캡처 2. 이전 baseline과 diff 3. 에이전트가 명백한 regression 1차 판정 4. 사용자가 최종 승인 → 새 baseline 채택 또는 수정 요청 수동으로 스크린샷을 모아 눈으로 비교하던 패턴을 자동화 + diff + 에이전트 사전 판정으로 옮긴 형태. ## When to Invoke | 트리거 | 행동 | |--------|------| | E2E 테스트 PASS + UI Track(csr-*/ssr-*/full) | 본 skill 호출 권유 | | UI 변경 PR review | visual diff 결과 review 입력으로 | | 의도적 디자인 변경 후 baseline 갱신 | "approve all" 옵션 | | Track이 data/tooling/executive | **skip** — UI 없음 | ## Pre-conditions - Playwright 또는 chrome-devtools MCP 사용 가능 (UI Track 설치 시 기본 포함) - 앱이 로컬에서 기동 가능 (예: `pnpm dev`, `docker-compose up`) - 핵심 화면 URL 리스트가 정의됨 (없으면 본 skill 첫 실행 시 사용자 질의) ## 브라우저를 띄우는 법 (영속 profile) `playwright-launch` 룰이 **금지**를 소유하고, 여기가 **절차**를 소유한다. 금지문은 상주해야 하지만(위반은 작업 도중에 일어난다) 아래 절차는 실제로 브라우저를 띄울 때만 필요하다. 핵심은 셋이다. ⓐ **영속 profile dir** — 프로젝트별로 분리해 매 iteration 재사용한다. cookie · IndexedDB · Service Worker 가 보존돼야 재로그인이 사라진다. ⓑ **Chrome for Testing 별도 binary** (`npx playwright install chromium`) — 사용자의 일반 Chrome 과 완전히 분리한다. ⓒ **사용자가 키를 입력하는 동안 자동화 layer 0** — main session 은 창을 띄우기만 하고, capture·검증은 입력이 끝난 뒤 별도 process 에서 돈다. ```js import { chromium } from 'playwright'; const PROFILE_DIR = process.env.PROJECT_PROFILE_DIR || `${process.env.HOME}/.<project>-audit-profile`; const TARGET = process.env.PROJECT_URL || 'http://localhost:<port>'; const ctx = await chromium.launchPersistentContext(PROFILE_DIR, {