| name | ui-visual-review |
| description | 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. Use after E2E tests pass on a UI track (csr-*, ssr-*, full). Adapts the GoalTrack screenshot-review pattern into a repeatable workflow. |
UI Visual Review
Purpose
E2E ํ
์คํธ๊ฐ PASS ํ์ด๋ ์๊ฐ์ ํ๊ท(layout shift, ์์/๊ฐ๊ฒฉ ๋ณํ, ๋น ํ๋ฉด, ์๋ฆผ)๋ functional test๊ฐ ๋ชป ์ก๋๋ค. ๋ณธ skill์:
- ํต์ฌ ์ฌ์ฉ์ ํ๋ฉด์ ์๋ ์บก์ฒ
- ์ด์ baseline๊ณผ diff
- ์์ด์ ํธ๊ฐ ๋ช
๋ฐฑํ regression 1์ฐจ ํ์
- ์ฌ์ฉ์๊ฐ ์ต์ข
์น์ธ โ ์ baseline ์ฑํ ๋๋ ์์ ์์ฒญ
GoalTrack์ docs/screenshots/ ์๋ ํจํด(mvp-home / v3-search / v4-wiki ๋ฑ)์ ์๋ํํ ํํ.
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 ์ฒซ ์คํ ์ ์ฌ์ฉ์ ์ง์)
Process
1. ํ๋ฉด ๋ฆฌ์คํธ์
(ํ ๋ฒ๋ง)
docs/visual-pages.json ๋ถ์ฌ ์ ์ฌ์ฉ์์๊ฒ ํต์ฌ ํ๋ฉด์ ๋ฌป๋๋ค (5-10๊ฐ ๊ถ์ฅ):
{
"base_url": "http://localhost:3000",
"pages": [
{ "id": "login", "path": "/login", "wait_for": "form" },
{ "id": "home", "path": "/", "wait_for": "main", "auth": "user1" },
{ "id": "detail", "path": "/items/sample", "auth": "user1" },
{ "id": "settings", "path": "/settings", "auth": "user1" }
],
"viewports": [
{ "name": "desktop", "width": 1440, "height": 900 },
{ "name": "mobile", "width": 375, "height": 812 }
]
}
auth ํค๋ docs/visual-auth.example.json(๋ณ๋ ์ํฌ๋ฆฟ)์์ ๋งคํ.
2. ์บก์ฒ
๊ฐ page ร viewport ์กฐํฉ์ผ๋ก ์คํฌ๋ฆฐ์ท ์บก์ฒ. chrome-devtools MCP ์ฌ์ฉ ์:
for page in pages:
navigate_page({url: base_url + page.path})
wait_for({text: page.wait_for})
take_screenshot({fullPage: true})
โ ์ ์ฅ: docs/screenshots/<branch-or-date>/<page.id>__<viewport.name>.png
์ ์ฅ ๊ฒฝ๋ก ๊ท์น: docs/screenshots/<phase>/<page_id>__<viewport>.png. phase๋ git branch ์ด๋ฆ ๋๋ YYYY-MM-DD-HHmm.
3. Diff (baseline ๋๋น)
baseline ์์น: docs/screenshots/baseline/. ์ฒซ ์คํ์ด๋ฉด ํ์ฌ ์บก์ฒ๊ฐ baseline.
๋น๊ต ๋ฐฉ์ (๊ฐ๋จ โ ์ ๋ฐ ์):
- L1 (ํด์):
sha256 ๋น๊ต. ๊ฐ์ผ๋ฉด PASS, ๋ค๋ฅด๋ฉด L2.
- L2 (pixelmatch):
pixelmatch ๋๋ ImageMagick compare -metric AE. threshold(์: 0.5%) ์ด๋ด PASS.
- L3 (์๊ฐ ๊ฒํ ): L2 fail ์ ์์ด์ ํธ๊ฐ ๋ ์ด๋ฏธ์ง๋ฅผ LLM ์
๋ ฅ์ผ๋ก ๋ณด๊ณ ์ฐจ์ด ์์ .
L1๋ง ๊ตฌํํด๋ 50% ๊ฐ์น. L2๋ ์์กด์ฑ ์ถ๊ฐ.
4. ์์ด์ ํธ 1์ฐจ ๋ฆฌ๋ทฐ (์๋)
L2/L3 fail์ด๊ฑฐ๋ ์ฐจ์ด๊ฐ ์๊ณ ์ด์์ด๋ฉด ์์ด์ ํธ๊ฐ ๋ค์ ํด๋ฆฌ์คํฑ์ผ๋ก ๋ช
๋ฐฑํ regression ํ์ :
| ์๊ทธ๋ | ๋ถ๋ฅ |
|---|
| ๋น ํ๋ฉด / ํฐ ํ์ด์ง | REGRESSION |
์ฝ์ ์๋ฌ (chrome-devtools list_console_messages) | REGRESSION |
| ํต์ฌ ์ปดํฌ๋ํธ(navbar, main content) ๋๋ฝ | REGRESSION |
| ์์/๊ฐ๊ฒฉ ๋ฏธ์ธ ๋ณํ | CHANGED (์ฌ์ฉ์ ํ๋จ) |
| ์๋๋ ์นดํผ/๋ ์ด์์ ๋ณ๊ฒฝ | EXPECTED (์ปค๋ฐ ๋ฉ์์ง ๋งค์นญ) |
5. ๊ฒฐ๊ณผ ๋ณด๊ณ
docs/visual-review-<phase>.md ์์ฑ:
# Visual Review โ 2026-04-20
## Summary
- 8 pages ร 2 viewports = 16 captures
- PASS (no diff): 12
- CHANGED (review needed): 3
- REGRESSION: 1
## REGRESSION
- `home__desktop`: ์ฝ์ ์๋ฌ "Cannot read properties of undefined" + main ์์ญ ๋น ํ๋ฉด
## CHANGED
- `login__mobile`: ๋ฒํผ ์์ ๋ณ๊ฒฝ (์๋ ์ถ์ โ git diff์ button.primary ์์ ๋ฐ๊ฒฌ)
- `settings__desktop`: spacing ๋ณํ
## PASS
- (์๋ต)
6. ์ฌ์ฉ์ ์น์ธ ๊ฒ์ดํธ
์ฌ์ฉ์๊ฐ docs/visual-review-<phase>.md ๋ณด๊ณ ๋ค์ ์ค ๊ฒฐ์ :
- REGRESSION ์์ โ ์์ ํ ์ฌ์คํ (Revision Gate)
- CHANGED๋ง ์์ โ ํญ๋ชฉ๋ณ approve ๋๋ reject. approve ์ baseline ์
๋ฐ์ดํธ
- PASS๋ง ์์ โ ์๋ baseline ์
๋ฐ์ดํธ ๊ฐ๋ฅ
Output
docs/screenshots/<phase>/*.png โ ์บก์ฒ๋ณธ
docs/screenshots/baseline/*.png โ ์น์ธ๋ baseline
docs/visual-review-<phase>.md โ diff ๋ฆฌํฌํธ
Integration with Workflow
- E2E ํ
์คํธ ํ: UI Track +
docs/visual-pages.json ์กด์ฌ ์ PASS ํ ๋ณธ skill ์๋ ํธ์ถ ๊ถ์
- Review ์: visual-review-.md ๊ฐ ์์ผ๋ฉด review ์
๋ ฅ์ผ๋ก ํก์. REGRESSION 1๊ฑด์ด๋ผ๋ ์์ผ๋ฉด ์ฐจ๋จ
- Revision loop ์ค: REGRESSION โ ์์ โ ์ฌ์บก์ฒ โ ์ฌdiff ๋ก ํฌํจ
Anti-Patterns
- ์ฌ์ฉ์ ์น์ธ ์์ด baseline ์๋ ๊ฐฑ์ โ ์๋ํ์ง ์์ regression์ด ์๊ตฌํ. ํญ์ ๋ช
์์ approve ํ์
- ๋ชจ๋ ํ์ด์ง ๋ค ์บก์ฒ (50+) โ ๋
ธ์ด์ฆ ํญ์ฆ. ํต์ฌ 5-10๊ฐ๋ก ์์
- viewport 1๊ฐ๋ง โ mobile ๊นจ์ง ๋์นจ. desktop + mobile ์ต์ 2๊ฐ
- L3(LLM ์๊ฐ ๋น๊ต) ๋งค๋ฒ ํธ์ถ โ ๋น์ฉ. L1/L2์์ ๋ชป ๊ฑฐ๋ฅธ ๊ฒ๋ง L3
- screenshots/ ๋๋ ํ ๋ฆฌ git์ ์ปค๋ฐ X โ ํ๊ท ๋น๊ต ๋ถ๊ฐ.
docs/screenshots/baseline/์ ์ปค๋ฐ, <phase>/๋ gitignore
Examples
GoalTrack ํ๋ก์ ํธ์ ์๋ ํจํด (์ฐธ๊ณ ):
docs/screenshots/mvp-home-empty.png, mvp-home-list.png โ ๊ฐ์ ํ๋ฉด ๋ค๋ฅธ ์ํ
crypto-365d-after-fix.png, crypto-365d-round2.png โ ์์ round๋ณ ๋ณด์กด
shared_portfolio.png, shared_simulation.png โ ๊ธฐ๋ฅ๋ณ ํต์ฌ ํ๋ฉด
๋ณธ skill์ ๊ทธ ํจํด์ ์๋ํ + diff + ์์ด์ ํธ ์ฌ์ ํ์ ์ถ๊ฐ.