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

> Learn to test Orca core module changes. Use Vitest for shared logic validation and Playwright for Electron integration. This guide ensures your modifications are robust.

- Repository: [Stably/orca](https://github.com/stablyai/orca)
- Tags: tutorial
- Published: 2026-05-25

---

**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)](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`](https://github.com/stablyai/orca/blob/main/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`](https://github.com/stablyai/orca/blob/main/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)](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)](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__/`:

```typescript
// 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:

```bash
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:

```typescript
// 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:

```bash
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`](https://github.com/stablyai/orca/blob/main/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`](https://github.com/stablyai/orca/blob/main/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.