返回 DeepSeek-Reasonix
performance-report-enrichment.test.ts
根目录 / desktop / frontend / src / __tests__ / performance-report-enrichment.test.ts
1 import assert from "node:assert/strict";
2 import { JSDOM } from "jsdom";
3 import { installDesktopHostStub } from "./desktopHostStub";
4 import { installPerformancePressureMonitor } from "../lib/crash";
5 import type { ProcessDiagnosticsSnapshot, RendererProfileResult } from "../lib/processDiagnostics";
6
7 const dom = new JSDOM("<!doctype html><body></body>", { url: "http://localhost" });
8 let now = 0;
9 let observe!: (list: { getEntries(): unknown[] }) => void;
10 let completeProfile!: (value: RendererProfileResult) => void;
11 let completeProcesses!: (value: ProcessDiagnosticsSnapshot) => void;
12 let cancelled = 0;
13 let heapRequests = 0;
14 const reports: string[] = [];
15 const copies: string[] = [];
16 Object.defineProperty(dom.window.document, "visibilityState", { value: "visible" });
17 dom.window.document.hasFocus = () => true;
18 dom.window.setInterval = () => 1;
19 Object.assign(globalThis, {
20 window: dom.window, document: dom.window.document, performance: { now: () => now },
21 PerformanceObserver: class { constructor(callback: typeof observe) { observe = callback; } observe() {} },
22 });
23 installDesktopHostStub({ ReportCrash: (_kind: string, payload: string) => { reports.push(payload); } }, {
24 clipboardWrites: copies,
25 processDiagnostics: () => new Promise((resolve) => { completeProcesses = resolve; }),
26 performance: {
27 captureRendererProfile: () => new Promise((resolve) => { completeProfile = resolve; }),
28 cancelRendererProfile: async () => { cancelled++; },
29 exportHeapSnapshot: async () => { heapRequests++; return { status: "cancelled" }; },
30 },
31 });
32 installPerformancePressureMonitor();
33 now = 20_000;
34 observe({ getEntries: () => [{ startTime: 20_000, duration: 900, name: "self" }] });
35 const host = document.getElementById("performance-report-prompt");
36 assert.ok(host, "base report appears before either diagnostic promise settles");
37 const copy = host.querySelector<HTMLButtonElement>(".performance-report__copy")!;
38 const send = host.querySelector<HTMLButtonElement>(".performance-report__send")!;
39 const flush = async () => { for (let i = 0; i < 20; i++) await Promise.resolve(); };
40 await flush();
41 completeProfile({ status: "captured", durationMs: 5000, frames: [{ label: "render (app.js:10)", samples: 4, selfMs: 40 }] });
42 await flush();
43 assert.equal(host.querySelector(".performance-report__copy"), copy, "enrichment preserves button identity");
44 copy.click(); send.click();
45 await flush();
46 assert.match(copies[0], /render \(app.js:10\)/);
47 assert.match(reports[0], /CPU profile after trigger: captured/);
48 assert.equal(heapRequests, 0, "heap capture never happens automatically");
49 host.querySelector<HTMLButtonElement>(".performance-report__dismiss")!.click();
50 assert.equal(cancelled, 0, "closing a completed report cannot cancel a later capture");
51 completeProcesses({ scope: "electron", samples: [] });
52 await flush();
53 assert.equal(document.getElementById("performance-report-prompt"), null, "late diagnostics never recreate a dismissed prompt");
54 dom.window.close();
55 console.log("performance report enrichment tests passed");
56
56 lines TYPESCRIPT