From 990639d80494a8152caf38b5205f66ec08bc9e98 Mon Sep 17 00:00:00 2001 From: Frederic Cabassut Date: Thu, 12 Mar 2026 09:31:06 +0100 Subject: [PATCH] fix: resolve flaky offline sync e2e test in CI Playwright's setOffline(false) doesn't reliably emit the browser's 'online' DOM event in headless/CI environments. Manually dispatch it as a safety net so the sync client always triggers. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 1 + tests/e2e/offline.spec.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 089eac8..605324c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -180,6 +180,7 @@ Write tests first or alongside features. Tests serve as living documentation of - Test database: `./data/test-crumbs.db` (cleaned via `global-setup.ts`) - Auth fixture: `tests/e2e/helpers/fixtures.ts` provides `authenticatedPage` (handles setup/login race conditions across parallel workers) - Auth tests use `test.describe.serial` because they depend on sequential database state +- **Offline/online tests**: After `setOffline(false)`, always manually dispatch the `online` event via `page.evaluate(() => window.dispatchEvent(new Event('online')))` — Playwright doesn't reliably emit it in headless/CI environments, causing flaky `waitForResponse` timeouts ### Gherkin-style Given/When/Then diff --git a/tests/e2e/offline.spec.ts b/tests/e2e/offline.spec.ts index 2bcf874..9875a62 100644 --- a/tests/e2e/offline.spec.ts +++ b/tests/e2e/offline.spec.ts @@ -62,8 +62,11 @@ test.describe('Offline Support', () => { await expect(page.getByText('Survive Reload')).toBeVisible(); // When the network is restored and sync completes - const syncResponse = page.waitForResponse('**/api/sync'); + const syncResponse = page.waitForResponse((resp) => resp.url().includes('/api/sync')); await page.context().setOffline(false); + // Manually dispatch the online event as a safety net — in CI/headless + // environments, setOffline(false) doesn't always emit it reliably + await page.evaluate(() => window.dispatchEvent(new Event('online'))); await syncResponse; // And the user reloads the page