import { expect, test } from "@playwright/test"; test("M13-03F disposes Worker resources to zero and is idempotent", async ({ page }) => { await page.goto("/"); const result = await page.evaluate(() => new Promise>((resolve, reject) => { const worker = new Worker("/src/workers/script-sandbox-dispose-test.worker.ts", { type: "module" }); let ready: Record | undefined; let first: Record | undefined; let lateTimerMessages = 0; worker.onmessage = (event: MessageEvent>) => { if (event.data.type === "ready") { ready = event.data; worker.postMessage({ type: "dispose" }); return; } if (event.data.type === "late-timer") { lateTimerMessages += 1; return; } if (event.data.type === "disposed" && first === undefined) { first = event.data; worker.postMessage({ type: "dispose" }); return; } if (event.data.type === "disposed") { const second = event.data; worker.terminate(); setTimeout(() => resolve({ ready, first, second, workerTerminated: true, lateTimerMessages }), 70); } }; worker.onerror = (event) => { worker.terminate(); reject(new Error(event.message)); }; worker.postMessage({ type: "init" }); })); expect(result.ready.resources).toEqual({ messagePorts: 2, timers: 1, abortControllers: 1, transferableBuffers: 1, pendingRequests: 1, cacheReferences: 1 }); expect(result.first.receipt).toMatchObject({ schemaVersion: 1, disposeCount: 1, idempotent: false, lateTimerMessages: 0 }); expect(result.first.resources).toEqual({ messagePorts: 0, timers: 0, abortControllers: 0, transferableBuffers: 0, pendingRequests: 0, cacheReferences: 0 }); expect(result.second.receipt).toMatchObject({ schemaVersion: 1, disposeCount: 2, idempotent: true, lateTimerMessages: 0 }); expect(result.second.resources).toEqual({ messagePorts: 0, timers: 0, abortControllers: 0, transferableBuffers: 0, pendingRequests: 0, cacheReferences: 0 }); expect(result.workerTerminated).toBe(true); expect(result.lateTimerMessages).toBe(0); });