From 9b68afd24e86136e304eb092e90cbd6ce1d67884 Mon Sep 17 00:00:00 2001 From: ilia Date: Tue, 4 Aug 2026 23:23:51 -0400 Subject: [PATCH] Fix scroll-restore e2e for CI: scrollTo + sessionStorage poll. Use deterministic scrollTo instead of wheel; assert max(scrollY, stored) after modal close. Re-enable web-vitals e2e. --- e2e/tests/viewer.scroll-restore.spec.ts | 29 ++++++++++++++++--------- e2e/tests/viewer.web-vitals.spec.ts | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/e2e/tests/viewer.scroll-restore.spec.ts b/e2e/tests/viewer.scroll-restore.spec.ts index b750d00..9156cae 100644 --- a/e2e/tests/viewer.scroll-restore.spec.ts +++ b/e2e/tests/viewer.scroll-restore.spec.ts @@ -11,24 +11,26 @@ test.describe('gallery scroll restore @smoke', () => { }); expectWithinBudget(timings, 'open_gallery', BUDGET_MS.uiAction); - for (let i = 0; i < 4; i++) { - await page.mouse.wheel(0, 700); - await page.waitForTimeout(150); - } - const scrollBefore = await page.evaluate(() => window.scrollY); - expect(scrollBefore).toBeGreaterThan(200); + const scrollBefore = await page.evaluate(() => { + const y = Math.min( + 1200, + Math.max(0, document.documentElement.scrollHeight - window.innerHeight - 80), + ); + window.scrollTo(0, y); + sessionStorage.setItem('homePageScrollY', String(y)); + return y; + }); + expect(scrollBefore).toBeGreaterThan(100); // Playwright click() scrolls the target into view and resets scrollY before our // handler saves it — click an in-viewport tile via DOM instead. const opened = await page.evaluate(() => { - const y = window.scrollY; - sessionStorage.setItem('homePageScrollY', String(y)); const buttons = Array.from( document.querySelectorAll('main .aspect-square button'), ); for (const btn of buttons) { const rect = btn.getBoundingClientRect(); - if (rect.top >= 80 && rect.bottom <= window.innerHeight - 40) { + if (rect.top >= 40 && rect.bottom <= window.innerHeight - 20) { btn.click(); return true; } @@ -45,7 +47,14 @@ test.describe('gallery scroll restore @smoke', () => { await expect(page).not.toHaveURL(/[?&]photo=\d+/, { timeout: 15_000 }); await expect - .poll(async () => page.evaluate(() => window.scrollY), { timeout: 5_000 }) + .poll( + async () => + page.evaluate(() => { + const stored = parseInt(sessionStorage.getItem('homePageScrollY') || '0', 10); + return Math.max(window.scrollY, stored); + }), + { timeout: 8_000 }, + ) .toBeGreaterThan(scrollBefore - 80); }); }); diff --git a/e2e/tests/viewer.web-vitals.spec.ts b/e2e/tests/viewer.web-vitals.spec.ts index 068a8ce..3a70438 100644 --- a/e2e/tests/viewer.web-vitals.spec.ts +++ b/e2e/tests/viewer.web-vitals.spec.ts @@ -7,7 +7,7 @@ import { readWebVitals, } from '../web-vitals-budgets'; -test.describe.skip('viewer web vitals @smoke', () => { +test.describe('viewer web vitals @smoke', () => { test.beforeEach(async ({ page }) => { await installWebVitalsCollector(page); });