import { expect, test } from "@playwright/test"; import { captureScreenshot, completeOnboarding, projectRow, rpc, signup, waitForChatComposer, } from "./helpers"; test("a project is one sidebar row with its own look, and its coordinator lists the delegated threads", async ({ page, }, testInfo) => { const stamp = Date.now(); await signup(page, `project-coordinator-${stamp}@rakazo.test`, "password12", "Coordinator"); await completeOnboarding(page); const projekte = page.locator(".sidebar-projekte"); await projekte.getByTestId("create-project-trigger").click(); const dialog = page.getByRole("dialog", { name: "New project" }); await dialog.getByLabel("Name").fill("Garden"); await dialog.getByRole("button", { name: "Create project", exact: true }).click(); await page.waitForURL(/\/app\/g\/[^/]+$/, { timeout: 30_000 }); await waitForChatComposer(page); const row = projectRow(projekte, "Garden"); await expect(row).toBeVisible({ timeout: 30_000 }); await expect(row).toHaveAttribute("aria-current", "page"); await expect(row.locator("[data-project-icon]")).toHaveAttribute("data-project-icon", "folder"); // Name, icon and color change from the row's menu. await row.click({ button: "right" }); await page.getByRole("menuitem", { name: "Customize" }).click(); const look = page.getByTestId("project-look-dialog"); await expect(look).toBeVisible(); await look.getByLabel("Name").fill("Garten"); await look.getByRole("radio", { name: "green" }).click(); await look.getByTestId("project-icon-leaf").click(); await captureScreenshot(page, testInfo, "project-look"); await look.getByRole("button", { name: "Save", exact: true }).click(); await expect(look).toBeHidden(); const renamed = projectRow(projekte, "Garten"); await expect(renamed.locator("[data-project-icon]")).toHaveAttribute("data-project-icon", "leaf"); await expect(renamed.locator("[data-project-icon]")).toHaveAttribute( "data-project-color", "green", ); await page.reload({ waitUntil: "domcontentloaded" }); await expect(renamed.locator("[data-project-icon]")).toHaveAttribute( "data-project-icon", "leaf", { timeout: 30_000 }, ); // The coordinator hands work to a specialist; the finished thread shows in its overview. await waitForChatComposer(page); await rpc(page, "bots/create", { name: "Gardener", title: "", description: "", instructions: "", notifyOnFinish: true, }); const composer = page.getByRole("combobox", { name: "Message" }); await composer.fill("delegate to the bot named Gardener: plan the spring beds"); await composer.press("Enter"); const card = page.getByTestId("transcript").getByTestId("delegated-task-card"); await expect(card).toHaveAttribute("data-status", "done", { timeout: 60_000 }); const overview = page.getByTestId("project-overview"); const done = overview.getByRole("button", { name: /Done/ }); await expect(done).toBeVisible({ timeout: 30_000 }); await done.click(); await expect(overview.getByText("Gardener").first()).toBeVisible(); await captureScreenshot(page, testInfo, "project-overview"); });