rpki/ui/rpki-explorer/tests/e2e/object-detail-api.spec.ts

66 lines
3.5 KiB
TypeScript

import { expect, test } from "@playwright/test";
test.setTimeout(120_000);
const screenshotRoot = "../../../../specs/develop/20260623_2/m6_full_e2e";
async function openFirstRepositoryObject(page: import("@playwright/test").Page) {
await page.goto("/");
await page.getByRole("button", { name: /Repositories/i }).click();
const reposSection = page.locator('section[aria-label="Repositories"]');
await reposSection.getByLabel("Filter repositories on current page").fill("sakuya");
await reposSection.locator(".stack-row-select").first().click();
await page.locator('section[aria-label="Publication points"] .stack-row-select').first().click();
const row = page.locator('section[aria-label="Objects for publication point"] tbody tr').first();
await expect(row).toBeVisible({ timeout: 70_000 });
const expectedUri = (await row.locator(".uri-cell .copyable-value-text").innerText()).trim();
await row.getByRole("button", { name: "Open" }).click();
await expect(page.locator(".object-detail-card")).toContainText(expectedUri, { timeout: 70_000 });
return expectedUri;
}
test("renders live object detail and lazy tab requests", async ({ page }) => {
const apiRequests: string[] = [];
const consoleErrors: string[] = [];
page.on("request", (request) => {
const url = new URL(request.url());
if (url.pathname.startsWith("/api/v1")) {
apiRequests.push(`${url.pathname}${url.search}`);
}
});
page.on("console", (message) => {
if (message.type() === "error") {
consoleErrors.push(message.text());
}
});
await openFirstRepositoryObject(page);
await expect(page.getByText("Object detail · live query service")).toBeVisible();
await expect(page.getByText("File and chain checks")).toBeVisible();
const objectDetail = page.getByRole("complementary", { name: "Live object detail" });
await expect(objectDetail.getByText("Authoritative", { exact: true })).toBeVisible();
await expect(page.getByRole("complementary", { name: "Publication point object list" })).toHaveCount(0);
await expect(page.getByRole("region", { name: "Publication point object table" })).toHaveCount(0);
await expect(page.getByRole("button", { name: "Copy selected object URI" })).toBeVisible();
await expect(page.getByRole("button", { name: "Copy SHA256" })).toBeVisible();
await expect(page.getByRole("button", { name: "Copy Repository" })).toBeVisible();
await expect(page.getByRole("button", { name: "Copy Publication Point" })).toBeVisible();
expect(apiRequests.some((request) => request.includes("/parsed"))).toBe(false);
await page.getByRole("tab", { name: "Parsed" }).click();
await expect(page.getByText(/Projection JSON|Projection unavailable/)).toBeVisible({ timeout: 30_000 });
expect(apiRequests.some((request) => request.includes("/parsed"))).toBe(true);
await page.getByRole("tab", { name: "Chain" }).click();
await expect(page.getByRole("tabpanel")).toHaveAttribute("aria-labelledby", "object-tab-chain");
expect(apiRequests.some((request) => request.includes("/chain"))).toBe(true);
await page.getByRole("tab", { name: "Validation" }).click();
await page.getByRole("button", { name: "Explain validation" }).click();
await expect(page.getByText(/audit_projection|cached audit projection|Explain failed/)).toBeVisible({ timeout: 30_000 });
expect(apiRequests.some((request) => request.includes("/validation/explain"))).toBe(true);
await page.screenshot({ path: `${screenshotRoot}/rpki-explorer-object-detail-live.png`, fullPage: true });
expect(consoleErrors).toEqual([]);
});