openpencil/packages/docs/development/testing.md
2026-09-10 21:41:10 +03:00

4.7 KiB

Testing

Overview

Type Framework Command Location
E2E visual regression Playwright bun run test tests/e2e/
Figma CDP reference Playwright bun run test:figma tests/figma/
Unit tests bun:test bun run test:unit tests/engine/

E2E Visual Regression

Playwright creates shapes on the canvas and compares screenshots against baseline PNGs.

bun run test              # Run tests, compare against baselines
bun run test:update       # Regenerate baseline screenshots

Server ownership and worktrees

The canonical playwright.config.ts starts Vite from the current checkout and waits for its HTTP URL. Vite starts and stops its MCP companion. Server reuse is off by default and always off in CI, so a test run cannot silently attach to another checkout on the default port.

Defaults are app port 1420 and MCP port 7600. For concurrent worktrees, choose a free, distinct pair:

OPENPENCIL_TEST_PORT=1482 OPENPENCIL_TEST_MCP_PORT=7682 \
  bunx playwright test tests/e2e/settings --project=openpencil

The configuration passes the app origin and MCP port to Vite; the companion receives matching CORS configuration and a port-specific socket/discovery directory. Port conflicts fail rather than silently selecting another endpoint. Do not reuse ports across concurrent runs.

For intentional local debugging against an already-running matching server, set OPENPENCIL_TEST_REUSE_SERVER=1. Do not use reuse for baseline comparisons: HTTP readiness does not establish checkout identity. Start a matching custom-port preview with OPENPENCIL_DEV_ORIGIN=http://localhost:1482 OPENPENCIL_DEV_MCP_PORT=7682 bun run dev --port 1482. Portless remains the preferred interactive worktree preview workflow, separate from managed fixed-port tests.

How It Works

  1. Tests load the editor in a headless browser
  2. The editor signals readiness via a data-ready HTML attribute
  3. Tests create shapes via the editor's API
  4. Screenshots are taken and compared against baselines using toMatchSnapshot
  5. Page is reused across test cases for speed (~2s total)

No-Chrome Test Mode

The editor supports a test mode that hides UI chrome (toolbar, panels) for clean screenshot capture. Activated via URL parameter.

Figma CDP Reference Tests

A separate Playwright project connects to Figma via Chrome DevTools Protocol to capture reference screenshots for pixel-perfect comparison.

bun run figma:debug       # Launch Figma with debugging port
bun run test:figma        # Connect to Figma, capture references

Requires Figma desktop app running with --remote-debugging-port=9222.

Unit Tests

Engine unit tests use bun:test and target < 50ms execution:

bun run test:unit

Tests cover:

  • Scene graph CRUD operations, parent-child relationships, z-ordering, hit testing
  • Fig-import pipeline — node type mapping, transforms, fills/strokes/effects, gradients, images, arcs, nested hierarchies (tests/engine/io/fig/import/legacy/*.test.ts)
  • Layout computation — Yoga auto-layout: direction, gap, padding, justify, align, child sizing (fixed/fill/hug), cross-axis sizing, wrap, nested layouts (tests/engine/layout/)

Writing Unit Tests

import { describe, expect, it } from 'bun:test'
import { SceneGraph } from '@open-pencil/scene-graph'

describe('SceneGraph', () => {
  it('creates and retrieves a node', () => {
    const sg = new SceneGraph()
    const node = sg.createNode('RECTANGLE', sg.root, { name: 'Test' })
    expect(sg.getNode(node.guid)).toBeDefined()
  })
})

E2E Test Coverage

Test file Scope
tests/e2e/layers-panel.spec.ts Layers panel tree structure, visibility toggles, selection sync
tests/e2e/visual.spec.ts Visual regression screenshots for shapes and rendering

Test Helpers

File Purpose
tests/helpers/canvas.ts Canvas setup and interaction utilities
tests/helpers/figma.ts Figma CDP connection helpers

Performance Targets

Metric Target
E2E suite total < 3s
Unit test suite total < 50ms
Screenshot comparison toMatchSnapshot (pixel-level)