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:
- No new
vue-tscerrors (~12 pre-existing baseline — track names, not counts) eslint+prettiercleannpm run buildsucceeds- Manual smoke test in the browser
See memory: frontend-verification.
1. Type-check
npx vue-tsc --noEmitCompare 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
npm run lint
npm run format:fixformat:fix writes; lint only reports. CI runs both.
3. Build
npm run buildThe 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.
composer dev # starts Laravel + Vite + queue + log watcherThen 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-tscshows 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
| Symptom | Likely cause |
|---|---|
vue-tsc errors in a wayfinder/ file | Controller method name collides — see Avoid Wayfinder Collisions |
| 405 Method Not Allowed on a file-upload form | Frontend spoofed PUT — set spoofMethod: false (memory: update-route-post-vs-spoofed-put) |
$can(...) returns undefined | Permission name typo — must match config/permissions.php exactly |
| Page works locally but build fails | Auto-imported component name conflicts; check for two components with the same basename |
| "Failed to fetch" on POST | CSRF token missing — Inertia handles this automatically; if you used raw axios, ensure withCredentials: true |
Checklist
- [ ]
npx vue-tsc --noEmit— no new errors - [ ]
npm run lintclean - [ ]
npm run format:fixapplied - [ ]
npm run buildsucceeds - [ ] Manually clicked the golden path in the browser
- [ ] Tried one edge case (empty / invalid / permission-denied)
- [ ] Browser console clean (no red)
