# UI Testing Rule (mandatory after frontend changes) > Procedure + commands: see the **`ui-testing`** skill (`.roo/skills/ui-testing/SKILL.md`). > This rule defines the **when** (obligation) and the **gate** (definition of done). ## When this rule applies Any change under `src/` that affects a **visible route or interaction**: pages, components, auth flows, sidebar/breadcrumbs, forms, charts, maps, i18n labels. Pure backend-only or docs-only changes are exempt. ## The gate (Definition of Done) A frontend task is **not done** until ALL of the following pass. Do not claim completion otherwise. 1. `yarn lint` (frontend) → 0 errors 2. `yarn build` (frontend) → 0 errors (`vue-tsc --noEmit`) 3. **Browser verification** — the changed behavior is actually exercised in a real browser (this is the non-negotiable step the user requires): - **Quick change / visual only** → **MCP browser** ad-hoc check: `browser_navigate` the affected route → `browser_snapshot` (assert the structure) → `browser_take_screenshot` → `browser_console_messages` (no app errors). - **Behavior that must not regress** → a **Playwright integration spec** in `../integration/tests/` that passes against the docker-compose stack. 4. If a Playwright spec was touched or added: `npx playwright test` green (Node ≥20, via nvm Node 22). ## How to run (cheat-sheet) ```bash # Playwright integration stack (repeatable / regression) cd ../integration export PATH="$HOME/.nvm/versions/node/v22.14.0/bin:$PATH" # Playwright needs Node ≥20 yarn up # docker compose up -d --build until curl -sf http://localhost:8000/api/v0/html_test/login >/dev/null; do sleep 2; done npx playwright test # all npx playwright test tests/.spec.ts # one yarn down # stop (keep DB) ``` MCP browser (ad-hoc) needs the app reachable: `yarn dev` → `:5173`, or the integration stack (`yarn up`) so the SPA talks to the real backend at `:8000`. ## Reporting When finishing a task, state explicitly in the completion message: - lint/build result - which browser verification was performed (MCP ad-hoc vs Playwright spec) and the outcome (pass/fail) - for Playwright: the spec name and that it is green ## Gotchas (must follow) - Frontend deps install with **yarn**, never npm (peer-dep conflict on `@unhead/vue` / vite). - Vuestic inputs have **floating labels → empty placeholder**: select by `input[type=email]` / `input[type=password]`, not by placeholder. - Sidebar = `