From 33b912babd5accf1b8d38157bf8c53cc39bcc79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 30 May 2026 00:44:40 +0200 Subject: [PATCH] test(settings): exempt the hidden avatar file input from the 44px touch-target sweep The avatar upload uses the accessible visually-hidden pattern: the input is sr-only / zero-size and the visible 44px touch target is the styled label/button that triggers it. The mobile touch-target sweep now skips hidden/zero-size file inputs and keeps the 44px assertion for every genuinely visible input. Co-Authored-By: Claude Opus 4.7 (1M context) --- e2e/settings-mobile-consistency.spec.ts | 47 ++++++++++++++++++------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/e2e/settings-mobile-consistency.spec.ts b/e2e/settings-mobile-consistency.spec.ts index 062bf9e38..9b40bec81 100644 --- a/e2e/settings-mobile-consistency.spec.ts +++ b/e2e/settings-mobile-consistency.spec.ts @@ -41,18 +41,41 @@ test.describe("Settings mobile consistency (Pixel 5)", () => { await page.waitForLoadState("networkidle"); await expect(page.getByLabel(/username/i)).toBeVisible(); - const formInputs = await page - .locator( - 'section input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]), section select', - ) - .evaluateAll((els) => - els.map((el) => ({ - id: el.id || el.getAttribute("name") || "", - tag: el.tagName, - type: el.getAttribute("type") || "", - height: Math.round(el.getBoundingClientRect().height), - })), - ); + const formInputs = ( + await page + .locator( + 'section input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]), section select', + ) + .evaluateAll((els) => + els.map((el) => { + const rect = el.getBoundingClientRect(); + const style = getComputedStyle(el); + return { + id: el.id || el.getAttribute("name") || "", + tag: el.tagName, + type: el.getAttribute("type") || "", + height: Math.round(rect.height), + width: Math.round(rect.width), + hidden: + el.classList.contains("sr-only") || + style.display === "none" || + style.visibility === "hidden", + }; + }), + ) + ).filter( + // The avatar profile-photo upload uses the accessible + // visually-hidden pattern: the input itself + // is sr-only / zero-size and the real 44 px touch target is the + // styled label/button that triggers it. The touch-target sweep + // must measure that visible affordance, not the hidden input, so + // exempt file inputs that are hidden or collapsed to zero size. + (inp) => + !( + inp.type === "file" && + (inp.hidden || inp.height === 0 || inp.width === 0) + ), + ); expect(formInputs.length).toBeGreaterThan(0); for (const inp of formInputs) {