Skip to content
ChatJS
Esc
navigateopen⌘Jpreview
On this page

Testing

Unit tests and end-to-end testing with Vitest and Playwright

ChatJS includes two testing layers: Vitest for unit tests and Playwright for end-to-end browser tests. For AI-specific quality evaluation, see Evaluations.

Unit Tests (Vitest)

Unit tests cover individual functions and modules. They live alongside the source code as *.test.ts files. Vitest is configured in vitest.config.ts to exclude *.e2e.ts files so E2E tests never run as unit tests.

# Run all unit tests
bun test:unit

Tests use standard Vitest patterns with vi.mock() for mocking dependencies:

import { describe, it, expect, vi } from "vitest";

describe("myFunction", () => {
  it("returns expected result", () => {
    expect(myFunction("input")).toBe("output");
  });
});

Mocking AI models

For tests that interact with AI models, mock the model resolution layer rather than the AI SDK directly:

vi.mock("../ai/app-models", () => ({
  getAppModelDefinition: vi.fn().mockImplementation((modelId: string) => {
    const models: Record<
      string,
      { pricing?: { input: string; output: string } }
    > = {
      "test-model": { pricing: { input: "0.00001", output: "0.00003" } },
    };
    return Promise.resolve(models[modelId] || {});
  }),
}));

End-to-End Tests (Playwright)

Playwright tests simulate real user interactions in a browser. Configuration is in playwright.config.ts.

# Run E2E tests
bun test:e2e

Test projects

The Playwright config defines five test projects that run in dependency order:

Project File Depends On Purpose
setup:auth auth.setup.e2e.ts - Authenticate and save session
setup:reasoning reasoning.setup.e2e.ts setup:auth Prepare reasoning model state
chat chat.e2e.ts setup:auth Core chat interactions
reasoning reasoning.e2e.ts setup:reasoning Reasoning model tests
artifacts artifacts.e2e.ts setup:auth Canvas and document tests

CI behavior

Setting Local CI
Workers Unlimited 1
Retries 1 2
Server Reuse running dev server Start fresh
Traces On first retry On first retry

Writing E2E tests

Create test files in the tests/ directory using the *.e2e.ts naming convention. Tests have access to authenticated sessions via Playwright’s storage state:

import { test, expect } from "@playwright/test";

test("send a message and get a response", async ({ page }) => {
  await page.goto("/");
  await page.fill('[data-testid="chat-input"]', "Hello");
  await page.click('[data-testid="send-button"]');
  await expect(page.locator('[data-testid="assistant-message"]')).toBeVisible();
});

Running All Tests

# Unit + E2E
bun test

This runs Playwright first, then Vitest.

Was this page helpful?