Files
mrleo1nid 11d769f466
CI / frontend (push) Failing after 18s
CI / backend (push) Failing after 34s
fix: handle MIST movie timer actions and verify skipping
2026-10-26 22:41:19 +03:00

99 lines
4.6 KiB
JavaScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "node:test";
import { makeEngine, until } from "./helpers/renpy-engine.mjs";
const original = process.env.PGAMES_MIST_RUNTIME;
const runtime = original ? JSON.parse(readFileSync(original, "utf8")) : null;
const click = (element) => element.onclick({ stopPropagation() {}, preventDefault() {} });
const enter = (engine, label) => engine.restart(() => engine.guardedJump(label));
test("MIST's actual movie Skip survives a queued redraw and returns before its timer", { skip: !runtime }, async () => {
const { engine, root, window } = makeEngine(runtime);
globalThis.HTMLVideoElement = window.HTMLVideoElement ?? class {};
const played = [], stopped = [];
engine.audio.play = (...args) => played.push(args);
engine.audio.stop = (...args) => stopped.push(args);
engine.audio.mediaOf = () => null;
try {
engine.newStore();
Object.assign(engine.store, { movielength: 63, movieplaying: "images/animations/movies/Intro_Movie.webm" });
const completed = engine.exec({ op: "call_screen", name: "custommoviescreen", args: [], kw: {} });
await until(() => root.querySelector(".pg-sadd")?.dataset.seen);
const button = [...root.querySelectorAll(".pg-sbtn")].find((element) => element.textContent === "Skip");
assert.ok(button);
assert.equal(button.classList.contains("pg-sdisabled"), false);
engine.screens.refresh();
window.dispatchEvent(new window.Event("pointerdown"));
const remaining = engine.store.movielength;
await until(() => engine.store.movielength < remaining);
assert.equal(button.isConnected, true);
window.dispatchEvent(new window.Event("pointerup"));
click(button);
await completed;
assert.equal(engine.store._return, 0);
assert.ok(engine.store.movielength > 60, "Skip returns without waiting for the movie timer");
assert.equal(root.querySelector(".pg-sbtn"), null);
assert.equal(played[0][0], "movie");
assert.equal(stopped.at(-1)[0], "movie");
} finally {
window.dispatchEvent(new window.Event("pointercancel"));
engine.destroy();
}
});
test("MIST's actual raise-hand loop accepts screen input and resumes after a save", { skip: !runtime }, async () => {
const { engine, root } = makeEngine(runtime);
try {
engine.newStore();
engine.store.keysqte = false;
engine.store.last_pressed = "";
engine.store.player_name = "Player";
enter(engine, "raisehand_label");
await until(() => engine.screens.interactionReturn && root.querySelector(".pg-simgbtn"));
for (let i = 0; i < 5; i++) {
click(root.querySelector(".pg-simgbtn"));
await until(() => engine.screens.interactionReturn);
}
const position = engine.store.object_pos;
assert.ok(position < 600 && position > 50);
const save = structuredClone(engine.snapshotState());
engine.restart(() => engine.applySave(save));
await until(() => engine.screens.interactionReturn);
assert.equal(engine.store.object_pos, position);
for (let i = 0; i < 30 && engine.store.object_pos > 50; i++) {
click(root.querySelector(".pg-simgbtn"));
await until(() => engine.screens.interactionReturn || engine.store.object_pos === 50);
}
assert.equal(engine.store.object_pos, 50);
} finally { engine.destroy(); }
});
test("MIST's actual QTE timer reaches the loss branch", { skip: !runtime }, async () => {
const { engine } = makeEngine(runtime);
try {
engine.newStore();
Object.assign(engine.store, { timer_on: true, keysqte: false, object_pos: 301, lose_pos: 300, finish_pos: 1600, last_pressed: "" });
engine.screens.show("game_scr");
enter(engine, "game_loop");
await until(() => engine.store.timer_on === false);
assert.ok(engine.store.object_pos <= 300);
assert.equal(engine.cur.label, "qte_lose");
} finally { engine.destroy(); }
});
test("MIST's actual QTE accepts alternating keys and reaches the win branch", { skip: !runtime }, async () => {
const { engine, root } = makeEngine(runtime);
try {
engine.newStore();
Object.assign(engine.store, { timer_on: true, keysqte: false, object_pos: 1590, lose_pos: 300, finish_pos: 1600, last_pressed: "q" });
engine.screens.show("game_scr");
enter(engine, "game_loop");
await until(() => engine.screens.interactionReturn && root.querySelectorAll(".pg-simgbtn").length === 2);
click(root.querySelectorAll(".pg-simgbtn")[1]);
await until(() => engine.store.timer_on === false);
assert.ok(engine.store.object_pos >= 1600);
assert.equal(engine.cur.label, "qte_win");
} finally { engine.destroy(); }
});