From 38703c75e646ee8328c6a2ae9f724f62467b5271 Mon Sep 17 00:00:00 2001 From: Kpa-clawbot Date: Tue, 5 May 2026 00:11:18 -0700 Subject: [PATCH] fix(e2e): make Nodes WS auto-update test deterministic (#1051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem The Playwright E2E test `Nodes page has WebSocket auto-update` (`test-e2e-playwright.js:259`) has flaked 7+ times this session, blocking CI. Failure mode: ``` page.waitForSelector: Timeout 10000ms exceeded waiting for locator('table tbody tr') to be visible ``` ## Root cause The test navigates to `/#/nodes`, waits for `[data-loaded="true"]` (passes), then waits for `table tbody tr` (10s, fails intermittently). Rows in this code path only appear via WebSocket push — which is timing-dependent in CI (no guaranteed live MQTT feed within the 10s window). ## Fix Drop the `table tbody tr` wait. This test's contract is **WS infrastructure existence**, not data delivery: - `#liveDot` element present - `onWS` / `offWS` globals defined - Best-effort connected-state check (already tolerant of failure) All those assertions are deterministic post-DOMContentLoaded. Initial table population is already covered by the preceding `Nodes page loads with data` test. ## Coverage No coverage loss — the WS infra assertions are unchanged. Only the timing-dependent row-presence wait is removed. ## TDD note This is a test-fix, not a behavior change. The "red" is the existing intermittent CI failure; the "green" is this commit removing the flaky wait. No production code touched. Co-authored-by: meshcore-bot --- test-e2e-playwright.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test-e2e-playwright.js b/test-e2e-playwright.js index bf1c0c48..0fc965ad 100644 --- a/test-e2e-playwright.js +++ b/test-e2e-playwright.js @@ -257,10 +257,13 @@ async function run() { }); // Test: Nodes page has WebSocket auto-update listener (#131) + // NOTE: This test verifies the WS *infrastructure* exists on the Nodes page. + // It deliberately does NOT wait for `table tbody tr` — that creates a flake + // because rows arriving via WS push are timing-dependent in CI. The preceding + // "Nodes page loads with data" test already covers initial table population. await test('Nodes page has WebSocket auto-update', async () => { await page.goto(`${BASE}/#/nodes`, { waitUntil: 'domcontentloaded' }); await page.waitForSelector('[data-loaded="true"]', { timeout: 15000 }); - await page.waitForSelector('table tbody tr'); // The live dot in navbar indicates WS connection status const liveDot = await page.$('#liveDot'); assert(liveDot, 'Live dot WebSocket indicator (#liveDot) not found'); @@ -269,7 +272,8 @@ async function run() { return typeof onWS === 'function' && typeof offWS === 'function'; }); assert(hasWsInfra, 'WebSocket listener infrastructure (onWS/offWS) should be available'); - // Wait for WS connection and verify liveDot shows connected state + // Best-effort: if WS connects within 5s, verify connected state. Don't fail otherwise — + // CI may not have a live MQTT feed. Infra-existence assertions above are the contract. try { await page.waitForFunction(() => { const dot = document.getElementById('liveDot');