mirror of
https://github.com/stablyai/orca.git
synced 2026-09-28 16:02:45 +00:00
test(e2e): fix failures and improve stability (#23480)
- Narrow toolbar width and set window minimums for consistent testing - Add node_modules symlink to fixture for ESM import resolution - Exercise manual paging and fix button selector - Preserve repo filters in reveal workflow - Adjust timing strategy and increase test timeout
This commit is contained in:
@@ -24,8 +24,8 @@ import { BROWSER_ADDRESS_BAR_MIN_INLINE_WIDTH } from '../../src/renderer/src/com
|
||||
// the middle of that band rather than a fixed window width, because how much
|
||||
// chrome flanks the pane (left sidebar, and a right sidebar that other startup
|
||||
// paths may re-open) varies between runs.
|
||||
const TARGET_TOOLBAR_WIDTH = 420
|
||||
const MIN_USABLE_TOOLBAR_WIDTH = BROWSER_ADDRESS_BAR_MIN_INLINE_WIDTH + 100
|
||||
const TARGET_TOOLBAR_WIDTH = 260
|
||||
const MIN_USABLE_TOOLBAR_WIDTH = BROWSER_ADDRESS_BAR_MIN_INLINE_WIDTH + 20
|
||||
const NARROW_WINDOW_HEIGHT = 800
|
||||
|
||||
async function startDestinationServer(): Promise<{ url: string; close: () => Promise<void> }> {
|
||||
@@ -62,6 +62,8 @@ async function setWindowWidth(electronApp: ElectronApplication, width: number):
|
||||
if (!window) {
|
||||
throw new Error('No Electron window')
|
||||
}
|
||||
// Window minimums otherwise mask the narrow-pane state on some runners.
|
||||
window.setMinimumSize(0, 0)
|
||||
window.setSize(size.width, size.height)
|
||||
},
|
||||
{ width: Math.round(width), height: NARROW_WINDOW_HEIGHT }
|
||||
@@ -118,8 +120,11 @@ async function settleToSqueezedRestingState(
|
||||
// Chrome flanking the pane is everything the toolbar didn't get.
|
||||
await setWindowWidth(electronApp, innerWidth - toolbar + TARGET_TOOLBAR_WIDTH)
|
||||
await addressBarInput(page).evaluate((node) => node.blur())
|
||||
const measuredToolbar = await toolbarWidth(page)
|
||||
return {
|
||||
toolbar: (await toolbarWidth(page)) > MIN_USABLE_TOOLBAR_WIDTH,
|
||||
toolbar:
|
||||
measuredToolbar > MIN_USABLE_TOOLBAR_WIDTH &&
|
||||
measuredToolbar <= TARGET_TOOLBAR_WIDTH + 5,
|
||||
collapsed: (await addressBarOverlay(page).count()) === 0
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
symlinkSync,
|
||||
writeFileSync
|
||||
} from 'node:fs'
|
||||
import { homedir, tmpdir } from 'node:os'
|
||||
import path from 'node:path'
|
||||
import { build } from 'esbuild'
|
||||
@@ -109,6 +117,12 @@ export async function createDaemonGenerationRuntime(
|
||||
const reconnectClientEntryPath = path.join(rootDir, 'daemon-generation-reconnect-client.cjs')
|
||||
const legacyCloseClientEntryPath = path.join(rootDir, 'daemon-generation-legacy-close-client.cjs')
|
||||
const repoRoot = process.cwd()
|
||||
// ESM imports in the bundled fixture resolve from its temp directory, not NODE_PATH.
|
||||
symlinkSync(
|
||||
path.join(repoRoot, 'node_modules'),
|
||||
path.join(rootDir, 'node_modules'),
|
||||
process.platform === 'win32' ? 'junction' : 'dir'
|
||||
)
|
||||
await buildFixtureEntry(
|
||||
path.join(repoRoot, 'tests/e2e/fixtures/daemon-generation-entry.ts'),
|
||||
entryPath
|
||||
|
||||
@@ -138,6 +138,13 @@ test.describe('Native chat transcript anchoring', () => {
|
||||
sessionId,
|
||||
transcriptPath
|
||||
})
|
||||
// Exercise the supported manual paging fallback while the reader stays mid-transcript.
|
||||
await orcaPage.evaluate(() => {
|
||||
Object.defineProperty(window, 'IntersectionObserver', {
|
||||
value: undefined,
|
||||
configurable: true
|
||||
})
|
||||
})
|
||||
await toggleTerminalTabToChatView(orcaPage, {
|
||||
tabId,
|
||||
worktreeId: descriptor.worktreeId
|
||||
|
||||
@@ -143,7 +143,7 @@ test.describe('Native chat message rail', () => {
|
||||
|
||||
// Activating the hover preview transfers focus into the prompt picker.
|
||||
await rail.press('Enter')
|
||||
await expect(panel.getByRole('button').first()).toBeFocused()
|
||||
await expect(panel.locator('button[data-current="true"]')).toBeFocused()
|
||||
await panel.getByRole('button', { name: 'Question 5:', exact: false }).click()
|
||||
await expect(panel).not.toBeVisible()
|
||||
const target = transcriptWindow.locator('[data-index="10"]')
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
} from './helpers/terminal'
|
||||
import { parkHiddenTabBehindDecoy, waitForTabParked } from './helpers/terminal-hidden-parking'
|
||||
import { waitForPtyShellEcho } from './terminal-pty-readiness'
|
||||
import { TERMINAL_TAB_PARK_FLIP_BURST_WINDOW_MS } from '../../src/renderer/src/components/terminal-pane/terminal-park-verdict-flip-telemetry'
|
||||
import { TERMINAL_TAB_PARK_FLIP_WINDOW_MS } from '../../src/renderer/src/components/terminal-pane/terminal-park-verdict-flip-telemetry'
|
||||
|
||||
// Why: the parking wiring registers this handle (dev/exposeStore builds only)
|
||||
// so tests can detect that hidden-view parking is compiled in and which delay
|
||||
@@ -43,7 +43,7 @@ test.use({
|
||||
|
||||
const PARKED_FRAME_SCRIPT_DELAY_MS = 750
|
||||
const PARKED_FRAME_COUNT = 25
|
||||
const PARK_VERDICT_BURST_SETTLE_MS = TERMINAL_TAB_PARK_FLIP_BURST_WINDOW_MS * 4
|
||||
const PARK_VERDICT_WINDOW_SETTLE_MS = Math.ceil(TERMINAL_TAB_PARK_FLIP_WINDOW_MS / 5)
|
||||
|
||||
function parkedTuiFrame(runId: string, frame: number): string {
|
||||
const progress = `${'█'.repeat((frame % 8) + 1)}${'░'.repeat(8 - ((frame % 8) + 1))}`
|
||||
@@ -478,7 +478,7 @@ test.describe('Terminal hidden view parking', () => {
|
||||
orcaPage,
|
||||
testRepoPath
|
||||
}, testInfo: TestInfo) => {
|
||||
test.setTimeout(180_000)
|
||||
test.setTimeout(420_000)
|
||||
await waitForSessionReady(orcaPage)
|
||||
const setup = await setUpParkableTabA(orcaPage)
|
||||
const { worktreeId, tabAId, tabAPtyId } = setup
|
||||
@@ -542,8 +542,8 @@ test.describe('Terminal hidden view parking', () => {
|
||||
const mismatches: string[] = []
|
||||
for (let cycle = 1; cycle < CYCLES; cycle++) {
|
||||
// Why: each cycle intentionally flips this tab's rendered verdict twice.
|
||||
// Let the production anti-churn burst window lapse before the next one.
|
||||
await orcaPage.waitForTimeout(PARK_VERDICT_BURST_SETTLE_MS)
|
||||
// Keep each tab below the 12-flip sustained-churn pin in a 60s window.
|
||||
await orcaPage.waitForTimeout(PARK_VERDICT_WINDOW_SETTLE_MS)
|
||||
const rows = await runOneParkRevealCycle(cycle)
|
||||
if (JSON.stringify(rows) !== JSON.stringify(referenceRows)) {
|
||||
mismatches.push(
|
||||
|
||||
@@ -40,7 +40,7 @@ test.describe('Reveal active workspace button', () => {
|
||||
// (not a scenario real users hit). Reveal-into-view is covered robustly by
|
||||
// the "outside the virtualized window" test below.
|
||||
|
||||
test('clears sidebar filters before revealing a hidden current workspace', async ({
|
||||
test('adjusts sidebar filters before revealing a hidden current workspace', async ({
|
||||
orcaPage,
|
||||
testRepoPath
|
||||
}, testInfo) => {
|
||||
@@ -94,6 +94,13 @@ test.describe('Reveal active workspace button', () => {
|
||||
if (!targetId) {
|
||||
throw new Error('Seeded secondary worktree is missing')
|
||||
}
|
||||
const targetRepoId = await orcaPage.evaluate(
|
||||
(repoPath) => window.__store!.getState().repos.find((repo) => repo.path === repoPath)?.id,
|
||||
testRepoPath
|
||||
)
|
||||
if (!targetRepoId) {
|
||||
throw new Error('Seeded repository is missing')
|
||||
}
|
||||
|
||||
const targetRows = orcaPage.locator(
|
||||
`[data-worktree-sidebar] [data-worktree-id=${JSON.stringify(targetId)}]`
|
||||
@@ -132,7 +139,7 @@ test.describe('Reveal active workspace button', () => {
|
||||
await revealButton.click()
|
||||
await orcaPage
|
||||
.getByRole('dialog', { name: 'Reveal hidden workspace?' })
|
||||
.getByRole('button', { name: 'Clear filters and reveal' })
|
||||
.getByRole('button', { name: 'Adjust filters and reveal' })
|
||||
.click()
|
||||
|
||||
await expect(targetRow).toBeVisible()
|
||||
@@ -149,10 +156,11 @@ test.describe('Reveal active workspace button', () => {
|
||||
}),
|
||||
{
|
||||
timeout: 10_000,
|
||||
message: 'Reveal button should clear repo filters that hide the current workspace'
|
||||
message:
|
||||
'Reveal button should preserve selected repos while revealing the current workspace'
|
||||
}
|
||||
)
|
||||
.toEqual([])
|
||||
.toEqual([filterRepoId, targetRepoId])
|
||||
})
|
||||
|
||||
test('reveals the current workspace when it starts outside the virtualized window', async ({
|
||||
|
||||
Reference in New Issue
Block a user