Skip to content

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.

Terminal window
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/.

Terminal window
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.

Terminal window
npm run build
npx 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.

Terminal window
npm run capture

Playwright 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.

What you’re testingTier
Pure function, parser, utilityUnit
Component rendering, user interaction, form validationUI
Real IPC, PTY spawning, terminal output, file I/OE2E
Terminal window
npm run test:unit # Unit tests (Vitest)
npx playwright test --project=ui --project=electron # UI + E2E tests (Playwright)

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):

TierWhere it runs in CIShards
Unit (Vitest)Linux3
UI (Playwright, headless Chromium)Linux9
E2E (Electron)Linux under xvfb5

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.

See also:

Kangentic is free and open source. A star helps other people find it.

Star on GitHub