diff --git a/desktop/playwright.config.ts b/desktop/playwright.config.ts index 446f3ecd40..2659a747ee 100644 --- a/desktop/playwright.config.ts +++ b/desktop/playwright.config.ts @@ -39,6 +39,7 @@ export default defineConfig({ "**/activity-scope-label-screenshots.spec.ts", "**/local-archive-screenshots.spec.ts", "**/agent-readiness-screenshots.spec.ts", + "**/edit-agent.spec.ts", "**/pubkey-display-screenshots.spec.ts", "**/file-attachment.spec.ts", "**/image-attachment-gallery.spec.ts", diff --git a/desktop/tests/e2e/edit-agent.spec.ts b/desktop/tests/e2e/edit-agent.spec.ts new file mode 100644 index 0000000000..28a5b8a579 --- /dev/null +++ b/desktop/tests/e2e/edit-agent.spec.ts @@ -0,0 +1,201 @@ +import { expect, test } from "@playwright/test"; + +import { installMockBridge, TEST_IDENTITIES } from "../helpers/bridge"; + +// Edit-agent dialog coverage (Phase 1B.3b-pre). Written against TODAY'S +// EditAgentDialog, before the B3b re-host, so the re-host is guarded by a +// pre-existing spec rather than one written alongside it. +// +// Mock-boundary caveat: the e2eBridge `update_managed_agent` handler echoes +// name/model/systemPrompt/envVars/respondTo/respondToAllowlist into the +// mock store — it does NOT +// model the diff-based partial-update wire semantics (change-detected-or-omit, +// tri-state provider, harnessOverride derivation), and it ignores +// agentCommand/harnessOverride entirely. This spec therefore pins UI behavior +// (open → edit → save → persisted in UI), not wire semantics. The inherit +// toggle is not reachable here at all (see the routing pin below) — its +// behavior is covered by B3b's component-level pinning test (inherit-toggle +// → gate → submit); wire semantics stay component-test territory +// (personaRuntimeModel.test.mjs). + +// Tyler's pubkey maps to gooseSurface in the mock bridge (runtimeId "goose"), +// which supports LLM provider selection — same seed the readiness-screenshot +// spec uses for its edit-dialog shot. +const AGENT_PUBKEY = TEST_IDENTITIES.tyler.pubkey; +const AGENT_NAME = "Tyler Agent"; +const PERSONA_ID = "persona-edit-e2e"; + +/** + * Open the Edit Agent dialog for the seeded managed agent via the profile + * panel (agents view → agent card → Edit quick action) — EditAgentDialog's + * only mount path. + */ +async function openEditDialog(page: import("@playwright/test").Page) { + await page.goto("/"); + await page.getByTestId("open-agents-view").click(); + + const agentButton = page.getByRole("button", { + name: `${AGENT_NAME} agent profile`, + }); + await expect(agentButton).toBeVisible({ timeout: 10_000 }); + await agentButton.click(); + + await expect(page.getByTestId("user-profile-panel")).toBeVisible({ + timeout: 10_000, + }); + await page.getByTestId("user-profile-edit-agent").click(); + + await expect(page.getByTestId("edit-agent-dialog")).toBeVisible({ + timeout: 10_000, + }); + // Provider field visible = runtime catalog loaded and form settled. + await expect(page.locator("#edit-agent-llm-provider")).toBeVisible({ + timeout: 10_000, + }); +} + +/** + * Pick an option from a PersonaDropdownField (menu-based, not a native + *