# Testing Patterns Only read this file when creating or modifying tests. This project uses: - Vitest - Playwright browser testing - Svelte Testing Library patterns through vitest/browser --- # Test Philosophy Tests should prove behavior. Do not write tests that only confirm implementation details. Every test must contain meaningful assertions. A test without assertions fails because: expect.requireAssertions is enabled. --- # Test Locations Tests are colocated with source files. Client tests: *.svelte.test.ts *.svelte.spec.ts Server tests: *.test.ts *.spec.ts --- # Vitest Projects There are two test environments. ## Client Used for Svelte components. Environment: Playwright Chromium browser. Used for: - rendering - user interaction - form behavior --- ## Server Used for: - load functions - actions - server utilities Environment: Node. --- # Before Each Test Always reset mocks: beforeEach(() => { vi.clearAllMocks(); }); --- # Server Tests Server route tests should cover: - authenticated behavior - unauthenticated behavior - authorization rules - successful operations - failed operations Mock: - $lib/db - authentication helpers - external services --- # Prisma Mocking Mock only the methods used. Example: vi.mock('$lib/db', () => ({ prisma: { proclamation: { findMany: vi.fn(), findUnique: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn() } } })); Do not create massive unused mocks. --- # Authentication Testing Use: createLocals() Examples: Unauthenticated: createLocals() Authenticated: createLocals(mockUser() as any) Specific roles: createLocals( mockUser({ roleId: 4 }) as any ) --- # Client Test Locators Available: getByRole getByText getByPlaceholder getByAltText getByTestId Unavailable: getByLabel getByDisplayValue --- # Role Queries Always use exact regex names. Preferred: page.getByRole( 'textbox', { name: /^Name$/ } ) Avoid: page.getByRole( 'textbox', { name: 'Name' } ) because substring matching can create strict-mode failures. --- # Select Testing Because selects use selected options instead of bind:value: const element = await page .getByRole( 'combobox', { name: /^Frequency$/ } ) .element(); expect( (element as HTMLSelectElement).value ).toBe('2'); --- # Svelte Component Mocking When mocking Svelte 5 components: Use: vi.mock('$lib/components/example.svelte', () => ({ default: ($anchor: Element) => { const div = document.createElement('div'); $anchor.replaceWith(div); } })); Imports using mocked modules must come after vi.mock(). If variables are needed inside mocks: Use vi.hoisted(). --- # Test Completion Rule After writing tests: Run: npm run test If failures occur: Fix them. Do not report "tests added" without verifying they pass.