Task
Make e2e/narrow-viewport.spec.ts measure layout only after the stylesheet has been applied, so the 320px overflow assertion stops failing intermittently on pages that render an image with intrinsic width/height attributes.
Observed failure
Hit on an unrelated PR (#229, a date-formatter change), run 33252617946:
1) [chromium] › e2e/narrow-viewport.spec.ts:45:5 › 320px viewport › /frontier-commits has no horizontal overflow
Error: elements wider than the 320px viewport
+ "<img class=\"h-28 w-28 shrink-0 rounded-lg border border-[var(--color-border)] sm:h-32 sm:w-32\">"
1 failed | 1 skipped | 32 passed
The same job passed on main two minutes earlier (#228), and the PR's /frontier-commits output is byte-identical to main's under TZ=UTC with the e2e fixture manifests — so the page content did not change. gh run rerun --failed went green.
Probable mechanism (not yet reproduced locally)
src/pages/frontier-commits/index.astro:29-35 renders the cover art with width="1400" height="1400" attributes and takes its real size from the h-28 w-28 classes:
<img src="/frontier-commits-cover.jpg" width="1400" height="1400"
class="h-28 w-28 shrink-0 rounded-lg border ... sm:h-32 sm:w-32" />
e2e/narrow-viewport.spec.ts:46 navigates with waitUntil: 'domcontentloaded' and measures immediately. In the window before the stylesheet is applied, the element lays out at its attribute width of 1400px and getBoundingClientRect().right clears the 320px viewport. /podcast/index.astro has the same shape and is equally exposed; it happened to pass in that run.
This is a hypothesis consistent with the evidence, not a confirmed reproduction — the race did not reproduce locally.
Pointers
e2e/narrow-viewport.spec.ts:46 — waitUntil: 'domcontentloaded', then overflowingElements(page) with no wait for styles
e2e/narrow-viewport.spec.ts:26-39 — overflowingElements()
src/pages/frontier-commits/index.astro:29 and src/pages/podcast/index.astro — the intrinsically-sized cover images
Constraints
- Do not weaken the assertion. It must still catch real overflow; adding slack or dropping the offending element defeats its purpose (#186 added it for a real bug).
- Prefer waiting on a deterministic condition (
document.fonts.ready, the stylesheet having applied, or waitUntil: 'load') over a fixed sleep.
- Test-only change; no product markup edits needed unless a real overflow is found.
Acceptance criteria
npx playwright test e2e/narrow-viewport.spec.ts --repeat-each=20 passes with no failures.
- The assertion still fails when a genuinely overflowing element is introduced — demonstrate with a temporary local edit and paste the failure.
- Full gate suite passes:
npm run format:check && npm run lint && npm run typecheck && npm test && npm run test:e2e.
Out of scope
- Changing how cover art is sized or removing the
width/height attributes — they are correct and prevent layout shift.
- Any other spec in
e2e/.
Task
Make
e2e/narrow-viewport.spec.tsmeasure layout only after the stylesheet has been applied, so the 320px overflow assertion stops failing intermittently on pages that render an image with intrinsicwidth/heightattributes.Observed failure
Hit on an unrelated PR (#229, a date-formatter change), run 33252617946:
The same job passed on
maintwo minutes earlier (#228), and the PR's/frontier-commitsoutput is byte-identical tomain's underTZ=UTCwith the e2e fixture manifests — so the page content did not change.gh run rerun --failedwent green.Probable mechanism (not yet reproduced locally)
src/pages/frontier-commits/index.astro:29-35renders the cover art withwidth="1400" height="1400"attributes and takes its real size from theh-28 w-28classes:e2e/narrow-viewport.spec.ts:46navigates withwaitUntil: 'domcontentloaded'and measures immediately. In the window before the stylesheet is applied, the element lays out at its attribute width of 1400px andgetBoundingClientRect().rightclears the 320px viewport./podcast/index.astrohas the same shape and is equally exposed; it happened to pass in that run.This is a hypothesis consistent with the evidence, not a confirmed reproduction — the race did not reproduce locally.
Pointers
e2e/narrow-viewport.spec.ts:46—waitUntil: 'domcontentloaded', thenoverflowingElements(page)with no wait for stylese2e/narrow-viewport.spec.ts:26-39—overflowingElements()src/pages/frontier-commits/index.astro:29andsrc/pages/podcast/index.astro— the intrinsically-sized cover imagesConstraints
document.fonts.ready, the stylesheet having applied, orwaitUntil: 'load') over a fixed sleep.Acceptance criteria
npx playwright test e2e/narrow-viewport.spec.ts --repeat-each=20passes with no failures.npm run format:check && npm run lint && npm run typecheck && npm test && npm run test:e2e.Out of scope
width/heightattributes — they are correct and prevent layout shift.e2e/.