From 2dcec2195e564dc5197b7078f97fd125b23d99f5 Mon Sep 17 00:00:00 2001 From: German Khokhlov Date: Tue, 10 Nov 2026 19:11:07 +0400 Subject: [PATCH] Check that a running mission replay survives an engine switch The session test now switches engines in both directions with the replay running, paused and resumed, and checks it stays active, unpaused and advancing. --- src/standalone/sessionSwitch.test.mjs | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/standalone/sessionSwitch.test.mjs b/src/standalone/sessionSwitch.test.mjs index 72d65173e..527b9ffde 100644 --- a/src/standalone/sessionSwitch.test.mjs +++ b/src/standalone/sessionSwitch.test.mjs @@ -74,6 +74,8 @@ async function fixture(t, { aircraft = null, failOpen = false } = {}) { }; const engines = []; const newEngine = (kind) => { + const retained = engines.find((engine) => engine.kind === kind); + if (retained) return retained; const engine = createFakeEngine({ kind, container: document.createElement('div'), @@ -250,6 +252,46 @@ test('Space Missions keeps its context, selection and paused replay across engin } }); +test('Space Missions keeps a running replay advancing across engines', async (t) => { + const f = await fixture(t); + assert.equal((await f.context.setContextMode('space-missions')).ok, true); + const launches = f.catalog.get('rocket-launches'); + launches.selectMissionAt(0); + launches.setReplaySpeed(4); + launches.startSelectedReplay(); + f.engine().camera.completeFlight(); + await flushLifecycleTasks(t, 16_000); + f.engine().fake.frame(); + launches.toggleReplayPause(); + f.address({ + enabledLayerIds: ['rocket-launches', 'satellites'], + options: {}, + }); + for (const kind of ['cesium', 'navara']) await f.switcher.select(kind); + launches.toggleReplayPause(); + await flushLifecycleTasks(t, 100); + f.engine().fake.frame(); + for (const kind of ['cesium', 'navara']) { + const before = launches.qaDrawn(); + assert.ok(before.replay.active); + assert.equal(before.paused, false); + assert.ok(before.replay.phaseProgress > 0); + await f.switcher.select(kind); + const after = launches.qaDrawn(); + assert.ok(after.replay.active); + assert.equal(after.paused, false); + await flushLifecycleTasks(t, 500); + f.engine().fake.frame(); + const advanced = launches.qaDrawn(); + assert.ok(advanced.replay.active); + assert.equal(advanced.paused, false); + assert.ok( + advanced.replay.phaseProgress > before.replay.phaseProgress, + 'a running replay advances on the incoming engine', + ); + } +}); + for (const aircraft of ['flights', 'military']) { test(`failed engine startup restores the ${aircraft} cockpit and session without history`, async (t) => { const f = await fixture(t, { aircraft, failOpen: true });