From f17b647f42dc41c2dbadd5ce8ad32a73725170cf Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Wed, 29 Jul 2026 03:34:35 -0700 Subject: [PATCH] test(terminal): bound perf marker scans --- ...icial-opencode-hidden-pressure-scenario.ts | 16 ++---- .../artificial-opencode-pane-interactions.ts | 50 ++++++++++++++++++- ...cial-opencode-revisit-pressure-scenario.ts | 17 +------ 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/tests/e2e/artificial-opencode-hidden-pressure-scenario.ts b/tests/e2e/artificial-opencode-hidden-pressure-scenario.ts index ca19daf7395..5145a12e6fa 100644 --- a/tests/e2e/artificial-opencode-hidden-pressure-scenario.ts +++ b/tests/e2e/artificial-opencode-hidden-pressure-scenario.ts @@ -7,6 +7,7 @@ import { type HiddenPressureOutputMode, writePressureOutputScript } from './artificial-opencode-hidden-pressure-script' +import { waitForMarkerLatency } from './artificial-opencode-pane-interactions' import { ensureTerminalVisible, getActiveWorktreeId, @@ -16,7 +17,6 @@ import { waitForSessionReady } from './helpers/store' import { - getTerminalContent, sendToTerminal, waitForActivePanePtyId, waitForActiveTerminalManager @@ -83,11 +83,8 @@ type HiddenPressureAckGate = { heldAckChars: number } -// Why: restore still has to finish promptly, but parallel Electron workers on -// Linux CI can overshoot the 1s product target without a responsiveness regression. -// Main relaxed this to 4s for drain-plus-poll overhead on loaded OSS runners; this -// branch keeps a far stricter budget with only a small margin for the whole-buffer -// serialize-poll overhead (seen at ~1.5s), so a genuinely slow restore is still caught. +// Why: keep a runtime backstop so loaded CI still emits the measurement; +// saved perf reports enforce the stricter 1s product budget. const MAX_HIDDEN_RESTORE_LATENCY_MS = 2_000 // Why: Phase-4 hidden-delivery gate contract — hidden PTY bytes are dropped in // main after model ingestion, so renderer-delivery pressure must stay FAR @@ -269,12 +266,7 @@ async function measureHiddenOutputRestoreLatency( ): Promise { const restoreStart = performance.now() await switchToWorktree(orcaPage, worktreeId) - await expect - .poll(() => getTerminalContent(orcaPage, 20_000), { - timeout: 20_000, - message: 'Hidden PTY output was not restored from main buffer on return' - }) - .toContain(`OPENCODE_PRESSURE_DONE_${runId}_`) + await waitForMarkerLatency(orcaPage, `OPENCODE_PRESSURE_DONE_${runId}_`, 20_000) return performance.now() - restoreStart } diff --git a/tests/e2e/artificial-opencode-pane-interactions.ts b/tests/e2e/artificial-opencode-pane-interactions.ts index f93c3a0788d..3d8a6005a7e 100644 --- a/tests/e2e/artificial-opencode-pane-interactions.ts +++ b/tests/e2e/artificial-opencode-pane-interactions.ts @@ -2,7 +2,6 @@ import type { Page } from '@stablyai/playwright-test' import { expect } from './helpers/orca-app' import { ensureTerminalVisible } from './helpers/store' import { - getTerminalContent, splitActiveTerminalPane, waitForActiveTerminalManager, waitForPaneIdentitySnapshot @@ -76,7 +75,7 @@ export async function waitForMarkerLatency( ): Promise { const start = performance.now() while (performance.now() - start < timeoutMs) { - if ((await getTerminalContent(page, 12_000)).includes(marker)) { + if (await activeTerminalTailContains(page, marker)) { return performance.now() - start } await page.waitForTimeout(5) @@ -84,6 +83,53 @@ export async function waitForMarkerLatency( throw new Error(`Timed out waiting for terminal marker ${marker}`) } +// Marker probes only need recent text; serializing full scrollback can dominate the latency under test. +export async function activeTerminalTailContains( + page: Page, + expected: string, + maxRows = 200 +): Promise { + return page.evaluate( + ({ expected, maxRows }) => { + const state = window.__store?.getState() + const worktreeId = state?.activeWorktreeId + const tabs = worktreeId ? (state?.tabsByWorktree[worktreeId] ?? []) : [] + const preferredTabId = + state?.activeTabType === 'terminal' + ? state.activeTabId + : worktreeId + ? (state?.activeTabIdByWorktree?.[worktreeId] ?? null) + : null + const tabId = + preferredTabId && tabs.some((tab) => tab.id === preferredTabId) + ? preferredTabId + : (tabs[0]?.id ?? null) + const manager = tabId ? window.__paneManagers?.get(tabId) : null + const pane = manager?.getActivePane?.() ?? manager?.getPanes?.()[0] ?? null + const buffer = pane?.terminal?.buffer?.active + if (!buffer) { + return false + } + const firstRow = Math.max(0, buffer.length - maxRows) + let logicalHead = '' + for (let row = buffer.length - 1; row >= firstRow; row -= 1) { + const line = buffer.getLine(row) + if (!line) { + logicalHead = '' + continue + } + logicalHead = line.translateToString(true) + logicalHead + if (logicalHead.includes(expected)) { + return true + } + logicalHead = line.isWrapped ? logicalHead.slice(0, expected.length) : '' + } + return false + }, + { expected, maxRows } + ) +} + export async function getTerminalContentForPtyId( page: Page, ptyId: string, diff --git a/tests/e2e/artificial-opencode-revisit-pressure-scenario.ts b/tests/e2e/artificial-opencode-revisit-pressure-scenario.ts index c533a395e22..29e1a708bb1 100644 --- a/tests/e2e/artificial-opencode-revisit-pressure-scenario.ts +++ b/tests/e2e/artificial-opencode-revisit-pressure-scenario.ts @@ -4,6 +4,7 @@ import { randomUUID } from 'node:crypto' import { rmSync } from 'node:fs' import path from 'node:path' import { writePressureOutputScript } from './artificial-opencode-hidden-pressure-script' +import { waitForMarkerLatency } from './artificial-opencode-pane-interactions' import { ensureTerminalVisible, getAllWorktreeIds, @@ -12,7 +13,6 @@ import { waitForSessionReady } from './helpers/store' import { - getTerminalContent, sendToTerminal, waitForActivePanePtyId, waitForActiveTerminalManager @@ -262,21 +262,6 @@ async function startRealPtyPressureCommands({ ) } -async function waitForMarkerLatency( - page: Page, - marker: string, - timeoutMs: number -): Promise { - const start = performance.now() - while (performance.now() - start < timeoutMs) { - if ((await getTerminalContent(page, 12_000)).includes(marker)) { - return performance.now() - start - } - await page.waitForTimeout(5) - } - throw new Error(`Timed out waiting for terminal marker ${marker}`) -} - function expectPressureStayedBounded({ ackGate, mainRendererPressureTargetChars,