orca/tests/e2e/worktree-lineage-agent-expa...

113 lines
4.4 KiB
TypeScript

import type { Page } from '@stablyai/playwright-test'
import { mkdirSync } from 'node:fs'
import { resolve } from 'node:path'
import { test, expect } from './helpers/orca-app'
import { waitForActiveWorktree, waitForSessionReady } from './helpers/store'
import { seedLineageScenario } from './worktree-lineage-state'
import { worktreeRow } from './worktree-row-locators'
// Set ORCA_CAPTURE_EVIDENCE=1 to also write before/after screenshots to
// pr-evidence/. Off by default so CI just runs the behavioral assertions.
const CAPTURE_EVIDENCE = process.env.ORCA_CAPTURE_EVIDENCE === '1'
const SHOT_DIR = resolve(process.cwd(), 'pr-evidence')
async function captureSidebar(page: Page, name: string): Promise<void> {
if (!CAPTURE_EVIDENCE) {
return
}
mkdirSync(SHOT_DIR, { recursive: true })
await sidebar(page).screenshot({ path: resolve(SHOT_DIR, name) })
}
// Seed two independent root agents on the parent worktree so its card shows the
// compact "2 agents" summary pill alongside the "N child workspaces" chip.
async function seedTwoParentAgents(page: Page, worktreeId: string): Promise<void> {
await page.evaluate((worktreeId) => {
const store = window.__store
if (!store) {
throw new Error('window.__store is not available')
}
const state = store.getState()
if (!state.worktreeCardProperties.includes('inline-agents')) {
state.toggleWorktreeCardProperty('inline-agents')
}
while ((store.getState().tabsByWorktree[worktreeId] ?? []).length < 2) {
store.getState().createTab(worktreeId)
}
const tabs = (store.getState().tabsByWorktree[worktreeId] ?? []).slice(0, 2)
const now = Date.now()
const specs = [
{ state: 'working' as const, prompt: 'Refactor auth middleware', agentType: 'claude' },
{ state: 'done' as const, prompt: 'Write unit tests for parser', agentType: 'codex' }
]
tabs.forEach((tab, index) => {
const spec = specs[index]!
const leafId = crypto.randomUUID()
store
.getState()
.setAgentStatus(
`${tab.id}:${leafId}`,
{ state: spec.state, prompt: spec.prompt, agentType: spec.agentType },
spec.agentType,
{ updatedAt: now, stateStartedAt: now }
)
})
}, worktreeId)
}
function sidebar(page: Page) {
return page.locator('[data-worktree-sidebar]').first()
}
function compactSummary(page: Page, parentId: string) {
return worktreeRow(page, parentId).locator('button.compact-agent-summary-button').first()
}
function childWorkspacesChip(page: Page, parentId: string) {
return worktreeRow(page, parentId)
.getByRole('button', { name: /child workspace/i })
.first()
}
test.describe('Worktree lineage agent-list expansion independence', () => {
test.describe.configure({ mode: 'serial' })
test.beforeEach(async ({ orcaPage }) => {
await waitForSessionReady(orcaPage)
await waitForActiveWorktree(orcaPage)
})
test('toggling child worktrees does not collapse the expanded agent summary', async ({
orcaPage
}) => {
const { parentId, childId } = await seedLineageScenario(orcaPage)
const parentRow = worktreeRow(orcaPage, parentId)
const childRow = worktreeRow(orcaPage, childId)
await parentRow.click()
await expect(parentRow).toHaveAttribute('aria-current', 'page')
await seedTwoParentAgents(orcaPage, parentId)
// Both sections present: the "2 agents" summary and the child-workspaces chip.
await expect(compactSummary(orcaPage, parentId)).toBeVisible({ timeout: 10_000 })
await expect(childWorkspacesChip(orcaPage, parentId)).toBeVisible()
await expect(childRow).toBeVisible()
await expect(compactSummary(orcaPage, parentId)).toHaveAttribute('aria-expanded', 'false')
await captureSidebar(orcaPage, '1-before-both-collapsed.png')
// Expand the agent summary.
await compactSummary(orcaPage, parentId).click()
await expect(compactSummary(orcaPage, parentId)).toHaveAttribute('aria-expanded', 'true')
await captureSidebar(orcaPage, '2-agents-expanded.png')
// Collapse the child worktrees via the chip. This remounts the parent card.
await childWorkspacesChip(orcaPage, parentId).click()
await expect(childRow).toBeHidden()
// FIXED: the agent summary stays expanded despite the card remount.
await expect(compactSummary(orcaPage, parentId)).toHaveAttribute('aria-expanded', 'true')
await captureSidebar(orcaPage, '3-after-children-toggle-agents-still-expanded.png')
})
})