Marketing screenshot public/app-workspace-screenshot.png depicts an empty workspace — first-impression asset shows no design #105

Closed
opened 2026-09-19 01:45:32 +00:00 by Mark · 1 comment
Owner

Bug: marketing asset public/app-workspace-screenshot.png shows an empty workspace, not a digitized design

Severity

High — this is the first-impression image on the home page in the "SEE IT IN ACTION" section. It markets the product. Currently it depicts a workspace with just 2 small color swatches and no actual embroidery design.

Reproduction

  1. Visit the home page /.
  2. Scroll to section "SEE IT IN ACTION — A Workspace Built for Embroiderers".
  3. Inspect the rendered image in the marketing column.

Expected: a workspace screenshot showing a recognizable digitized design (flower or similar) with stitch geometry rendered inside the hoop.
Actual: an empty workspace with hoop outline, faint dot grid, and two small color swatches (blue + green rectangles). No flower shape, no stitch paths visible.

Evidence

http://127.0.0.1:3000/app-workspace-screenshot.png (1440x836 PNG, 8.5 KB-ish).

Vision model on the image:

"What is visible: only a blank, beige textured background … two small colored rectangles (blue and green) that appear to be test color swatches or placeholder thread color blocks, not a flower. … This looks more like an initial/empty workspace state or possibly a failed/malformed rendering of a design, rather than a completed or in-progress digitized flower."

This screenshot is auto-regenerated by the CI workspace-screenshot job on every push to main (.forgejo/workflows/ci.yml "Regenerate Workspace marketing screenshot"). The current binary in public/ is the live output of that job — it IS what the regen produces.

Source

tests/e2e/screenshot-workspace.spec.ts seeds the workspace via window.__workspaceDispatch with two stitch objects (Petal A, Petal B). The seeds are:

SEED_OBJECT_1 = {
  id: "seed-obj-1",
  name: "Petal A",
  type: "satin",
  boundingBox: { x: 60, y: 60, width: 40, height: 80 },
  points: [
    { x: 60, y: 80 }, { x: 80, y: 60 }, { x: 100, y: 80 },
    { x: 100, y: 140 }, { x: 80, y: 160 }, { x: 60, y: 140 }
  ],
  stitchCount: 320,
  // …
};
SEED_OBJECT_2 = { id: "seed-obj-2", …, boundingBox: { x: 140, y: 80, width: 40, height: 80 }, … };

The SEED_REGION at (60, 60) size (120, 120) is also small.

The screenshot is captured via:

const workspace = page.locator('[data-testid="workspace-root"]');
const buffer = await workspace.screenshot({ type: "png", omitBackground: false });

Root cause (best guess)

The seeds run in a 240x240 virtual coordinate space at (60-180, 60-180) — about 50% of the canvas diagonal. They produce stitchCount: 320 per petal, but the screenshot is taken with await page.waitForTimeout(500) after the dispatch — perhaps not enough time for the canvas to finish rendering the geometry at 1440x836 capture scale. Or the seeds are too sparse at viewport scale — 6 points per petal means a low-density visual that doesn't read as a "digitized flower" at scale.

Worse: the seed had setState flipped to 'digitized' and SET_STITCH_OBJECTS called, but the dispatched events may not have triggered the canvas re-render in time before the 500ms wait. The screenshot could be capturing the workspace post-dispatch but pre-repaint.

Suggested fix

  1. Bump the await page.waitForTimeout(500) to 2000 or wait for a stable selector that confirms canvas render.
  2. Increase seed coordinates to fill more of the hoop (e.g. boundingBox: { x: 30, y: 30, width: 180, height: 180 }) so the visual is more readable at the marketing scale.
  3. Verify the seed produces visible geometry via await page.evaluate('document.querySelector("canvas")?.toDataURL()') and confirm pixel coverage > 5%.
  4. Re-run the spec locally and visually inspect public/app-workspace-screenshot.png before committing.
# Bug: marketing asset `public/app-workspace-screenshot.png` shows an empty workspace, not a digitized design ## Severity High — this is the first-impression image on the home page in the "SEE IT IN ACTION" section. It markets the product. Currently it depicts a workspace with just 2 small color swatches and no actual embroidery design. ## Reproduction 1. Visit the home page `/`. 2. Scroll to section "SEE IT IN ACTION — A Workspace Built for Embroiderers". 3. Inspect the rendered image in the marketing column. Expected: a workspace screenshot showing a recognizable digitized design (flower or similar) with stitch geometry rendered inside the hoop. Actual: an empty workspace with hoop outline, faint dot grid, and two small color swatches (blue + green rectangles). No flower shape, no stitch paths visible. ## Evidence `http://127.0.0.1:3000/app-workspace-screenshot.png` (1440x836 PNG, 8.5 KB-ish). Vision model on the image: > "What is visible: only a blank, beige textured background … two small colored rectangles (blue and green) that appear to be test color swatches or placeholder thread color blocks, not a flower. … This looks more like an initial/empty workspace state or possibly a failed/malformed rendering of a design, rather than a completed or in-progress digitized flower." This screenshot is auto-regenerated by the CI `workspace-screenshot` job on every push to main (`.forgejo/workflows/ci.yml` "Regenerate Workspace marketing screenshot"). The current binary in `public/` is the live output of that job — it IS what the regen produces. ## Source `tests/e2e/screenshot-workspace.spec.ts` seeds the workspace via `window.__workspaceDispatch` with two stitch objects (Petal A, Petal B). The seeds are: ```ts SEED_OBJECT_1 = { id: "seed-obj-1", name: "Petal A", type: "satin", boundingBox: { x: 60, y: 60, width: 40, height: 80 }, points: [ { x: 60, y: 80 }, { x: 80, y: 60 }, { x: 100, y: 80 }, { x: 100, y: 140 }, { x: 80, y: 160 }, { x: 60, y: 140 } ], stitchCount: 320, // … }; SEED_OBJECT_2 = { id: "seed-obj-2", …, boundingBox: { x: 140, y: 80, width: 40, height: 80 }, … }; ``` The SEED_REGION at `(60, 60)` size `(120, 120)` is also small. The screenshot is captured via: ```ts const workspace = page.locator('[data-testid="workspace-root"]'); const buffer = await workspace.screenshot({ type: "png", omitBackground: false }); ``` ## Root cause (best guess) The seeds run in a 240x240 virtual coordinate space at `(60-180, 60-180)` — about 50% of the canvas diagonal. They produce `stitchCount: 320` per petal, but the screenshot is taken with `await page.waitForTimeout(500)` after the dispatch — perhaps not enough time for the canvas to finish rendering the geometry at 1440x836 capture scale. Or the seeds are too sparse at viewport scale — 6 points per petal means a low-density visual that doesn't read as a "digitized flower" at scale. Worse: the seed had `setState` flipped to 'digitized' and `SET_STITCH_OBJECTS` called, but the dispatched events may not have triggered the canvas re-render in time before the 500ms wait. The screenshot could be capturing the workspace post-dispatch but pre-repaint. ## Suggested fix 1. Bump the `await page.waitForTimeout(500)` to `2000` or wait for a stable selector that confirms canvas render. 2. Increase seed coordinates to fill more of the hoop (e.g. `boundingBox: { x: 30, y: 30, width: 180, height: 180 }`) so the visual is more readable at the marketing scale. 3. Verify the seed produces visible geometry via `await page.evaluate('document.querySelector("canvas")?.toDataURL()')` and confirm pixel coverage > 5%. 4. Re-run the spec locally and visually inspect `public/app-workspace-screenshot.png` before committing.
Author
Owner

Fixed in commit 7461c67 (pushed to main).

Three bugs converged to produce the empty marketing screenshot:

  1. CI workflow path — .forgejo/workflows/ci.yml referenced
    tests/screenshot-workspace.spec.ts but the spec was relocated to
    tests/e2e/ in commit 456af08. The workspace-screenshot CI job has
    been failing to find the spec since Sep 18 07:06 — every run
    silently no-op'd.

  2. REPO_ROOT resolution — the spec used path.resolve(__dirname, "..") which from tests/e2e/ resolves to tests/, so the
    regenerated PNG wrote to tests/public/app-workspace-screenshot.png
    instead of the canonical public/app-workspace-screenshot.png that
    src/pages/Home.tsx references (/app-workspace-screenshot.png).
    CI's drift gate saw the new file appear and committed it to the
    wrong location; the public/ asset stayed frozen at the original
    #80 regeneration.

  3. Seeds too small + wait too short — even when the spec did run,
    boundingBox (60-180, 60-180) on a 200px hoop and a 500ms wait
    produced a screenshot where the canvas re-renders hadn't finished
    yet. Result: empty hoop, two color swatches, no stitch geometry.

Fixes in 7461c67:

  • ci.yml: path corrected to tests/e2e/screenshot-workspace.spec.ts
  • spec: REPO_ROOT walks two levels up to land at the real public/
  • spec: petal boundingBoxes grown to ~110×110 / 140×60 (filling ~30%
    of the hoop); coordinates in the same virtual pixel space the
    canvas renderer uses at default zoom=1, pan=0
  • spec: waitForTimeout bumped 500ms → 2000ms to cover the
    SET_IMAGE → SET_STITCH_OBJECTS → SET_COLOR_REGIONS → SET_STATE
    re-render cascade
  • spec: post-wait pixel-coverage probe samples a 400×400 box centered
    on the hoop via getImageData, asserts ≥5% of pixels are non-linen.
    Future empty-hoop regens will fail the test instead of silently
    shipping
  • spec: buffer.byteLength threshold raised 2KB → 8KB to catch the
    empty-hoop regression independently
  • Remove tests/public/app-workspace-screenshot.png (redundant
    leftover from the original relocation)

Regenerated public/app-workspace-screenshot.png locally with the new
seeds. Verified thread-color coverage in the committed PNG:

  • PR-005 Sky Blue #6CCFF6 = 5,710 px
  • PR-007 Mint Green #A8E6CF = 8,795 px

The hoop now renders the flower-like arrangement at the
marketing-image scale.

Verification:

  • npx tsc --noEmit: pass
  • npm run lint: pass
  • npm test: 335/335 pass
  • npx playwright test tests/e2e/screenshot-workspace.spec.ts: pass
Fixed in commit 7461c67 (pushed to main). Three bugs converged to produce the empty marketing screenshot: 1. **CI workflow path** — `.forgejo/workflows/ci.yml` referenced `tests/screenshot-workspace.spec.ts` but the spec was relocated to `tests/e2e/` in commit 456af08. The `workspace-screenshot` CI job has been failing to find the spec since Sep 18 07:06 — every run silently no-op'd. 2. **REPO_ROOT resolution** — the spec used `path.resolve(__dirname, "..")` which from `tests/e2e/` resolves to `tests/`, so the regenerated PNG wrote to `tests/public/app-workspace-screenshot.png` instead of the canonical `public/app-workspace-screenshot.png` that `src/pages/Home.tsx` references (`/app-workspace-screenshot.png`). CI's drift gate saw the new file appear and committed it to the wrong location; the `public/` asset stayed frozen at the original #80 regeneration. 3. **Seeds too small + wait too short** — even when the spec did run, `boundingBox (60-180, 60-180)` on a 200px hoop and a 500ms wait produced a screenshot where the canvas re-renders hadn't finished yet. Result: empty hoop, two color swatches, no stitch geometry. Fixes in 7461c67: - ci.yml: path corrected to `tests/e2e/screenshot-workspace.spec.ts` - spec: REPO_ROOT walks two levels up to land at the real `public/` - spec: petal boundingBoxes grown to ~110×110 / 140×60 (filling ~30% of the hoop); coordinates in the same virtual pixel space the canvas renderer uses at default zoom=1, pan=0 - spec: `waitForTimeout` bumped 500ms → 2000ms to cover the SET_IMAGE → SET_STITCH_OBJECTS → SET_COLOR_REGIONS → SET_STATE re-render cascade - spec: post-wait pixel-coverage probe samples a 400×400 box centered on the hoop via `getImageData`, asserts ≥5% of pixels are non-linen. Future empty-hoop regens will fail the test instead of silently shipping - spec: `buffer.byteLength` threshold raised 2KB → 8KB to catch the empty-hoop regression independently - Remove `tests/public/app-workspace-screenshot.png` (redundant leftover from the original relocation) Regenerated `public/app-workspace-screenshot.png` locally with the new seeds. Verified thread-color coverage in the committed PNG: - PR-005 Sky Blue #6CCFF6 = 5,710 px - PR-007 Mint Green #A8E6CF = 8,795 px The hoop now renders the flower-like arrangement at the marketing-image scale. Verification: - `npx tsc --noEmit`: pass - `npm run lint`: pass - `npm test`: 335/335 pass - `npx playwright test tests/e2e/screenshot-workspace.spec.ts`: pass
Mark closed this issue 2026-09-19 01:57:02 +00:00
Sign in to join this conversation.
No description provided.