Testing
Kangentic uses a three-tier testing strategy. Each tier targets a different layer of the application, and each has its own tradeoffs between speed, coverage, and realism.
Unit Tests
Section titled “Unit Tests”npm run test:unit- Runner: Vitest
- Speed: Sub-second
- What to test: Pure logic - parsers, filters, state machines, utility functions
- No build needed, no browser, no Electron
Unit tests live in tests/unit/. They’re fast and focused - test a function’s input/output without any framework overhead.
There is also an opt-in integration tier in tests/integration/. Those tests hit real CLIs, the file system, or the network, so while vitest.config.ts includes them, npm run test:unit pins the tests/unit path and skips them. Run them on demand with npx vitest run tests/integration/.
UI Tests
Section titled “UI Tests”npx playwright test --project=ui- Runner: Playwright with headless Chromium
- Speed: Fast - hundreds of tests run headless in parallel
- What to test: React components, forms, dialogs, drag-and-drop, board interactions
- No build needed - runs against the Vite dev server (auto-started by Playwright)
UI tests live in tests/ui/. They use a full in-memory mock of window.electronAPI (injected via addInitScript()) that supports complete CRUD for projects, tasks, swimlanes, actions, sessions, config, and attachments.
Use window.__mockPreConfigure(fn) to set up mock state before React mounts.
E2E Tests
Section titled “E2E Tests”npm run buildnpx playwright test --project=electron- Runner: Playwright with
_electron.launch() - Speed: Slower - opens real windows (no headless mode on Windows)
- What to test: PTY sessions, terminal rendering, session lifecycle, shell detection, config persistence
- Build required before running
E2E tests live in tests/e2e/. These exercise the full Electron application with real IPC, real file I/O, and real terminal sessions.
Captures
Section titled “Captures”npm run capturePlaywright also defines a fourth project, captures (tests/captures/, *.capture.ts files). It is not a test tier: it drives the same mocked renderer as the UI tier in headless Chromium to produce screenshots and screen recordings of staged app states for marketing and documentation. Run it on demand with npm run capture.
Decision Guide
Section titled “Decision Guide”| What you’re testing | Tier |
|---|---|
| Pure function, parser, utility | Unit |
| Component rendering, user interaction, form validation | UI |
| Real IPC, PTY spawning, terminal output, file I/O | E2E |
Running All Tests
Section titled “Running All Tests”npm run test:unit # Unit tests (Vitest)npx playwright test --project=ui --project=electron # UI + E2E tests (Playwright)Continuous Integration
Section titled “Continuous Integration”Every push and pull request runs the full suite on GitHub Actions. Lint, type check, and a production build each run as their own standalone job, and the three test tiers run as sharded matrices on Linux (Node 22):
| Tier | Where it runs in CI | Shards |
|---|---|---|
| Unit (Vitest) | Linux | 3 |
| UI (Playwright, headless Chromium) | Linux | 9 |
| E2E (Electron) | Linux under xvfb | 5 |
The E2E tier runs only on Linux in CI. The suite is platform-neutral, so Linux covers the macOS and Linux users while the team dogfoods the Windows build locally. On CI each E2E shard runs at workers=8; any local (non-CI) run, on every OS, pins the E2E project to workers=1 - Windows cannot run concurrent electron.launch(), and a local run on any platform should not spawn a swarm of app windows - so a local E2E run is serial and opens real windows.
Next steps
Section titled “Next steps”See also:
- Contributing - development setup and conventions
- Architecture - what the three tiers map onto
Kangentic is free and open source. A star helps other people find it.
Star on GitHub