Files
pikasTech-HWLAB/web/hwlab-cloud-web/tests/workbench-e2e/specs/admin-hwpod-performance.spec.ts
T

103 lines
6.6 KiB
TypeScript

import { expect, test } from "../fixtures/test";
test("admin HWPOD groups renders node-ops as structured UI before raw JSON is requested", async ({ page }) => {
await page.goto("/admin/hwpod-groups");
await expect(page.getByRole("heading", { name: "HWPOD 分组" })).toBeVisible();
await expect(page.getByText("hwpod-node-ops-v1")).toBeVisible();
await expect(page.getByText("/v1/hwpod-node-ops")).toBeVisible();
await expect(page.getByText("node.health")).toBeVisible();
await expect(page.getByText("node-d601-f103-v2")).toBeVisible();
await expect(page.locator("[data-testid='hwpod-raw-json']")).toHaveCount(0);
await expect(page.locator("body")).not.toContainText('"contractVersion"');
await page.getByTestId("hwpod-raw-json-toggle").click();
await expect(page.getByTestId("hwpod-raw-json")).toContainText('"contractVersion"');
});
test("performance dashboard renders Chinese charts and keeps drill-down reachable", async ({ page }) => {
await page.goto("/performance");
await expect(page.getByRole("heading", { name: "性能监控" })).toBeVisible();
await expect(page.locator(".performance-contract-item")).toHaveCount(5);
await expect(page.locator(".performance-contract-item").filter({ hasText: "观测窗口" })).toContainText("最近 15 分钟");
await expect(page.locator(".performance-contract-item").filter({ hasText: "生成时间" })).toContainText("fake-server");
await expect(page.locator(".performance-contract-item").filter({ hasText: "样本覆盖" })).toContainText("路由");
await expect(page.locator(".performance-contract-item").filter({ hasText: "数据质量" })).toContainText("低样本阈值 5 个样本");
await expect(page.locator(".performance-contract-item").filter({ hasText: "统计口径" })).toContainText("精确窗口分位");
await expect(page.locator(".performance-collection-item")).toHaveCount(4);
await expect(page.locator(".performance-collection-item").filter({ hasText: "最近样本" })).toContainText("归因字段不完整");
await expect(page.locator(".performance-collection-item").filter({ hasText: "当前窗口样本" })).toContainText("保留");
await expect(page.locator(".performance-collection-item").filter({ hasText: "来源组成" })).toContainText("工作台");
await expect(page.locator(".performance-collection-item").filter({ hasText: "归因完整性" })).toContainText("不完整");
await expect(page.getByText("工作台归因不完整")).toBeVisible();
await expect(page.getByText("工作台体感趋势")).toBeVisible();
await expect(page.getByText("状态分布")).toBeVisible();
await expect(page.getByText("慢 API TopN")).toBeVisible();
await expect(page.locator("svg.performance-line-chart")).toHaveCount(3);
await expect(page.locator(".chart-point")).not.toHaveCount(0);
await expect(page.locator(".performance-row-contract").filter({ hasText: "桶化估算" }).first()).toBeVisible();
await expect(page.locator(".performance-row-contract").filter({ hasText: "低样本" }).first()).toBeVisible();
await expect(page.locator(".performance-row-contract").filter({ hasText: "后端证据" }).first()).toContainText("已匹配后端");
await expect(page.locator(".performance-row-contract").filter({ hasText: "RUM 慢于后端" }).first()).toBeVisible();
await expect(page.locator("body")).not.toContainText(/Metric|Route|Count|Status|Samples|Problems|Workbench|Web Vitals|API Timing|Long Tasks/u);
await expect(page.locator("body")).not.toContainText(/sessionId|traceId|runId|stdout|stderr|Secret/u);
await page.getByRole("tab", { name: "1 小时" }).click();
await expect(page.locator(".performance-contract-item").filter({ hasText: "观测窗口" })).toContainText("最近 1 小时");
await page.screenshot({ path: ".state/workbench-e2e/performance-dashboard-desktop.png", fullPage: true });
await page.setViewportSize({ width: 390, height: 844 });
await page.goto("/performance");
await expect(page.getByText("性能明细")).toBeVisible();
await expect(page.locator("svg.performance-line-chart")).toHaveCount(3);
await page.screenshot({ path: ".state/workbench-e2e/performance-dashboard-mobile.png", fullPage: true });
const scrollers = await page.locator(".performance-page .data-table-wrap").evaluateAll((items) => items.map((item) => ({
clientWidth: Math.round(item.clientWidth),
scrollWidth: Math.round(item.scrollWidth),
overflowX: getComputedStyle(item).overflowX
})));
expect(scrollers.length).toBeGreaterThanOrEqual(1);
expect(scrollers.every((item) => item.clientWidth <= 390)).toBeTruthy();
expect(scrollers.some((item) => item.scrollWidth > item.clientWidth + 120)).toBeTruthy();
expect(scrollers.every((item) => item.overflowX === "auto" || item.overflowX === "scroll")).toBeTruthy();
const documentScrollWidth = await page.evaluate(() => Math.round(document.documentElement.scrollWidth));
expect(documentScrollWidth).toBeLessThanOrEqual(390);
});
test.describe("performance dashboard empty collection", () => {
test.use({ scenarioId: "performance-empty" });
test("renders the empty summary contract without invented rows", async ({ page }) => {
await page.goto("/performance");
await expect(page.getByRole("heading", { name: "性能监控" })).toBeVisible();
await expect(page.locator(".performance-contract-item")).toHaveCount(5);
await expect(page.locator(".performance-contract-item").filter({ hasText: "样本覆盖" })).toContainText("0 样本");
await expect(page.locator(".performance-collection-item")).toHaveCount(4);
await expect(page.locator(".performance-collection-item").filter({ hasText: "最近样本" })).toContainText("采集器尚未上报样本");
await expect(page.locator(".performance-collection-item").filter({ hasText: "当前窗口样本" })).toContainText("0 样本");
await expect(page.getByText("暂无采集样本")).toBeVisible();
await expect(page.getByText("等待数据").first()).toBeVisible();
await expect(page.getByText("暂无性能样本。请先打开工作台或执行一次真实页面操作后刷新。")).toBeVisible();
await expect(page.locator(".performance-row-contract")).toHaveCount(0);
});
});
test.describe("performance dashboard summary error", () => {
test.use({ scenarioId: "performance-summary-error" });
test("surfaces the summary read-model failure without stale dashboard data", async ({ page }) => {
await page.goto("/performance");
await expect(page.getByRole("heading", { name: "性能监控" })).toBeVisible();
await expect(page.getByText("性能监控加载失败")).toBeVisible();
await expect(page.getByRole("button", { name: "重试" })).toBeVisible();
await expect(page.locator(".performance-contract-item")).toHaveCount(0);
});
});