Skip to content

Roasters: fix pinned header overlap on phones; add Playwright layout tests - #25

Merged
jameshiggins merged 2 commits into
mainfrom
fix/pinned-header-overlap
Sep 25, 2026
Merged

jameshiggins merged 2 commits into
mainfrom
fix/pinned-header-overlap

Conversation

@jameshiggins

Copy link
Copy Markdown
Owner

Summary

The bug. The collapsed "Pinned roasters (N)" header previewed the first few pinned names beside the label. On a phone the label (whitespace-nowrap) sat inside a flex item that was allowed to shrink (min-w-0), so it spilled under the preview and the two rendered on top of each other.

The fix.

  • Dropped the name preview. The count already says what is inside and the names are one tap away. The label is flex-shrink-0 so nothing can be laid out over it again.
  • The divider under the group read "All roasters", which stopped being true once pinned roasters were pulled out of it. It now reads "Everything else (N)", the Gmail inbox-split convention: accurate beneath a "Pinned" group, reads as a section rather than a filter, and carries a count so the two headings mirror each other.

Never again. The Vitest suite runs in jsdom, which has no layout engine, so it proved the header had the right text and could not see that the text was painted on top of itself. This PR adds a browser-level layer that measures geometry:

  • playwright.config.js builds the production bundle (separate outDir) and serves it, then drives real Chromium as a Pixel 7 in dark mode and as a desktop window.
  • e2e/support/mockApi.js answers every API call with fixtures (20 roasters with real-length names, a signed-in user, N favourites) and aborts every other off-box request. No network.
  • e2e/support/layout.js
    • expectNoTextOverlap() walks every rendered text node, takes per-line boxes, clips them by overflow-hidden ancestors, and fails if any two from different elements intersect. Run against the pre-fix build it reported "Pinned roasters (12)" over "49th Parallel Coffee Roasters, Agro Roasters, …" by 84×14 px.
    • expectNoHorizontalOverflow() fails if the page scrolls sideways.
  • e2e/roasters.spec.js covers the directory signed out, with a few pins (group open) and with many pins (collapsed, then expanded), at both sizes.
  • CI gains an e2e job (installs Chromium, runs the suite, uploads the Playwright report on failure). README documents npm run test:e2e and how to add a scenario.

@playwright/test is pinned to 1.56.1 to match the Chromium build in the dev environment.

Test plan

  • npm run lint (0 errors)
  • npm run typecheck
  • npm test (343 passing, e2e folder excluded from Vitest)
  • npm run test:e2e fails on the pre-fix build with the overlap named, passes on this branch (6/6)
  • Phone screenshots of collapsed and expanded states eyeballed
  • CI e2e job green on this PR (first run installs Chromium)

🤖 Generated with Claude Code

https://claude.ai/code/session_01WQPoqZvpFtcjR76PFyVv99


Generated by Claude Code

The collapsed "Pinned roasters (N)" header previewed the first few pinned
names beside the label. On a phone the label (whitespace-nowrap) sat inside
a flex item that was allowed to shrink (min-w-0), so it spilled under the
preview and the two rendered on top of each other.

Drop the preview: the count already says what is inside, and the names are
one tap away. The label is now flex-shrink-0 so nothing can be laid out over
it again.

The divider under the group read "All roasters", which stopped being true
the moment pinned roasters were pulled out of it. It now reads "Everything
else (N)" — the Gmail inbox-split convention: accurate beneath a "Pinned"
group, reads as a section rather than a filter, and carries a count so the
two headings mirror each other.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQPoqZvpFtcjR76PFyVv99
…them in CI

The Vitest suite runs in jsdom, which has no layout engine: it proved the
pinned-roasters header had the right text and never noticed that the text
was painted on top of itself on a phone.

This adds a browser-level layer that measures geometry:

- playwright.config.js builds the production bundle (separate outDir) and
  serves it, then drives Chromium as a Pixel 7 in dark mode and as a desktop
  window. VITE_API_BASE points at a host that exists only inside the tests.
- e2e/support/mockApi.js answers every API call the app makes with fixtures
  (20 roasters with real-length names, a signed-in user, N favourites) and
  aborts every other off-box request, so the tests never touch the network.
- e2e/support/layout.js: expectNoTextOverlap() walks every rendered text
  node, takes per-line boxes, clips them by overflow-hidden ancestors, and
  fails if any two from different elements intersect; run against the
  pre-fix build it reported "Pinned roasters (12)" over the preview by
  84×14 px. expectNoHorizontalOverflow() fails if the page scrolls sideways.
- e2e/roasters.spec.js covers the directory signed out, with a few pins
  (group open) and with many pins (collapsed, then expanded), at both sizes.

CI gains an e2e job that installs Chromium and runs the suite, uploading the
Playwright report on failure. Vitest and ESLint are told to ignore the e2e
folder and the e2e build output respectively. @playwright/test is pinned to
1.56.1 to match the Chromium build in this project's dev environment.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQPoqZvpFtcjR76PFyVv99
@vercel

vercel Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
coffee-tracker-react Ready Ready Preview Sep 25, 2026 4:49am UTC
coffee-tracker-react-rrhm Ready Ready Preview Sep 25, 2026 4:49am UTC

@jameshiggins
jameshiggins marked this pull request as ready for review September 25, 2026 05:23
@jameshiggins
jameshiggins merged commit 6909f82 into main Sep 25, 2026
5 checks passed

This branch was successfully deployed

2 active deployments
Preview – coffee-tracker-react-rrhm — 3c15a037 Deployed Sep 25, 2026 by vercel[bot]
Preview – coffee-tracker-react — 3c15a037 Deployed Sep 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants