import { expect, test } from "@playwright/test"; import fs from "node:fs"; import path from "node:path"; const fixtures = { CURVE: path.resolve(import.meta.dirname, "../../../tests/files/web/nonmesh_scene.blend"), GREASE_PENCIL: path.resolve(import.meta.dirname, "../../../tests/files/web/modifier_grease_pencil_scene.blend"), PAINT: path.resolve(import.meta.dirname, "../../../tests/files/web/attribute_scene.blend"), }; test("M9-14 recovers Curve, Grease Pencil and Paint after Worker, OOM and GPU release faults", async ({ page }) => { test.setTimeout(180_000); await page.goto("/"); const input = Object.fromEntries(Object.entries(fixtures).map(([domain, file]) => [domain, Array.from(fs.readFileSync(file))])); const reports = await page.evaluate(async (bytes) => { const { runEditingDomainRecoverySuite } = await import("/src/testing/editing-domain-recovery.ts"); const buffers = Object.fromEntries(Object.entries(bytes).map(([domain, value]) => [domain, Uint8Array.from(value as number[]).buffer])); return runEditingDomainRecoverySuite(buffers); }, input); expect(reports.map((report) => report.domain)).toEqual(["CURVE", "GREASE_PENCIL", "PAINT"]); for (const report of reports) { expect(report.schemaVersion).toBe(1); expect(report.workerRestart).toMatchObject({ status: "RECOVERED", workerGeneration: 2, temporaryResourcesAfter: 0 }); expect(report.workerRestart.hashAfter).toBe(report.baseline.identityHash); expect(report.oom).toMatchObject({ status: "RECOVERED", faultPoint: "GPU_GEOMETRY_UPLOAD", code: "GPU_GEOMETRY_BUDGET_EXCEEDED", temporaryResourcesAfter: 0 }); expect(report.oom.hashAfter).toBe(report.baseline.identityHash); expect(report.gpuRelease).toMatchObject({ status: "RECOVERED", backend: "WEBGL2", releaseCount: 1, reinitCount: 1 }); expect(report.gpuRelease.disposedResources).toBeGreaterThan(0); expect(report.gpuRelease.visiblePixels).toBeGreaterThan(0); expect(report.smallScene).toMatchObject({ status: "RECOVERED", identityHash: report.baseline.identityHash, revision: report.baseline.revision, objectCount: report.baseline.objectCount }); expect(report.smallScene.visiblePixels).toBeGreaterThan(0); } });