Skip to content
File

Blob: docs/VERIFICATION.md

Markdown95 lines

wimp - Verification

The app was verified end to end in a real headless Chromium driven by Playwright, in addition to type checking and production builds. This matters because the critical paths (OffscreenCanvas transform, wasm-vips init, jSquash WASM encoders, Web Worker messaging, cross-origin isolation) only truly exercise at runtime.

Static checks

  • npx tsc -> 0 errors (strict, single config).
  • npm run build -> succeeds; worker chunk and all codec .wasm assets emit; wasm-vips bundles (vips.wasm ~5.9 MB, lazy-loaded).
  • React Compiler -> confirmed active: the production bundle contains useMemoCache and __COMPILER_RUNTIME.
  • Tailwind v4 -> custom @theme utilities (bg-surface, text-muted, bg-checker, ring-accent-strong, opacity variants) all present in the built CSS.

Runtime matrix (headless Chromium via Playwright)

Source for these runs: a generated 2000x1500 RGB PNG (a gradient with a grid). Served with npm run preview (COOP/COEP headers on). crossOriginIsolated was true. No console errors and no page errors in any run.

Scenario Output format Dimensions Engine Encoder
OG image template JPEG 1200x630 vips jsquash
Avatar template WebP 512x512 vips jsquash
Favicon template PNG 256x256 vips jsquash
Favicon, format switched to AVIF AVIF 256x256 vips jsquash
Original (no downscale) JPEG 2000x1500 canvas jsquash
Keyboard rotate ']' + flip 'h' JPEG 1500x1125 canvas jsquash
YouTube thumb template JPEG 1280x720 canvas/vips jsquash

Format was confirmed by magic bytes; JPEG dimensions parsed from the SOF marker. The result-card text reported the same dimensions plus the engine and encoder.

Notes:

  • vips engages on meaningful downscales (output smaller than the crop) and when cross-origin isolation is available; the "canvas" rows confirm the fallback path is healthy too.
  • Exact target dimensions for fixed-output templates prove the transform and output sizing are correct.

Layout (responsive)

  • Desktop 1366px: both side trays inline (left x=0, right flush to the right edge), the mobile pill hidden.
  • Mobile 390px: trays sit off-canvas at rest (left right-edge at x<=0, right at x>=viewport width); tapping Edit slides the tools drawer to x=0; tapping Export slides the export drawer in; export works from inside the drawer.

Framing guide

  • US passport template: one head ellipse rendered, bounded inside the crop area (593x593 in the test viewport), plus an eye line.
  • Other templates (e.g. OG): no guide rendered.

A screenshot was captured during these runs showing the full UI with the guide.

Reproducing locally

Prerequisites: a Chromium that Playwright can launch.

npm run build
npm run preview        # serves dist/ on http://localhost:4173 with COOP/COEP

Then a Playwright script can:

  1. goto the preview URL and assert self.crossOriginIsolated is true.
  2. setInputFiles on input[type=file] with an image to load it.
  3. Open the template picker (button aria-label "Choose template") and click a template by name; or set the format via the Segmented control (role=tab).
  4. Wait until the "Export & download" button is enabled, click it, and capture the download event. Inspect magic bytes and dimensions.
  5. Read the result card (the

    containing the word "engine") for the reported format, encoder, and engine.

Environment note: in the build environment used here, no browser was on PATH; Playwright was pointed at an existing binary with launch({ executablePath: ... }). A committed E2E suite is listed as deferred work because the browser path is environment-specific (see docs/deferred/enhancements.md).

Known gaps in verification

  • Visual quality of the vips vs canvas resample was not pixel-compared; both paths produce correct dimensions and valid files.
  • Clipboard Copy and AVIF behavior vary by browser; see docs/deferred/known-limitations.md.
  • Tested in Chromium only. Safari-specific canvas filter behavior is documented as a known limitation rather than tested.