143 lines
4.4 KiB
TypeScript
143 lines
4.4 KiB
TypeScript
import { expect, test } from "../helpers/serve-dist";
|
|
import {
|
|
assertSemanticFaultOracle,
|
|
authorizedFaultUrl,
|
|
collectBrowserErrors,
|
|
readUnhandledRejections,
|
|
triggerFaultAction,
|
|
} from "../helpers/test-build-auth";
|
|
import {
|
|
installSceneInstrumentation,
|
|
readSceneInstrumentation,
|
|
} from "../helpers/scene-instrumentation";
|
|
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
test.skip(
|
|
testInfo.project.name !== "desktop-chromium",
|
|
"Audio fault matrix runs once on current desktop Chromium.",
|
|
);
|
|
await installSceneInstrumentation(page);
|
|
});
|
|
|
|
const startAudio = async (
|
|
page: import("@playwright/test").Page,
|
|
): Promise<void> => {
|
|
await page.getByRole("button", { name: "PLAY SOUNDTRACK" }).click();
|
|
};
|
|
|
|
const assertAudioContained = async (
|
|
page: import("@playwright/test").Page,
|
|
pageErrors: readonly string[],
|
|
expectedLiveContexts: number,
|
|
): Promise<void> => {
|
|
await assertSemanticFaultOracle(page);
|
|
expect(pageErrors).toEqual([]);
|
|
expect(await readUnhandledRejections(page)).toEqual([]);
|
|
const resources = await readSceneInstrumentation(page);
|
|
expect(resources.unhandledRejections).toEqual([]);
|
|
expect(resources.audioContextsConstructed).toBe(1);
|
|
expect(resources.liveAudioContexts).toBe(expectedLiveContexts);
|
|
};
|
|
|
|
test("F10 contains initial Web Audio start rejection and creates no reusable graph", async ({
|
|
page,
|
|
distUrl,
|
|
}) => {
|
|
const errors = await collectBrowserErrors(page);
|
|
await page.goto(authorizedFaultUrl(distUrl, "F10-audio-start-rejection"), {
|
|
waitUntil: "domcontentloaded",
|
|
});
|
|
await startAudio(page);
|
|
|
|
await expect(
|
|
page.getByText("Audio unavailable. Continue without sound."),
|
|
).toBeVisible();
|
|
await expect(
|
|
page.getByRole("button", { name: "PLAY SOUNDTRACK" }),
|
|
).toHaveCount(0);
|
|
await assertSemanticFaultOracle(page);
|
|
expect(errors.pageErrors).toEqual([]);
|
|
expect(await readUnhandledRejections(page)).toEqual([]);
|
|
expect((await readSceneInstrumentation(page)).audioContextsConstructed).toBe(
|
|
0,
|
|
);
|
|
});
|
|
|
|
test("F11 keeps an interrupted intact graph suspended after resume rejection", async ({
|
|
page,
|
|
distUrl,
|
|
}) => {
|
|
const errors = await collectBrowserErrors(page);
|
|
await page.goto(authorizedFaultUrl(distUrl, "F11-audio-resume-rejection"), {
|
|
waitUntil: "domcontentloaded",
|
|
});
|
|
await startAudio(page);
|
|
await expect(page.getByRole("button", { name: "Mute sound" })).toBeVisible();
|
|
|
|
await triggerFaultAction(page, "audio-interruption");
|
|
await expect(
|
|
page.getByRole("button", { name: "Resume sound" }),
|
|
).toBeVisible();
|
|
await page.getByRole("button", { name: "Resume sound" }).click();
|
|
|
|
await expect(
|
|
page.getByRole("button", { name: "Resume sound" }),
|
|
).toBeVisible();
|
|
await expect(
|
|
page.getByText("Audio unavailable. Continue without sound."),
|
|
).toHaveCount(0);
|
|
await assertAudioContained(page, errors.pageErrors, 1);
|
|
});
|
|
|
|
test("F12 tears down a graph that becomes invalid during resume", async ({
|
|
page,
|
|
distUrl,
|
|
}) => {
|
|
const errors = await collectBrowserErrors(page);
|
|
await page.goto(authorizedFaultUrl(distUrl, "F12-audio-graph-invalid"), {
|
|
waitUntil: "domcontentloaded",
|
|
});
|
|
await startAudio(page);
|
|
await triggerFaultAction(page, "audio-interruption");
|
|
await expect(
|
|
page.getByRole("button", { name: "Resume sound" }),
|
|
).toBeVisible();
|
|
await page.getByRole("button", { name: "Resume sound" }).click();
|
|
|
|
await expect(
|
|
page.getByText("Audio unavailable. Continue without sound."),
|
|
).toBeVisible();
|
|
await expect
|
|
.poll(async () => (await readSceneInstrumentation(page)).liveAudioContexts)
|
|
.toBe(0);
|
|
await assertAudioContained(page, errors.pageErrors, 0);
|
|
});
|
|
|
|
test("F13 synchronously silences and closes the graph when hide-time suspend rejects", async ({
|
|
page,
|
|
distUrl,
|
|
}) => {
|
|
const errors = await collectBrowserErrors(page);
|
|
await page.goto(authorizedFaultUrl(distUrl, "F13-audio-suspend-rejection"), {
|
|
waitUntil: "domcontentloaded",
|
|
});
|
|
await startAudio(page);
|
|
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(
|
|
page.getByText("Audio unavailable. Continue without sound."),
|
|
).toBeVisible();
|
|
await expect
|
|
.poll(async () => (await readSceneInstrumentation(page)).liveAudioContexts)
|
|
.toBe(0);
|
|
await assertAudioContained(page, errors.pageErrors, 0);
|
|
});
|