Commit 8be26fb8 by PLN (Algolia)

fix(slop): refuse to capture a scrim — PARTIAL, a second modal is still in the way

The 19 bake-off clips all shipped with the photosensitivity warning sitting on
top of the visuals. PLN: "lol all clips have the epilepsy warning on top of the
viz xD and all seem to have very low fps, like maybe 5 ?"

Extracting a frame showed one cause behind all three symptoms: the warning modal
itself; the app's full UI chrome still visible (FX rail, top bar, shortcut strip)
because the modal swallowed the "minimal performance shell" click and the `h`
keypress; and the apparent ~5 fps, because ~90% of every frame was static chrome
behind a dark scrim while 17.6 frames/s were captured faithfully. The frame rate
was never the problem — I had measured it correctly and drawn the wrong picture
of what was being measured.

Seeding localStorage does NOT suppress it: hexa installs a dev-only bridge that
persists localStorage to disk through the dev server and calls
`hydrateLocalStorageFromDisk()` at boot, overwriting anything an init script
seeded. Verified by trapping `Storage.prototype.setItem` and reading the stack —
the write came from `localStorageBridge.ts:150`. So use the app's own control:
uncheck "Show this warning at startup", click OK, which writes through the bridge
and flushes to disk.

PARTIAL, deliberately. The new guard now throws rather than capturing, and on the
next run it caught a SECOND modal behind the first: "START A SESSION". So the
bake-off clips were not slow — the scene had never started. Committing the guard
alone because it is strictly better than silently shipping 19 more scrims, and
refusing loudly is the behaviour worth having even before the fix is complete.

Still to do (see the task board): a `git pull` brought 50 commits that also
inverted the mode semantics — `?studio=1` is now stripped and Studio is the
DEFAULT, with `?live=1` opting into the full-bleed performance shell; Studio
freezes shader time when `studioTransportActive === false`, which is the other
half of "no motion"; and the "Minimal performance shell" button this script
clicks no longer exists at all.
parent 05c8ab30
......@@ -325,6 +325,50 @@ try {
await page.goto(`${BASE}/`, { waitUntil: "domcontentloaded", timeout: 60000 });
await page.waitForSelector("#hydra-canvas", { timeout: 30000 });
// ------------------------------------------------------------------------
// Dismiss the photosensitivity modal, or refuse to capture.
//
// The first bake-off shipped 19 clips with this warning sitting on top of the
// visuals. It cost three symptoms from one cause: the warning itself; the app
// chrome staying visible (the FX rail, the top bar, the shortcut strip),
// because the modal swallowed the "minimal performance shell" click and the
// `h` keypress; and an apparent ~5 fps, because ~90% of every frame was static
// UI behind a dark scrim while 17.6 frames/s were being captured faithfully.
//
// It is a Radix Dialog with `hideClose`, `onEscapeKeyDown` prevented and
// `onPointerDownOutside` prevented, so its OK button is the ONLY exit.
//
// Seeding `localStorage` does not work: hexa installs a DEV-ONLY bridge
// (`localStorageBridge.ts`) that persists localStorage to disk through the dev
// server and calls `hydrateLocalStorageFromDisk()` at boot, which overwrites
// anything an init script seeded — verified by trapping `setItem` and reading
// the stack. So use the app's own control: UNCHECK "Show this warning at
// startup" and click OK. That writes "false" through the bridge, which flushes
// to disk, so later renders start clean too.
for (let attempt = 0; attempt < 3; attempt++) {
if (!(await page.locator('[role="dialog"]').count())) break;
// Uncheck first, while the dialog is still open — after OK it is gone.
const box = page.locator('[role="dialog"] input[type="checkbox"]').first();
if (await box.count()) {
await box.uncheck({ timeout: 3000 }).catch(() => {});
}
const ok = page.locator('[role="dialog"]')
.getByRole("button", { name: /^ok$/i }).first();
if (await ok.count()) await ok.click({ timeout: 3000 }).catch(() => {});
await sleep(700);
}
// Verify, do not assume. A blind click would let 30 s of scrim be captured,
// and that is exactly the failure this whole block exists to undo.
const stuck = await page.locator('[role="dialog"]').count();
if (stuck) {
const what = await page.locator('[role="dialog"]').first().innerText()
.catch(() => "?");
throw new Error(
`a modal dialog is still covering the canvas (${stuck}): `
+ `${what.replace(/\s+/g, " ").slice(0, 80)}\n`
+ ` refusing to capture ${job.dur}s of a scrim.`);
}
await page.waitForFunction(
() => typeof window.__hydraApplyScene === "function", { timeout: 30000 });
await page.waitForFunction(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment