Skip to content

Last updated:

How-To: Verify a UI Change End-to-End

There is no JS test runner in this project (no Vitest suite, no Playwright). UI changes are gated on:

  1. No new vue-tsc errors (~12 pre-existing baseline — track names, not counts)
  2. eslint + prettier clean
  3. npm run build succeeds
  4. Manual smoke test in the browser

See memory: frontend-verification.

1. Type-check

bash
npx vue-tsc --noEmit

Compare the failure names, not the count — the project has a small number of pre-existing errors. If your change adds an error in a file you didn't touch, that's a Wayfinder regeneration issue — see Avoid Wayfinder Collisions.

2. Lint + format

bash
npm run lint
npm run format:fix

format:fix writes; lint only reports. CI runs both.

3. Build

bash
npm run build

The Inertia build emits public/build/manifest.json. If you're running tests after building, the manifest needs to exist for Inertia::render(...) tests to pass — see memory fresh-worktree-test-setup.

4. Smoke-test in the browser

Start the dev server and walk the change yourself.

bash
composer dev    # starts Laravel + Vite + queue + log watcher

Then visit the page in your browser. Don't take "the page loaded" as proof — actually use the feature:

  • Golden path: the thing the user is trying to do
  • Empty state: what happens with zero rows
  • Validation: submit with bad data; check field-level errors
  • Permission: if guarded, log in as a user without the permission and verify the link is hidden + the route returns 403
  • Multi-branch: if branch-scoped, switch branches and confirm data isolation
  • Mobile width: resize to ~375px; nothing should overflow

5. Sentry sanity check

For changes that touch error paths, look at storage/logs/laravel.log and watch the browser console while you click around. Any unexpected stack trace is a regression.

What you can't claim without verification

"The feature works."

You can claim:

  • ✅ The build passes
  • vue-tsc shows no new errors
  • ✅ I manually clicked through the happy path + one edge case

If you couldn't actually open the page (e.g. the dev server wouldn't start in your environment), say so rather than claiming success.

See memory: frontend-verification. The verification skill in superpowers is built around this exact principle: evidence before assertions.

Common gotchas

SymptomLikely cause
vue-tsc errors in a wayfinder/ fileController method name collides — see Avoid Wayfinder Collisions
405 Method Not Allowed on a file-upload formFrontend spoofed PUT — set spoofMethod: false (memory: update-route-post-vs-spoofed-put)
$can(...) returns undefinedPermission name typo — must match config/permissions.php exactly
Page works locally but build failsAuto-imported component name conflicts; check for two components with the same basename
"Failed to fetch" on POSTCSRF token missing — Inertia handles this automatically; if you used raw axios, ensure withCredentials: true

Checklist

  • [ ] npx vue-tsc --noEmit — no new errors
  • [ ] npm run lint clean
  • [ ] npm run format:fix applied
  • [ ] npm run build succeeds
  • [ ] Manually clicked the golden path in the browser
  • [ ] Tried one edge case (empty / invalid / permission-denied)
  • [ ] Browser console clean (no red)

CPR - Clinical Patient Records