66 lines
2.6 KiB
JavaScript
66 lines
2.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { test } from "node:test";
|
|
import ts from "typescript";
|
|
import { parseHTML } from "linkedom";
|
|
|
|
const source = readFileSync(new URL("../src/player/cutscene.ts", import.meta.url), "utf8");
|
|
const { outputText } = ts.transpileModule(source, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext } });
|
|
const { cutscene } = await import(`data:text/javascript;base64,${Buffer.from(outputText).toString("base64")}`);
|
|
|
|
function setup(options = {}, blocked = false) {
|
|
const { document } = parseHTML("<!doctype html><html><body></body></html>");
|
|
globalThis.document = document;
|
|
const create = document.createElement.bind(document);
|
|
let starts = 0;
|
|
document.createElement = (name) => {
|
|
const element = create(name);
|
|
if (name === "video") {
|
|
element.play = () => { starts++; return blocked ? Promise.reject(new Error("gesture")) : Promise.resolve(); };
|
|
element.pause = () => {};
|
|
}
|
|
return element;
|
|
};
|
|
const movie = cutscene(document.body, "/film.webm", { delay: null, loops: 0, volume: 0.5, ...options });
|
|
return { ...movie, document, video: document.querySelector("video"), starts: () => starts };
|
|
}
|
|
|
|
test("a cutscene waits for its final loop and returns false on natural completion", async () => {
|
|
const movie = setup({ loops: 1 });
|
|
movie.video.onended();
|
|
assert.equal(movie.starts(), 2);
|
|
movie.video.onended();
|
|
assert.equal(await movie.finished, false);
|
|
movie.destroy();
|
|
assert.equal(movie.document.querySelector("video"), null);
|
|
});
|
|
|
|
test("clicking skips a cutscene and delay -1 holds its last frame", async () => {
|
|
const movie = setup({ delay: -1 });
|
|
movie.video.onended();
|
|
let resolved = false;
|
|
movie.finished.then(() => { resolved = true; });
|
|
await Promise.resolve();
|
|
assert.equal(resolved, false);
|
|
movie.document.querySelector(".pg-cutscene").onclick({ stopPropagation() {} });
|
|
assert.equal(await movie.finished, true);
|
|
movie.destroy();
|
|
});
|
|
|
|
test("a timed cutscene completes after playback starts", async () => {
|
|
const movie = setup({ delay: 0 });
|
|
movie.video.onplaying();
|
|
assert.equal(await movie.finished, false);
|
|
movie.destroy();
|
|
});
|
|
|
|
test("blocked autoplay offers a play button, and media errors fail explicitly", async () => {
|
|
const movie = setup({}, true);
|
|
await Promise.resolve();
|
|
assert.equal(movie.document.querySelector("button").hidden, false);
|
|
const failed = assert.rejects(movie.finished, /Не удалось воспроизвести/);
|
|
movie.video.onerror();
|
|
await failed;
|
|
movie.destroy();
|
|
});
|