mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
Record manifest-default features without adding A/B selection. Keep scored builds free of the optional function-name profiling switch. Exercise CLI persistence, interruption, browser failure and legacy page interactions through separate diagnostics. Share readable reports and warn when offline comparisons include failed runs. Validate with 50 focused tests, browser and CLI fault checks, two full corpus workflow runs, and headed rectangle cases. Shadow graphics and sampling calibration remain open. AI-assisted-by: GPT-6
164 lines
5.7 KiB
JavaScript
164 lines
5.7 KiB
JavaScript
// Unscored checks of the actual playground pages, including real pointer/wheel
|
|
// events. Expose the mounted adapter only in this diagnostic routing layer.
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { parseArgs } from "node:util";
|
|
import { chromium } from "playwright";
|
|
import { bounded } from "../renderer-benchmarks.js";
|
|
import { scenarios } from "../../resources/wasm-playground/scenes/index.js";
|
|
|
|
const { values } = parseArgs({
|
|
options: {
|
|
filter: { type: "string", default: "" },
|
|
headed: { type: "boolean", default: false },
|
|
},
|
|
});
|
|
const frontend = fileURLToPath(new URL("../../", import.meta.url));
|
|
const selected = scenarios.filter((s) => s.id.includes(values.filter));
|
|
assert.ok(selected.length, "No matching scenes");
|
|
const server = await chromium.launchServer({
|
|
headless: !values.headed,
|
|
args: ["--enable-gpu"],
|
|
});
|
|
const browser = await chromium.connect(server.wsEndpoint());
|
|
try {
|
|
for (const scenario of selected) {
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1920, height: 1080 },
|
|
deviceScaleFactor: 2,
|
|
});
|
|
try {
|
|
await bounded(
|
|
(async () => {
|
|
await context.route("http://benchmark.invalid/**", async (route) => {
|
|
const pathname = new URL(route.request().url()).pathname;
|
|
const base = path.join(
|
|
frontend,
|
|
pathname.startsWith("/wasm-playground/")
|
|
? "resources"
|
|
: "resources/public",
|
|
);
|
|
const target = path.resolve(base, `.${pathname}`);
|
|
if (!target.startsWith(`${base}/`)) return route.abort();
|
|
if (pathname === "/wasm-playground/js/lib.js") {
|
|
const source = await fs.readFile(target, "utf8");
|
|
await route.fulfill({
|
|
contentType: "text/javascript",
|
|
body:
|
|
source.replace(
|
|
"export async function mountScenario(",
|
|
"async function mountOriginalScenario(",
|
|
) +
|
|
`
|
|
export async function mountScenario(...args) {
|
|
const adapter = await mountOriginalScenario(...args);
|
|
const render = adapter.module._render;
|
|
const view = adapter.module._set_view;
|
|
globalThis.playgroundProbe = { full: 0, views: [] };
|
|
adapter.module._render = (...args) => {
|
|
const result = render(...args);
|
|
if (result === 2) globalThis.playgroundProbe.full++;
|
|
return result;
|
|
};
|
|
adapter.module._set_view = (...args) => {
|
|
globalThis.playgroundProbe.views.push(args);
|
|
return view(...args);
|
|
};
|
|
globalThis.playgroundAdapter = adapter;
|
|
return adapter;
|
|
}`,
|
|
});
|
|
} else {
|
|
try {
|
|
await route.fulfill({ path: target });
|
|
} catch {
|
|
await route.fulfill({
|
|
status: 404,
|
|
body: "Missing diagnostic asset",
|
|
});
|
|
}
|
|
}
|
|
});
|
|
const page = await context.newPage();
|
|
const errors = [];
|
|
page.on("pageerror", (error) => errors.push(error.message));
|
|
page.on("console", (message) => {
|
|
if (message.type() === "error") errors.push(message.text());
|
|
});
|
|
await page.goto(
|
|
`http://benchmark.invalid/wasm-playground/${scenario.id}.html?seed=42`,
|
|
);
|
|
await page.waitForFunction(
|
|
() =>
|
|
globalThis.playgroundAdapter || document.querySelector("#error"),
|
|
null,
|
|
{ timeout: 30000 },
|
|
);
|
|
assert.equal(
|
|
await page.locator("#error").count(),
|
|
0,
|
|
"page must mount successfully",
|
|
);
|
|
await page.mouse.move(800, 400);
|
|
await page.mouse.down();
|
|
await page.mouse.move(860, 430, { steps: 3 });
|
|
await page.mouse.up();
|
|
await page.waitForFunction(
|
|
() => globalThis.playgroundProbe.full >= 1,
|
|
);
|
|
await page.evaluate(() => {
|
|
globalThis.playgroundProbe.full = 0;
|
|
});
|
|
await page.mouse.wheel(0, -100);
|
|
await page.waitForFunction(
|
|
() => globalThis.playgroundProbe.full >= 1,
|
|
);
|
|
const state = await page.evaluate(() => ({
|
|
views: globalThis.playgroundProbe.views,
|
|
lost: document
|
|
.querySelector("canvas")
|
|
.getContext("webgl2")
|
|
.isContextLost(),
|
|
}));
|
|
assert.equal(state.lost, false);
|
|
assert.ok(
|
|
state.views.some(([scale, x]) => scale === 1 && x > 0),
|
|
"pointer drag must pan",
|
|
);
|
|
assert.ok(
|
|
state.views.some(([scale]) => scale > 1),
|
|
"wheel must zoom",
|
|
);
|
|
assert.deepEqual(errors, []);
|
|
await bounded(
|
|
page.evaluate(() => globalThis.playgroundAdapter.dispose()),
|
|
5000,
|
|
);
|
|
console.log(
|
|
`PASS ${scenario.id}: legacy mount, pan, zoom and disposal (unscored)`,
|
|
);
|
|
})(),
|
|
65000,
|
|
);
|
|
} catch (error) {
|
|
process.exitCode = 1;
|
|
console.error(`FAIL ${scenario.id}: ${error.stack ?? error}`);
|
|
} finally {
|
|
await bounded(context.close(), 5000);
|
|
}
|
|
}
|
|
} finally {
|
|
try {
|
|
await bounded(browser.close(), 5000);
|
|
} catch {
|
|
server.process()?.kill("SIGKILL");
|
|
}
|
|
try {
|
|
await bounded(server.close(), 5000);
|
|
} catch {
|
|
server.process()?.kill("SIGKILL");
|
|
}
|
|
}
|