--- name: verify description: Drive the proposal-system web SPA headlessly to verify changes at the browser surface (no API required for auth/shell flows). --- # Verify web changes (headless, no API) Build/launch: ```bash cd web && npm run dev # vite on http://localhost:5173 ``` Drive with Playwright resolved from the SHOC checkout (this repo doesn't ship it), using the cached headless chromium: ```js const { chromium, } = require('/Users/adammoussa/Documents/repositories/seahaven/shoc-frontend-new/node_modules/playwright'); const browser = await chromium.launch({ executablePath: '/Users/adammoussa/Library/Caches/ms-playwright/chromium_headless_shell-1228/chrome-headless-shell-mac-arm64/chrome-headless-shell', }); ``` Fake a session without the API by seeding sessionStorage with a future-exp JWT (AuthUser shape: `{ id, email, displayName, role, token }`, roles: SysAdmin/Admin/Dispatcher): ```js await ctx.addInitScript((v) => sessionStorage.setItem('proposal_system_token', v), userJson); ``` Gotchas: - `addInitScript` re-runs on every document load — a full-page reload re-seeds the token, so "logged-out then reload" probes need a fresh un-seeded context. - Dev-login buttons on /login call the real API (`/auth/dev-login`) — they fail without the .NET API running; seed storage instead. - Sidebar drawer width: expanded 244px, collapsed 76px — read `.MuiDrawer-paper` bounding rect to assert toggles. Flows worth driving: unauthenticated redirect to /login, seeded session renders shell (user chip + role-gated nav groups), sidebar toggle + localStorage persistence, logout (toast, storage cleared), expired/malformed token treated as unauthenticated, Dispatcher bounced from /admin by RoleGuard.