The third and final layer of the stale-tile bug: saving invalidated the dashboard snapshot with the default refetchType 'active', but the dashboard page is unmounted while the user sits in settings — the cell only went stale, and the snapshot query's deliberate refetchOnMount: false then suppressed the re-read on same-tab navigation back. The save, reset and ring mutations now invalidate with refetchType 'all', refreshing the cell mounted or not (proven live in one SPA session against the real query client). The sortable settings editors (dashboard layout, medication order, modules, mood tags x2) painted a second page scrollbar: the sr-only drag hint below each list is position: absolute, no ancestor was positioned, so it resolved against the initial containing block, escaped the shell's overflow clipping and lengthened the DOCUMENT by its static offset. The list wrappers are now relative; the e2e overscroll guard asserts the one-scroll-floor on these routes and was negative-tested against the revert.
e2e/
End-to-end browser tests. Playwright 1.60 drives a production build of the app against a real PostgreSQL, with @axe-core/playwright for accessibility assertions. This is the heaviest test tier; CI runs it on every PR, and locally it is worth running when a change touches a UI flow.
Running
pnpm e2e
The Playwright config (../playwright.config.ts) builds the app (next build) and brings up Postgres before the specs run; setup/global-setup.ts seeds the auth + fixture state. The suite is not part of the fast local gate (typecheck / lint / test) — it surfaces at PR CI, so expect responsive/wizard/nav reworks to flag here first.
Layout
setup/—global-setup.ts(auth + DB seeding),test-helpers.ts(shared login + navigation helpers).utils/— fixtures such asmock-dashboard-snapshot.ts.*.spec.ts— one spec per flow: auth/login/redirect, dashboard, charts, the medication-wizard cadences (medications-wizard-*), insights generation + scroll restoration, doctor report, settings, mobile-viewport consistency, locale switch, accessibility (a11y.spec.ts), and thev1427-*regression set.
Convention
Assert against stable data-* attributes (data-slot, data-display-step, root display attrs), not viewport-dependent visible text. Responsive sm:hidden UI changes break getByText on desktop while the underlying element is still present — anchoring on data attributes keeps the specs stable across breakpoints. See ../CLAUDE.md.