testing-reactlisted
Install: claude install-skill iliaal/whetstone
## Test Classification
| Type | Tool | Target | File pattern |
|------|------|--------|-------------|
| Unit | Vitest | Pure functions, utilities, services | Co-located `*.test.ts` |
| Component | Vitest + RTL | React components | Co-located `*.test.tsx` |
| Hook | Vitest + RTL | Custom hooks | Co-located `*.test.ts` |
| E2E | Playwright | User flows, critical paths | Separate `e2e/` directory |
Default to component tests for React components. Unit tests for pure functions and service classes. See [e2e-testing](references/e2e-testing.md) for Playwright patterns.
## Setup
Vitest config: `environment: 'jsdom'`, `globals: true`, `setupFiles` pointing to a file that imports `@testing-library/jest-dom/vitest`. Use `@vitejs/plugin-react` and mirror path aliases from `tsconfig.json`.
## Critical Rules
- **Query priority**: `getByRole` > `getByLabelText` > `getByPlaceholderText` > `getByText` > `getByTestId`. Use `data-testid` only when no accessible query works.
- **Mock boundaries**: Mock API services, navigation, and external providers. Render child components and UI libraries real for integration confidence.
- **One behavior per test** with AAA structure. Name tests `should <behavior> when <condition>`.
- **Async**: Use `findBy*` for async elements, `waitFor` after state-triggering actions, `vi.useFakeTimers()` for debounce/timer logic.
- **User events**: Prefer `userEvent` over `fireEvent` for realistic interactions.
- **Cleanup**: `vi.clearAllMocks()` in `beforeEach`. Rec