Skip to content

Testing Guide

Juca uses Vitest for unit/integration tests, Testing Library for component tests, and Playwright for E2E tests. This page covers running tests, writing tests, and the project’s test conventions.

ToolVersionPurpose
Vitest^4.0.18Unit and integration test runner
@vitest/coverage-v8^4.0.18V8 coverage provider
Playwright^1.58.0E2E testing (Chromium only)
Testing Library^16.3.2React component test utilities
jest-dom^6.9.1DOM assertion matchers
user-event^14.6.1User interaction simulation
jsdom^28.0.0Browser environment for unit tests
Terminal window
# Unit tests (single run)
npm test
# Watch mode (re-runs on file changes)
npm run test:watch
# Coverage report
npm run test:coverage
# E2E tests
npm run test:e2e
# E2E with visible browser
npm run test:e2e:headed
# E2E with UI mode (visual debugger)
npm run test:e2e:ui

Tests live alongside the code they test:

Code LocationTest LocationExample
src/app/api/unified/sessions/route.tssrc/app/api/unified/sessions/__tests__/route.test.tsAPI route test
src/lib/blocks/types.tssrc/lib/blocks/__tests__/types.test.tsLibrary test
src/components/blocks/DiagnosisBlock.tsxsrc/components/blocks/__tests__/DiagnosisBlock.test.tsxComponent test
src/actions/briefing.tssrc/actions/__tests__/briefing.test.tsServer action test
(E2E flows)e2e/*.spec.tsEnd-to-end specs
(E2E data)e2e/fixtures/briefing-blocks.tsShared fixtures

Vitest test files can specify their environment:

// @vitest-environment node
// Use for: server-side code (jsPDF, SQLite, file system)
// @vitest-environment jsdom
// Use for: component tests (React, DOM manipulation)

Default environment is jsdom (configured in vitest.config.ts).

import { createDiagnosisData } from '@/lib/blocks/types';
import { makeBlock } from './helpers';
describe('createDiagnosisData', () => {
it('creates diagnosis block from analysis', () => {
const analysis = { /* mock CaseAnalysis */ };
const data = createDiagnosisData(analysis);
expect(data).toHaveProperty('situation');
expect(data).toHaveProperty('area');
});
});

The makeBlock() test helper creates block fixtures with type and data overrides:

const block = makeBlock({
type: 'diagnosis',
data: { situation: 'pesquisando', area: 'civil' }
});

E2E tests use Playwright with API mocking via page.route():

import { test, expect } from '@playwright/test';
test('renders briefing blocks', async ({ page }) => {
// Mock the API response
await page.route('/api/unified/analyze', async route => {
await route.fulfill({
json: { success: true, data: { blocks: mockBlocks } }
});
});
await page.goto('/');
await expect(page.getByTestId('work-canvas')).toBeVisible();
});

Playwright configuration highlights:

SettingValue
BrowserChromium only (Desktop Chrome)
Paralleltrue
Retries2 in CI, 0 locally
ScreenshotsOn failure only
TracesOn first retry
Base URLhttp://localhost:3000
AreaTest FilesCoverage
API Routes (src/app/api/)51Good
Backend lib (src/lib/)48Good
Components (src/components/)24Partial (ui/ and blocks/ covered)
Server Actions (src/actions/)2Partial
E2E specs (e2e/)8Main flows covered

GitHub Actions runs on every push to main/develop and on PRs to main:

  1. lint-and-build job: npm cinpm run lintnpm run build
  2. test-unit job: npm cinpm testnpm run test:coverage

Coverage artifacts are uploaded with 14-day retention.