orbit/dev/queue-celebrate.mjs

82 lines
3.5 KiB
JavaScript

/**
* Dev check — the QUEUED celebration path: research completes while the
* console is closed, and the ignition still plays when the player reopens
* the console within the fresh window (a stale one is dropped, not played).
* Drives itself and exposes `window.__QUEUE_CHECK__`:
*
* node dev/server.mjs 8090
* node dev/cdp-shot.mjs "http://127.0.0.1:8090/dev/queue-celebrate.html" \
* /tmp/q.png "window.__QUEUE_CHECK__"
* # then read the report via CDP eval: window.__QUEUE_CHECK__.lines
*/
import Phaser from '../js/vendor/phaser.js';
import { config } from '../js/config/Config.js';
import { ConfigLoader } from '../js/config/ConfigLoader.js';
import { createGameConfig } from '../js/config/GameConfig.js';
import { GameScene } from '../js/scenes/GameScene.js';
const data = await ConfigLoader.load();
config.init(data);
const errors = [];
const origErr = console.error.bind(console);
console.error = (...a) => { errors.push(a.map(String).join(' ')); origErr(...a); };
window.addEventListener('error', (e) => errors.push(String(e.message)));
window.addEventListener('unhandledrejection', (e) => errors.push(`rejection: ${e.reason}`));
const gameConfig = createGameConfig();
gameConfig.scene = [GameScene];
const game = new Phaser.Game(gameConfig);
window.game = game;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function waitScene() {
for (let i = 0; i < 100; i++) {
const s = game.scene.getScene('GameScene');
if (s && s.ship && s.researchWindow) return s;
await sleep(100);
}
throw new Error('GameScene never booted');
}
const lines = [];
try {
const s = await waitScene();
await sleep(800);
const win = s.researchWindow;
// 1 — open, start a short project, CLOSE the console while in flight
s.deckAction('research');
await sleep(900); // boot reveal
s.researchState.start('exploration', 'tether_l2', 400, s.time.now);
await sleep(150);
s.deckAction('research'); // toggle → close (fade ~150 ms)
await sleep(700); // completion happens HERE, console closed → QUEUED
const q1 = win.celebration;
lines.push(`queued at close: ${q1 ? `cat=${q1.catId} played=${q1.played}` : 'NONE'}`);
if (!q1 || q1.played) errors.push('CELEBRATE not queued while console closed');
// 2 — reopen within the fresh window → the ignition must play
s.deckAction('research');
await sleep(200);
lines.push(`after reopen: played=${win.celebration?.played} bursts=${win.bursts.length} open=${win.openState}`);
if (!win.celebration?.played) errors.push('CELEBRATE did not play after reopen');
if (win.bursts.length === 0) errors.push('no bursts alive after reopen');
// 3 — stale-drop: a completion older than the fresh window is dropped,
// not played (simulate by backdating `at`). Let step 2's bursts expire
// first so the count below is meaningful.
await sleep(1400);
win.celebration = { catId: 'exploration', id: 'tether_l3', at: s.time.now - 60000, played: false };
win._maybeCelebrate();
lines.push(`stale drop: played=${win.celebration.played} bursts=${win.bursts.length}`);
if (!win.celebration.played) errors.push('stale celebration was not dropped');
if (win.bursts.length !== 0) errors.push('stale celebration still pushed bursts');
} catch (err) {
errors.push(`FATAL: ${err.message}`);
}
lines.unshift(errors.length === 0 ? 'QUEUE CHECK OK — no console errors' : 'FAILURES:');
window.__QUEUE_CHECK__ = { ok: errors.length === 0, lines, errors };
console.info('queue-celebrate: done', errors.length === 0);