Each project is now a single sidebar row with its own icon and color that opens the project's coordinator conversation. The whole row drags to reorder. The row menu gains Customize for name, icon and color. Inside the coordinator conversation, an overview lists the project's agent threads that need the user, are running, or recently finished. Claude-Session: https://claude.ai/code/session_01Tgvrj34NMnaqvtgvruYQZZ Co-authored-by: Claude <noreply@anthropic.com>
47 lines
1.9 KiB
TypeScript
47 lines
1.9 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { completeOnboarding, projectRow, routePatchRpc, rpc, signup } from "./helpers";
|
|
|
|
test("empty project space offers Start before the main conversation exists", async ({ page }) => {
|
|
const stamp = Date.now();
|
|
await signup(page, `empty-project-${stamp}@rakazo.test`, "password12", "Empty Project");
|
|
await completeOnboarding(page);
|
|
|
|
const side = await rpc<{ id: string }>(page, "spaces/create", { name: "Empty project" });
|
|
|
|
// spaces/create provisions a main conversation server-side; strip it from bootstrap so the
|
|
// shell shows the pre-start empty project UI.
|
|
await routePatchRpc(page, "bootstrap", (json) => {
|
|
const groups = (json.groups as Array<{ spaceId: string }>).filter(
|
|
(group) => group.spaceId !== side.id,
|
|
);
|
|
const bots = (json.bots as Array<{ spaceId: string }>).filter((bot) => bot.spaceId !== side.id);
|
|
const spaces = (
|
|
json.spaces as Array<{
|
|
id: string;
|
|
bots: unknown[];
|
|
groups: unknown[];
|
|
hasContent: boolean;
|
|
}>
|
|
).map((space) =>
|
|
space.id === side.id ? { ...space, bots: [], groups: [], hasContent: false } : space,
|
|
);
|
|
return { ...json, groups, bots, spaces };
|
|
});
|
|
|
|
await page.evaluate((spaceId) => {
|
|
window.localStorage.setItem("rakazo:space-id", spaceId);
|
|
}, side.id);
|
|
await page.goto("/app", { waitUntil: "domcontentloaded" });
|
|
await expect(page.getByTestId("shell-root")).toHaveAttribute("data-ready", "true", {
|
|
timeout: 60_000,
|
|
});
|
|
|
|
const mainStart = page.getByTestId("project-start-main");
|
|
await expect(mainStart).toBeVisible({ timeout: 30_000 });
|
|
await expect(mainStart).toContainText(/Start|Starten/i);
|
|
|
|
// The sidebar lists the project as one row; opening it starts the main conversation.
|
|
const projekte = page.locator(".sidebar-projekte");
|
|
await expect(projectRow(projekte, "Empty project")).toBeVisible({ timeout: 30_000 });
|
|
});
|