Miguel de Benito Delgado 731bcc5664 🎉 Add playground renderer benchmark suite
Share seven deterministic fixtures with the playground pages and measure
renderer lifecycle, pan, and zoom through a prepared Playwright runner.
Retain raw attempts and failures with offline statistical comparisons.

Add focused tests and separate browser fault diagnostics. Full-suite
calibration and shadow GPU validation remain tracked follow-up work.

AI-assisted-by: GPT-6
2026-10-28 19:17:38 +01:00

98 lines
2.7 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import {
drain,
interact,
restore,
} from "../../../resources/wasm-playground/benchmarks/protocol.js";
function runtime(results) {
let time = 0;
const flags = [];
return {
flags,
now: () => time,
frame: async () => (time += 16),
sleep: async (ms) => {
time += ms;
},
check: () => {},
module: {
_render: (_timestamp, flag) => {
flags.push(flag);
time += 2;
return results.shift();
},
_set_view_start: () => {
time += 1;
},
_set_view: () => {
time += 1;
},
_render_from_cache: () => {
time += 2;
},
_set_view_end: () => {
time += 5;
},
},
};
}
test("progressive rendering retains returned states and stops at Full", async () => {
const rt = runtime([1, 3, 2]);
const result = await drain(rt, { flags: 0 });
assert.deepEqual(rt.flags, [0, 1, 3]);
assert.equal(result.slices.length, 3);
assert.ok(result.viewportReadyMs < result.fullMs);
});
test("immediate Full supplies both completion boundaries", async () => {
const result = await drain(runtime([2]));
assert.equal(result.viewportReadyMs, result.fullMs);
});
test("Partial can finish directly at Full without ViewportReady", async () => {
const rt = runtime([1, 2]);
const result = await drain(rt);
assert.deepEqual(rt.flags, [0, 1]);
assert.equal(result.viewportReadyMs, result.fullMs);
});
test("preparation drains to Full and applies SyncTiles only initially", async () => {
const rt = runtime([1, 3, 2]);
const result = await restore(rt, { scale: 1, x: 0, y: 0 });
assert.deepEqual(rt.flags, [4, 1, 3]);
assert.equal(result.slices.at(-1).frameType, 2);
});
test("None and unknown frame types fail explicitly", async () => {
for (const frame of [0, 7, NaN]) {
await assert.rejects(drain(runtime([frame])), /frame type/);
}
});
test("finalization includes set_view_end but separates the settling delay", async () => {
const rt = runtime([3, 2]);
const result = await interact(rt, {
frames: [{ scale: 1, x: 3, y: 4 }],
settleMs: 100,
});
assert.equal(result.metrics.setViewEndMs, 5);
assert.equal(result.metrics.settlingActualMs, 100);
assert.ok(result.metrics.timeToViewportReadyMs >= 7);
assert.ok(
result.metrics.lastInputToFullMs >= 100 + result.metrics.timeToFullMs,
);
assert.deepEqual(rt.flags, [4, 3]);
});
test("cancellation stops further progressive work", async () => {
const rt = runtime([1, 2]);
rt.check = () => {
if (rt.flags.length) throw new Error("Canceled");
};
await assert.rejects(drain(rt), /Canceled/);
assert.equal(rt.flags.length, 1);
});