From df452a09e758efa916c4a97286fe89e400be67bb Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Fri, 11 Sep 2026 23:45:33 +0200 Subject: [PATCH] test(app): align restore coverage and await fixture readiness Workspace restore leaves agents archived until explicit Unarchive. Keep that distinction covered for multiple agents. Compile the recovery fixture before its interaction test starts, and wait for sidebar agent hydration before asserting tab presence. --- packages/app/e2e/browser/root-error-recovery.spec.ts | 6 ++++++ packages/app/e2e/browser/sidebar-model-b.spec.ts | 6 +++--- packages/app/e2e/browser/worktree-restore.spec.ts | 9 ++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/app/e2e/browser/root-error-recovery.spec.ts b/packages/app/e2e/browser/root-error-recovery.spec.ts index 26fc70c4bb..55f5f37b42 100644 --- a/packages/app/e2e/browser/root-error-recovery.spec.ts +++ b/packages/app/e2e/browser/root-error-recovery.spec.ts @@ -4,9 +4,15 @@ import { expect, test, type Page, type TestInfo } from "@playwright/test"; let server: Server; let appUrl: string; test.beforeAll(async () => { + // Compile this separate fixture entrypoint in setup, like the main app warmup. + // Cold Metro compilation must not consume the recovery interaction's timeout. + test.setTimeout(120_000); const metroPort = process.env.E2E_METRO_PORT; if (!metroPort) throw new Error("E2E_METRO_PORT is required"); const bundle = `http://localhost:${metroPort}/packages/app/e2e/support/recovery-app.bundle?platform=web&dev=true&minify=false&hot=false&lazy=true&transform.engine=hermes&transform.routerRoot=src%2Fapp`; + const compiled = await fetch(bundle, { signal: AbortSignal.timeout(120_000) }); + if (!compiled.ok) throw new Error(`Recovery fixture compilation failed: HTTP ${compiled.status}`); + await compiled.arrayBuffer(); server = createServer((_request, response) => { response.setHeader("Content-Type", "text/html"); response.end( diff --git a/packages/app/e2e/browser/sidebar-model-b.spec.ts b/packages/app/e2e/browser/sidebar-model-b.spec.ts index 33e6ff8ddc..336ed97245 100644 --- a/packages/app/e2e/browser/sidebar-model-b.spec.ts +++ b/packages/app/e2e/browser/sidebar-model-b.spec.ts @@ -7,7 +7,6 @@ import { getServerId } from "../support/helpers/server-id"; import { projectEquivalenceViewKey } from "../support/helpers/project-view-key"; import { selectSidebarStatusGrouping } from "../support/helpers/sidebar"; import { waitForSidebarHydration } from "../support/helpers/workspace-ui"; -import { getVisibleWorkspaceAgentTabIds } from "../support/helpers/workspace-tabs"; // Model B sidebar shape: every project — git or non-git, single- or // multi-workspace — renders as the same expandable parent, the deepest sidebar @@ -96,8 +95,9 @@ test.describe("Model B sidebar shape", () => { try { // Open the workspace and materialize both an agent tab and a terminal tab. await gotoWorkspace(page, mock.workspaceId); - const agentTabs = await getVisibleWorkspaceAgentTabIds(page); - expect(agentTabs).toContain(`workspace-tab-agent_${mock.agentId}`); + await expect( + page.getByTestId(`workspace-tab-agent_${mock.agentId}`).filter({ visible: true }), + ).toBeVisible(); await clickNewTerminal(page); await expect( diff --git a/packages/app/e2e/browser/worktree-restore.spec.ts b/packages/app/e2e/browser/worktree-restore.spec.ts index 4f6096ed07..3926b43a97 100644 --- a/packages/app/e2e/browser/worktree-restore.spec.ts +++ b/packages/app/e2e/browser/worktree-restore.spec.ts @@ -265,7 +265,7 @@ test.describe("Worktree restore", () => { ).toHaveText(switchedBranch, { timeout: 30_000 }); }); - test("recovers the selected agent with its workspace and later rescues another archived agent", async ({ + test("restores the workspace before explicitly unarchiving each selected agent", async ({ page, }) => { const { agents, worktree } = await createArchivedMissingWorktree("restore-agents", { @@ -292,9 +292,16 @@ test.describe("Worktree restore", () => { await expect( page.getByTestId(`workspace-tab-agent_${firstAgent.id}`).filter({ visible: true }).first(), ).toBeVisible({ timeout: 30_000 }); + await expect( + page.getByTestId(`workspace-tab-agent_${firstAgent.id}`).filter({ visible: true }).first(), + ).toHaveAttribute("aria-selected", "true"); + expect(await fetchAgentArchivedAt(client, firstAgent.id)).not.toBeNull(); + expect(await fetchAgentArchivedAt(client, secondAgent.id)).not.toBeNull(); + await page.getByRole("button", { name: "Unarchive", exact: true }).click(); await expect .poll(() => fetchAgentArchivedAt(client, firstAgent.id), { timeout: 30_000 }) .toBeNull(); + expect(await fetchAgentArchivedAt(client, secondAgent.id)).not.toBeNull(); await expect(page.getByRole("button", { name: "Unarchive" })).toHaveCount(0, { timeout: 30_000, });