Files
workinf_Blender_Wasm/web/tests/e2e/glb-negative-cases.spec.ts
mes123456 380cbed4ff
Some checks are pending
M6 deployable RC / quick (push) Waiting to run
M6 deployable RC / chromium (push) Blocked by required conditions
M6 deployable RC / release (push) Blocked by required conditions
Checkpoint web parity through Chromium input tasks
2026-08-19 10:39:03 -04:00

47 lines
2.9 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { expect, test } from "@playwright/test";
const root = path.resolve(import.meta.dirname, "../../..");
const source = fs.readFileSync(path.join(root, "tests/files/web/m12_glb_desktop_v1/mesh.glb"));
const maxBytes = 512 * 1024;
function rewriteJson(mutator: (document: any) => void): Buffer {
const jsonLength = source.readUInt32LE(12);
const document = JSON.parse(source.subarray(20, 20 + jsonLength).toString("utf8").trim());
mutator(document);
const json = Buffer.from(JSON.stringify(document));
const paddedLength = (json.length + 3) & ~3;
const output = Buffer.alloc(12 + 8 + paddedLength + (source.length - (20 + jsonLength)));
output.writeUInt32LE(0x46546c67, 0); output.writeUInt32LE(2, 4); output.writeUInt32LE(output.length, 8);
output.writeUInt32LE(paddedLength, 12); output.writeUInt32LE(0x4e4f534a, 16); json.copy(output, 20);
output.fill(0x20, 20 + json.length, 20 + paddedLength);
output.writeUInt32LE(source.readUInt32LE(20 + jsonLength), 20 + paddedLength);
output.writeUInt32LE(source.readUInt32LE(24 + jsonLength), 24 + paddedLength);
source.subarray(28 + jsonLength).copy(output, 28 + paddedLength);
return output;
}
test("rejects GLB sparse, extension, external URI and over-budget cases in a Chromium Worker", async ({ page }) => {
await page.goto("/");
const cases = [
{ id: "sparse", bytes: rewriteJson((document) => { document.accessors[0].sparse = { count: 1 }; }) },
{ id: "extension", bytes: rewriteJson((document) => { document.extensionsUsed = ["KHR_draco_mesh_compression"]; }) },
{ id: "external-uri", bytes: rewriteJson((document) => { document.buffers[0].uri = "external.bin"; }) },
{ id: "over-budget", bytes: Buffer.concat([source, Buffer.alloc(maxBytes + 1 - source.length)]) },
].map((candidate) => ({ id: candidate.id, bytes: Array.from(candidate.bytes) }));
const result = await page.evaluate((input) => new Promise<{ ok: boolean; results?: Array<{ id: string; code: string }>; error?: string }>((resolve, reject) => {
const worker = new Worker("/src/workers/glb-negative-cases-test.worker.ts", { type: "module" });
worker.onmessage = (event: MessageEvent<{ ok: boolean; results?: Array<{ id: string; code: string }>; error?: string }>) => { worker.terminate(); resolve(event.data); };
worker.onerror = (event) => { worker.terminate(); reject(new Error(event.message)); };
const cases = input.map((candidate) => ({ id: candidate.id, bytes: Uint8Array.from(candidate.bytes).buffer }));
worker.postMessage({ cases }, cases.map((candidate) => candidate.bytes));
}), cases);
expect(result).toEqual({ ok: true, results: [
{ id: "sparse", code: "GLB_SPARSE_ACCESSOR_UNSUPPORTED" },
{ id: "extension", code: "GLB_EXTENSION_UNSUPPORTED" },
{ id: "external-uri", code: "GLB_EXTERNAL_URI_BLOCKED" },
{ id: "over-budget", code: "GLB_IMPORT_BUDGET_EXCEEDED" },
] });
});