rpki/ui/rpki-explorer/tests/e2e/overview.spec.ts

77 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { expect, test } from "@playwright/test";
import { installMockApi } from "./mockApi";
test("overview renders run strip, KPIs, charts, top repos and reasons", async ({ page }) => {
await installMockApi(page);
await page.goto("/");
// Run strip
await expect(page.locator(".overview-run-strip").getByText("run_0002")).toBeVisible();
await expect(page.getByText("delta sync")).toBeVisible();
// KPI cards with fixture values
await expect(page.getByText("VRPs")).toBeVisible();
await expect(page.getByText("987")).toBeVisible();
await expect(page.locator(".kpi-grid").getByText("Rejected")).toBeVisible();
// Repositories KPI from stats/overview
const reposKpi = page.locator(".kpi-grid > *", { hasText: "Repositories" });
await expect(reposKpi).toBeVisible();
await expect(reposKpi).toContainText("3");
// Charts render (recharts svg)
await expect(page.locator(".recharts-responsive-container").first()).toBeVisible();
// Top repositories table, sorted by objects desc (900 > 300 > 84),
// not the fixture index order (300, 900, 84).
const repoRows = page.locator(".overview-bottom table tbody tr");
await expect(repoRows.first()).toContainText("repo-a.example");
await expect(repoRows.nth(1)).toContainText("repo-b.example");
await expect(repoRows.nth(2)).toContainText("repo-c.example");
// Top reject reasons, clustered by prefix: the two validation_time
// variants merge into one row with a combined count.
const cluster = page.getByRole("link", { name: /manifest is not valid at validation_time/ });
await expect(cluster).toBeVisible();
await expect(cluster).toContainText("×2");
await expect(cluster).toContainText("5");
await expect(page.getByRole("link", { name: "certificate expired" })).toBeVisible();
});
test("overview does not request the global object list (first-screen discipline)", async ({
page,
}) => {
await installMockApi(page);
const objectListRequests: string[] = [];
page.on("request", (req) => {
const url = new URL(req.url());
if (/\/api\/v1\/runs\/[^/]+\/objects$/.test(url.pathname)) {
objectListRequests.push(req.url());
}
});
await page.goto("/");
await expect(page.getByText("987")).toBeVisible();
expect(objectListRequests).toEqual([]);
});
test("overview drill-down: repo row navigates to repository detail", async ({ page }) => {
await installMockApi(page);
await page.goto("/");
await page.getByRole("cell", { name: "repo-b.example" }).click();
await expect(page).toHaveURL(/\/repositories\/repo-b2c3d4e5f6a7/);
await expect(page.getByRole("heading", { name: "repo-b.example" })).toBeVisible();
});
test("overview drill-down: reason navigates to filtered validation page", async ({ page }) => {
await installMockApi(page);
await page.goto("/");
await page.getByRole("link", { name: /manifest stale/ }).click();
await expect(page).toHaveURL(/\/validation\?reason=manifest/);
await expect(page.getByRole("heading", { name: "Validation" })).toBeVisible();
});
test("overview shows an explicit error state when the run cannot be loaded", async ({ page }) => {
await installMockApi(page, { failLatestRun: true });
await page.goto("/");
await expect(page.getByRole("alert")).toContainText("Failed to load run latest");
});