# Frontend Standards - Visual/Snapshot Testing > **Module:** testing-visual.md | **Sections:** 4 | **Parent:** [frontend.md](../frontend.md) This module covers visual and snapshot testing patterns for React/Next.js applications. Ensures UI consistency through snapshot testing, responsive coverage, and component state verification. > **Gate Reference:** This module is loaded by `ring:qa-analyst-frontend` at Gate 4 (Visual Testing). --- ## Table of Contents | # | [Section Name](#anchor-link) | Description | |---|------------------------------|-------------| | 1 | [Snapshot Testing Patterns](#snapshot-testing-patterns-mandatory) | toMatchSnapshot usage with Vitest | | 2 | [States Coverage](#states-coverage-mandatory) | All component states must be captured | | 3 | [Responsive Snapshots](#responsive-snapshots-mandatory) | Mobile, tablet, desktop viewports | | 4 | [Component Duplication Check](#component-duplication-check-mandatory) | Prevent recreating sindarian-ui components | **Meta-sections:** [Output Format (Gate 4 - Visual Testing)](#output-format-gate-4---visual-testing), [Anti-Rationalization Table](#anti-rationalization-table-visual-testing) --- ## Snapshot Testing Patterns (MANDATORY) **HARD GATE:** All UI components MUST have snapshot tests covering all states and viewports. ### Required Tool Setup | Tool | Purpose | Config | |------|---------|--------| | Vitest | Test runner | `vitest.config.ts` | | `@testing-library/react` | Component rendering | Standard setup | | `toMatchSnapshot()` | Snapshot comparison | Built into Vitest | ### Basic Snapshot Pattern ```tsx import { render } from '@testing-library/react'; describe('TransactionCard snapshots', () => { it('MUST match snapshot for default state', () => { const { container } = render( ); expect(container).toMatchSnapshot(); }); it('MUST match snapshot for pending state', () => { const { container } = render( ); expect(container).toMatchSnapshot(); }); }); ``` ### Naming Convention | Pattern | Example | |---------|---------| | `{Component}.snapshot.test.tsx` | `TransactionCard.snapshot.test.tsx` | | `{Page}.snapshot.test.tsx` | `DashboardPage.snapshot.test.tsx` | ### Snapshot Update Protocol When snapshots change intentionally: 1. Review the diff carefully - MUST verify change is intentional 2. Update with `vitest --update` only after review 3. Commit updated snapshots with descriptive message ### FORBIDDEN Patterns ```tsx // FORBIDDEN: Snapshot of entire page without isolation expect(document.body).toMatchSnapshot(); // Too broad, too brittle // FORBIDDEN: Skipping snapshot update review // Running vitest --update without reviewing diffs // FORBIDDEN: Snapshot without component states describe('Button', () => { it('snapshot', () => { // WRONG: Only default state expect(render(