Advance M8-M11 parity workflows
This commit is contained in:
96
web/tests/e2e/paint-pbvh-capability.spec.ts
Normal file
96
web/tests/e2e/paint-pbvh-capability.spec.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
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,
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user