| 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 { RendererProfileResult } from "../lib/processDiagnostics"; |
| 6 | |
| 7 | const dom = new JSDOM("<!doctype html><body></body>", { url: "http://localhost" }); |
| 8 | let now = 0; |
| 9 | let wall = 1_000_000; |
| 10 | const oldDateNow = Date.now; |
| 11 | Date.now = () => wall; |
| 12 | let observe!: (list: { getEntries(): unknown[] }) => void; |
| 13 | const captures: { id?: string; finish(value: RendererProfileResult): void }[] = []; |
| 14 | const cancelled: (string | undefined)[] = []; |
| 15 | Object.defineProperty(dom.window.document, "visibilityState", { value: "visible" }); |
| 16 | dom.window.document.hasFocus = () => true; |
| 17 | dom.window.setInterval = () => 1; |
| 18 | Object.assign(globalThis, { |
| 19 | window: dom.window, document: dom.window.document, performance: { now: () => now }, |
| 20 | PerformanceObserver: class { constructor(callback: typeof observe) { observe = callback; } observe() {} }, |
| 21 | }); |
| 22 | installDesktopHostStub({}, { performance: { |
| 23 | captureRendererProfile: (id) => new Promise((finish) => { captures.push({ id, finish }); }), |
| 24 | cancelRendererProfile: async (id) => { cancelled.push(id); }, |
| 25 | } }); |
| 26 | const flush = async () => { for (let i = 0; i < 20; i++) await Promise.resolve(); }; |
| 27 | try { |
| 28 | installPerformancePressureMonitor(); |
| 29 | now = 20_000; |
| 30 | observe({ getEntries: () => [{ startTime: now, duration: 900, name: "self" }] }); |
| 31 | await flush(); |
| 32 | const staleDismiss = document.querySelector<HTMLButtonElement>(".performance-report__dismiss")!; |
| 33 | now += 620_000; |
| 34 | wall += 620_000; |
| 35 | observe({ getEntries: () => [{ startTime: now, duration: 900, name: "self" }] }); |
| 36 | await flush(); |
| 37 | assert.equal(captures.length, 2); |
| 38 | assert.ok(captures[0].id && captures[1].id && captures[0].id !== captures[1].id); |
| 39 | staleDismiss.click(); |
| 40 | assert.ok(document.getElementById("performance-report-prompt"), "stale actions cannot close a newer report"); |
| 41 | assert.deepEqual(cancelled, []); |
| 42 | document.querySelector<HTMLButtonElement>(".performance-report__dismiss")!.click(); |
| 43 | assert.deepEqual(cancelled, [captures[1].id], "dismissal cancels only its own capture"); |
| 44 | captures[0].finish({ status: "captured", frames: [] }); |
| 45 | captures[1].finish({ status: "cancelled" }); |
| 46 | await flush(); |
| 47 | assert.equal(document.getElementById("performance-report-prompt"), null); |
| 48 | console.log("performance report cancellation identity tests passed"); |
| 49 | } finally { |
| 50 | for (const capture of captures) capture.finish({ status: "cancelled" }); |
| 51 | Date.now = oldDateNow; |
| 52 | dom.window.close(); |
| 53 | } |
| 54 |