This document outlines the comprehensive testing and consistency strategy for the CapOpt Platform, ensuring reliable, schema-aligned, and testable development using Prisma, PostgreSQL, and Cursor as an AI pair.
- β Selector alignment across components, tests, and seeds
- β Schema-aware generation of UI, logic, and test code
- β Reliable test coverage across unit, integration, and E2E layers
- β False validation avoidance, especially with AI-assisted code
- β CI pipeline compatibility using consistent test data and ERD-informed artefacts
| Layer | Toolset | Target | Coverage |
|---|---|---|---|
| Unit | Jest + @testing-library/react | Components, pure logic, hooks | 70% |
| Integration | Jest + Prisma + seeded DB | Pages, API handlers, DB I/O | 20% |
| API Route | node-mocks-http + supertest | /app/api/* |
5% |
| E2E | Playwright | Full stack + UI interaction | 5% |
| Schema | ERD + PlantUML + Markdown Docs | Authoritative structure reference | - |
/lib/testSelectors.ts # β
COMPLETED - Centralized test IDs
/docs/schema-docs/*.schema.md # β
COMPLETED - Schema documentation
/.cursor/rules/ai-aware-testing.mdc # β
COMPLETED - AI prompt rules
/scripts/lint-test-ids.ts # β
COMPLETED - Test ID linter
/jest.config.js # β
COMPLETED - Jest configuration
/jest.setup.js # β
COMPLETED - Enhanced test utilities
/tests/unit/components/*.test.tsx # β
COMPLETED - Complex component tests
/tests/integration/api/*.test.ts # β
COMPLETED - API integration tests
/playwright.config.ts # β
COMPLETED - E2E configuration
/docs/gap-analysis-report.md # β
COMPLETED - Gap analysis
{
"devDependencies": {
"@testing-library/react": "^16.3.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/user-event": "^14.0.0",
"jest": "^29.0.0",
"jest-environment-jsdom": "^29.0.0",
"@types/jest": "^29.0.0",
"playwright": "^1.40.0",
"supertest": "^6.0.0",
"@types/supertest": "^2.0.0",
"msw": "^2.0.0",
"@faker-js/faker": "^9.0.0"
}
}{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:unit": "jest tests/unit",
"test:integration": "jest tests/integration",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed",
"lint:test-ids": "ts-node scripts/lint-test-ids.ts",
"lint:test-ids:fix": "ts-node scripts/lint-test-ids.ts --fix",
"validate:schema": "ts-node scripts/validate-schema.ts",
"test:setup": "npm run db:reset && npm run seed",
"test:ci": "npm run test:setup && npm run test && npm run test:e2e"
}
}- Enhanced Test Selectors - Comprehensive test IDs for all entities
- Complex Component Testing Patterns - Hierarchy, bulk operations, real-time editing
- Enhanced Jest Setup - Advanced test utilities and mock data factories
- Complex API Testing Patterns - Include clauses, query parameters, cache control
- Validation Schema Testing - Complex Zod schemas with arrays, enums, transforms
- Error Handling Testing - Database errors, validation errors, edge cases
- Hierarchy Operations Testing - Parent-child relationships, circular reference detection
- Real-time Editing Testing - Auto-save, concurrent editing, form validation
- Drag-and-Drop Testing - Canvas reordering, drop target validation
- Enhanced Schema Documentation - Complete documentation for all 40+ entities
- Complex Test Data Factories - Realistic Australian business data
- Testing Strategy Updates - Comprehensive documentation and examples
/**
* @test ComponentName.test.tsx
* @schema EntityName { field1, field2, field3 }
* @testIds from `lib/testSelectors.ts`
* @seed from `/prisma/seed/entity/`
* @note Demonstrates AI-aware testing strategy
*/
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { entityTestIds } from '@/lib/testSelectors';
describe('ComponentName', () => {
const mockData = global.testUtils.createMockEntity();
it('should render with valid test IDs', () => {
render(<Component data={mockData} />);
expect(screen.getByTestId(entityTestIds.componentContainer)).toBeInTheDocument();
expect(screen.getByTestId(entityTestIds.inputField)).toBeInTheDocument();
// Validate all test IDs are valid
const validation = global.testUtils.validateTestIds(screen.container);
expect(validation.valid).toBe(true);
});
it('should handle complex user interactions', async () => {
const user = userEvent.setup();
render(<Component data={mockData} />);
// Test real-time editing
const changes = [
{ type: 'input', target: entityTestIds.inputField, value: 'New Value' },
{ type: 'select', target: entityTestIds.selectField, value: 'OPTION_1' }
];
await global.testUtils.simulateRealTimeEditing(screen, changes);
// Verify changes were applied
expect(screen.getByDisplayValue('New Value')).toBeInTheDocument();
});
});/**
* @test entity.test.ts
* @schema EntityName API endpoints
* @testIds from `lib/testSelectors.ts`
* @seed from `/prisma/seed/entity/`
* @note Complex API testing patterns
*/
describe('Entity API', () => {
it('should handle complex query parameters', async () => {
const req = createMockRequest(
'GET',
'/api/entity?include=relation1,relation2&enterpriseId=test-enterprise'
);
const res = createMockResponse();
await GET(req, res);
expect(prisma.entity.findMany).toHaveBeenCalledWith({
where: { enterpriseId: 'test-enterprise' },
include: { relation1: true, relation2: true },
orderBy: expect.any(Array)
});
});
it('should validate complex metadata fields', async () => {
const complexData = {
name: 'Test Entity',
metadata: {
legalName: 'Test Corp Pty Ltd',
abn: '12345678901',
sectors: ['COAL', 'PRODUCTION'],
complianceRequirements: ['WHS', 'ISO14001']
}
};
const req = createMockRequest('POST', '/api/entity', complexData);
const res = createMockResponse();
await POST(req, res);
expect(prisma.entity.create).toHaveBeenCalledWith({
data: expect.objectContaining(complexData),
include: expect.any(Object)
});
});
});/**
* @test entity.spec.ts
* @schema EntityName E2E workflows
* @testIds from `lib/testSelectors.ts`
* @seed from `/prisma/seed/entity/`
* @note Full-stack user journey testing
*/
test('complete entity creation workflow', async ({ page }) => {
await page.goto('/entities');
// Navigate to create form
await page.click('[data-testid="test-entity-create-button"]');
// Fill complex form
await page.fill('[data-testid="test-input-entity-name"]', 'New Entity');
await page.fill('[data-testid="test-input-legal-name"]', 'New Entity Pty Ltd');
await page.fill('[data-testid="test-input-abn"]', '12345678901');
await page.selectOption('[data-testid="test-input-industry"]', 'MINING');
// Submit form
await page.click('[data-testid="test-entity-save-button"]');
// Verify success
await expect(page.locator('[data-testid="test-entity-success-message"]')).toBeVisible();
});# Check for invalid test IDs
npm run lint:test-ids
# Auto-fix test ID issues
npm run lint:test-ids:fix# Validate schema alignment
npm run validate:schema- Unit Tests: 70% minimum coverage
- Integration Tests: 20% minimum coverage
- E2E Tests: 5% minimum coverage
- Total Coverage: 90% minimum
- All test IDs must be valid
- All components must have test IDs
- All API endpoints must be tested
- All validation schemas must be tested
- All error scenarios must be covered
name: Test Suite
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm run db:reset
- run: npm run seed
- run: npm run test:unit
- run: npm run test:integration
- run: npm run test:e2e
- run: npm run lint:test-ids
- run: npm run validate:schema{
"husky": {
"hooks": {
"pre-commit": "npm run lint:test-ids && npm run test:unit",
"pre-push": "npm run test:integration && npm run test:e2e"
}
}
}// β
CORRECT - Import from centralized file
import { entityTestIds } from '@/lib/testSelectors';
<div data-testid={entityTestIds.container}>
<input data-testid={entityTestIds.inputField} />
</div>
// β INCORRECT - Hardcoded test IDs
<div data-testid="test-container">
<input data-testid="test-input" />
</div>// β
CORRECT - Use test utilities
const mockEntity = global.testUtils.createMockEntity({
name: 'Custom Name',
status: 'ACTIVE'
});
// β INCORRECT - Manual mock data
const mockEntity = {
id: 'test-id',
name: 'Test Entity',
// ... missing required fields
};// β
CORRECT - Validate against schema
const validation = global.testUtils.validateComplexForm(formData, entitySchema);
expect(validation.valid).toBe(true);
// β
CORRECT - Test Australian business data
expect(mockEntity).toBeAustralianBusinessData();// β
CORRECT - Test error scenarios
it('should handle validation errors', async () => {
const invalidData = { name: '', status: 'INVALID' };
const req = createMockRequest('POST', '/api/entity', invalidData);
const res = createMockResponse();
await POST(req, res);
expect(res.status).toHaveBeenCalledWith(400);
expect(res.json).toHaveBeenCalledWith(
expect.objectContaining({ error: 'Validation failed' })
);
});# Check for invalid test IDs
npm run lint:test-ids
# Common fixes:
# 1. Import test IDs from lib/testSelectors.ts
# 2. Use correct test ID constants
# 3. Update testSelectors.ts if new IDs are needed# Validate schema alignment
npm run validate:schema
# Common fixes:
# 1. Update schema documentation
# 2. Align test data with schema
# 3. Update validation schemas# Generate coverage report
npm run test:coverage
# Common fixes:
# 1. Add missing test cases
# 2. Test error scenarios
# 3. Test edge cases// Optimize test performance
describe('Performance Tests', () => {
it('should handle large datasets efficiently', () => {
const largeDataset = global.testUtils.createMultipleEntities(1000);
expect(largeDataset).toHaveLength(1000);
});
it('should handle complex hierarchies efficiently', () => {
const hierarchy = global.testUtils.createEntityHierarchy(5, 3);
expect(hierarchy).toBeDefined();
});
});- Unit Tests: 70%+ coverage achieved
- Integration Tests: 20%+ coverage achieved
- E2E Tests: 5%+ coverage achieved
- Total Coverage: 90%+ coverage achieved
- Test ID Validation: 100% valid test IDs
- Schema Alignment: 100% schema documentation complete
- Error Coverage: 100% error scenarios tested
- Performance: All tests complete within time limits
- Phase 1: Critical fixes completed
- Phase 2: API testing completed
- Phase 3: Advanced features completed
- Phase 4: Documentation completed
- Run test suite:
npm run test - Validate test IDs:
npm run lint:test-ids - Check coverage:
npm run test:coverage - Run E2E tests:
npm run test:e2e
- Weekly: Review test coverage reports
- Monthly: Update schema documentation
- Quarterly: Review and update test patterns
- Annually: Comprehensive strategy review
- Visual Regression Testing: Add visual testing for UI components
- Performance Testing: Add performance benchmarks
- Security Testing: Add security-focused test scenarios
- Accessibility Testing: Add accessibility compliance tests
Last Updated: January 2024
Version: 2.0.0
Status: β
Implementation Complete