mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 00:04:01 +00:00
test(cmd-j): harden visible performance oracle
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { act } from 'react'
|
||||
import { createRoot, type Root } from 'react-dom/client'
|
||||
import { fireEvent } from '@testing-library/react'
|
||||
import { fireEvent, waitFor } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type * as ReactI18Next from 'react-i18next'
|
||||
import { useAppStore } from '@/store'
|
||||
@@ -356,9 +356,9 @@ describe('WorktreeJumpPalette', () => {
|
||||
await act(async () => {
|
||||
setCommandQuery?.('Feature')
|
||||
})
|
||||
await flushEffects()
|
||||
|
||||
expect(testContainer.textContent).toContain('Feature workspace')
|
||||
await waitFor(() => {
|
||||
expect(testContainer.textContent).toContain('Feature workspace')
|
||||
})
|
||||
})
|
||||
|
||||
// STA-4343 closed: two workspaces sharing `repoId::path` across hosts are two distinct
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { act } from 'react'
|
||||
import { createRoot, type Root } from 'react-dom/client'
|
||||
import { waitFor } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type * as ReactI18Next from 'react-i18next'
|
||||
import type { Repo } from '../../../shared/repo-types'
|
||||
@@ -314,12 +315,13 @@ describe('WorktreeJumpPalette interleaved primary sections', () => {
|
||||
await act(async () => {
|
||||
setCommandQuery?.('perf')
|
||||
})
|
||||
await flushEffects()
|
||||
await waitFor(() => {
|
||||
const rows = getPrimaryRowsBySectionHeader()
|
||||
expect(rows.filter((row) => row.rowId.startsWith('workspace-tab:'))).toHaveLength(8)
|
||||
expect(rows.filter((row) => row.rowId.startsWith('worktree:'))).toHaveLength(5)
|
||||
})
|
||||
|
||||
const rows = getPrimaryRowsBySectionHeader()
|
||||
// Why the counts: both remainders must still render, just under a re-emitted header.
|
||||
expect(rows.filter((row) => row.rowId.startsWith('workspace-tab:'))).toHaveLength(8)
|
||||
expect(rows.filter((row) => row.rowId.startsWith('worktree:'))).toHaveLength(5)
|
||||
for (const { header, rowId } of rows) {
|
||||
expect(header).toBe(rowId.startsWith('workspace-tab:') ? 'Open Tabs' : 'Worktrees')
|
||||
}
|
||||
@@ -331,7 +333,11 @@ describe('WorktreeJumpPalette interleaved primary sections', () => {
|
||||
await act(async () => {
|
||||
setCommandQuery?.('perf')
|
||||
})
|
||||
await flushEffects()
|
||||
await waitFor(() => {
|
||||
const rows = getPrimaryRowsBySectionHeader()
|
||||
expect(rows.filter((row) => row.rowId.startsWith('workspace-tab:'))).toHaveLength(8)
|
||||
expect(rows.filter((row) => row.rowId.startsWith('worktree:'))).toHaveLength(5)
|
||||
})
|
||||
|
||||
const renderedIds = Array.from(
|
||||
testContainer.querySelectorAll<HTMLElement>('[data-command-item]')
|
||||
@@ -370,10 +376,11 @@ describe('WorktreeJumpPalette interleaved primary sections', () => {
|
||||
await act(async () => {
|
||||
setCommandQuery?.('ubuntu')
|
||||
})
|
||||
await flushEffects()
|
||||
|
||||
const rows = getPrimaryRowsBySectionHeader()
|
||||
expect(rows).toEqual([{ header: 'Open Tabs', rowId: 'workspace-tab:tab-0' }])
|
||||
await waitFor(() => {
|
||||
expect(getPrimaryRowsBySectionHeader()).toEqual([
|
||||
{ header: 'Open Tabs', rowId: 'workspace-tab:tab-0' }
|
||||
])
|
||||
})
|
||||
expect(testContainer.textContent).toContain('Open Tabs')
|
||||
expect(testContainer.textContent).not.toContain('Worktrees')
|
||||
})
|
||||
|
||||
@@ -28,6 +28,7 @@ export const PALETTE_MATCH_BUDGET = {
|
||||
export const PALETTE_INTERACTION_BUDGET = {
|
||||
rendererStoreDispatchMs: 50,
|
||||
firstVisibleResultsMs: 100,
|
||||
coldIndexReadyMs: 350,
|
||||
coldImmediateQueryResultsMs: 250,
|
||||
/** Five 60 Hz frames, including the palette's initial layout and focus commit. */
|
||||
maxFrameGapMs: 84
|
||||
|
||||
@@ -7,6 +7,7 @@ const WORKSPACE_COUNT = 800
|
||||
const {
|
||||
rendererStoreDispatchMs: MAX_STORE_DISPATCH_MS,
|
||||
firstVisibleResultsMs: MAX_FIRST_VISIBLE_MS,
|
||||
coldIndexReadyMs: MAX_COLD_INDEX_READY_MS,
|
||||
coldImmediateQueryResultsMs: MAX_COLD_IMMEDIATE_QUERY_MS,
|
||||
maxFrameGapMs: MAX_FRAME_GAP_MS
|
||||
} = PALETTE_INTERACTION_BUDGET
|
||||
@@ -317,7 +318,7 @@ async function waitForStableFrameCadence(page: Page): Promise<void> {
|
||||
const now = performance.now()
|
||||
stableFrames = now - previousFrameAt <= 25 ? stableFrames + 1 : 0
|
||||
previousFrameAt = now
|
||||
if (stableFrames >= 6) {
|
||||
if (stableFrames >= 12) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
@@ -342,7 +343,22 @@ async function expectHostQualifiedNeedleOrder(dialog: Locator): Promise<void> {
|
||||
expect(matchingTexts[1]).toContain('acme/orca-local')
|
||||
}
|
||||
|
||||
test.describe('Cmd-J cold accumulated-workspace performance', () => {
|
||||
async function expectHostSpecificNeedle(
|
||||
dialog: Locator,
|
||||
query: string,
|
||||
expectedName: string,
|
||||
expectedRepo: string
|
||||
): Promise<void> {
|
||||
await dialog.getByPlaceholder(/Search chats, terminals, worktrees/).fill(query)
|
||||
const matchingRows = dialog
|
||||
.locator('[cmdk-item]:has([data-slot="palette-worktree-name"])')
|
||||
.filter({ hasText: 'Needle' })
|
||||
await expect(matchingRows).toHaveCount(1)
|
||||
await expect(matchingRows).toContainText(expectedName)
|
||||
await expect(matchingRows).toContainText(expectedRepo)
|
||||
}
|
||||
|
||||
test.describe('Cmd-J cold accumulated-workspace performance @headful', () => {
|
||||
test.beforeEach(async ({ orcaPage }) => {
|
||||
await waitForSessionReady(orcaPage)
|
||||
await waitForActiveWorktree(orcaPage)
|
||||
@@ -381,14 +397,28 @@ test.describe('Cmd-J cold accumulated-workspace performance', () => {
|
||||
expect(indexedQuery).not.toBeNull()
|
||||
|
||||
await expectHostQualifiedNeedleOrder(dialog)
|
||||
await expectHostSpecificNeedle(
|
||||
dialog,
|
||||
'accumulated-0399-remote',
|
||||
TARGET_REMOTE_NAME,
|
||||
'acme/orca-remote'
|
||||
)
|
||||
await expectHostSpecificNeedle(
|
||||
dialog,
|
||||
'accumulated-0399-local',
|
||||
TARGET_LOCAL_NAME,
|
||||
'acme/orca-local'
|
||||
)
|
||||
|
||||
await togglePaletteFromMain(electronApp)
|
||||
await expect(dialog).not.toBeVisible()
|
||||
// Reopen inside the close linger so documents and matcher indexes remain mounted.
|
||||
await orcaPage.waitForTimeout(100)
|
||||
await expect(dialog).toHaveAttribute('data-state', 'closed')
|
||||
await beginProbe(orcaPage, [TARGET_REMOTE_NAME, TARGET_LOCAL_NAME])
|
||||
await togglePaletteFromMain(electronApp)
|
||||
await expect(dialog).toBeVisible()
|
||||
await expect(dialog.locator('[data-worktree-index-pending]')).toHaveAttribute(
|
||||
'data-worktree-index-pending',
|
||||
'false'
|
||||
)
|
||||
await expect.poll(() => readMetrics(orcaPage), { timeout: 10_000 }).not.toBeNull()
|
||||
const warmReopen = await readMetrics(orcaPage)
|
||||
expect(warmReopen).not.toBeNull()
|
||||
@@ -414,10 +444,12 @@ test.describe('Cmd-J cold accumulated-workspace performance', () => {
|
||||
expect(coldOpen!.storeDispatchMs).not.toBeNull()
|
||||
expect(coldOpen!.storeDispatchMs!).toBeLessThanOrEqual(MAX_STORE_DISPATCH_MS)
|
||||
expect(coldOpen!.firstVisibleMs).toBeLessThanOrEqual(MAX_FIRST_VISIBLE_MS)
|
||||
expect(coldOpen!.indexReadyMs).toBeLessThanOrEqual(MAX_COLD_INDEX_READY_MS)
|
||||
expect(coldOpen!.maxFrameGapMs).toBeLessThanOrEqual(MAX_FRAME_GAP_MS)
|
||||
expect(indexedQuery!.firstVisibleMs).toBeLessThanOrEqual(MAX_FIRST_VISIBLE_MS)
|
||||
expect(indexedQuery!.maxFrameGapMs).toBeLessThanOrEqual(MAX_FRAME_GAP_MS)
|
||||
expect(warmReopen!.firstVisibleMs).toBeLessThanOrEqual(MAX_FIRST_VISIBLE_MS)
|
||||
expect(warmReopen!.indexReadyMs).toBe(warmReopen!.firstVisibleMs)
|
||||
expect(warmReopen!.maxFrameGapMs).toBeLessThanOrEqual(MAX_FRAME_GAP_MS)
|
||||
|
||||
await orcaPage.evaluate(() => (window as PerformanceProbeWindow).__cmdJPerformanceProbe?.stop())
|
||||
|
||||
Reference in New Issue
Block a user