mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 16:03:17 +00:00
* fix(e2e): repair release e2e suite — parking regression tests, stale/flaky specs, profile switcher gate Diagnosed 20 failing tests across the release e2e shards. Most are test debt, plus two genuine product-side issues. Product fixes: - OrcaProfileSwitcher: the PROD gate hid the "Switch profile" button in the e2e build (electron-vite build bakes NODE_ENV=production). Exempt MODE==='e2e' so the specs render it while packaged prod builds stay hidden. Parking cluster (8 tests): #8262 intentionally keeps the most-recently-hidden tab warm (exempt from cold-park). The specs hid exactly one tab — always the exempt one — so it never parked. Open a throwaway decoy tab that absorbs the last-active exemption so the target parks. (terminal-hidden-view-parking, terminal-pane-close-layout-consistency) Stale tests updated to match intended product behavior: - rich-markdown-link-bubble: match Edit link by aria-label (title dropped in #8307) - terminal-codex-hidden-startup-background: drop the dead hiddenRendererSkipCount poll (Phase-4 main-side delivery gate #7214 bypasses that renderer path) Brittle threshold/geometry/timing hardening (no product regression): - agent-session-log-tail-stability: assert full-model length instead of a machine-specific word-wrap pixel baseline - artificial-opencode revisit: dedicated under-backpressure latency bound - terminal-history-size-typing-latency: gate p90 not max (tolerate one checkpoint-in-window spike; median stays strict) - combined-diff-scroll-restore: assert viewport barely moved vs exact anchor key - terminal-shortcuts: idempotent kitty-flag reset instead of a racing stack pop - agent-session-live-force-exit-resume: drive the product quit-capture path - renderer-crash-recovery-terminal-input: poll the transport probe over the recovery budget (still flags a permanently frozen pane) terminal-push-delivery-loss-recovery left unchanged (no safe test-only improvement; recovery is wall-clock bounded with ample slack). * Extract shared parking helpers into terminal-hidden-parking.ts for e2e s - Deduplicate waitForTabParked/parkHiddenTabBehindDecoy, previously copy-pasted across the parking and layout-consistency specs - Parameterize parkDelayMs so the helper no longer depends on a file-local PARKING_DELAY_MS constant
66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
import type { Page } from '@stablyai/playwright-test'
|
|
import { expect } from '@stablyai/playwright-test'
|
|
import { getActiveTabId } from './store'
|
|
import { waitForActiveTerminalManager, waitForPaneIdentitySnapshot } from './terminal'
|
|
|
|
function resolveParkWaitTimeoutMs(parkDelayMs?: number): number {
|
|
const delay = parkDelayMs ?? (Number(process.env.ORCA_E2E_TERMINAL_PARKING_DELAY_MS) || 500)
|
|
return Math.max(20_000, delay * 10)
|
|
}
|
|
|
|
// Why: TerminalPane unmount deletes its entry from window.__paneManagers, so a
|
|
// missing manager is the observable signal that the tab's xterm was parked.
|
|
export async function waitForTabParked(
|
|
page: Page,
|
|
tabId: string,
|
|
options?: { parkDelayMs?: number }
|
|
): Promise<number> {
|
|
const parkWaitStartedAt = Date.now()
|
|
await expect
|
|
.poll(async () => page.evaluate((id) => window.__paneManagers?.get(id) !== undefined, tabId), {
|
|
timeout: resolveParkWaitTimeoutMs(options?.parkDelayMs),
|
|
message: `terminal tab ${tabId} did not park (pane manager still mounted)`
|
|
})
|
|
.toBe(false)
|
|
return Date.now() - parkWaitStartedAt
|
|
}
|
|
|
|
async function createActiveTerminalTab(page: Page, worktreeId: string): Promise<string> {
|
|
const tabId = await page.evaluate((worktreeId) => {
|
|
const store = window.__store
|
|
if (!store) {
|
|
throw new Error('createActiveTerminalTab: window.__store is unavailable')
|
|
}
|
|
const state = store.getState()
|
|
const tab = state.createTab(worktreeId, undefined, undefined, { activate: true })
|
|
state.setActiveTab(tab.id)
|
|
state.setActiveTabType('terminal')
|
|
return tab.id
|
|
}, worktreeId)
|
|
|
|
await expect
|
|
.poll(() => getActiveTabId(page), {
|
|
timeout: 5_000,
|
|
message: 'newly created terminal tab did not become active'
|
|
})
|
|
.toBe(tabId)
|
|
await waitForActiveTerminalManager(page, 30_000)
|
|
await waitForPaneIdentitySnapshot(page, 1)
|
|
return tabId
|
|
}
|
|
|
|
// Why: #8262 exempts the single most-recently-hidden tab from cold-park to keep
|
|
// the just-left view instantly warm, so a lone hidden tab never parks. Opening
|
|
// one more tab hides the current view (which then holds that exemption) and
|
|
// leaves the older `targetTabId` free to cold-park. Returns waitForTabParked's
|
|
// elapsed-ms so callers keep their parking annotations.
|
|
export async function parkHiddenTabBehindDecoy(
|
|
page: Page,
|
|
worktreeId: string,
|
|
targetTabId: string,
|
|
options?: { parkDelayMs?: number }
|
|
): Promise<number> {
|
|
await createActiveTerminalTab(page, worktreeId)
|
|
return waitForTabParked(page, targetTabId, options)
|
|
}
|