This project uses a layered testing strategy:
- Unit tests for utilities and focused logic
- Component tests for UI behavior
- End-to-end tests for user journeys, SEO, accessibility, theme behavior, and visual stability
- Jest (via react-scripts) for unit and component tests
- Testing Library for DOM-oriented assertions
- Cypress for component and end-to-end tests
- Playwright for browser e2e, accessibility/SEO checks, and visual regression snapshots
- Jest tests: src/tests/**
- Cypress component tests: cypress/component/**
- Cypress e2e tests: cypress/e2e/**
- Playwright tests: e2e/**
Playwright specs use shared stabilization helpers in e2e/helpers/reliability.ts.
- gotoAndWaitForStablePage(page, url, options):
- Navigates to a route
- Waits for a stable load state
- Waits for body visibility and font readiness
- Optionally asserts key heading presence before test assertions
- waitForPageToBeStable(page, options):
- Reused when a test has already navigated and only needs stabilization
Use this pattern for new e2e tests to reduce flakiness in accessibility, SEO, and visual checks.
Install dependencies:
npm installRun Jest suite:
npm testRun Cypress component tests:
npm run cypress-componentRun Cypress e2e tests:
npm run cypress-e2eRun Playwright tests:
npm run playwright:testRun Playwright headed mode:
npm run playwright:test:headedUpdate Playwright visual snapshots when intentional UI changes are made:
npm run playwright:test:update-snapshotsIf Playwright browsers are not installed yet:
npx playwright install chromium- npm test
- npm run cypress-e2e
- npm run playwright:test
This gives fast feedback from Jest first, then validates full-browser behavior in both e2e suites.
- Core UI and component behavior in unit/component tests
- Route-level and section-level user journeys in Cypress e2e
- Metadata and SEO assertions
- Theme toggle and persistence behavior
- Responsive viewport behavior
- Accessibility scans in Playwright
- Visual regression snapshots for key regions in Playwright
- Prefer user-observable outcomes over implementation details.
- Test failure paths, not just happy paths.
- Keep mocks narrow and realistic.
- Make each test name describe behavior and expected outcome.
- Avoid placeholder assertions (for example, expect(true).toBe(true)).
- Keep visual snapshots intentional and review diffs before accepting updates.
When presenting this project, describe your testing design as:
- Layered: unit + component + e2e with two complementary browser runners
- Behavior-first: assertions target user-visible and system-relevant outcomes
- Defensive: metadata, edge conditions, and non-happy paths are explicitly tested
- Practical: fast local feedback from Jest, broad browser confidence from Cypress and Playwright