Caret uses a layered test strategy: Vitest for the React frontend and all Node backend services, and Pytest for the Python AI service. Unit tests validate individual functions, components, and classes in complete isolation from the network and database. Integration tests cover API boundaries, protocol behaviour, and multi-layer flows. End-to-end browser tests are planned via Playwright but are not yet configured in the repository — until they are, the collaboration debug harness serves as the primary manual E2E check.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/arrozet/caret/llms.txt
Use this file to discover all available pages before exploring further.
Test Tooling at a Glance
| Area | Framework | Environment |
|---|---|---|
| Frontend | Vitest 4, jsdom, React Testing Library | jsdom (browser-like) |
| Node services (api-gateway, auth, document, collab) | Vitest 3 | Node |
| Python AI service | Pytest, pytest-asyncio | Python 3.x |
| E2E | Not yet configured — Playwright planned | — |
Test File Locations
Tests live close to the code they cover. The following tree shows the canonical paths for each service:Frontend Testing
The frontend uses Vitest 4 with a jsdom environment and React Testing Library for rendering and interacting with components. There are two separate Vitest configuration files —vitest.unit.config.ts and vitest.integration.config.ts — so unit and integration suites can be run independently with different settings.
src/test/setup.ts runs before every test suite and takes care of installing @testing-library/jest-dom matchers and mocking browser APIs that jsdom does not implement, such as matchMedia and scrollIntoView.
Frontend Commands
What the Frontend Tests Cover
- Component states — rendering, conditional visibility, and error states for UI components.
- Hooks and stores — Zustand stores and custom React hooks in isolation with mocked Supabase and API clients.
- Editor utilities and extensions — Tiptap/ProseMirror extension logic and document transformation helpers.
- AI streaming UI — chunk rendering and markdown display with mocked SSE streams.
- Collaboration helpers — URL/session/presence utilities with mocked WebSocket and Y.js boundaries.
Node Service Testing
All four Node backend services share the same Vitest-based testing pattern. Use the commands below from inside each service directory, or use the Makefile shortcuts from the repository root.Per-Service Commands
Makefile Shortcuts (From Repo Root)
What the Node Tests Cover
- API Gateway — proxy routing logic, CORS header enforcement, rate-limit behaviour, and OpenAPI metadata endpoints.
- Document service — request validation, repository and service-layer behaviour, permission checks, document CRUD flows, and correct HTTP status codes.
- Auth service — JWT validation middleware and shared error-handling middleware.
- Collab service — Y.js sync and awareness message handling at the protocol layer,
CollabPersistenceServicein isolation from WebSocket handling, JWT handshake validation, and repository behaviour fordocument_collab_updatesanddocument_collab_snapshots.
AI Service Testing (Python / Pytest)
The Python AI service uses Pytest with pytest-asyncio for async test cases. Run tests from theapp/backend/ai-service directory using uv.
AI Service Commands
Makefile Shortcuts (From Repo Root)
What the AI Tests Cover
- Pydantic schemas — request/response model validation and serialisation edge cases.
- Agent orchestration — prompt assembly, dependency injection, and model catalog selection without calling real LLM providers.
- SSE chunk behaviour — streaming output correctness with mocked provider clients.
- Embedding indexing and search — pgvector query construction and result ranking with mocked embedding clients.
- Repository behaviour — SQL query logic for AI tables and pgvector searches.
Linting and Formatting
Linting and format checks are a required step before committing. They run as the first stage in the CI pipeline.Frontend and Node Services
Makefile Shortcuts
Python AI Service
The AI service uses Ruff for linting and Pyright for static type checking, both invoked through uv:Test Principles
These principles guide how tests are written across all services:- Deterministic and network-free — unit tests must not make real HTTP, database, WebSocket, or LLM calls. Mock all external boundaries.
- Mock at the right boundary — mock Supabase, Drizzle, SQLAlchemy, WebSocket, and LLM clients in unit tests; use real HTTP in integration tests.
- API boundary behaviour in integration tests — route-level status codes, error shapes, and middleware interactions belong in integration tests, not unit tests.
- Regression tests at the lowest useful layer — when fixing a bug, add a test at the layer where the bug lived.
- No production data — never connect to real Supabase user data in automated tests. Use isolated test projects or mocked clients.
- No secrets in test files — keep API keys, JWT secrets, and database URLs out of test source files and snapshots.
The collaboration debug harness at
http://localhost:5173/debug/collab-harness is the recommended tool for manual WebSocket and Y.js synchronisation testing. It lets you simulate multiple connected clients from a single browser tab, observe sync messages, and inspect awareness state — useful for scenarios that are difficult to cover with automated tests.