feat(sim): audio on/off toggle -> 0-10 level dial; first video lifts it to 3/10
Operator request. Replaces the Audio checkbox with a 0-10 range slider that sets the master soundtrack gain (audioVol = level/10), scaling both the per-scale rest volume and the two-track scrub crossfade. Level 0 = silent. Turning Video on for the first time now raises audio to 3/10 (was: full on) so the experience opens gently; raising the slider from 0 unlocks playback in-gesture (Safari). E2E: dial is range 0-10 default 0, and first video-on lifts it to 3/10. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,13 +29,13 @@ async function wheelOnStage(page: Page, deltaY: number) {
|
||||
await page.locator("#stage").dispatchEvent("wheel", { deltaY });
|
||||
}
|
||||
|
||||
// The Audio toggle is a visually-hidden checkbox styled as a switch; set it + fire
|
||||
// `change` directly (headless Chromium relaxes the autoplay gesture requirement).
|
||||
// The Audio control is a 0–10 level slider; set it to full + fire `input` directly
|
||||
// (headless Chromium relaxes the autoplay gesture requirement).
|
||||
async function enableAudio(page: Page) {
|
||||
await page.evaluate(() => {
|
||||
const c = document.querySelector("#audio") as HTMLInputElement;
|
||||
c.checked = true;
|
||||
c.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
c.value = "10";
|
||||
c.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,6 +55,27 @@ test("two audio elements exist for crossfade", async ({ page }) => {
|
||||
expect(n).toBe(2);
|
||||
});
|
||||
|
||||
test("audio is a 0-10 level dial, defaulting to 0", async ({ page }) => {
|
||||
await boot(page);
|
||||
const ctl = await page.evaluate(() => {
|
||||
const c = document.querySelector("#audio") as HTMLInputElement;
|
||||
return { type: c.type, min: c.min, max: c.max, value: c.value };
|
||||
});
|
||||
expect(ctl.type).toBe("range");
|
||||
expect(ctl.min).toBe("0");
|
||||
expect(ctl.max).toBe("10");
|
||||
expect(ctl.value).toBe("0"); // silent until raised
|
||||
});
|
||||
|
||||
test("turning video on for the first time lifts audio to 3/10", async ({ page }) => {
|
||||
await boot(page);
|
||||
expect(await page.evaluate(() => (document.querySelector("#audio") as HTMLInputElement).value)).toBe("0");
|
||||
await enableVideo(page); // first video-on couples audio at a gentle level
|
||||
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");
|
||||
});
|
||||
|
||||
test("dragging the dial scrubs morph currentTime and audio gains", async ({ page }) => {
|
||||
await boot(page);
|
||||
await enableAudio(page); // hidden custom toggle → set + dispatch change
|
||||
|
||||
Reference in New Issue
Block a user