Enigma uses a hybrid testing approach to handle the complexities of testing both frontend React components and backend plugin system functionality.
- Location:
src/**/*.test.js,src/**/*.test.jsx - Framework: Vitest
- Run with:
npm testornpm run test:run - CI: Runs on every push/PR via
.github/workflows/vitest.yml
All frontend tests run smoothly with vitest's default configuration.
The backend plugin system uses better-sqlite3, a native Node.js module that causes segmentation faults when loaded in vitest's worker pool. To work around this, we use two approaches:
- Location:
backend/test-scripts/*.js - Framework: Plain Node.js (no test framework)
- Run with:
npm run test:backend-standalone - CI: Runs in both workflows
- What it tests:
- Plugin database isolation
- Data separation between plugins
- File system operations
- Database size checking
Example output:
🧪 Testing Plugin Database Isolation...
✅ PASS: Plugin databases are separate files
✅ PASS: Plugin A can store data
✅ PASS: Plugin B cannot access Plugin A tables
✅ PASS: Plugin B can store independent data
✅ PASS: Plugin A still cannot see Plugin B data
✅ PASS: Can calculate database file size
- Location:
tests/integration/backend-plugins.test.js - Framework: Vitest
- Run with:
npm run test:backend-integration - Status: Placeholder tests, ready for HTTP API testing
- Requires: Backend server running (
cd backend && npm start)
These tests will verify plugin functionality through HTTP endpoints once the plugin API is exposed.
- Location:
backend/src/plugins/*.test.js - Status: Cannot run with vitest (worker fork crashes)
- Purpose: Documentation and reference for expected behavior
- Options:
- Convert to standalone scripts (like approach #1)
- Convert to integration tests (like approach #2)
- Run with Node's native test runner (requires rewriting)
- Run with Jest
--runInBand(requires different test framework)
npm test
# or
npm run test:runnpm run test:backend-standalonenpm run test:run && npm run test:backend-standalonenpm test -- src/pages/Sudoku/Sudoku.test.jsnpm testRuns on every push and PR:
- Frontend tests (
npm run test:run) - Backend plugin standalone tests (
npm run test:backend-standalone)
Runs when backend or integration test files change:
- Backend plugin standalone tests
- Integration tests (currently placeholders)
Problem: better-sqlite3 is a native Node.js addon that causes segmentation faults when loaded in vitest's worker threads/forks.
Solutions tried:
- ❌ Different vitest pool configurations (threads, forks, vmThreads)
- ❌ Lazy loading in
beforeAllhooks - ❌ Version consolidation (both root and backend use same version)
- ❌ Single fork mode
Root cause: Native modules and worker pools fundamentally don't mix well.
Final solution:
- ✅ Standalone scripts run in main Node.js process (no workers)
- ✅ Tests real SQLite behavior (not mocked)
- ✅ Fast and reliable
- ✅ No test framework dependency issues
Create *.test.js or *.test.jsx files next to your components. They'll automatically be picked up by vitest.
- For quick verification: Add to or create new scripts in
backend/test-scripts/ - For API testing: Add to
tests/integration/backend-plugins.test.js - For reference: Keep comprehensive unit tests in
backend/src/plugins/*.test.jsas documentation
Run coverage reports:
npm run test:coverageView in browser:
npm run test:ui:coverage- These should no longer appear after excluding
backend/src/plugins/*.test.js - If they return, check
vite.config.jsexclude patterns
- Ensure you're in the root directory
- Check that
better-sqlite3is installed:npm list better-sqlite3 - Verify Node.js version (requires v18+):
node --version
- Backend server must be running for integration tests
- Start with:
cd backend && npm start - Check backend is available at
http://localhost:3000/api/health