From aa7afabb1d436ddcef7b4c62a72342e307b8f321 Mon Sep 17 00:00:00 2001 From: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com> Date: Tue, 13 Oct 2026 10:00:18 -0400 Subject: [PATCH] test(e2e): wait for the paired-reveal decoy to settle at its new size (#28319) * test(e2e): read the parked-reveal decoy grid only after it settles at the new fit * test(e2e): name the settle wait and give it the file's reveal timeout --- ...rminal-parked-reveal-interactivity.spec.ts | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts b/tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts index 1b9e87d50b2..f6963a28e1b 100644 --- a/tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts +++ b/tests/e2e/paired-remote-terminal-parked-reveal-interactivity.spec.ts @@ -191,6 +191,22 @@ async function readActivePaneGrid( }, webTabId) } +/** The pane's grid, or null while it differs from what its container fits. */ +async function readFittedPaneGrid( + page: Page, + webTabId: string +): Promise<{ cols: number; rows: number } | null> { + return page.evaluate((id) => { + const manager = window.__paneManagers?.get(id) + const pane = manager?.getActivePane?.() ?? manager?.getPanes?.()[0] ?? null + const fit = pane?.fitAddon.proposeDimensions() + if (!pane || !fit || pane.terminal.cols !== fit.cols || pane.terminal.rows !== fit.rows) { + return null + } + return { cols: fit.cols, rows: fit.rows } + }, webTabId) +} + /** Reads the target tab's own buffer. `getTerminalContent` resolves whatever * tab the store thinks is active, which hides per-tab reveal failures. */ async function readPaneContent(page: Page, webTabId: string): Promise { @@ -423,10 +439,25 @@ test('paired client keeps revealed remote terminals interactive', async ({ await openClientTab(client.page, worktreeId, decoys[0].webTabId) const originalGrid = await readActivePaneGrid(client.page, target.webTabId) await client.page.setViewportSize({ width: 960, height: 800 }) + // Why fitted: a late reveal replay briefly parses at the host's old grid before refitting (#7279, #18132). + const fitted: { lastKey: string | null; settled: { cols: number; rows: number } | null } = { + lastKey: null, + settled: null + } await expect - .poll(() => readActivePaneGrid(client.page, decoys[0].webTabId)) - .not.toEqual(originalGrid) - const revealGrid = await readActivePaneGrid(client.page, decoys[0].webTabId) + .poll( + async () => { + const grid = await readFittedPaneGrid(client.page, decoys[0].webTabId) + const key = grid && JSON.stringify(grid) + const isNewFit = key !== null && key !== JSON.stringify(originalGrid) + fitted.settled = isNewFit && key === fitted.lastKey ? grid : null + fitted.lastKey = isNewFit ? key : null + return fitted.settled !== null + }, + { timeout: 60_000, message: 'decoy never settled at the new viewport fit' } + ) + .toBe(true) + const revealGrid = fitted.settled if (!revealGrid) { throw new Error('visible decoy has no grid') }