Skip to content

Frontend Testing

Ankit Upadhyay edited this page Jul 24, 2026 · 2 revisions

Frontend: Testing

How the web app is tested. General strategy: Testing Strategy. Part of Frontend Overview.

Layout and scale

Jest + React Testing Library. All unit tests live under src/app/__tests__/, mirroring source paths (stores/, hooks/, services/, components/, pages/, ui/, lib/, features/, …) — ~850 test files. Every Zustand store has a sibling test in __tests__/stores/.

Coverage: a governance mandate

  • jest.config.ts sets coverageProvider: 'v8', reporters text-summary + lcov. collectCoverageFrom scans src/**/*.{ts,tsx} and excludes .d.ts, tests, mocks, barrels, types, layout.tsx/page.tsx, constants, then re-includes three real components that happen to be index.tsx.
  • coverageThreshold is commented out — the ≥95% statements/branches/functions/lines bar is enforced by governance (AGENTS.md) and Sonar, not the Jest gate. New files must hit ≥90%.
  • Because the provider is v8, use /* v8 ignore next N */ (not istanbul hints) for genuinely untestable lines.

Config and setup

  • moduleNameMapper aliases @/(.*)src/$1, @yosemite-crew/fhirpackages/fhir/src, @yosemite-crew/typespackages/types/src, and stubs next/navigation with src/app/jest.mocks/nextNavigation.ts.
  • testEnvironment: 'jsdom', setupFilesAfterEnv: ['jest.setup.ts']. jest.setup.ts configures jest-axe (WCAG 2.1 AA; contrast disabled in jsdom), polyfills matchMedia/IntersectionObserver/ResizeObserver/scrollTo, and turns any unexpected console.warn/console.error into a thrown failure (so DOM-nesting warnings fail the test).

Key conventions and gotchas

  • Zustand mocking: reset stores in beforeEach; when a hook calls useXxxStore.getState(), the mock must expose getState (Object.assign(jest.fn(), { getState: jest.fn() })).
  • @yosemite-crew/types requireActual: because the package is aliased to real source, any jest.mock('@yosemite-crew/types') must spread ...jest.requireActual('@yosemite-crew/types') or DTO mappers/enums break at load. (ESLint bans require() in test bodies, so requireActual is the sanctioned escape hatch.)
  • Other rules: mock react-icons as <span>; mock axios.isAxiosError via a factory (not spyOn); Task uses _id.

E2E and accessibility

Playwright config (playwright.config.ts) → testDir: './e2e', specs smoke.spec.ts, a11y.spec.ts (via @axe-core/playwright), auth-flow.spec.ts. baseURL http://127.0.0.1:3001, chromium always + firefox in CI. Scripts e2e:smoke/e2e:a11y/e2e:auth. The Playwright public suite is what catches the nonce-CSP-on-static-routes class of regression (Frontend: Public and Marketing Pages).

Related

Product & Domain
Architecture
Applications
Design & Accessibility
Engineering Handbook
Decisions (ADRs)
Design Docs & Plans
Roadmap
Operations
Meta

Canonical code & docs: main repo · Auto-generated companion: DeepWiki

Clone this wiki locally