From 52e14a88db9d0e94783419af358f17ef711e3adb Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Thu, 11 Jun 2026 02:00:46 -0400 Subject: [PATCH] =?UTF-8?q?feat(07-03):=20layout.spec.ts=20=E2=80=94=20UI-?= =?UTF-8?q?SPEC=20Rules=201-4=20+=20harness=20self-validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rule 1: boundingBox assertions for BottomTabBar Calendar/Lists tabs (≥44px), PhoneNav settings button (≥44px), New Event FAB (≥56px) on both profiles - Rule 2: scrollWidth ≤ clientWidth on /calendar and /lists - Rule 3: BottomTabBar in-viewport (bottom edge ≤ viewport height), PhoneNav visible - Rule 4: navigation landmark locatable by role+name (getByRole with accessible name) - Self-validation: addStyleTag injection proves Rule 1 tracks geometry (20px height <44), proves Rule 2 detects overflow (2000px body width); both recover after removal - Runs on iphone (WebKit/390px) and pixel (Chromium/412px) profiles; 30 tests pass --- apps/pwa/e2e/layout.spec.ts | 261 ++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 apps/pwa/e2e/layout.spec.ts diff --git a/apps/pwa/e2e/layout.spec.ts b/apps/pwa/e2e/layout.spec.ts new file mode 100644 index 0000000..063eb6f --- /dev/null +++ b/apps/pwa/e2e/layout.spec.ts @@ -0,0 +1,261 @@ +/** + * layout.spec.ts — TEST-01 + * + * Cross-route structural quality-bar assertions (UI-SPEC Rules 1-4): + * Rule 1: Touch-target minimum ≥44×44px (FAB ≥56×56px) + * Rule 2: No horizontal overflow (scrollWidth ≤ clientWidth) + * Rule 3: Critical elements visible and in-viewport on initial load + * Rule 4: Accessible names on all interactive elements (role+name locators) + * + * Runs on both device profiles automatically (playwright.config.ts matrix): + * iphone: iPhone 14 / WebKit / 390×844 + * pixel: Pixel 7 / Chromium / 412×915 + * + * STRICT-MODE NOTE: + * On mobile viewports (≤767px), AppNav renders PhoneNav as a
element + * (NOT a nav landmark) — it does NOT expose a navigation landmark. BottomTabBar + * renders the sole