test(web): cover user-visible error diagnostics matrix
This commit is contained in:
@@ -227,6 +227,12 @@ async function handleRequest(request: IncomingMessage, response: ServerResponse)
|
||||
if (path === "/v1/hwpod-node-ops") return json(response, 200, hwpodNodeOpsPayload());
|
||||
if (path === "/v1/web-performance/summary") {
|
||||
if (state.scenarioId === "performance-summary-error") return errorDiagnosticResponse(response, 502, "/v1/web-performance/summary", "upstream_unavailable", "暂时无法连接上游。");
|
||||
const matrixStatus = performanceSummaryErrorStatus(state.scenarioId);
|
||||
if (matrixStatus !== null) return errorDiagnosticResponse(response, matrixStatus, "/v1/web-performance/summary", `e2e_http_${matrixStatus}`, `模拟 ${matrixStatus} 错误。`, { traceId: statusMatrixTraceId(matrixStatus), requestId: `req_e2e_api_status_${matrixStatus}`, category: matrixStatus >= 500 ? "server" : "client" });
|
||||
if (state.scenarioId === "performance-network-error") {
|
||||
response.destroy(new Error("e2e performance network reset"));
|
||||
return;
|
||||
}
|
||||
if (state.scenarioId === "performance-empty") return json(response, 200, webPerformanceEmptyPayload(url));
|
||||
if (state.scenarioId === "performance-stale-window") return json(response, 200, webPerformanceStaleWindowPayload(url));
|
||||
return json(response, 200, webPerformanceSummaryPayload(url));
|
||||
@@ -1887,6 +1893,15 @@ function authLoginResponse(response: ServerResponse): void {
|
||||
return json(response, 401, { ok: false, status: "failed", error: { code: "invalid_credentials", message: "invalid credentials" } });
|
||||
}
|
||||
|
||||
function performanceSummaryErrorStatus(scenarioId: string): number | null {
|
||||
const match = /^performance-summary-error-(400|401|403|404|409|500)$/u.exec(scenarioId);
|
||||
return match ? Number(match[1]) : null;
|
||||
}
|
||||
|
||||
function statusMatrixTraceId(status: number): string {
|
||||
return String(status).repeat(11).slice(0, 32);
|
||||
}
|
||||
|
||||
function redactRequestBody(value: JsonRecord): JsonRecord {
|
||||
const output: JsonRecord = {};
|
||||
for (const [key, item] of Object.entries(value)) output[key] = /secret|token|key|password|authorization/iu.test(key) ? "<redacted>" : item;
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Page } from "@playwright/test";
|
||||
import { expect, fakeServerState, test } from "../fixtures/test";
|
||||
|
||||
type RequestLedgerEntry = { path?: string; query?: Record<string, string> };
|
||||
const performanceErrorStatuses = [400, 401, 403, 404, 409, 500] as const;
|
||||
|
||||
async function performanceSummaryRequests(page: Page): Promise<RequestLedgerEntry[]> {
|
||||
const state = await fakeServerState(page);
|
||||
@@ -159,3 +160,53 @@ test.describe("performance dashboard summary error", () => {
|
||||
await expect(page.locator(".performance-contract-item")).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
for (const status of performanceErrorStatuses) {
|
||||
test.describe(`performance dashboard HTTP ${status} diagnostic`, () => {
|
||||
test.use({ scenarioId: `performance-summary-error-${status}` });
|
||||
|
||||
test(`surfaces HTTP ${status} trace diagnostics without stale dashboard data`, async ({ page }) => {
|
||||
await page.goto("/performance");
|
||||
|
||||
await expect(page.getByRole("heading", { name: "性能监控" })).toBeVisible();
|
||||
await expect(page.getByText("性能监控加载失败")).toBeVisible();
|
||||
const diagnostic = page.locator(".api-error-diagnostic");
|
||||
await expect(diagnostic).toContainText("trace_id");
|
||||
await expect(diagnostic).toContainText(statusTraceId(status));
|
||||
await expect(diagnostic).toContainText("requestId");
|
||||
await expect(diagnostic).toContainText(`req_e2e_api_status_${status}`);
|
||||
await expect(diagnostic).toContainText(`e2e_http_${status}`);
|
||||
await expect(diagnostic).toContainText("/v1/web-performance/summary");
|
||||
await expect(diagnostic).toContainText(String(status));
|
||||
await expect(diagnostic).toContainText("valuesPrinted");
|
||||
await expect(diagnostic).toContainText("false");
|
||||
await expect(page.getByRole("button", { name: "重试" })).toBeVisible();
|
||||
await expect(page.locator(".performance-contract-item")).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test.describe("performance dashboard browser network diagnostic", () => {
|
||||
test.use({ scenarioId: "performance-network-error" });
|
||||
|
||||
test("surfaces browser generated trace diagnostics when the request has no response", async ({ page }) => {
|
||||
await page.goto("/performance");
|
||||
|
||||
await expect(page.getByRole("heading", { name: "性能监控" })).toBeVisible();
|
||||
await expect(page.getByText("性能监控加载失败")).toBeVisible();
|
||||
const diagnostic = page.locator(".api-error-diagnostic");
|
||||
await expect(diagnostic).toContainText("trace_id");
|
||||
await expect(diagnostic).toContainText("requestId");
|
||||
await expect(diagnostic).toContainText("browser_network_error");
|
||||
await expect(diagnostic).toContainText("web / network");
|
||||
await expect(diagnostic).toContainText("/v1/web-performance/summary");
|
||||
await expect(diagnostic).toContainText("browser");
|
||||
await expect(diagnostic).toContainText("valuesPrinted");
|
||||
await expect(diagnostic).toContainText("false");
|
||||
await expect(page.locator(".performance-contract-item")).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
function statusTraceId(status: number): string {
|
||||
return String(status).repeat(11).slice(0, 32);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user