import { expect, test } from "@playwright/test"; import fs from "node:fs"; import path from "node:path"; import { paintPBVHBrushInventory } from "../../protocol/paint-pbvh-capability"; const attributeBlend = path.resolve(import.meta.dirname, "../../../tests/files/web/attribute_scene.blend"); test("M9-13 production Worker blocks the full PBVH brush inventory without changing Main", async ({ page }) => { test.setTimeout(120_000); await page.goto("/"); const blendBytes = fs.readFileSync(attributeBlend); const result = await page.evaluate(async ({ blendBytes, inventory }) => { const { WebEngineClient } = await import("/src/engine-client/WebEngineClient.ts"); const engine = new WebEngineClient({ timeoutMs: 60_000 }); await engine.init(); const opened = await engine.openBlend(blendBytes.buffer.slice(blendBytes.byteOffset, blendBytes.byteOffset + blendBytes.byteLength)); const object = opened.snapshot.nodes.find((candidate) => candidate.id === opened.snapshot.activeObjectId && candidate.type === "MESH"); if (!object?.dataId) throw new Error("PBVH fixture has no active Mesh object"); const before = await engine.snapshot(); const gates = []; for (const entry of inventory) { gates.push(await engine.queryPaintPBVHCapability({ schemaVersion: 1, operation: "PBVH_BRUSH", domain: entry.domain, brush: entry.brush, objectId: object.id, meshId: object.dataId, baseRevision: before.snapshot.revision, })); } const stale = await engine.queryPaintPBVHCapability({ schemaVersion: 1, operation: "PBVH_BRUSH", domain: "WEIGHT", brush: "DRAW", objectId: object.id, meshId: object.dataId, baseRevision: before.snapshot.revision + 1, }); let malformed: { code?: string; severity?: string; recoverable?: boolean } = {}; try { await engine.queryPaintPBVHCapability({ schemaVersion: 1, operation: "PBVH_BRUSH", domain: "WEIGHT", brush: "DRAW", objectId: object.id, meshId: object.dataId, baseRevision: before.snapshot.revision, proxySuccess: true, } as never); } catch (error) { malformed = error as typeof malformed; } const after = await engine.snapshot(); engine.terminate(); return { count: gates.length, statuses: [...new Set(gates.map((gate) => gate.status))], taskIds: [...new Set(gates.map((gate) => gate.taskId))], issueCodes: [...new Set(gates.flatMap((gate) => gate.issues.map((issue) => issue.code)))], capabilities: new Set(gates.map((gate) => gate.capability)).size, staleCode: stale.issues[0]?.code, malformed, beforeRevision: before.snapshot.revision, afterRevision: after.snapshot.revision, beforeHandles: before.status.liveHandles, afterHandles: after.status.liveHandles, beforeBytes: before.status.allocatedBytes, afterBytes: after.status.allocatedBytes, }; }, { blendBytes: new Uint8Array(blendBytes), inventory: paintPBVHBrushInventory() }); expect(result).toEqual({ count: 46, statuses: ["BLOCKED"], taskIds: ["N-017"], issueCodes: ["PAINT_PBVH_UNAVAILABLE"], capabilities: 46, staleCode: "REVISION_CONFLICT", malformed: { code: "PAINT_SCHEMA_INVALID", severity: "error", recoverable: true, message: "PBVH capability request contains unsupported field proxySuccess", }, beforeRevision: result.beforeRevision, afterRevision: result.beforeRevision, beforeHandles: result.beforeHandles, afterHandles: result.beforeHandles, beforeBytes: result.beforeBytes, afterBytes: result.beforeBytes, }); });