From 392141bfc50d73c3e151862ea57100b2f96d1515 Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Tue, 13 Oct 2026 15:02:02 +0400 Subject: [PATCH] test(street-level): the gate waits for the photo line to be pickable Draped lines build in a worker after their tile decoded: on a slow CI runner the single pick scan ran before the line existed and the gate failed at "a sequence line across the middle of the view". The scan now retries for up to 30 s. Co-Authored-By: Claude Fable 5.1 --- scripts/qa-street-level.mjs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/qa-street-level.mjs b/scripts/qa-street-level.mjs index c93da5649..6d8315dac 100644 --- a/scripts/qa-street-level.mjs +++ b/scripts/qa-street-level.mjs @@ -296,6 +296,20 @@ const findPick = (page, prefix, { box = null, step = 3 } = {}) => step, ); +/** + * `findPick`, retried until a hit or `timeout`: draped lines build in a + * worker after their tile decoded, so a scan right after LOADING clears can + * come too early on a slow machine. + */ +async function findPickUntil(page, prefix, { timeout = 30_000 } = {}) { + const deadline = Date.now() + timeout; + for (;;) { + const hit = await findPick(page, prefix); + if (hit || Date.now() >= deadline) return hit; + await new Promise((resolve) => setTimeout(resolve, 500)); + } +} + /** Park the camera over the photo line; a late startup flight can move it. */ async function park(page) { for (let attempt = 0; attempt < 5; attempt++) { @@ -455,7 +469,7 @@ async function main() { 'a line selects its sequence, and a cone opens its photo with a caption', async () => { // Fixtures answer lookups for the photo sequence only. - const line = await findPick( + const line = await findPickUntil( page, fixtures ? `mly:seq:${PHOTO_SEQUENCE_ID}` : 'mly:seq:', );