New tooling in tests/tools/screenshots/ (TypeScript via tsx):
- compare.ts: one pixelmatch engine (AA-excluded), connected-component
"where to look" boxes, old|new+boxes|heatmap triptych, per-engine floors.
- promote.ts: churn-free updater — overwrite a baseline only when decoded
pixels differ beyond the floor, copying CI bytes verbatim (no re-encode
churn); pulls a CI run via `gh run download` or a local --from dir.
- post-discord.ts: always-on CI-on-main report (SHA + e2e status + the
track-only runtime-perf table), then screenshot triptychs, batched +
size-capped + flood-collapsed + 429-aware.
- perf-report.ts: perf table with Δ vs the previous main run (via gh).
- changelog.ts: no-build git-history baseline differ (Discord trigger B).
- noise.ts / gen-manifest.ts: calibration + manifest generation.
CI wiring:
- wasm-build.yml: post-test step runs the gate + report on the already-
produced test-results (no extra build); report-only (continue-on-error),
posts only on push to main, inert without DISCORD_WEBHOOK_URL.
- ci-ubicloud.yml: secrets: inherit (pass the webhook through).
- screenshot-changelog.yml: ~30s no-build changelog on baseline changes.
screenshot-manifest.json: canonical 354-name set + best-effort engine tags
(313 chromium-swiftshader / 41 firefox-llvmpipe).
Normalize scale:'device'->'css' across 18 spec files (no-op at CI DSF=1)
so committed baselines are uniformly css-scaled.
Design: CI's Linux render is the single source of truth; no pinned
container (accept rare env drift -> re-promote); dev commits via promote.
Replaces the byte-cmp compare-screenshots.sh + file-size-proxy
update-baseline-screenshots.sh (kept for now until the first re-baseline).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
backend-example (open ref backend): USER_HEADER, scope on the project DTO, raw routes under /api/scopes/:scope, no-op reportDrift + DOM lib (was red on main → now typecheck-green). GPL web specs (tools-open, symbol/footprint-write-remote, global-setup-web): /p/demo/:tool/* → /:scope/projects/demo/(file | -/:tool), direct API fetches scoped + x-pcbjam-owner → x-pcbjam-user. Reference backend keeps lib type 'user' (cosmetic vs closed 'org').
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The web tool-open smoke booted 6 of the 7 standalone tools; add the
footprint_editor case so every tool the editor exposes is exercised. It
boots file-less (like symbol_editor/gerbview) and asserts its frame title.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rework HomePage into KiCad-launcher-style zones: local file-load, a Tools grid,
backend projects, and a backend libraries listing (useLibs over the shared
listLibs). The Tools grid shows all seven tools in KiCad's standalone order
(Schematic/Symbol/PCB/Footprint editors, Gerber Viewer, Calculator, Drawing
Sheet); clicking a tool or a library launches the editor with no project
(launchedTool → WasmTool slug=local) — file-less editors browse backend libs,
document editors open blank. Harden the web e2e global-setup to assert the
self-provisioned origin libs (Device, Resistor_SMD) are present, failing fast.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Register the newly WASM-ported Gerber Viewer in the web app the same way as
the other tools — registry entries only, no UI edits (ProjectDetailPage renders
launch links generically from FILELESS_TOOLS).
GERBVIEW_FRAME opens gerber/drill files through its own File→Open UI and projects
carry no gerber files to auto-open, so it's treated as file-less (boot standalone),
mirroring symbol_editor. It boots through single_top.cpp's STARTWIZARD, so it seeds
config to skip the first-run wizard (TOOL_NEEDS_CONFIG_SEED) and gets a
/usr/bin/gerbview argv0.
- contract: add "gerbview" to TOOLS, TOOL_LABELS ("Gerber Viewer"), FILELESS_TOOLS
- frontend: add gerbview to TOOL_ARGV0 and TOOL_NEEDS_CONFIG_SEED
- e2e: add file-less gerbview case to tools-open.spec.ts (title "Gerber Viewer",
canvas painted, wizard-free, no WASM abort)
Verified in-browser via npm run test:web: gerbview boots wizard-free with the
viewer chrome (toolbars + layers manager), 0 console errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an e2e suite that drives the real React web app (not the standalone
harness): tests/playwright-web.config.ts + tests/web/tools-open.spec.ts navigate
/p/demo/<tool>/<file> for all five tools and assert each boots, opens its demo
file (title drops "untitled"), shows no first-run wizard, and emits no WASM abort
or URL-regex modal. global-setup-web.ts re-seeds the demo project through the API
if missing, so the suite is self-sufficient against a running dev stack. Wired as
`npm run test:web`.
Also at the harness level:
- pl_editor-load.spec.ts: prove the pl_editor kicadOpenFile embind hook opens a
.kicad_wks (mirrors eeschema-load.spec.ts).
- seed KiCad config in pl_editor.html / symbol_editor.html (matching eeschema.html
and the web app's boot.ts) so the harness boots wizard-free; repurpose
pl_editor.spec.ts's stale "wizard completes" test into a wizard-skip regression.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>