How to Test Changes Made to Orca's Core Modules: The Complete Guide

Use Vitest to validate pure logic in src/shared with pnpm test, and Playwright to verify Electron integration via pnpm test:e2e.

The stablyai/orca repository isolates its business logic in src/shared, making it straightforward to verify changes without booting the full Electron application. Understanding the dual testing architecture—Vitest for fast unit feedback and Playwright for end-to-end confidence—ensures modifications to core modules remain stable across releases.

Testing Architecture Overview

Orca employs a layered testing strategy that maps directly to its directory structure. Pure TypeScript logic resides in src/shared and is exercised by Vitest in a Node.js environment, while the full Electron application lifecycle is validated by Playwright specs under tests/e2e.

Unit Testing with Vitest

The Vitest configuration in [config/vitest.config.ts](https://github.com/stablyai/orca/blob/main/config/vitest.config.ts#L4-L14) runs tests in a Node environment and resolves repository aliases like @renderer. It automatically discovers any file matching src/**/*.test.ts.

Key infrastructure files:

  • Configuration: config/vitest.config.ts defines the test environment and coverage settings
  • Test location: Unit tests live alongside source code or in src/shared/__tests__/
  • Scripts: package.json maps pnpm test to the Vitest runner

End-to-End Testing with Playwright

Playwright manages the Electron binary lifecycle via [tests/playwright.config.ts](https://github.com/stablyai/orca/blob/main/tests/playwright.config.ts). This configuration launches the packaged app in headless or headful mode, allowing specs to interact with the actual UI while exercising the core modules indirectly through user workflows.

Running the Test Suite

Execute the appropriate command based on the scope of your changes:

  • pnpm test – Runs Vitest unit tests against src/**/*.test.ts files. Ideal for rapid feedback on logic changes in src/shared.
  • pnpm test:e2e – Runs the full Playwright suite in headless Electron. Use this before committing to ensure integration stability.
  • pnpm test:e2e:headful – Launches Playwright with a visible Electron window for debugging UI-related failures.

Note: The npm scripts automatically invoke ensure-native-runtime.mjs to guarantee the correct Node/Electron runtime is available before testing begins.

Writing Unit Tests for Core Modules

Core modules are pure TypeScript functions that can be imported directly without Electron. For example, [src/shared/workspace-session-schema.ts](https://github.com/stablyai/orca/blob/main/src/shared/workspace-session-schema.ts) exports parseWorkspaceSession, a zod-based validator for persisted workspace state.

Create a test file adjacent to your module or in src/shared/__tests__/:

// src/shared/__tests__/workspace-session-schema.test.ts
import { parseWorkspaceSession } from '../workspace-session-schema'

describe('parseWorkspaceSession', () => {
  it('accepts a valid session object', () => {
    const raw = {
      activeRepoId: null,
      activeWorktreeId: null,
      activeTabId: null,
      tabsByWorktree: {},
      terminalLayoutsByTabId: {}
    }
    const result = parseWorkspaceSession(raw)
    expect(result.ok).toBe(true)
  })

  it('rejects malformed data with detailed error paths', () => {
    const raw = { activeRepoId: 123 } // Invalid type: should be string or null
    const result = parseWorkspaceSession(raw)
    expect(result.ok).toBe(false)
    if (!result.ok) {
      expect(result.error.issues[0].path).toContain('activeRepoId')
    }
  })
})

Run this specific test in isolation:

pnpm test src/shared/__tests__/workspace-session-schema.test.ts

Adding Integration Tests with Playwright

When changes affect how core modules interact with the Electron main process or renderer, add a Playwright spec under tests/e2e/. These tests launch the actual application binary and verify behavior through the UI.

Example integration test for workspace session persistence:

// tests/e2e/workspace-lifecycle.spec.ts
import { test, expect } from '@playwright/test'

test('persists workspace session across reloads', async ({ page }) => {
  // Playwright automatically starts the Electron app per tests/playwright.config.ts
  await page.click('text=New Worktree')
  await page.fill('[data-testid="worktree-name"]', 'test-worktree')
  await page.click('text=Create')
  
  // Verify session storage contains valid state
  const session = await page.evaluate(() => 
    window.localStorage.getItem('workspaceSession')
  )
  expect(session).toContain('test-worktree')
  
  // Reload and verify restoration
  await page.reload()
  await expect(page.locator('text=test-worktree')).toBeVisible()
})

Execute this specific spec:

pnpm test:e2e -- tests/e2e/workspace-lifecycle.spec.ts

Summary

  • Unit tests for src/shared logic use Vitest and reside in *.test.ts files alongside the source code.
  • Integration tests use Playwright under tests/e2e/ to validate core modules within the full Electron context.
  • Fast feedback: Run pnpm test for unit tests during development; reserve pnpm test:e2e for pre-commit validation.
  • Validation: The parseWorkspaceSession function in src/shared/workspace-session-schema.ts demonstrates how schema validation is tested in isolation before reaching the UI.

Frequently Asked Questions

Where should I place new unit tests for core modules?

Place them in src/shared/__tests__/ or co-locate them as *.test.ts files next to the module being tested. Vitest automatically discovers any file matching src/**/*.test.ts according to the configuration in config/vitest.config.ts.

How do I run only a specific test file during development?

Pass the file path directly to the test command. For Vitest: pnpm test src/shared/my-module.test.ts. For Playwright: pnpm test:e2e -- tests/e2e/my-spec.spec.ts. This filters the test runner to only execute the specified file.

Can I test Electron-specific APIs in unit tests?

No, unit tests run in a pure Node.js environment without Electron APIs. Keep core modules in src/shared free of Electron dependencies so they remain testable with Vitest. Electron-specific logic should be tested via Playwright under tests/e2e/.

What should I do if Playwright tests fail after changing a core module?

First, verify the unit tests for that module pass with pnpm test. If unit tests pass but e2e fails, the issue likely involves serialization or IPC between the main and renderer processes. Check that your changes properly handle data transfer across the Electron boundary, as core modules often validate data coming from the main process.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →