Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:36:21 +02:00
commit cb5be898ea
663 files changed
+82674

No files matched your search

+56
View File
@@ -0,0 +1,56 @@
import AxeBuilder from "@axe-core/playwright";
import { expect, loginAs, test, type Persona } from "./fixtures";
const routes: { path: string; persona: Persona }[] = [
{ path: "/", persona: "hub-viewer" },
{ path: "/projects", persona: "hub-viewer" },
{ path: "/servers", persona: "hub-viewer" },
{ path: "/tools", persona: "hub-viewer" },
{ path: "/connectors", persona: "hub-viewer" },
{ path: "/clients", persona: "hub-viewer" },
{ path: "/policies", persona: "hub-viewer" },
{ path: "/operations", persona: "hub-viewer" },
{ path: "/audit", persona: "hub-auditor" },
{ path: "/settings", persona: "hub-viewer" },
];
test.describe("accessibility and responsive baseline", () => {
test("the unauthenticated gateway has landmarks, a skip link, and no serious axe findings", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("link", { name: "Skip to main content" })).toBeVisible();
await expect(page.getByRole("main")).toHaveCount(1);
const result = await new AxeBuilder({ page }).analyze();
expect(result.violations.filter((violation) => ["serious", "critical"].includes(violation.impact ?? ""))).toEqual([]);
});
for (const viewport of [{ width: 390, height: 844 }, { width: 1440, height: 900 }]) {
test(`authorized routes have no serious axe findings or page overflow at ${viewport.width}px`, async ({ page }) => {
test.setTimeout(90_000);
await page.setViewportSize(viewport);
for (const persona of ["hub-viewer", "hub-auditor"] as const) {
const personaRoutes = routes.filter((route) => route.persona === persona);
if (!personaRoutes.length) continue;
await loginAs(page, persona);
for (const route of personaRoutes) {
await page.goto(route.path);
await expect(page.getByRole("main")).toBeVisible();
const overflow = await page.evaluate(() => document.documentElement.scrollWidth > window.innerWidth + 1);
expect(overflow, `${route.path} must not cause page-level horizontal overflow`).toBe(false);
const result = await new AxeBuilder({ page }).analyze();
expect(result.violations.filter((violation) => ["serious", "critical"].includes(violation.impact ?? "")), route.path).toEqual([]);
}
}
});
}
test("mobile drawer and modal preserve keyboard focus", async ({ page }) => {
await page.setViewportSize({ width: 390, height: 844 });
await loginAs(page, "hub-viewer");
await page.goto("/");
const trigger = page.getByRole("button", { name: "Open navigation" });
await trigger.focus();
await trigger.press("Enter");
await page.getByRole("button", { name: "Close navigation" }).press("Escape");
await expect(trigger).toBeFocused();
});
});
+65
View File
@@ -0,0 +1,65 @@
import { expect, loginAs, test } from "./fixtures";
test.describe("authentication", () => {
test("an unauthenticated visitor sees the sign-in panel, not management data", async ({ page }) => {
await page.goto("/");
await expect(page.getByRole("heading", { name: "Inspect your governed MCP estate." })).toBeVisible();
await expect(page.getByRole("link", { name: "Continue to sign in" })).toHaveAttribute("href", "/auth/login");
// No management chrome or data leaks before authentication.
await expect(page.getByRole("navigation", { name: "Primary navigation" })).toHaveCount(0);
await expect(page.getByRole("link", { name: "Open platform settings" })).toHaveCount(0);
await expect(page.getByRole("heading", { name: "Governed MCP, with the current signal first." })).toHaveCount(0);
});
test("a real PKCE/BFF login lands on an authenticated dashboard with real data", async ({ page }) => {
await loginAs(page, "hub-viewer");
await expect(page).toHaveURL(/\/$/);
await expect(page.getByText("Authenticated", { exact: true })).toBeVisible();
await expect(page.getByRole("heading", { name: "Governed MCP, with the current signal first." })).toBeVisible();
// Real backend data, not a placeholder: Ludarium is the seeded catalog project.
await expect(page.getByText("Ludarium", { exact: true })).toBeVisible();
});
test("an authenticated user can sign out and stale management data disappears", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/settings");
await page.getByRole("button", { name: "Sign out" }).click();
await expect(page.getByRole("heading", { name: "Inspect your governed MCP estate." })).toBeVisible();
await expect(page.getByRole("heading", { name: "Governed MCP, with the current signal first." })).toHaveCount(0);
});
test("an invalidated session cookie safely falls back to the sign-in panel, not stale data", async ({
page,
context,
}) => {
await loginAs(page, "hub-viewer");
await expect(page.getByRole("heading", { name: "Governed MCP, with the current signal first." })).toBeVisible();
const cookies = await context.cookies();
const sessionCookie = cookies.find((cookie) => cookie.name === "hub_session");
expect(sessionCookie).toBeDefined();
await context.addCookies([{ ...sessionCookie!, value: "tampered-session-value" }]);
await page.reload();
await expect(page.getByRole("heading", { name: "Inspect your governed MCP estate." })).toBeVisible();
// The stale dashboard from before tampering must not still be showing.
await expect(page.getByRole("heading", { name: "Governed MCP, with the current signal first." })).toHaveCount(0);
});
test("a mutating request with a missing CSRF token is safely rejected, not silently accepted", async ({
page,
}) => {
await loginAs(page, "hub-admin");
await page.goto("/policies");
await page.route("**/api/policies/simulate", async (route) => {
const headers = { ...route.request().headers() };
delete headers["x-csrf-token"];
await route.continue({ headers });
});
await page.getByLabel("Project").selectOption({ index: 0 });
await page.getByRole("button", { name: "Explain decision" }).click();
await expect(page.getByRole("alert")).toBeVisible();
// No decision card was rendered from an unauthenticated-CSRF response.
await expect(page.getByRole("status").filter({ hasText: "Matched:" })).toHaveCount(0);
});
});
+37
View File
@@ -0,0 +1,37 @@
import { test as base, expect, type Page } from "@playwright/test";
/** Matches services/control_api/auth/models.py's ManagementRole group names,
* and tests/e2e/harness.py's ROLE_GROUPS -- these are the only group names
* the real per-endpoint RBAC matrix (services/control_api/authz.py) maps to
* a role at all; anything else is denied by default. */
export type Persona = "hub-viewer" | "hub-auditor" | "hub-operator" | "hub-admin";
/** Drives the real PKCE/BFF login flow through a real browser navigation:
* GET /auth/login (real 307 to the fake OIDC provider's real HTTPS
* /authorize), rewriting only the *outbound request URL* to add a
* `persona` hint the fake provider reads (see fake_provider.py) -- no
* production auth code is touched or bypassed, only the request this test
* harness itself sends to a fake dependency. */
export async function loginAs(page: Page, persona: Persona): Promise<void> {
// Rewriting the *navigation request itself* to /authorize (page.route
// continue({url})) does not reliably apply to a same-navigation redirect
// hop in Chromium -- verified by hand: the outbound request to
// /authorize still carried no persona param, and the fake provider fell
// back to its default group. Instead, intercept the /auth/login response
// (a 307), fetch it with redirects disabled, and rewrite the outgoing
// Location header before letting the browser follow it.
await page.route("**/auth/login", async (route) => {
const response = await route.fetch({ maxRedirects: 0 });
const headers = response.headers();
if (!headers.location) throw new Error("expected /auth/login to redirect with a Location header");
const location = new URL(headers.location);
location.searchParams.set("persona", persona);
await route.fulfill({ status: response.status(), headers: { ...headers, location: location.toString() } });
});
await page.goto("/auth/login");
await page.waitForLoadState("networkidle");
await page.unroute("**/auth/login");
}
export const test = base;
export { expect };
+56
View File
@@ -0,0 +1,56 @@
import { expect, loginAs, test } from "./fixtures";
// The persistent sidebar becomes an off-canvas drawer below 840px (see
// styles.css's compact-navigation media block) -- these tests only make
// sense at that width, so every test in this file pins a mobile viewport.
test.use({ viewport: { width: 390, height: 844 } });
test.describe("mobile navigation drawer", () => {
test.beforeEach(async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/");
});
test("opens via the hamburger trigger and exposes its state to assistive tech", async ({ page }) => {
const trigger = page.getByRole("button", { name: "Open navigation" });
await expect(trigger).toHaveAttribute("aria-expanded", "false");
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(0);
await trigger.click();
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(1);
await expect(trigger).toHaveAttribute("aria-expanded", "true");
});
test("closes via its own close button", async ({ page }) => {
await page.getByRole("button", { name: "Open navigation" }).click();
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(1);
await page.getByRole("button", { name: "Close navigation" }).click();
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(0);
});
test("closes on Escape", async ({ page }) => {
await page.getByRole("button", { name: "Open navigation" }).click();
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(1);
await page.keyboard.press("Escape");
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(0);
});
test("closes on backdrop click", async ({ page }) => {
await page.getByRole("button", { name: "Open navigation" }).click();
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(1);
// The backdrop spans the full viewport (position:fixed; inset:0), but
// the open sidebar itself sits on top of its left ~240px and intercepts
// pointer events there -- click well to the right of the drawer's own
// width so the hit lands on the backdrop, not the drawer.
await page.locator(".nav-backdrop").click({ position: { x: 350, y: 400 } });
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(0);
});
test("closes automatically after navigating to another page", async ({ page }) => {
await page.getByRole("button", { name: "Open navigation" }).click();
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(1);
await page.getByRole("link", { name: "Catalog", exact: true }).click();
await expect(page).toHaveURL(/\/tools$/);
await expect(page.locator(".sidebar.sidebar-open")).toHaveCount(0);
});
});
+88
View File
@@ -0,0 +1,88 @@
import { expect, loginAs, test } from "./fixtures";
test.describe("role-based authorization, driven end to end from the browser", () => {
test("a viewer never sees the client-create form; an admin does", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/clients");
await expect(page.getByRole("button", { name: "Create pending client" })).toHaveCount(0);
await expect(page.getByText("Client creation requires the admin role.")).toBeVisible();
await loginAs(page, "hub-admin");
await page.goto("/clients");
await expect(page.getByRole("button", { name: "Create pending client" })).toBeVisible();
});
test("client.create is still server-enforced even if the hidden form were bypassed", async ({ page, request }) => {
// Proves the security property independent of the UI: the hidden
// button is a usability affordance, not the authorization boundary.
await loginAs(page, "hub-viewer");
const cookies = await page.context().cookies();
const sessionCookie = cookies.find((cookie) => cookie.name.toLowerCase().includes("session"));
if (!sessionCookie) throw new Error("expected a session cookie to be set after login");
const sessionResponse = await request.get("/auth/session", { headers: { Cookie: `${sessionCookie.name}=${sessionCookie.value}` } });
const { csrf_token: csrfToken } = await sessionResponse.json();
const response = await request.post("/api/client-management", {
headers: { Cookie: `${sessionCookie.name}=${sessionCookie.value}`, "X-CSRF-Token": csrfToken },
data: { name: "e2e-bypass-attempt", project: "ludarium", environment: "prod", kind: "native-2026" },
});
expect(response.status()).toBe(403);
});
test("an auditor can read the audit log; a viewer never sees the Audit nav link at all", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/");
await expect(page.getByRole("link", { name: "Audit" })).toHaveCount(0);
await loginAs(page, "hub-auditor");
await page.goto("/");
await expect(page.getByRole("link", { name: "Audit" })).toBeVisible();
await page.goto("/audit");
await expect(page.getByRole("alert")).toHaveCount(0);
await expect(page.getByText(/total · server paginated/)).toBeVisible();
});
test("a viewer cannot select the audit section of a project workspace", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/projects/ludarium?tab=Audit");
await expect(page.getByRole("link", { name: "Audit" })).toHaveCount(0);
await expect(page.getByRole("link", { name: "Summary" })).toHaveAttribute("aria-current", "page");
});
test("an operator sees state-appropriate client actions; a viewer does not", async ({ page }) => {
await loginAs(page, "hub-admin");
await page.goto("/clients");
await page.getByLabel("Name").fill("e2e-operator-target");
await page.getByRole("button", { name: "Create pending client" }).click();
await expect(page.getByText(/Client created: e2e-operator-target/)).toBeVisible();
await loginAs(page, "hub-viewer");
await page.goto("/clients");
const viewerRow = page.getByRole("row", { name: /e2e-operator-target/ });
await expect(viewerRow).toBeVisible();
await expect(viewerRow.getByRole("button", { name: "Disable" })).toHaveCount(0);
await loginAs(page, "hub-operator");
await page.goto("/clients");
const operatorRow = page.getByRole("row", { name: /e2e-operator-target/ });
await expect(operatorRow.getByRole("button", { name: "Disable" })).toBeDisabled();
await operatorRow.getByRole("button", { name: "Revoke" }).click();
// The confirmation modal's title is dynamic ("Revoke e2e-operator-target?"),
// which makes an exact accessible-name match on the confirm button awkward
// to pin reliably against the row-scoped locator above. This is the one
// deliberate exception to this file's role/text-based query convention,
// justified by the dynamic title: DataTable.tsx's modal confirm button
// carries data-testid="confirm-action" specifically for this case.
await page.getByTestId("confirm-action").click();
await expect(page.getByText(/completed\./)).toBeVisible();
});
test("tool readiness is hidden below operator and visible to an operator", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/tools");
await expect(page.getByRole("button", { name: "Readiness" })).toHaveCount(0);
await loginAs(page, "hub-operator");
await page.goto("/tools");
await expect(page.getByRole("button", { name: "Readiness" }).first()).toBeVisible();
});
});
+41
View File
@@ -0,0 +1,41 @@
import { expect, loginAs, test } from "./fixtures";
// Playwright's default browser color-scheme emulation is "light", which
// would make styles.css's `@media (prefers-color-scheme: light)` block
// apply even with no `data-theme` attribute set, collapsing the "dark"
// and "light" reads below into the same value. Pin the emulated OS
// preference to dark so the initial (no localStorage) state is
// deterministic and the toggle's own explicit `data-theme` write -- not
// an OS-preference coincidence -- is what the test is proving out.
test.use({ colorScheme: "dark" });
test.describe("theme toggle", () => {
test("switching to light theme persists across reload and changes the rendered background", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/settings");
const darkBackground = await page.evaluate(() => getComputedStyle(document.documentElement).backgroundColor);
await page.getByRole("button", { name: "Light" }).click();
const lightBackground = await page.evaluate(() => getComputedStyle(document.documentElement).backgroundColor);
expect(lightBackground).not.toBe(darkBackground);
await page.reload();
const afterReload = await page.evaluate(() => getComputedStyle(document.documentElement).backgroundColor);
expect(afterReload).toBe(lightBackground);
await page.getByRole("button", { name: "Dark" }).click();
});
test("appearance toggle exposes which theme is selected, not just the applied state", async ({ page }) => {
// Regression test alongside the density toggle fix: SettingsPage had no
// state tracking the current theme at all, so Dark/Light always
// rendered as the same solid pill regardless of which was active.
await loginAs(page, "hub-viewer");
await page.goto("/settings");
const dark = page.getByRole("button", { name: "Dark" });
const light = page.getByRole("button", { name: "Light" });
await expect(dark).toHaveAttribute("aria-pressed", "true");
await expect(light).toHaveAttribute("aria-pressed", "false");
await light.click();
await expect(dark).toHaveAttribute("aria-pressed", "false");
await expect(light).toHaveAttribute("aria-pressed", "true");
await dark.click();
});
});
+106
View File
@@ -0,0 +1,106 @@
import { expect, loginAs, test } from "./fixtures";
const captureReview = Boolean(process.env.SOL_VISUAL_REVIEW);
async function expectNoPageOverflow(page: import("@playwright/test").Page) {
const dimensions = await page.evaluate(() => ({ documentWidth: document.documentElement.scrollWidth, viewportWidth: window.innerWidth }));
expect(dimensions.documentWidth, `document width at ${dimensions.viewportWidth}px`).toBeLessThanOrEqual(dimensions.viewportWidth + 1);
}
test.describe("product-quality interaction and composition", () => {
test("the public gateway uses the available canvas and stays usable from desktop to mobile", async ({ page }, testInfo) => {
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto("/");
await expect(page.getByRole("heading", { name: "Inspect your governed MCP estate." })).toBeVisible();
await expect(page.getByLabel("How governed MCP access works")).toBeVisible();
const desktopLayout = await page.locator(".auth-layout").boundingBox();
expect(desktopLayout?.width ?? 0).toBeGreaterThan(1100);
await expectNoPageOverflow(page);
if (captureReview) await page.screenshot({ path: testInfo.outputPath("public-desktop.png"), fullPage: true });
await page.setViewportSize({ width: 390, height: 844 });
await expect(page.getByRole("link", { name: /Continue to sign in/ })).toBeVisible();
await expect(page.getByText("Project scoped", { exact: true })).toBeVisible();
await expectNoPageOverflow(page);
if (captureReview) await page.screenshot({ path: testInfo.outputPath("public-mobile.png"), fullPage: true });
});
test("quick jump is keyboard-first, access-aware and routes without a reload", async ({ page }) => {
await loginAs(page, "hub-viewer");
await page.goto("/");
await expect(page.getByRole("button", { name: "Open quick jump" })).toBeVisible();
await page.keyboard.press("Control+K");
const dialog = page.getByRole("dialog", { name: "Quick jump" });
await expect(dialog).toBeVisible();
const search = dialog.getByLabel("Find a workspace");
await expect(search).toBeFocused();
await expect(dialog.getByRole("button", { name: /Audit/ })).toHaveCount(0);
await search.fill("catalog");
await dialog.getByRole("button", { name: /Catalog/ }).click();
await expect(page).toHaveURL(/\/tools$/);
await expect(page.getByRole("heading", { name: "Catalog", level: 2 })).toBeVisible();
});
test("resource filtering is debounced, normalized and URL-addressable", async ({ page }) => {
await loginAs(page, "hub-admin");
await page.goto("/tools");
const filter = page.getByLabel("Filter records");
await filter.fill(" Fleet Ops ");
await expect(page).toHaveURL(/\/tools\?q=Fleet%20Ops$/);
await expect(page.getByText("Updating results…")).toHaveCount(0);
await filter.fill(" ");
await expect(page).toHaveURL(/\/tools$/);
});
test("the authenticated control plane retains hierarchy and has no overflow at key viewports", async ({ page }, testInfo) => {
await loginAs(page, "hub-viewer");
for (const viewport of [{ width: 1440, height: 900 }, { width: 1280, height: 800 }, { width: 768, height: 1024 }, { width: 390, height: 844 }]) {
await page.setViewportSize(viewport);
await page.goto("/");
await expect(page.getByRole("heading", { name: "Governed MCP, with the current signal first." })).toBeVisible();
await expect(page.getByLabel("Governed MCP request path")).toBeVisible();
const topbar = await page.locator(".topbar").boundingBox();
expect(topbar?.y ?? Number.POSITIVE_INFINITY, `topbar position at ${viewport.width}px`).toBeLessThan(100);
await expectNoPageOverflow(page);
if (captureReview) await page.screenshot({
path: testInfo.outputPath(`dashboard-${viewport.width}.png`),
fullPage: false,
});
}
});
test("catalog, operations and onboarding remain workable beyond the dashboard", async ({ page }, testInfo) => {
const consoleErrors: string[] = [];
page.on("console", (message) => { if (message.type() === "error") consoleErrors.push(message.text()); });
await loginAs(page, "hub-admin");
await page.setViewportSize({ width: 1440, height: 900 });
await page.goto("/tools");
await expect(page.getByRole("heading", { name: "Catalog", level: 2 })).toBeVisible();
await expect(page.getByLabel("Filter records")).toBeVisible();
await expectNoPageOverflow(page);
if (captureReview) await page.screenshot({ path: testInfo.outputPath("catalog-desktop.png"), fullPage: false });
await page.goto("/operations");
await expect(page.getByRole("heading", { name: "Governed-call trend" })).toBeVisible();
await expectNoPageOverflow(page);
if (captureReview) await page.screenshot({ path: testInfo.outputPath("operations-desktop.png"), fullPage: false });
await page.goto("/clients");
const onboarding = page.locator(".onboarding-panel");
await expect(onboarding).toBeVisible();
await expectNoPageOverflow(page);
if (captureReview) await onboarding.screenshot({ path: testInfo.outputPath("client-onboarding.png") });
await page.setViewportSize({ width: 390, height: 844 });
await page.goto("/tools");
await expect(page.getByLabel("Filter records")).toBeVisible();
await expectNoPageOverflow(page);
if (captureReview) await page.screenshot({ path: testInfo.outputPath("catalog-mobile.png"), fullPage: false });
expect(consoleErrors).toEqual([]);
});
});
+230
View File
@@ -0,0 +1,230 @@
import { expect, loginAs, test } from "./fixtures";
test.describe("management workflows, driven end to end from the browser", () => {
test.beforeEach(async ({ page }) => {
await loginAs(page, "hub-admin");
});
test("tool catalog pagination is real: Next/Previous move through disjoint, server-issued pages", async ({
page,
}) => {
await page.goto("/tools");
const firstRowId = () => page.locator("table tbody tr").first().locator("small").first().textContent();
const firstPageFirstId = await firstRowId();
await expect(page.getByRole("button", { name: "Previous page" })).toBeDisabled();
await page.getByRole("button", { name: "Next page" }).click();
await expect(page.locator("table tbody tr").first().locator("small").first()).not.toHaveText(firstPageFirstId ?? "");
const secondPageFirstId = await firstRowId();
await page.getByRole("button", { name: "Previous page" }).click();
await expect(page.locator("table tbody tr").first().locator("small").first()).toHaveText(firstPageFirstId ?? "");
await page.getByRole("button", { name: "Next page" }).click();
await expect(page.locator("table tbody tr").first().locator("small").first()).toHaveText(secondPageFirstId ?? "");
});
test("project detail renders real registered environments and connector bindings, not a fixed 'prod'", async ({
page,
}) => {
await page.goto("/projects/ludarium?tab=Environments");
await expect(page.getByLabel("Project detail sections").getByRole("link", { name: "Environments" })).toHaveAttribute("aria-current", "page");
await expect(page.getByRole("cell", { name: "prod", exact: true })).toBeVisible();
// ludarium never registered a staging environment (docs/known-state, and
// tests/test_wp230_ui_completion.py's equivalent backend assertion).
await expect(page.getByRole("cell", { name: "staging" })).toHaveCount(0);
await page.getByLabel("Project detail sections").getByRole("link", { name: "Connectors" }).click();
await expect(page.getByRole("cell", { name: "knowledge", exact: true })).toBeVisible();
});
test("an unregistered project is a real 404, not a fabricated default", async ({ page }) => {
await page.goto("/projects/does-not-exist");
await expect(page.getByRole("alert")).toBeVisible();
await expect(page.getByText(/is not registered/)).toBeVisible();
});
test("policy simulation is wired to the real engine: a known-allow case explains its decision", async ({
page,
}) => {
await page.goto("/policies");
await page.getByLabel("Project").selectOption({ label: "Ludarium" });
await page.getByLabel("Environment").selectOption("prod");
await page.getByLabel("Tool").selectOption({ label: "Knowledge Document Search" });
await page.getByRole("button", { name: "Explain decision" }).click();
const decisionCard = page.getByRole("status").filter({ hasText: "Matched:" });
await expect(decisionCard).toBeVisible();
await expect(decisionCard.getByText(/Trace [0-9a-f-]{8,}/)).toBeVisible();
await expect(decisionCard.getByText("Matched: none")).toHaveCount(0);
});
test("catalog preview surfaces a real validation result, driven by a real project selector", async ({ page }) => {
await page.goto("/tools");
await page.getByRole("button", { name: "Validate and preview" }).click();
const outcome = page.getByText(/Valid preview|Validation blocked/);
await expect(outcome).toBeVisible();
const applyButton = page.getByRole("button", { name: "Apply approved catalog" });
if (await outcome.filter({ hasText: "Valid preview" }).count()) {
await expect(applyButton).toBeEnabled();
await applyButton.click();
await page.getByRole("button", { name: "Confirm apply" }).click();
} else {
await expect(applyButton).toBeDisabled();
}
});
test("connector state is communicated as visible text, not color alone", async ({ page }) => {
await page.goto("/connectors");
await expect(page.locator("table tbody tr").first()).toBeVisible();
const statusCells = page.locator("table tbody tr td .status");
const count = await statusCells.count();
expect(count).toBeGreaterThan(0);
for (let index = 0; index < count; index += 1) {
const text = (await statusCells.nth(index).innerText()).trim();
expect(["Healthy", "Degraded", "Unavailable", "Unknown"]).toContain(text);
}
});
test("table density toggle changes row padding without changing row count or data", async ({ page }) => {
await page.goto("/tools");
await expect(page.locator("table tbody tr").first()).toBeVisible();
const rowCountBefore = await page.locator("table tbody tr").count();
await page.getByRole("button", { name: "Compact" }).click();
await expect(page.locator(".table-wrap")).toHaveClass(/density-compact/);
expect(await page.locator("table tbody tr").count()).toBe(rowCountBefore);
await page.getByRole("button", { name: "Comfortable" }).click();
await expect(page.locator(".table-wrap")).toHaveClass(/density-comfortable/);
});
test("density toggle exposes which option is selected, not just the applied state", async ({ page }) => {
// Regression test for a real bug found during WP-235's visual polish
// pass: the Stitch retokenization made .button's default look a solid
// accent pill, which is also what the "active" class resolved to --
// Comfortable and Compact rendered identically, so neither the sighted
// UI nor assistive tech could tell which density was selected.
await page.goto("/tools");
const comfortable = page.getByRole("button", { name: "Comfortable" });
const compact = page.getByRole("button", { name: "Compact" });
await expect(comfortable).toHaveAttribute("aria-pressed", "true");
await expect(compact).toHaveAttribute("aria-pressed", "false");
await expect(compact).toHaveClass(/button-secondary/);
await compact.click();
await expect(comfortable).toHaveAttribute("aria-pressed", "false");
await expect(compact).toHaveAttribute("aria-pressed", "true");
await expect(comfortable).toHaveClass(/button-secondary/);
});
test("policy simulation renders a step-by-step decision trace, not just the top-line result", async ({ page }) => {
await page.goto("/policies");
await page.getByLabel("Project").selectOption({ label: "Ludarium" });
await page.getByLabel("Environment").selectOption("prod");
await page.getByLabel("Tool").selectOption({ label: "Knowledge Document Search" });
await page.getByRole("button", { name: "Explain decision" }).click();
await expect(page.getByText("Decision logic trace")).toBeVisible();
const steps = page.locator(".trace-step");
await expect(steps.first()).toBeVisible();
expect(await steps.count()).toBeGreaterThan(0);
// Every rendered step must carry a real phase name from the engine's
// trace, not an empty placeholder row.
const firstStepPhase = await steps.first().locator("strong").innerText();
expect(firstStepPhase.trim().length).toBeGreaterThan(0);
});
test("generated client configuration never renders secret material into the DOM", async ({ page }) => {
await page.goto("/clients");
await page.getByLabel("Name").fill("e2e-config-check");
await page.getByRole("button", { name: "Create pending client" }).click();
await expect(page.getByText(/Client created: e2e-config-check/)).toBeVisible();
await page.reload();
const targetRow = page.getByRole("row", { name: /e2e-config-check/ });
await expect(targetRow).toBeVisible();
await targetRow.getByRole("button", { name: "Config" }).click();
await expect(page.getByText(/Generated configuration for/)).toBeVisible();
const bodyText = await page.locator("body").innerText();
expect(bodyText).not.toMatch(/"secret"|client_secret|bearer [a-z0-9]{20,}/i);
expect(bodyText).toContain("Secret material is write-only");
});
test("client onboarding does not claim that the Hub provisions an Authentik identity", async ({ page }) => {
await page.goto("/clients");
await expect(page.getByText(/External identity provisioning is a separate administrator task/)).toBeVisible();
await expect(page.getByText(/Authentik hand-off reference/)).toHaveCount(0);
});
test("Operations page renders the same real drift/backup/denial data as the dashboard, not a fabricated summary", async ({ page }) => {
await page.goto("/");
const dashboardDrift = await page.locator(".metric-card", { hasText: "Reconcile drift" }).locator("strong").innerText();
await page.goto("/operations");
await expect(page.getByRole("heading", { name: "Operations" })).toBeVisible();
const operationsDrift = await page.locator(".metric-card", { hasText: "Reconcile drift" }).locator("strong").innerText();
expect(operationsDrift).toBe(dashboardDrift);
});
test("tool readiness validates the full registered path without invoking the tool", async ({ page }) => {
await page.goto("/tools");
await page.getByRole("button", { name: "Validate and preview" }).click();
await expect(page.getByText("Valid preview")).toBeVisible();
await page.getByRole("button", { name: "Apply approved catalog" }).click();
await page.getByRole("button", { name: "Confirm apply" }).click();
await expect(page.getByText(/Catalog reconciliation completed and verified/)).toBeVisible();
await page.getByLabel("Filter records").fill("Fleet Ops Operations Summary");
const row = page.getByRole("row", { name: /Fleet Ops Operations Summary/ });
await row.getByRole("button", { name: "Readiness" }).click();
await page.getByRole("dialog").getByLabel("Project").selectOption({ label: "Fleet Ops" });
await page.getByRole("dialog").getByLabel("Environment").selectOption("prod");
await page.getByRole("button", { name: "Run readiness check" }).click();
await expect(page.getByRole("dialog").getByText("Ready", { exact: true })).toBeVisible();
await expect(page.getByRole("dialog").getByText(/no MCP tool invocation was performed/i)).toBeVisible();
await expect(page.getByRole("dialog").getByText(/healthy/i).first()).toBeVisible();
});
test("closing a Modal returns keyboard focus to the element that opened it, not document.body", async ({ page }) => {
// Regression test for a real bug found during WP-235 Task 12's manual
// accessibility pass: Modal moved focus into the dialog on open but
// never restored it on close, silently dropping keyboard users back to
// document.body. Uses the tools "Readiness" button's Modal as an isolated,
// side-effect-free trigger.
await page.goto("/tools");
const trigger = page.locator("table tbody tr").first().getByRole("button", { name: "Readiness" });
await trigger.click();
await expect(page.getByRole("dialog")).toBeVisible();
await page.keyboard.press("Escape");
await expect(page.getByRole("dialog")).toHaveCount(0);
await expect(trigger).toBeFocused();
});
test("an open Modal locks background scroll and traps keyboard focus", async ({ page }) => {
await page.goto("/tools");
await page.locator("table tbody tr").first().getByRole("button", { name: "Readiness" }).click();
const dialog = page.getByRole("dialog");
await expect(dialog).toBeVisible();
await expect.poll(() => page.evaluate(() => document.body.style.overflow)).toBe("hidden");
await page.keyboard.press("Control+K");
await expect(page.getByRole("dialog")).toHaveCount(1);
await expect(page.getByRole("dialog", { name: "Quick jump" })).toHaveCount(0);
const close = dialog.getByRole("button", { name: "Close dialog" });
const readiness = dialog.getByRole("button", { name: "Run readiness check" });
await expect(readiness).toBeEnabled();
await close.focus();
await page.keyboard.press("Shift+Tab");
await expect(readiness).toBeFocused();
await page.keyboard.press("Tab");
await expect(close).toBeFocused();
await close.click();
await expect.poll(() => page.evaluate(() => document.body.style.overflow)).toBe("");
});
test("Operations page shows an honest placeholder for approvals, not a fabricated queue", async ({ page }) => {
await page.goto("/operations");
await expect(page.getByRole("heading", { name: "Approvals" })).toBeVisible();
await expect(page.getByText(/Approval workflow is not yet part of the authorized v1 management surface/)).toBeVisible();
});
});