Loading...
Loading...
WORKFLOW tự-kiểm THỊ GIÁC khép kín cho SPA local (app do /br sinh, hoặc bất kỳ web app): chụp headless từng route → BASELINE pixel-diff (bắt thay đổi ngoài ý muốn) → bất biến máy-kiểm (design conformance) → agent ĐỌC HẾT ảnh theo rubric → FINDINGS.md → sửa → chụp lại → chỉ pass khi máy VÀ mắt cùng sạch. Dùng khi đổi theme/UI/rebrand, khi extension MCP không chụp được localhost, hoặc cần gate UI cho frame. Trigger: "qa thị giác", "visual qa", "route-shots", "screenshot từng route", "kiểm giao diện", "baseline diff", "UI có regression không", "test giao diện headless", "/visual-qa".
npx skill4agent add rheinmir/setup visual-qaVì sao tồn tại: agent sửa UI rồi tự khen là sai lệch có hệ thống (failure). Ảnh chụp ra mà không ai mở = như chưa test. Workflow này thay "agent tự nhìn rồi tự cho pass" bằng ba tầng kiểm độc lập, trong đó hai tầng là máy.ui-pass-without-full-visual-reviewQuyết định 13/07/26 (từ /last30days): ngành chỉ có MỘT thứ đã chín cho UI-do-AI-sinh — baseline snapshot + pixel diff (: "detects unintended visual changes"; Playwrightargos-ci/argos). Tầng "LLM-judge chấm screenshot theo rubric" còn là biên giới (Agent-as-a-Judge, paper-stage) — nên ta tự làm tầng đó, không chờ ai.toHaveScreenshot
ui_role≠nonebrcomputer-use/qc-uiuxapp chạy + route list THẬT + login → route-shots (ảnh + MANIFEST, mọi theme/state) → tầng 1 baseline diff (ngưỡng 0) → tầng 2 bất biến in-page (contrast-aa · monochrome-surface · rogue-slab · shadow-clipped · overlap · row-misalign) → tầng 3 đọc đủ N ảnh theo rubric → FINDINGS.md → sửa → chụp lại + đọc lại| Field | Required? | Ý nghĩa | |
|---|---|---|---|
| In | app đang chạy ( | có | SPA localhost |
| In | route list từ router THẬT + tài khoản login | có | không đoán; login fail thì gate phải chết |
| In | danh sách theme/state từ chính app | có | không hardcode |
| In | thư mục baseline | không | lần đầu tự tạo |
| Out | | có | không có file = CHƯA TỪNG CHỤP |
| Out | exit code với | có cho gate | 1 khi route lỗi / thiếu ảnh / vi phạm bất biến / lệch baseline |
| Out | | có | một dòng cho MỖI route, kể cả "sạch" |
/auth.dark<html>prefers-color-scheme--themes light,darkcolor:#ffflight,darkdefaultdefault-darkpaperpaperTHEME_OPTIONS.darkdata-themelocalStorage.darkprefers-color-schemedocumentElement.classListdata-themelocalStorage<style>!important.dark{}/auth--assertanimation/transition:none; caret-color:transparent--diff-threshold[class*="cursor"]cursor-pointercursor-textplaywright-corenode route-shots.mjsskills/visual-qa/assets/package.jsonnpm i --prefix skills/visual-qa/assetsui-pass-without-full-visual-reviewgetComputedStyleoverflow:hiddenoverflow-x:visibleautopixelmatchpngjsnetworkidledomcontentloadedcomputer-use--assertplaywright-corenpm i --prefix skills/visual-qa/assets--update-baseline| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|---|---|---|---|---|
| W01 | deterministic | app, router, tài khoản | Xác nhận app chạy, lấy route list THẬT + theme list từ app | route + theme list | app không chạy → blocked |
| W02 | effect | route list | Chụp bằng | ảnh + | login fail → failed |
| W03 | deterministic | ảnh + baseline | Baseline diff ngưỡng 0 | diff | ≠ 0 → xem + duyệt (B02) hoặc sửa |
| W04 | deterministic | trang in-page | Bất biến máy-kiểm | vi phạm hoặc sạch | FAIL cứng → W06 |
| W05 | judgment | MANIFEST N route | | dòng cho mỗi route | thiếu ảnh chưa đọc → chưa xong |
| W06 | effect | findings | | code đã sửa | — |
| W07 | deterministic | code đã sửa | Chụp lại → đọc lại | máy sạch VÀ mắt sạch | còn lỗi → W06 |
node skills/visual-qa/assets/route-shots.mjs \
--base http://localhost:5230 --out <dir>/qa-shots \
--baseline <dir>/qa-baseline \
--user demo --pass demo --assert<out>/*.pngMANIFEST.json--update-baselinecontrast-aamonochrome-surfacerogue-slabmonochrome-surface<div>shadow-clippedoverflow:hiddenoverlapbutton/a/input/[role=button]position:fixedrow-misalign/redesign-existing-projectsRead# · route · vấn đề · mức · **nguyên nhân GỐC** · cách sửa| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|---|---|---|---|---|
| B01 | conditional_required | frame gate chỉ cần 1 route | chạy | — | W03 |
| B02 | user_optional | lệch baseline là thay đổi CỐ Ý đã xem | | chưa xem ảnh → không được duyệt | W04 |
| B03 | capability_optional | có | chạy baseline diff | không có → tự bỏ qua baseline | W04 |
| B04 | recovery | user báo lỗi mà gate xanh | tái hiện ĐÚNG state (route + theme + bundle + đăng nhập/focus), đo rồi mới nói | không tái hiện được → nói thẳng | W02 |
--assert/brTHEME_OPTIONSroute-shots.mjs --assertRead--themes light,dark--assert--diff-threshold--base--out--user--pass--route <r>--assert--baseline <dir>--update-baseline--diff-threshold <%>