import { randomUUID } from "node:crypto"; import { expect } from "@playwright/test"; import { test } from "./fixtures"; import { getServerId } from "./helpers/server-id"; import { connectSeedClient } from "./helpers/seed-client"; import { createTempGitRepo } from "./helpers/workspace"; import { buildHostWorkspaceRoute } from "@/utils/host-routes"; import { archiveAgentFromDaemon, archiveAgentFromSessions, clickSessionRow, createIdleAgent, expectSessionRowArchived, expectSessionRowVisible, expectWorkspaceArchiveOutcome, expectWorkspaceTabHidden, fetchAgentArchivedAt, openSessions, openWorkspaceWithAgents, primeAdditionalPage, resetSeededPageState, reloadWorkspace, } from "./helpers/archive-tab"; test.describe("Archive tab reconciliation", () => { let client: Awaited>; let tempRepo: { path: string; cleanup: () => Promise }; let projectId: string; let workspaceId: string; test.describe.configure({ timeout: 300_000 }); test.beforeAll(async () => { tempRepo = await createTempGitRepo("archive-tab-"); client = await connectSeedClient(); const created = await client.createWorkspace({ source: { kind: "directory", path: tempRepo.path }, }); if (!created.workspace) { throw new Error(created.error ?? `Failed to create workspace ${tempRepo.path}`); } projectId = created.workspace.projectId; workspaceId = created.workspace.id; }); test.afterAll(async () => { await client?.removeProject(projectId).catch(() => undefined); await client?.close().catch(() => undefined); await tempRepo?.cleanup(); }); test("non-UI archive prunes the archived tab across open pages and reload", async ({ page }) => { const archived = await createIdleAgent(client, { cwd: tempRepo.path, workspaceId, title: `cli-archive-${randomUUID().slice(0, 8)}`, }); const surviving = await createIdleAgent(client, { cwd: tempRepo.path, workspaceId, title: `cli-control-${randomUUID().slice(0, 8)}`, }); const passivePage = await page.context().newPage(); try { await primeAdditionalPage(passivePage); await resetSeededPageState(page); await resetSeededPageState(passivePage); await openSessions(page); await expectSessionRowVisible(page, archived.title); await expectSessionRowVisible(page, surviving.title); await openSessions(passivePage); await expectSessionRowVisible(passivePage, archived.title); await expectSessionRowVisible(passivePage, surviving.title); await openWorkspaceWithAgents(page, [archived, surviving]); await openWorkspaceWithAgents(passivePage, [archived, surviving]); await archiveAgentFromDaemon(client, archived.id); await expectWorkspaceArchiveOutcome(page, { archivedAgentId: archived.id, survivingAgentId: surviving.id, }); await expectWorkspaceArchiveOutcome(passivePage, { archivedAgentId: archived.id, survivingAgentId: surviving.id, }); await reloadWorkspace(passivePage, surviving.workspaceId); await expectWorkspaceTabHidden(passivePage, archived.id); } finally { await passivePage.close(); } }); test("Sessions archive prunes the archived tab across open pages", async ({ page }) => { const archived = await createIdleAgent(client, { cwd: tempRepo.path, workspaceId, title: `ui-archive-${randomUUID().slice(0, 8)}`, }); const surviving = await createIdleAgent(client, { cwd: tempRepo.path, workspaceId, title: `ui-control-${randomUUID().slice(0, 8)}`, }); const passivePage = await page.context().newPage(); try { await primeAdditionalPage(passivePage); await resetSeededPageState(page); await resetSeededPageState(passivePage); await openWorkspaceWithAgents(page, [archived, surviving]); await openWorkspaceWithAgents(passivePage, [archived, surviving]); await openSessions(page); await archiveAgentFromSessions(page, { agentId: archived.id, title: archived.title }); await reloadWorkspace(page, surviving.workspaceId); await expectWorkspaceTabHidden(page, archived.id); await expectWorkspaceArchiveOutcome(passivePage, { archivedAgentId: archived.id, survivingAgentId: surviving.id, }); } finally { await passivePage.close(); } }); test("clicking an archived session navigates without unarchiving it", async ({ page }) => { const archived = await createIdleAgent(client, { cwd: tempRepo.path, workspaceId, title: `unarchive-archived-${randomUUID().slice(0, 8)}`, }); const surviving = await createIdleAgent(client, { cwd: tempRepo.path, workspaceId, title: `unarchive-control-${randomUUID().slice(0, 8)}`, }); await resetSeededPageState(page); await openWorkspaceWithAgents(page, [archived, surviving]); await archiveAgentFromDaemon(client, archived.id); const archivedAt = await fetchAgentArchivedAt(client, archived.id); expect(archivedAt).not.toBeNull(); await openSessions(page); await expectSessionRowArchived(page, archived.title); await clickSessionRow(page, archived.title); expect(await fetchAgentArchivedAt(client, archived.id)).toBe(archivedAt); await expect(page).toHaveURL(buildHostWorkspaceRoute(getServerId(), archived.workspaceId), { timeout: 30_000, }); }); });