import { expect, loginAs, test } from "./fixtures"; test.describe("operator review regressions", () => { test.beforeEach(async ({ page }) => { await loginAs(page, "hub-admin"); }); test("filter changes retain the URL project and environment at the API boundary", async ({ page }) => { await page.goto("/connectors?project=ludarium&environment=prod"); await expect(page.getByLabel("Filter records")).toBeVisible(); const response = page.waitForResponse((value) => { const url = new URL(value.url()); return url.pathname === "/api/connectors" && url.searchParams.get("q") === "knowledge-default"; }); await page.getByLabel("Filter records").fill("knowledge-default"); const actual = new URL((await response).url()); expect(actual.searchParams.get("project")).toBe("ludarium"); expect(actual.searchParams.get("environment")).toBe("prod"); await expect.poll(() => new URL(page.url()).searchParams.get("q")).toBe("knowledge-default"); expect(new URL(page.url()).searchParams.get("project")).toBe("ludarium"); expect(new URL(page.url()).searchParams.get("environment")).toBe("prod"); await expect(page.getByRole("link", { name: "Knowledge Default", exact: true })).toBeVisible(); }); test("catalog scope stays locked until an explicit apply finishes", async ({ page }) => { let release!: () => void; const pending = new Promise((resolve) => { release = resolve; }); await page.route("**/api/catalog/preview", (route) => route.fulfill({ json: { valid: true, changes: ["Review fixture change"], errors: [] } })); await page.route("**/api/catalog/apply", async (route) => { await pending; await route.fulfill({ json: { accepted: true, message: "Reviewed catalog apply completed" } }); }); await page.goto("/tools?project=ludarium"); const workflow = page.locator(".workflow-panel").filter({ has: page.getByRole("heading", { name: "Catalog validation and preview" }) }); await workflow.getByRole("button", { name: "Validate and preview" }).click(); await workflow.getByRole("button", { name: "Apply approved catalog" }).click(); await page.getByRole("button", { name: "Confirm apply" }).click(); await expect(workflow.getByRole("combobox", { name: "Project", exact: true })).toBeDisabled(); await expect(workflow.getByRole("button", { name: "Applying…" })).toBeDisabled(); release(); await expect(workflow.getByText("Reviewed catalog apply completed")).toBeVisible(); await expect(workflow.getByRole("combobox", { name: "Project", exact: true })).toBeEnabled(); }); test("a pending client created after SPA navigation retains a visible resume path", async ({ page }) => { let release!: () => void; const pending = new Promise((resolve) => { release = resolve; }); let createdId = ""; await page.route("**/api/client-management", async (route) => { if (route.request().method() !== "POST") { await route.continue(); return; } const response = await route.fetch(); createdId = ((await response.json()) as { client: { id: string } }).client.id; await pending; await route.fulfill({ response }); }); await page.goto("/clients"); const name = `creation-navigation-${Date.now()}`; await page.getByLabel("Name", { exact: true }).fill(name); await page.getByRole("button", { name: "Create pending client" }).click(); await expect.poll(() => createdId).not.toBe(""); await page.getByRole("navigation", { name: "Primary navigation" }).getByRole("link", { name: "Operations", exact: true }).click(); await expect(page.getByRole("heading", { name: "Operations", level: 1 })).toBeVisible(); release(); const notice = page.locator(".client-created-notice"); await expect(notice).toContainText(name); expect(new URL(page.url()).pathname).toBe("/operations"); await expect(notice.getByRole("link", { name: "Resume onboarding" })).toHaveAttribute("href", `/clients?onboard=${createdId}`); await notice.getByRole("link", { name: "Resume onboarding" }).click(); await expect(page.getByText(/Resumable Hub identity/)).toBeVisible(); expect(new URL(page.url()).searchParams.get("onboard")).toBe(createdId); }); test("operation-check results link to registered connector identities", async ({ page }) => { await page.route("**/api/operations/check", (route) => route.fulfill({ json: { generatedAt: new Date().toISOString(), healthy: true, connectors: { "itworx-knowledge": { reachable: true, status: "healthy", detail: "Bounded contract fixture", connectorRefs: [{ id: "knowledge-default", name: "Knowledge Default" }], connectorRefsTruncated: false } }, } })); await page.goto("/operations"); await page.getByRole("button", { name: "Run live checks" }).click(); const registration = page.locator(".connector-checks").getByRole("link", { name: "Knowledge Default", exact: true }); await expect(registration).toHaveAttribute("href", "/connectors/knowledge-default"); await registration.click(); await expect(page.getByRole("heading", { name: "Knowledge Default", exact: true })).toBeVisible(); }); test("Quick Jump sends an ordinary client to its filtered records instead of an unavailable onboarding workflow", async ({ page }) => { await page.route("**/api/clients?*", (route) => route.fulfill({ json: { kind: "clients", generatedAt: new Date().toISOString(), rows: [{ id: "ordinary-fixture-client", name: "Ordinary fixture client", status: "healthy", summary: "Existing client", project: "ludarium", environment: "prod" }], page: { total: 1, nextCursor: null }, } })); await page.getByRole("button", { name: "Open quick jump" }).click(); const dialog = page.getByRole("dialog", { name: "Quick jump" }); await dialog.getByRole("combobox").fill("ordinary-fixture-client"); await dialog.getByRole("group", { name: "Clients", exact: true }).getByRole("option", { name: /Ordinary fixture client/ }).click(); await expect(page).toHaveURL(/\/clients\?q=ordinary-fixture-client$/); await expect(page.locator(".desktop-data-table").getByText("Existing client", { exact: true })).toBeVisible(); const desktopRecord = page.locator(".desktop-data-table").getByRole("link", { name: "Ordinary fixture client", exact: true }); await expect(desktopRecord).toHaveAttribute("href", "/clients?q=ordinary-fixture-client"); await desktopRecord.click(); await expect(page).toHaveURL(/\/clients\?q=ordinary-fixture-client$/); await page.setViewportSize({ width: 390, height: 844 }); const mobileRecord = page.locator(".mobile-record-list").getByRole("link", { name: "Ordinary fixture client", exact: true }); await expect(mobileRecord).toHaveAttribute("href", "/clients?q=ordinary-fixture-client"); await mobileRecord.click(); await expect(page).toHaveURL(/\/clients\?q=ordinary-fixture-client$/); await expect(page.getByText(/Resumable Hub identity/)).toHaveCount(0); }); test("Quick Jump retains the selected audit trace as its destination filter", async ({ page }) => { await page.route("**/api/audit?*", (route) => route.fulfill({ json: { kind: "audit", generatedAt: new Date().toISOString(), rows: [{ id: "audit-fixture", name: "tool.invocation", status: "healthy", summary: "Fixture event", traceId: "review-fixture-trace", project: "ludarium" }], page: { total: 1, nextCursor: null }, } })); await page.getByRole("button", { name: "Open quick jump" }).click(); const dialog = page.getByRole("dialog", { name: "Quick jump" }); await dialog.getByRole("combobox").fill("review-fixture-trace"); await dialog.getByRole("group", { name: "Audit", exact: true }).getByRole("option", { name: /tool.invocation/ }).click(); await expect(page).toHaveURL(/\/audit\?q=review-fixture-trace$/); await expect(page.getByLabel("Filter records")).toHaveValue("review-fixture-trace"); }); });