Files
workinf_Blender_Wasm/web/tests/e2e/paint-pbvh-capability.spec.ts
mes123456 0fe8d2bb56
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Advance M8-M11 parity workflows
2026-08-17 04:37:07 -04:00

97 lines
3.7 KiB
TypeScript

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,
});
});