mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
test: await fresh inventory after headless terminal materialization (#19028)
* test: restore headless folder terminal materialization coverage * test: await a fresh terminal census after materialization
This commit is contained in:
@@ -9,6 +9,7 @@ import type {
|
||||
import { toWebTerminalSurfaceTabId } from '../../../src/shared/terminal-surface-id'
|
||||
import { expect } from './orca-app'
|
||||
import { getTerminalContent, waitForActivePanePtyId } from './terminal'
|
||||
import { readFreshTerminalInventory } from './terminal-inventory-observation'
|
||||
|
||||
const RECOVERY_DEADLINE_MS = 8_000
|
||||
|
||||
@@ -76,10 +77,6 @@ function count(text: string, marker: string): number {
|
||||
return text.split(marker).length - 1
|
||||
}
|
||||
|
||||
function isTransientPtyLivenessError(error: unknown): boolean {
|
||||
return error instanceof Error && error.message.includes('terminal_liveness_unavailable')
|
||||
}
|
||||
|
||||
async function expectSingleOwningPty(
|
||||
page: Page,
|
||||
worktreeId: string,
|
||||
@@ -90,24 +87,15 @@ async function expectSingleOwningPty(
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
try {
|
||||
const listed = await callStartupExecRuntime<RuntimeTerminalListResult>(
|
||||
page,
|
||||
'terminal.list',
|
||||
{
|
||||
worktree: `id:${worktreeId}`,
|
||||
requireFreshPtyLiveness: true
|
||||
}
|
||||
)
|
||||
return listed.terminals
|
||||
.filter((candidate) => candidate.tabId === tabId)
|
||||
.map((candidate) => ({ handle: candidate.handle, ptyId: candidate.ptyId }))
|
||||
} catch (error) {
|
||||
if (isTransientPtyLivenessError(error)) {
|
||||
return []
|
||||
}
|
||||
throw error
|
||||
}
|
||||
const listed = await readFreshTerminalInventory(() =>
|
||||
callStartupExecRuntime<RuntimeTerminalListResult>(page, 'terminal.list', {
|
||||
worktree: `id:${worktreeId}`,
|
||||
requireFreshPtyLiveness: true
|
||||
})
|
||||
)
|
||||
return (listed?.terminals ?? [])
|
||||
.filter((candidate) => candidate.tabId === tabId)
|
||||
.map((candidate) => ({ handle: candidate.handle, ptyId: candidate.ptyId }))
|
||||
},
|
||||
{ timeout: 30_000 }
|
||||
)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { RuntimeTerminalListResult } from '../../../src/shared/runtime-types'
|
||||
|
||||
export async function readFreshTerminalInventory(
|
||||
read: () => Promise<RuntimeTerminalListResult>
|
||||
): Promise<RuntimeTerminalListResult | null> {
|
||||
try {
|
||||
return await read()
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.includes('terminal_liveness_unavailable')) {
|
||||
return null
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
launchPairedElectronClient
|
||||
} from './helpers/paired-electron-client'
|
||||
import { getTerminalContent, waitForActivePanePtyId } from './helpers/terminal'
|
||||
import { readFreshTerminalInventory } from './helpers/terminal-inventory-observation'
|
||||
|
||||
const scratch = mkdtempSync(path.join(os.tmpdir(), 'orca-paired-materialize-'))
|
||||
const fixturePath = path.join(scratch, 'materialize-terminal.mjs')
|
||||
@@ -316,18 +317,17 @@ async function runMaterializationJourney(
|
||||
await tab.click()
|
||||
await expect.poll(() => getTerminalContent(page), { timeout: 10_000 }).toContain(marker)
|
||||
|
||||
const listed = await callRuntime<RuntimeTerminalListResult>(
|
||||
page,
|
||||
environmentId,
|
||||
'terminal.list',
|
||||
{
|
||||
worktree: `id:${worktreeId}`,
|
||||
requireFreshPtyLiveness: true
|
||||
}
|
||||
)
|
||||
expect(
|
||||
listed.terminals.filter((terminal) => terminal.tabId === created.tab.parentTabId)
|
||||
).toHaveLength(1)
|
||||
await expect
|
||||
.poll(async () => {
|
||||
const listed = await readFreshTerminalInventory(() =>
|
||||
callRuntime<RuntimeTerminalListResult>(page, environmentId, 'terminal.list', {
|
||||
worktree: `id:${worktreeId}`,
|
||||
requireFreshPtyLiveness: true
|
||||
})
|
||||
)
|
||||
return listed?.terminals.filter((terminal) => terminal.tabId === created.tab.parentTabId)
|
||||
})
|
||||
.toHaveLength(1)
|
||||
await callRuntime(page, environmentId, 'terminal.closeTab', { terminal: replacementHandle })
|
||||
}
|
||||
|
||||
@@ -354,15 +354,7 @@ test('materializes a stopped terminal on reconnect from a headed paired host', a
|
||||
}
|
||||
})
|
||||
|
||||
// Why fixme: this journey's fault injection cannot be set up on a headless `orca serve` host.
|
||||
// `terminal.stopExact` keeps returning terminal_exact_stop_failed because stopAndWait's
|
||||
// keep-history verification window expires before the parked PTY is observed gone, so the pane
|
||||
// never reaches pending-handle and the reconnect behavior is never exercised. That precondition
|
||||
// fails identically on this PR's base, so it is a pre-existing exact-stop defect rather than a
|
||||
// reconnect-activation one. The recovery behavior itself was confirmed by hand in this topology
|
||||
// (the host materializes the pending surface and the client rebinds to the replacement PTY);
|
||||
// re-enable once exact stop settles deterministically against a serve host.
|
||||
test.fixme('materializes a stopped terminal on reconnect from a headless folder host', async ({
|
||||
test('materializes a stopped terminal on reconnect from a headless folder host', async ({
|
||||
testRepoPath
|
||||
}, testInfo) => {
|
||||
test.setTimeout(150_000)
|
||||
|
||||
Reference in New Issue
Block a user