From 9735d0c6e71cea1ccd75aa38ce080f96520adb11 Mon Sep 17 00:00:00 2001 From: Rohit C Prasad Date: Thu, 20 Aug 2026 21:19:50 -0700 Subject: [PATCH] e2e: repair specs broken by the shipping lineup Folder-gate and picker specs drive Security Coworker (Code ships disabled). Automations detail opens via the nav row (account-menu entry removed). --- surfaces/gui/e2e/boot.spec.ts | 2 +- surfaces/gui/e2e/family-gate.spec.ts | 34 +++++++++++---------- surfaces/gui/e2e/standing-approvals.spec.ts | 4 +-- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/surfaces/gui/e2e/boot.spec.ts b/surfaces/gui/e2e/boot.spec.ts index 53743b95..620bc053 100644 --- a/surfaces/gui/e2e/boot.spec.ts +++ b/surfaces/gui/e2e/boot.spec.ts @@ -70,6 +70,6 @@ test("coworker picker recovers when the persona fetch dies during sidecar boot", // The menu must list real coworkers, not just its Import/Manage footer. const menu = page.locator(".setup-menu"); - await expect(menu.getByText("Code Coworker")).toBeVisible({ timeout: 10_000 }); + await expect(menu.getByText("Security Coworker")).toBeVisible({ timeout: 10_000 }); await expect(menu.getByTestId("import-coworker")).toBeVisible(); }); diff --git a/surfaces/gui/e2e/family-gate.spec.ts b/surfaces/gui/e2e/family-gate.spec.ts index 0b6a2088..ccd0db01 100644 --- a/surfaces/gui/e2e/family-gate.spec.ts +++ b/surfaces/gui/e2e/family-gate.spec.ts @@ -1,10 +1,12 @@ import { test, expect } from "./fixtures"; -// UX-029: the persona FAMILY still decides workspace behavior, but code-family -// enforcement moved from a modal gate at session start to the SEND moment: -// code → send with no folder → "Where should … work?" dialog (recents / native -// picker / "Start in a temporary folder", git-init'd, created only now) -// knowledge → starts orphan on a transparent temporary dir — never gated +// The persona's requires_folder trait decides workspace behavior +// (workspace-scratch-design.md), enforced at the SEND moment: +// requires_folder → send with no folder → "Where should … work?" dialog (recents / +// native picker / "Start in a temporary folder", git-init'd, created +// only now). Exercised through Security Coworker — the enabled gated +// persona in the shipped lineup (Code ships disabled). +// everything else → starts orphan on a transparent temporary dir — never gated // The coworker pick lives in the setup chip row above the composer, only before the // first message of a new session; afterwards the row leaves and the facts move to the // session header. @@ -15,7 +17,7 @@ async function newDraftAs(page: import("@playwright/test").Page, coworker: RegEx await page.locator(".setup-menu").getByRole("button", { name: coworker }).click(); } -test("knowledge coworker: new session starts instantly, no gate, no dialog", async ({ page }) => { +test("scratch coworker: new session starts instantly, no gate, no dialog", async ({ page }) => { await page.goto("/"); await newDraftAs(page, /Ops Coworker/); @@ -27,20 +29,20 @@ test("knowledge coworker: new session starts instantly, no gate, no dialog", asy await expect(page.getByTestId("send-folder-dialog")).toHaveCount(0); }); -test("code coworker: send with no folder asks where to work; temp folder sends the message", async ({ +test("gated coworker: send with no folder asks where to work; temp folder sends the message", async ({ page, }) => { await page.goto("/"); - await newDraftAs(page, /Code Coworker/); + await newDraftAs(page, /Security Coworker/); // No modal gate up front — the composer is live and the draft is composable. await expect(page.locator(".gate-overlay")).toHaveCount(0); - await page.getByPlaceholder(/Ask the coder/).fill("fix the tests"); + await page.getByPlaceholder(/Ask the coworker/).fill("fix the tests"); await page.getByRole("button", { name: "Send" }).click(); const dlg = page.getByTestId("send-folder-dialog"); await expect(dlg).toBeVisible(); - await expect(dlg.getByText("Where should Code Coworker work?")).toBeVisible(); + await expect(dlg.getByText("Where should Security Coworker work?")).toBeVisible(); await dlg.getByTestId("start-temp-folder").click(); // The message flies as soon as the choice lands — no second send click, and the local @@ -51,7 +53,7 @@ test("code coworker: send with no folder asks where to work; temp folder sends t // The raw temp path never shows: header says "Temporary folder" + Save as project…. const sub = page.getByTestId("session-subtitle"); - await expect(sub).toContainText("Code Coworker"); + await expect(sub).toContainText("Security Coworker"); await expect(sub).toContainText("Temporary folder"); await expect(sub).not.toContainText("ow-temp"); await expect(page.getByTestId("save-as-project")).toBeVisible(); @@ -64,11 +66,11 @@ test("code coworker: send with no folder asks where to work; temp folder sends t await expect(page.getByTestId("folder-chip")).toContainText("Choose folder"); }); -test("code coworker: Choose a folder… binds the picked project and sends", async ({ page }) => { +test("gated coworker: Choose a folder… binds the picked project and sends", async ({ page }) => { await page.goto("/"); - await newDraftAs(page, /Code Coworker/); + await newDraftAs(page, /Security Coworker/); - await page.getByPlaceholder(/Ask the coder/).fill("hello repo"); + await page.getByPlaceholder(/Ask the coworker/).fill("hello repo"); await page.getByRole("button", { name: "Send" }).click(); // Native pick is mocked server-side → /tmp/picked-folder. @@ -80,9 +82,9 @@ test("code coworker: Choose a folder… binds the picked project and sends", asy test("escape restores the draft instead of losing it", async ({ page }) => { await page.goto("/"); - await newDraftAs(page, /Code Coworker/); + await newDraftAs(page, /Security Coworker/); - const box = page.getByPlaceholder(/Ask the coder/); + const box = page.getByPlaceholder(/Ask the coworker/); await box.fill("precious draft"); await page.getByRole("button", { name: "Send" }).click(); await expect(page.getByTestId("send-folder-dialog")).toBeVisible(); diff --git a/surfaces/gui/e2e/standing-approvals.spec.ts b/surfaces/gui/e2e/standing-approvals.spec.ts index 7eb0ec97..ca46263a 100644 --- a/surfaces/gui/e2e/standing-approvals.spec.ts +++ b/surfaces/gui/e2e/standing-approvals.spec.ts @@ -7,8 +7,8 @@ import { test, expect } from "./fixtures"; async function openTaskDetail(page: import("@playwright/test").Page) { await page.goto("/"); - await page.getByTestId("account-row").click(); - await page.getByTestId("account-menu").getByRole("button", { name: "Automations", exact: true }).click(); + // Via the nav row — the account-menu Automations entry was removed (UX-035 chrome cleanup). + await page.getByTestId("nav-automations").click(); await page.getByText("Daily AI News").first().click(); await expect(page.getByRole("button", { name: /Run now/ })).toBeVisible(); }