Files
DOSSIER-STANDALONE/scripts/probe-engine-parity.mjs
T
karim 23410f9b9e 2D-Engine-Parität: WASM-Pfad rendert deckungsgleich zum SVG-Referenzpfad
Sechs Lücken geschlossen: Text-Massstab vom Geometrie-Massstab entkoppelt
(set_text_scale, spiegelt SVG-Referenzskala); glyphon auf ColorMode::Web
(Text war linear-konvertiert zu dunkel); z-basierte Maler-Reihenfolge
(interleavte draw_sequence statt fills-vor-lines, Alt-Szenen unverändert);
CSS-Klassenfarben/-Opacities in toRenderScene gespiegelt (Türschwenk etc.);
greyed-Dimmung 0.3 auf allen Primitiven; Dämmschraffur am Modell-Ursprung
verankert (userSpaceOnUse), exakte Bézier-Wellenform statt Sinus und
kachelgekoppelte Strichbreite (widthScreen-Modus). Probe
scripts/probe-engine-parity.mjs vergleicht ?gl=0 gegen ?engine=wasm;
Rest-Diff nur AA/Glyphen-Rasterung. cargo 17/17, vitest 94/94, Builds grün.
2026-07-03 08:17:01 +02:00

61 lines
2.2 KiB
JavaScript

// Vergleicht den SVG-Referenzpfad gegen den nativen render2d-WASM/WebGPU-Pfad
// (?engine=wasm): lädt die App einmal ohne Engine-Param (SVG) und einmal mit
// ?engine=wasm, gleicher Viewport/Zoom, schießt je einen Screenshot. Prüft
// zusätzlich, ob WebGPU verfügbar ist und der native Renderer tatsächlich
// initialisiert hat (statt still auf SVG zurückzufallen).
import puppeteer from "puppeteer";
const BASE = process.env.PROBE_URL || "http://localhost:5187/";
const browser = await puppeteer.launch({
headless: "new",
args: [
"--no-sandbox",
"--enable-unsafe-webgpu",
"--enable-features=Vulkan",
"--use-angle=vulkan",
"--ignore-gpu-blocklist",
],
});
async function shoot(url, path, tag) {
const page = await browser.newPage();
await page.setViewport({ width: 1400, height: 900, deviceScaleFactor: 1 });
const logs = [];
page.on("console", (m) => logs.push(`[${m.type()}] ${m.text()}`));
page.on("pageerror", (e) => logs.push(`[PAGEERROR] ${e.message}`));
try {
await page.goto(url, { waitUntil: "networkidle0", timeout: 30000 });
} catch (e) {
logs.push(`[GOTO] ${e.message}`);
}
// Warten, bis Plan + evtl. WASM/WebGPU-Renderer initialisiert und gezeichnet hat.
await new Promise((r) => setTimeout(r, 2500));
const info = await page.evaluate(() => {
const svg = document.querySelector(".plan-svg");
const canvases = document.querySelectorAll("canvas");
return {
hasGpu: typeof navigator !== "undefined" && "gpu" in navigator,
hasSvg: !!svg,
svgChildren: svg ? svg.querySelectorAll("path,polygon,polyline,line,rect,text").length : 0,
canvasCount: canvases.length,
};
});
await page.screenshot({ path });
console.log(`\n=== ${tag} (${url}) ===`);
console.log(JSON.stringify(info, null, 2));
const warns = logs.filter((l) => /warn|error|PAGEERROR/i.test(l));
console.log("Warnungen/Fehler:", warns.length ? "\n" + warns.join("\n") : "(keine)");
await page.close();
return info;
}
await shoot(BASE + "?gl=0", "scripts/probe-parity-svg.png", "SVG-Referenzpfad");
await shoot(BASE + "?engine=wasm", "scripts/probe-parity-wasm.png", "WASM/WebGPU-Engine");
await browser.close();
console.log("\nScreenshots: scripts/probe-parity-svg.png vs scripts/probe-parity-wasm.png");