feat(frontend): Topologies page — catalog browser + builder
New authed workspace page (/topologies, in the global nav) that browses the topology catalog and builds + visualizes a topology from a kind + roles: - lib/api/topology.ts: zod schemas + fetchTopologyCatalog (server, authed). - TopologyGraphView: lightweight SVG renderer (no new deps), laid out per kind (row for pipeline/ring, star for delegation kinds, circle otherwise). - TopologyExplorer (client): catalog list + roles input → POST /api/topologies/build via the /api proxy → render the graph. - ShellNav: add the Topologies nav item. - e2e (p8): sign in → nav → browse catalog → build a pipeline → graph renders. Full suite green (38); npm build + TS clean. Goes live with the next server+ frontend deploy (compare/Pareto UI to follow). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a35c82d860
commit
7648487a59
@@ -0,0 +1,33 @@
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
|
||||
// The Topologies page: browse the catalog and build a topology graph against
|
||||
// the real /api/topologies endpoints (frontend → proxy → backend).
|
||||
|
||||
const OWNER_EMAIL = "[email protected]";
|
||||
const OWNER_PASSWORD = "e2e-password";
|
||||
|
||||
async function signIn(page: Page) {
|
||||
await page.goto("/login");
|
||||
await page.getByLabel("Email").fill(OWNER_EMAIL);
|
||||
await page.getByRole("button", { name: /Continue with work email/ }).click();
|
||||
await page.getByLabel("Password").fill(OWNER_PASSWORD);
|
||||
await page.getByRole("button", { name: "Sign in" }).click();
|
||||
await expect(page.getByRole("heading", { name: "Clawmates" })).toBeVisible();
|
||||
}
|
||||
|
||||
test("browse the topology catalog and build a graph", async ({ page }) => {
|
||||
await signIn(page);
|
||||
|
||||
await page.getByRole("link", { name: "Topologies" }).click();
|
||||
await expect(page).toHaveURL(/\/topologies$/);
|
||||
await expect(page.getByRole("heading", { name: "Topologies" })).toBeVisible();
|
||||
|
||||
// The catalog lists the kinds.
|
||||
await expect(page.getByRole("button", { name: /hierarchical/i })).toBeVisible();
|
||||
|
||||
// Build a pipeline topology and confirm the graph renders.
|
||||
await page.getByRole("button", { name: /^pipeline$/i }).click();
|
||||
await page.getByLabel(/Roles/).fill("alpha, beta, gamma");
|
||||
await page.getByRole("button", { name: "Build" }).click();
|
||||
await expect(page.locator("svg[aria-label*='topology']")).toBeVisible();
|
||||
});
|
||||
Reference in New Issue
Block a user