From e8d0660198a90c8ec4fdab10d80830e480e3d1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 10 May 2026 19:49:32 +0200 Subject: [PATCH] fix(e2e): exempt truncate-clamped elements from per-element overflow walk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The api-tokens mobile no-overflow spec walks every descendant of the mobile card-list and asserts `scrollWidth <= clientWidth + 1`. The v1.4.19 fix wrapped long token names / usernames / permissions in a `` (Tailwind `truncate` ⇒ `overflow:hidden + text-overflow:ellipsis + white-space:nowrap`), which by design keeps `clientWidth` clamped to the parent column while `scrollWidth` reflects the full text — exactly the case the assertion was tripping on. Skip elements whose computed `text-overflow: ellipsis` and clamped `overflow-x` show they are intentionally truncating. The page-level `document.documentElement.scrollWidth <= innerWidth + 1` assertion remains the authoritative no-scrollbar guard, so the regression intent is preserved without false-positives on the truncate helper. Co-Authored-By: Claude Opus 4.7 (1M context) --- e2e/admin-api-tokens-mobile.spec.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/e2e/admin-api-tokens-mobile.spec.ts b/e2e/admin-api-tokens-mobile.spec.ts index 221738589..12fa90d04 100644 --- a/e2e/admin-api-tokens-mobile.spec.ts +++ b/e2e/admin-api-tokens-mobile.spec.ts @@ -167,9 +167,31 @@ test.describe("/admin/api-tokens mobile no-overflow", () => { // Walk every element inside the mobile card-list and assert no // child has a wider scrollWidth than its container. This is the // Pixel-5 worst-case Marc kept hitting. + // + // Elements clamped via `truncate` (Tailwind's `overflow:hidden + + // text-overflow:ellipsis + white-space:nowrap` shorthand) are by + // design `scrollWidth > clientWidth` whenever the underlying text + // is longer than the parent column — that IS the truncation, not + // an overflow leak. Skip those so the assertion only fires on real + // layout culprits (a span without a width clamp pushing its parent + // wider). The page-level `dims.scrollWidth <= dims.innerWidth + 1` + // assertion below remains the authoritative no-scrollbar guard. const culprits = await page .getByTestId("admin-tokens-mobile-list") .evaluate((root) => { + const isTruncated = (el: Element): boolean => { + const cs = window.getComputedStyle(el); + if (cs.textOverflow === "ellipsis" && cs.overflowX !== "visible") { + return true; + } + // Tailwind's `truncate` shorthand and any explicit overflow + // clamp also legitimately keep the visible content inside + // clientWidth even though scrollWidth measures full content. + if (cs.overflowX === "hidden" || cs.overflowX === "clip") { + return true; + } + return false; + }; const out: Array<{ tag: string; klass: string; @@ -177,7 +199,7 @@ test.describe("/admin/api-tokens mobile no-overflow", () => { clientWidth: number; }> = []; for (const el of root.querySelectorAll("*")) { - if (el.scrollWidth > el.clientWidth + 1) { + if (el.scrollWidth > el.clientWidth + 1 && !isTruncated(el)) { out.push({ tag: el.tagName, klass: