test(e2e): retry click on table rows when handles detach (#943)

## Problem

E2E test `Node detail loads` intermittently fails with:

> elementHandle.click: Element is not attached to the DOM

(e.g. PR #938 CI run job 73889426640.) Same flake class as #ngStats
hydration race fixed in #940.

## Root cause

```js
const firstRow = await page.$('table tbody tr');
await firstRow.click();
```

Between the `$()` and `.click()`, the nodes table re-renders from a
WebSocket push. The captured handle is detached from the new DOM, click
throws.

## Fix

Switch to a selector-based click with a small retry loop (3 attempts ×
200ms backoff), so a detach mid-attempt re-resolves a fresh element.

Test logic unchanged; just defensive against re-render between query and
click.

Co-authored-by: Kpa-clawbot <bot@example.invalid>
This commit is contained in:
Kpa-clawbot
2026-04-30 20:46:03 -07:00
committed by GitHub
co-authored by Kpa-clawbot
parent a4b99a98e1
commit 8c3b2e2248
+16 -4
View File
@@ -224,10 +224,22 @@ async function run() {
// Test 5: Node detail loads (reuses nodes page from test 2)
await test('Node detail loads', async () => {
await page.waitForSelector('table tbody tr');
// Click first row
const firstRow = await page.$('table tbody tr');
assert(firstRow, 'No node rows found');
await firstRow.click();
// Use a stable selector + retry-on-detach pattern. Querying a row handle
// and clicking it later races with WebSocket-driven table re-renders that
// detach the original element. Click via a fresh selector each time and
// retry on the "not attached" error.
let lastErr;
for (let attempt = 0; attempt < 3; attempt++) {
try {
await page.click('table tbody tr:first-child', { timeout: 2000 });
lastErr = null;
break;
} catch (err) {
lastErr = err;
await page.waitForTimeout(200);
}
}
if (lastErr) throw lastErr;
// Wait for detail pane to appear
await page.waitForSelector('.node-detail');
const html = await page.content();