82 lines
3.5 KiB
JavaScript
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);
|