import { expect, type Locator, type Page } from "@playwright/test"; import type { SeededWorkspace } from "./seed-client"; import { openCommandCenter } from "./command-center"; import { openAgentRoute, type MockAgentWorkspace } from "./mock-agent"; export interface CommandCenterAgentControlChoice { query: string; choice: string; } /** * Focuses a seeded mock agent — which is what makes its model and mode contributions register — * opens the Command Center over it, and hands back the query input. Seeding stays in the test so * the workspace lifecycle is owned by the `try`/`finally` that cleans it up. */ export async function openCommandCenterForAgent( page: Page, workspace: Pick, ): Promise { await openAgentRoute(page, { workspaceId: workspace.workspaceId, agentId: workspace.agentId }); await expect( page.getByRole("button", { name: /^Select agent mode \(/ }).filter({ visible: true }), ).toBeVisible({ timeout: 30_000 }); const panel = await openCommandCenter(page); return panel.getByTestId("command-center-input"); } /** * Types a query that matches both the agent's modes and its models, and waits until rows from both * groups are listed. The agent's controls register after the panel opens; a key pressed before * then lands on whatever else matched, such as file search. */ export async function searchAgentControls(page: Page, query: string): Promise { const panel = page.getByTestId("command-center-panel"); await panel.getByTestId("command-center-input").fill(query); await expect(panel.getByRole("button", { name: /^Mode › / }).first()).toBeVisible({ timeout: 30_000, }); await expect(panel.getByRole("button", { name: /^Model › / }).first()).toBeVisible({ timeout: 30_000, }); } export async function chooseCommandCenterAgentControl(input: { page: Page; query: string; choice: string; }): Promise { const panel = input.page.getByTestId("command-center-panel"); await panel.getByRole("textbox").fill(input.query); const choice = panel.getByRole("button", { name: input.choice }); await expect(choice).toBeVisible({ timeout: 30_000 }); await choice.click(); } export async function expectCommandCenterAgentControlSelected(input: { page: Page; query: string; choice: string; }): Promise { const panel = input.page.getByTestId("command-center-panel"); await panel.getByRole("textbox").fill(input.query); const choice = panel.getByRole("button", { name: input.choice }); await expect(choice).toHaveRole("button"); await expect(choice).toHaveAttribute("aria-pressed", "true"); } export async function applyCommandCenterAgentControls( page: Page, choices: readonly CommandCenterAgentControlChoice[], ): Promise { for (const choice of choices) { await openCommandCenter(page); await chooseCommandCenterAgentControl({ page, ...choice }); } } export async function expectFocusedAgentControls( page: Page, choices: readonly CommandCenterAgentControlChoice[], ): Promise { await openCommandCenter(page); for (const choice of choices) { await expectCommandCenterAgentControlSelected({ page, ...choice }); } } export async function submitDraftAgent(page: Page, prompt: string): Promise { const composer = page.getByRole("textbox", { name: "Message agent..." }).first(); await expect(composer).toBeEditable({ timeout: 30_000 }); await composer.fill(prompt); await composer.press("Enter"); await expect(page.getByText(prompt, { exact: true }).first()).toBeVisible({ timeout: 30_000 }); } export async function waitForDraftComposer(page: Page): Promise { await expect(page.getByRole("textbox", { name: "Message agent..." }).first()).toBeEditable({ timeout: 30_000, }); } export async function expectWorkspaceAgentConfiguration( workspace: Pick, expected: { id?: string; provider: string; model: string | null; modeId: string | null }, ): Promise { await expect .poll( async () => { const entries = (await workspace.client.fetchAgents({ scope: "active" })).entries; const agent = entries .map((entry) => entry.agent) .find( (candidate) => candidate.workspaceId === workspace.workspaceId && (expected.id === undefined || candidate.id === expected.id), ); return agent ? { id: agent.id, provider: agent.provider, model: agent.model, modeId: agent.currentModeId, } : null; }, { timeout: 30_000 }, ) .toMatchObject(expected); }