From 13ca7630116fddc0946dabeb80b232ae6f9bf36e Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Fri, 7 Aug 2026 22:48:26 -0700 Subject: [PATCH] test(ssh): make the reconnect settle window actually wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The settle poll reused a matcher the assertion 15 lines above had already satisfied, and Playwright's poll engine probes immediately and returns as soon as the matcher passes — so it observed the same state twice and elapsed 0ms. A shell grafted a second or two after reattach reported ready slipped through into the next cycle. Reviewer was right on #13111. Test-only; no production change. Co-authored-by: Orca --- .../ssh-reconnect-pane-cardinality.spec.ts | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/e2e/ssh-reconnect-pane-cardinality.spec.ts b/tests/e2e/ssh-reconnect-pane-cardinality.spec.ts index cc8c8753ef7..722c33e26d8 100644 --- a/tests/e2e/ssh-reconnect-pane-cardinality.spec.ts +++ b/tests/e2e/ssh-reconnect-pane-cardinality.spec.ts @@ -43,6 +43,9 @@ const RECONNECT_CYCLES = 3 // remote shells die too, reconnect degrades to a cold spawn, and the reattach // path this spec exists to bound is never entered. const RELAY_GRACE_PERIOD_SECONDS = 900 +// Why: a graft lands after reattach reports ready, so the census has to be +// re-read once the dust settles rather than the instant the wait passes. +const SETTLE_MS = 6_000 test.use({ seedTestRepo: false }) @@ -198,15 +201,25 @@ test.describe('SSH reconnect pane and remote PTY cardinality', () => { `reconnect ${cycle} changed the workspace tabs` ).toEqual(baselinePanes.tabIds) - // Settle before the next cycle so a late graft is attributed to the - // reconnect that caused it instead of leaking into the next assertion. - await expect - .poll(() => readDockerSshRelayRemotePtys(relayTarget).map((pty) => pty.pid), { - intervals: [2_000, 2_000, 2_000], - timeout: 8_000, - message: `reconnect ${cycle} grew the remote shells after settling` - }) - .toEqual(baselinePids) + // Why not poll here: poll returns on its first passing probe, so + // re-polling a value that already matched waits 0ms and observes + // nothing. Sit out the settle window, then re-read every dimension a + // late graft could move, so it is attributed to the reconnect that + // caused it instead of leaking into the next cycle. + await orcaPage.waitForTimeout(SETTLE_MS) + const settled = await readRemotePaneCensus(orcaPage, remote.worktreeId) + expect( + readDockerSshRelayRemotePtys(relayTarget).map((pty) => pty.pid), + `reconnect ${cycle} changed the remote shells after settling` + ).toEqual(baselinePids) + expect( + settled.paneIds, + `reconnect ${cycle} changed the visible terminal panes after settling` + ).toEqual(baselinePanes.paneIds) + expect( + settled.tabIds, + `reconnect ${cycle} changed the workspace tabs after settling` + ).toEqual(baselinePanes.tabIds) } testInfo.annotations.push({