From bfd390977ca0508912de540d8331036f367bd8e9 Mon Sep 17 00:00:00 2001 From: Joris Wouter Jonkers Date: Sat, 5 Sep 2026 21:56:01 +0200 Subject: [PATCH] test(island): the pass's aim is read once the band stands at it `aimedAt` took the first inline height it found on the swipe element and called that the figure the pass is aiming at. `carry()` in `BandSwipe.vue` pins the height it is leaving before it can measure the one it is arriving at, so on a stop arriving without a gesture the first height there is where the band was rather than where it is going. The helper now takes the height stood at and waits past it, which tells the two apart. Measured on the failing read: from=556 swiped=914 hit=914 stands=681, where `hit` should have been 681 and instead repeated the height the swipe had left behind. The race is in the helper rather than in the band, and it has always been there: which of the two heights is read depends on when the poll lands between the pin and the measure. --- .../frontend/tests/e2e/boards-swipe.motion.spec.ts | 4 ++-- services/frontend/tests/e2e/sliceBand.ts | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/services/frontend/tests/e2e/boards-swipe.motion.spec.ts b/services/frontend/tests/e2e/boards-swipe.motion.spec.ts index 50de0a408..832ab3250 100644 --- a/services/frontend/tests/e2e/boards-swipe.motion.spec.ts +++ b/services/frontend/tests/e2e/boards-swipe.motion.spec.ts @@ -184,7 +184,7 @@ test.describe("dragging the board page", () => { // The pass a finger plays measures the board it is dragging in, which is drawn open — the // axis is claimed before it is mounted — so the figure it aims at is the finished layout. await dragBand(page, band, {by: 260}) - const swiped = await aimedAt(page, SWIPE) + const swiped = await aimedAt(page, SWIPE, from) await expect(page).toHaveURL(/\?board=2$/) // Aimed at a real difference rather than at the height it already stood at, which is what @@ -198,7 +198,7 @@ test.describe("dragging the board page", () => { // The pass the band plays for itself, a stop arriving without a gesture, aims at the same // thing: it measures the arriving board a frame after it was built, and it was built open. await page.getByTestId("board-node-5").click() - const hit = await aimedAt(page, SWIPE) + const hit = await aimedAt(page, SWIPE, swiped) await expect(page.getByTestId("board-band-name")).toHaveText("Eeveelutions") expect(Math.abs(hit - swiped)).toBeGreaterThan(HAIR) diff --git a/services/frontend/tests/e2e/sliceBand.ts b/services/frontend/tests/e2e/sliceBand.ts index a0e157020..81037916d 100644 --- a/services/frontend/tests/e2e/sliceBand.ts +++ b/services/frontend/tests/e2e/sliceBand.ts @@ -138,12 +138,18 @@ export function heldHeight(page: Page, swipe: string): Promise { * Both of the band's height animations set the resting height on the element before animating * over it, so what is written there is the end of the pass stated at the start of it — which is * the intention, where a height sampled mid-pass is only a frame of one. + * + * A pass that swaps the stop pins the height it is leaving first, a tick before it can measure + * the one it is arriving at, so the first inline height there is where the band was rather than + * where it is going. [stoodAt] is the height it is leaving, and tells the two apart. */ -export async function aimedAt(page: Page, swipe: string): Promise { - const handle = await page.waitForFunction((sel) => { +export async function aimedAt(page: Page, swipe: string, stoodAt: number): Promise { + const handle = await page.waitForFunction(([sel, held]) => { const aim = (document.querySelector(sel) as HTMLElement | null)?.style.height - return aim ? Math.round(parseFloat(aim)) : null - }, swipe) + if (!aim) return null + const px = Math.round(parseFloat(aim)) + return px === held ? null : px + }, [swipe, stoodAt] as const) return handle.jsonValue() }