From e5fe00e948aa60ad327a86c57b5c1b17cb99c6f1 Mon Sep 17 00:00:00 2001 From: BenStullsBets Date: Tue, 30 Jun 2026 06:31:38 -0700 Subject: [PATCH] =?UTF-8?q?fix(sim):=20boot=20silent=20(video=20off,=20aud?= =?UTF-8?q?io=200)=20=E2=80=94=20no=20un-gestured=20auto-start?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The post-load autoStart() flipped Video on and lifted audio to 3/10 with no user gesture. Browser autoplay policy blocks an audio play() made outside a gesture (muted video survives, sound does not), so auto-start showed video but stayed silent. Boot SILENT instead and wait for the operator to turn Video on — that click IS the gesture, and its handler couples audio to 3/10 and starts the soundtrack in-gesture, so sound reliably comes up with video. Updates the pytest e2e + Playwright e2e specs to assert boot-silent + the video-on-couples-audio wiring instead of the old auto-start wiring. Co-Authored-By: Claude Opus 4.8 (1M context) --- simulator/e2e/tests/altitude-lock.spec.ts | 11 +++--- simulator/static/app.js | 20 ++++------- tests/test_e2e_audio.py | 43 ++++++++++++++++------- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/simulator/e2e/tests/altitude-lock.spec.ts b/simulator/e2e/tests/altitude-lock.spec.ts index 4c9c3d9..a6da1d3 100644 --- a/simulator/e2e/tests/altitude-lock.spec.ts +++ b/simulator/e2e/tests/altitude-lock.spec.ts @@ -83,13 +83,14 @@ test("audio is a 0-10 level dial", async ({ page }) => { expect(ctl.max).toBe("10"); }); -test("the experience auto-starts once loaded: video on + audio at 3/10", async ({ page }) => { +test("boots silent (video off, audio 0); turning video on couples audio to 3/10", async ({ page }) => { await boot(page); - // No gesture needed — autoStart() flips Video on and lifts audio to a gentle level - // the moment the preload finishes. - await expect.poll(() => page.evaluate(() => (document.querySelector("#visual") as HTMLInputElement).checked)).toBe(true); + // Boots SILENT — no un-gestured auto-start, so the browser autoplay block never bites. + expect(await page.evaluate(() => (document.querySelector("#visual") as HTMLInputElement).checked)).toBe(false); + expect(await page.evaluate(() => (document.querySelector("#audio") as HTMLInputElement).value)).toBe("0"); + // Turning Video on (a click gesture) lifts the audio dial to a gentle 3/10. + await enableVideo(page); await expect.poll(() => page.evaluate(() => (document.querySelector("#audio") as HTMLInputElement).value)).toBe("3"); - // The level label reflects it. expect(await page.evaluate(() => document.querySelector("#audio-level-val")?.textContent)).toBe("3"); }); diff --git a/simulator/static/app.js b/simulator/static/app.js index dbe005e..7fe28d1 100644 --- a/simulator/static/app.js +++ b/simulator/static/app.js @@ -1260,8 +1260,12 @@ async function main() { $("stage").addEventListener("wheel", onWheel, { passive: false }); update(); // render the initial state (both toggles off → black, silent) await preloadAllMedia(); // download all media, updating the loading bar - hideLoading(); // experience is ready to run smoothly - autoStart(); // once loaded: video on + gentle audio (3/10), no gesture needed + hideLoading(); // experience is ready — boots SILENT (video off, audio 0) + // No un-gestured auto-start: a browser autoplay policy blocks an audio play() made + // outside a user gesture (muted video survives, sound does not), so an auto-start + // would show video but stay silent. Instead the experience waits for the operator to + // turn Video on — that click IS the gesture, and its handler (above) lifts audio to + // 3/10 and starts the soundtrack in-gesture, so sound reliably comes up with video. } // Populate the language dropdown from the registry and wire live switching. @@ -1297,16 +1301,4 @@ function setLanguage(lang) { if (lastAffect) renderAffect(lastAffect.strength, lastAffect.intensity, lastAffect.right); } -// Auto-start the experience the moment media is ready: bring Video on and the audio -// level to 3/10 (the same gentle default the first manual Video-on couples in). The -// audio