feat: integrate authored nightdrive soundtrack

This commit is contained in:
2026-09-04 14:39:28 +03:00
parent eb7f276b91
commit 745fa8169e
39 changed files with 1013 additions and 714 deletions

View File

@@ -7,6 +7,8 @@ test.beforeEach(async ({ page }) => {
0;
(window as unknown as { __audioContexts: AudioContext[] }).__audioContexts =
[];
(window as unknown as { __audioResumeCalls: number }).__audioResumeCalls = 0;
(window as unknown as { __audioSuspendCalls: number }).__audioSuspendCalls = 0;
if (!OriginalAudioContext) return;
class TrackingAudioContext extends OriginalAudioContext {
constructor(options?: AudioContextOptions) {
@@ -18,6 +20,14 @@ test.beforeEach(async ({ page }) => {
state.__audioConstructed += 1;
state.__audioContexts.push(this);
}
override resume(): Promise<void> {
(window as unknown as { __audioResumeCalls: number }).__audioResumeCalls += 1;
return super.resume();
}
override suspend(): Promise<void> {
(window as unknown as { __audioSuspendCalls: number }).__audioSuspendCalls += 1;
return super.suspend();
}
}
Object.defineProperty(window, "AudioContext", {
configurable: true,
@@ -238,6 +248,35 @@ test("requires a direct visitor action after browser interruption without creati
.toBe(1);
});
test("automatically suspends and resumes the same graph across ordinary visibility changes", async ({
page,
distUrl,
}) => {
await page.goto(distUrl, { waitUntil: "domcontentloaded" });
await page.getByRole("button", { name: "Play soundtrack" }).click();
await expect(page.getByRole("button", { name: "Mute sound" })).toBeVisible();
await page.evaluate(() => {
Object.defineProperty(document, "visibilityState", { configurable: true, value: "hidden" });
document.dispatchEvent(new Event("visibilitychange"));
});
await expect.poll(() => page.evaluate(() => (
window as unknown as { __audioSuspendCalls: number }
).__audioSuspendCalls)).toBe(1);
await page.evaluate(() => {
Object.defineProperty(document, "visibilityState", { configurable: true, value: "visible" });
document.dispatchEvent(new Event("visibilitychange"));
});
await expect.poll(() => page.evaluate(() => (
window as unknown as { __audioResumeCalls: number }
).__audioResumeCalls)).toBe(2);
expect(await page.evaluate(() => (
window as unknown as { __audioConstructed: number }
).__audioConstructed)).toBe(1);
await expect(page.getByRole("button", { name: "Mute sound" })).toBeVisible();
});
test("shows a concise non-blocking message when initial audio start is rejected", async ({
page,
distUrl,