Checkpoint web parity through Chromium input tasks
This commit is contained in:
62
web/tests/e2e/stl-edge-parity.spec.ts
Normal file
62
web/tests/e2e/stl-edge-parity.spec.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
const root = path.resolve(import.meta.dirname, "../../..");
|
||||
const edgeRoot = path.join(root, "tests/files/web/m12_stl_edges_v1");
|
||||
const capabilityRoot = path.join(root, "tests/files/web/m12_stl_capability_v1");
|
||||
const desktop = JSON.parse(fs.readFileSync(path.join(root, "tests/golden/M12-07E/desktop-edge-report.json"), "utf8"));
|
||||
const desktopCanonical = JSON.parse(JSON.stringify(desktop));
|
||||
const reportPath = path.join(root, "tests/golden/M12-07E/web-edge-report.json");
|
||||
|
||||
test("M12-07E compares STL normal/unit/degenerate/trailing behavior in Chromium and Blender", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
const fixtures = [
|
||||
{ id: "BINARY_UNIT_1", bytes: Array.from(fs.readFileSync(path.join(edgeRoot, "capability-binary.stl"))), variant: "STL_BINARY", unitScale: 1 },
|
||||
{ id: "BINARY_UNIT_001", bytes: Array.from(fs.readFileSync(path.join(edgeRoot, "capability-binary.stl"))), variant: "STL_BINARY", unitScale: 0.001 },
|
||||
{ id: "ASCII_UNIT_1", bytes: Array.from(fs.readFileSync(path.join(capabilityRoot, "capability-ascii.stl"))), variant: "STL_ASCII", unitScale: 1 },
|
||||
{ id: "DEGENERATE_TRIANGLE", bytes: Array.from(fs.readFileSync(path.join(edgeRoot, "degenerate-binary.stl"))), variant: "STL_BINARY", unitScale: 1 },
|
||||
{ id: "TRAILING_BYTES", bytes: Array.from(fs.readFileSync(path.join(edgeRoot, "trailing-binary.stl"))), variant: "STL_BINARY", unitScale: 1 },
|
||||
];
|
||||
const browser = await page.evaluate(async (input) => new Promise<any>((resolve, reject) => {
|
||||
const worker = new Worker("/src/workers/stl-edge-test.worker.ts", { type: "module" });
|
||||
worker.onmessage = (event: MessageEvent<any>) => { worker.terminate(); resolve(event.data); };
|
||||
worker.onerror = (event) => { worker.terminate(); reject(new Error(event.message)); };
|
||||
const cases = input.map((candidate) => ({ ...candidate, bytes: Uint8Array.from(candidate.bytes).buffer }));
|
||||
worker.postMessage({ cases }, cases.map((candidate) => candidate.bytes));
|
||||
}), fixtures);
|
||||
expect(browser.ok).toBe(true);
|
||||
const byId = Object.fromEntries(browser.results.map((result: any) => [result.id, result]));
|
||||
const desktopById = Object.fromEntries(desktop.cases.map((result: any) => [result.id, result]));
|
||||
expect(byId.TRAILING_BYTES).toEqual({ id: "TRAILING_BYTES", status: "BLOCKED", code: "STL_TRAILING_BYTES" });
|
||||
const unitOne = byId.BINARY_UNIT_1.result.bounds.max[0];
|
||||
const unitSmall = byId.BINARY_UNIT_001.result.bounds.max[0];
|
||||
const desktopUnitOne = desktopById.BINARY_UNIT_1.result.bounds.max[0];
|
||||
const desktopUnitSmall = desktopById.BINARY_UNIT_001.result.bounds.max[0];
|
||||
const report = {
|
||||
schemaVersion: 1,
|
||||
task: "M12-07E",
|
||||
operation: "STL_NORMAL_UNIT_EDGE_PARITY",
|
||||
browser: browser.results,
|
||||
desktop: desktopCanonical,
|
||||
comparisons: {
|
||||
binaryAsciiNormalExact: JSON.stringify(byId.BINARY_UNIT_1.result.normals) === JSON.stringify(byId.ASCII_UNIT_1.result.normals),
|
||||
desktopNormalExact: JSON.stringify(byId.BINARY_UNIT_1.result.normals) === JSON.stringify(desktopById.BINARY_UNIT_1.result.polygonNormals),
|
||||
webUnitRatio: unitOne / unitSmall,
|
||||
desktopUnitRatio: desktopUnitOne / desktopUnitSmall,
|
||||
unitRatioExactWithinFloat32: Math.abs(unitOne / unitSmall - desktopUnitOne / desktopUnitSmall) < 0.001,
|
||||
degenerateTriangleExact: byId.DEGENERATE_TRIANGLE.result.triangleCount === desktopById.DEGENERATE_TRIANGLE.result.triangleCount && byId.DEGENERATE_TRIANGLE.result.removedDegenerateTriangles === 1,
|
||||
trailingBytes: { web: "BLOCKED/STL_TRAILING_BYTES", desktop: "ACCEPTED_EMPTY", parity: "STRICTER_WEB_BLOCK" },
|
||||
},
|
||||
nextTask: "M12-07F",
|
||||
};
|
||||
if (process.env.UPDATE_STL_EDGE_REPORT === "1") {
|
||||
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
|
||||
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2) + "\n");
|
||||
}
|
||||
expect(report).toEqual(JSON.parse(fs.readFileSync(reportPath, "utf8")));
|
||||
expect(report.comparisons.binaryAsciiNormalExact).toBe(true);
|
||||
expect(report.comparisons.desktopNormalExact).toBe(true);
|
||||
expect(report.comparisons.unitRatioExactWithinFloat32).toBe(true);
|
||||
expect(report.comparisons.degenerateTriangleExact).toBe(true);
|
||||
});
|
||||
Reference in New Issue
Block a user