refactor: consolidate Playwright projects
This commit is contained in:
parent
445b85ddc0
commit
9be2e76bf6
|
|
@ -70,7 +70,8 @@ App dialogs compose the Reka-backed components under `src/components/ui/dialog/`
|
|||
- `bun run dev` — fixed `http://localhost:1420` server for Playwright, Tauri, and Dev Containers.
|
||||
- `bun run check` — complete build, lint, type, architecture, docs, package, dependency, security, tooling, and duplication gate.
|
||||
- `bun run format` — format and sort imports.
|
||||
- `bun run test:unit` / `bun run test` — engine/unit and Playwright suites.
|
||||
- `bun run test:unit` / `bun run test` — engine/unit and app Playwright suites.
|
||||
- `bun run test:storybook` — the Storybook Playwright project in `playwright.config.ts`. Test scripts select their server; direct Playwright commands start both servers unless `OPENPENCIL_TEST_SERVER=app|storybook|all` is set.
|
||||
- `bun run tauri dev` — desktop app with hot reload.
|
||||
- `bun open-pencil --help` — current CLI command list.
|
||||
|
||||
|
|
@ -210,7 +211,7 @@ Keep responsibilities distinct: engine tests cover state contracts, Playwright b
|
|||
- Section/frame title text never scales — render at fixed font size, ellipsize to fit
|
||||
- Rulers are rendered on the canvas (not DOM), with selection range badges that don't overlap tick numbers
|
||||
- Remote cursors: Figma-style colored arrows with white border + name pill, rendered in screen space
|
||||
- Pixel-affecting renderer features need committed visual coverage, not just mock/geometry assertions. Add or update a Playwright canvas snapshot for changes to fills, gradients, images, blend modes, masks, boolean geometry, corners, strokes, shadows, blur, text rendering, or demo showcase scenes. Use targeted snapshot updates such as `bunx playwright test tests/e2e/canvas/renderer-visuals.spec.ts --project=openpencil --update-snapshots` and then rerun the same test without `--update-snapshots`.
|
||||
- Pixel-affecting renderer features need committed visual coverage, not just mock/geometry assertions. Add or update a Playwright canvas snapshot for changes to fills, gradients, images, blend modes, masks, boolean geometry, corners, strokes, shadows, blur, text rendering, or demo showcase scenes. Use targeted snapshot updates such as `bun run test tests/e2e/canvas/renderer-visuals.spec.ts --update-snapshots` and then rerun the same test without `--update-snapshots`.
|
||||
|
||||
## Scene graph
|
||||
|
||||
|
|
|
|||
|
|
@ -55,10 +55,11 @@
|
|||
"check:packages": "bun tools/package-quality/src/cli.ts check",
|
||||
"check:arch": "steiger .",
|
||||
"check:vue": "vue-tsc --noEmit -p tsconfig.json && vue-tsc --noEmit -p packages/vue/tsconfig.json",
|
||||
"test": "playwright test --project=openpencil --grep-invert @real-llm",
|
||||
"test:real-llm": "playwright test --project=openpencil --grep @real-llm",
|
||||
"test:update": "playwright test --project=openpencil --update-snapshots",
|
||||
"test:figma": "playwright test --project=figma",
|
||||
"test": "OPENPENCIL_TEST_SERVER=app playwright test --project=openpencil --grep-invert @real-llm",
|
||||
"test:storybook": "OPENPENCIL_TEST_SERVER=storybook playwright test --project=storybook-chromium",
|
||||
"test:real-llm": "OPENPENCIL_TEST_SERVER=app playwright test --project=openpencil --grep @real-llm",
|
||||
"test:update": "OPENPENCIL_TEST_SERVER=app playwright test --project=openpencil --update-snapshots",
|
||||
"test:figma": "OPENPENCIL_TEST_SERVER=app playwright test --project=figma",
|
||||
"figma:debug": "open -a Figma --args --remote-debugging-port=9222",
|
||||
"typecheck": "tsgo --noEmit && bun run check:vue",
|
||||
"test:unit": "bun test ./tests/engine",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
| --------------------- | ---------- | -------------------- | --------------- |
|
||||
| E2E visual regression | Playwright | `bun run test` | `tests/e2e/` |
|
||||
| Figma CDP reference | Playwright | `bun run test:figma` | `tests/figma/` |
|
||||
| Storybook components | Playwright | `bun run test:storybook` | `tests/e2e/storybook/` |
|
||||
| Unit tests | bun:test | `bun run test:unit` | `tests/engine/` |
|
||||
|
||||
## E2E Visual Regression
|
||||
|
|
@ -19,13 +20,15 @@ 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.
|
||||
The canonical `playwright.config.ts` owns app, Figma, and Storybook projects. The `test`, `test:update`, `test:real-llm`, and `test:figma` scripts select only the app server; `test:storybook` selects only Storybook on port `6017`. Direct Playwright commands start both servers by default. Set `OPENPENCIL_TEST_SERVER=app`, `storybook`, or `all` to select servers explicitly; `--project` selects tests, not servers.
|
||||
|
||||
App tests start Vite from the current checkout and wait 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:
|
||||
|
||||
```sh
|
||||
OPENPENCIL_TEST_PORT=1482 OPENPENCIL_TEST_MCP_PORT=7682 \
|
||||
bunx playwright test tests/e2e/settings --project=openpencil
|
||||
bun run test tests/e2e/settings
|
||||
```
|
||||
|
||||
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.
|
||||
|
|
@ -44,6 +47,15 @@ For intentional local debugging against an already-running matching server, set
|
|||
|
||||
The editor supports a test mode that hides UI chrome (toolbar, panels) for clean screenshot capture. Activated via URL parameter.
|
||||
|
||||
## Storybook Component Tests
|
||||
|
||||
```sh
|
||||
bun run test:storybook
|
||||
bun run test:storybook --list
|
||||
```
|
||||
|
||||
The `storybook-chromium` project preserves its own viewport, device scale, screenshot defaults, and reduced-motion browser context. Storybook specs are excluded from the app projects. Snapshot updates use `bun run test:storybook --update-snapshots`.
|
||||
|
||||
## Figma CDP Reference Tests
|
||||
|
||||
A separate Playwright project connects to Figma via Chrome DevTools Protocol to capture reference screenshots for pixel-perfect comparison.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { defineConfig } from '@playwright/test'
|
||||
import { defineConfig, type PlaywrightTestConfig } from '@playwright/test'
|
||||
|
||||
const appPort = process.env.OPENPENCIL_TEST_PORT ?? '1420'
|
||||
const mcpPort = process.env.OPENPENCIL_TEST_MCP_PORT ?? '7600'
|
||||
|
|
@ -14,10 +14,16 @@ if (reuse !== undefined && reuse !== '0' && reuse !== '1') {
|
|||
throw new Error('OPENPENCIL_TEST_REUSE_SERVER must be 0 or 1')
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
timeout: 15_000,
|
||||
workers: 1,
|
||||
const server = process.env.OPENPENCIL_TEST_SERVER ?? 'all'
|
||||
if (!['app', 'storybook', 'all'].includes(server)) {
|
||||
throw new Error('OPENPENCIL_TEST_SERVER must be app, storybook, or all')
|
||||
}
|
||||
const storybookPort = 6017
|
||||
if (server === 'all' && [appPort, mcpPort].some((port) => Number(port) === storybookPort)) {
|
||||
throw new Error('App, MCP, and Storybook test ports must differ')
|
||||
}
|
||||
|
||||
const appDefaults = {
|
||||
expect: {
|
||||
toHaveScreenshot: {
|
||||
maxDiffPixelRatio: 0.01,
|
||||
|
|
@ -37,17 +43,26 @@ export default defineConfig({
|
|||
launchOptions: {
|
||||
args: ['--enable-unsafe-swiftshader']
|
||||
}
|
||||
},
|
||||
}
|
||||
} satisfies Pick<PlaywrightTestConfig, 'expect' | 'use'>
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests',
|
||||
timeout: 15_000,
|
||||
workers: 1,
|
||||
projects: [
|
||||
{
|
||||
...appDefaults,
|
||||
name: 'openpencil',
|
||||
testDir: './tests/e2e',
|
||||
testIgnore: '**/native/**',
|
||||
testIgnore: ['**/native/**', '**/storybook/**'],
|
||||
fullyParallel: false
|
||||
},
|
||||
{
|
||||
...appDefaults,
|
||||
name: 'openpencil-webkit',
|
||||
testDir: './tests/e2e',
|
||||
testIgnore: ['**/native/**', '**/storybook/**'],
|
||||
testMatch: [
|
||||
'**/*.webkit.spec.ts',
|
||||
'**/design/panel.spec.ts',
|
||||
|
|
@ -55,23 +70,53 @@ export default defineConfig({
|
|||
'**/fonts/settings.spec.ts'
|
||||
],
|
||||
use: {
|
||||
...appDefaults.use,
|
||||
browserName: 'webkit'
|
||||
}
|
||||
},
|
||||
{
|
||||
...appDefaults,
|
||||
name: 'figma',
|
||||
testDir: './tests/figma'
|
||||
},
|
||||
{
|
||||
name: 'storybook-chromium',
|
||||
testDir: './tests/e2e/storybook',
|
||||
timeout: 30_000,
|
||||
use: {
|
||||
baseURL: `http://localhost:${storybookPort}`,
|
||||
viewport: { width: 800, height: 600 },
|
||||
deviceScaleFactor: 1,
|
||||
contextOptions: { reducedMotion: 'reduce' }
|
||||
}
|
||||
}
|
||||
],
|
||||
webServer: {
|
||||
command: `bun run dev --port ${appPort} --strictPort`,
|
||||
cwd: import.meta.dirname,
|
||||
url: origin,
|
||||
env: {
|
||||
OPENPENCIL_DEV_ORIGIN: origin,
|
||||
OPENPENCIL_DEV_MCP_PORT: mcpPort,
|
||||
PORTLESS_URL: ''
|
||||
},
|
||||
reuseExistingServer: !process.env.CI && reuse === '1'
|
||||
}
|
||||
webServer: [
|
||||
...(server === 'storybook'
|
||||
? []
|
||||
: [
|
||||
{
|
||||
command: `bun run dev --port ${appPort} --strictPort`,
|
||||
cwd: import.meta.dirname,
|
||||
url: origin,
|
||||
env: {
|
||||
OPENPENCIL_DEV_ORIGIN: origin,
|
||||
OPENPENCIL_DEV_MCP_PORT: mcpPort,
|
||||
PORTLESS_URL: ''
|
||||
},
|
||||
reuseExistingServer: !process.env.CI && reuse === '1'
|
||||
}
|
||||
]),
|
||||
...(server === 'app'
|
||||
? []
|
||||
: [
|
||||
{
|
||||
command: `bun run storybook -- --port ${storybookPort} --ci --no-open`,
|
||||
cwd: import.meta.dirname,
|
||||
url: `http://localhost:${storybookPort}`,
|
||||
reuseExistingServer: false,
|
||||
timeout: 120_000
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
import { defineConfig } from '@playwright/test'
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests/e2e/storybook',
|
||||
timeout: 30_000,
|
||||
workers: 1,
|
||||
use: {
|
||||
baseURL: 'http://localhost:6017',
|
||||
viewport: { width: 800, height: 600 },
|
||||
deviceScaleFactor: 1,
|
||||
reducedMotion: 'reduce'
|
||||
},
|
||||
projects: [{ name: 'storybook-chromium' }],
|
||||
webServer: {
|
||||
command: 'bun run storybook -- --port 6017 --ci --no-open',
|
||||
url: 'http://localhost:6017',
|
||||
reuseExistingServer: false,
|
||||
timeout: 120_000
|
||||
}
|
||||
})
|
||||
Loading…
Reference in a new issue