feat: add workbench performance dashboard

This commit is contained in:
lyon
2026-06-19 16:49:13 +08:00
parent 80dc11f073
commit 0645e7ffa6
7 changed files with 1072 additions and 155 deletions
@@ -16,19 +16,32 @@ test("admin HWPOD groups renders node-ops as structured UI before raw JSON is re
await expect(page.getByTestId("hwpod-raw-json")).toContainText('"contractVersion"');
});
test("performance tables keep wide columns reachable inside local mobile scrollers", async ({ page }) => {
await page.setViewportSize({ width: 390, height: 844 });
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.getByText("Problem rows")).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("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.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(4);
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();