From 5d0c5a18efa2ab1f736b1bf1ae3bf88f3e283e0c Mon Sep 17 00:00:00 2001 From: Tyler Dane Date: Sat, 5 Sep 2026 08:51:29 -0600 Subject: [PATCH] test(e2e): wait for the slot picker before public booking tests start preparePublicBookingPage returned once the h1 was visible, while the slots request was often still pending. Tests that start typing immediately raced it: "walks the picker with the keyboard via the skip link" pressed Enter on the skip link before the "Pick a time" heading existed, the click handler found no target, and focus went nowhere. It was 5 of the 8 retry-only passes in 705 CI shard jobs during the 2026-09 audit, across 5 branches. The harness now waits for the "Pick a time" heading, which renders only once slots have loaded, unless the test is deliberately observing the pending, failed, or unavailable state. Co-Authored-By: Claude Fable 5.1 --- e2e/booking/booking-harness.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/e2e/booking/booking-harness.ts b/e2e/booking/booking-harness.ts index 814e09e6b..aa87ab7d2 100644 --- a/e2e/booking/booking-harness.ts +++ b/e2e/booking/booking-harness.ts @@ -574,6 +574,21 @@ export async function preparePublicBookingPage( await expect( page.getByRole("heading", { name: "Book with Tyler Dane" }), ).toBeVisible({ timeout: 15000 }); + // The h1 renders before the slots request settles, and while slots are + // pending the picker shows a skeleton without the "Pick a time" heading. + // A test that starts typing right away (Tab to the skip link, Enter) would + // race that request: the skip link finds no target and focus goes nowhere. + // Wait for the picker itself unless the test is deliberately observing the + // pending, failed, or unavailable state. + if ( + options.bookable !== false && + !options.slotFailGate && + !options.holdFirstSlots + ) { + await expect( + page.getByRole("heading", { name: "Pick a time" }), + ).toBeVisible(); + } return captured; }