Fixed world clock: no player time controls (ISS-117)
CI / build + unit + e2e (pull_request) Failing after 12m10s
CI / build + unit + e2e (pull_request) Failing after 12m10s
The world always runs at WORLD_TIME_SCALE = 24 (lib/worldClock.ts). A server
background tick (instrumentation.ts -> startBackgroundTick, 1 s interval)
advances the sim with no open browser; idle-pause freezes the clock exactly
while no plane is flying or in repair. Fresh worlds start year 2000
(STARTING_CLOCK_MS in seed.ts).
- Removed: POST /api/sim + OpenAPI entry, applyTimeControls/clampTimeScale,
lib/timeScale.ts, LeftPane pause button + scale slider machinery,
ISS-057 slow-on-landing/resume in flyPlane.
- Snapshot simState is now { clockMs } only; client extrapolates at the fixed
rate between polls and freezes while idle (useSimClock).
- New test-only hook POST /api/test/set-timescale behind FLIGHT_TEST_HOOKS=1
(sibling of set-health); all e2e setScale helpers call it, afterEach restores
the world rate. E2E pause tests replaced by idle-pause assertions; sim.spec.ts
activates the world via set-health + /repair for advance/expiry tests.
This commit is contained in:
+9
-16
@@ -9,7 +9,8 @@ import { expect, test } from '@playwright/test';
|
||||
// works for FLYING planes — it then appends to POST /api/planes/{id}/queue instead of flying now.
|
||||
// Marker-size regression is covered by the existing e2e/map.spec.ts click tests, not here.
|
||||
|
||||
const SCALE = 1000; // fastest sim speed (v0.14.0 ladder top) — keeps cleanup flights to seconds of real time
|
||||
const SCALE = 1000; // test rate for fast-forwarding legs — keeps cleanup flights to seconds of real time
|
||||
const WORLD = 24; // the fixed world rate (ISS-117) — must match lib/worldClock.ts
|
||||
const HUB = 'EDDF'; // Frankfurt Main — the seeded starter plane's home base (lib/game/seed.ts)
|
||||
// LFRS Nantes Atlantique — same isolated marker as e2e/map.spec.ts: its nearest neighbour is ~78 px
|
||||
// away at the initial zoom, so a click on its projected center cannot hit another circle.
|
||||
@@ -33,20 +34,13 @@ async function setFuelFull(page: Page, planeId: string): Promise<void> {
|
||||
expect((await page.request.post('/api/test/set-fuel', { data: { planeId, fuel: p.maxFuel } })).status()).toBe(200);
|
||||
}
|
||||
|
||||
async function postSim(page: Page, body: Record<string, unknown>): Promise<void> {
|
||||
const res = await page.request.post('/api/sim', { data: body });
|
||||
expect(res.ok()).toBeTruthy();
|
||||
}
|
||||
|
||||
// Set the time scale and VERIFY from the response that it stuck — if something external ever
|
||||
// resets the live instance's controls mid-test, fail loudly here instead of timing out later.
|
||||
// ISS-041 also clears pause: a landing pauses the sim, so any fast-forward after one must
|
||||
// resume it or the clock stays frozen and the next wait hangs.
|
||||
// Test hook (FLIGHT_TEST_HOOKS=1): set the world rate and VERIFY from the response that it stuck —
|
||||
// if something external ever resets the live instance's controls mid-test, fail loudly here instead of timing out later.
|
||||
async function setScale(page: Page, scale: number): Promise<void> {
|
||||
const res = await page.request.post('/api/sim', { data: { timeScale: scale, paused: false } });
|
||||
const res = await page.request.post('/api/test/set-timescale', { data: { timeScale: scale } });
|
||||
expect(res.status()).toBe(200);
|
||||
const body = (await res.json()) as { timeScale: number };
|
||||
expect(body.timeScale, `timeScale should be ${scale} after POST /api/sim`).toBe(scale);
|
||||
expect(body.timeScale, `timeScale should be ${scale} after POST /api/test/set-timescale`).toBe(scale);
|
||||
}
|
||||
|
||||
// Closest airport to the hub from /api/airports → shortest possible leg (fuel trivial).
|
||||
@@ -83,8 +77,7 @@ async function flyHomeViaApi(page: Page): Promise<void> {
|
||||
plane = s.planes.find((p) => p.id === 'plane-starter')!;
|
||||
}
|
||||
if (plane.locationIcao !== HUB) {
|
||||
// ISS-041: the landing above paused the sim — setScale clears pause so the return leg
|
||||
// fast-forwards instead of taking real-time hours.
|
||||
// Make sure the world rate is back at SCALE so the return leg fast-forwards.
|
||||
await setScale(page, SCALE);
|
||||
const res = await page.request.post(`/api/planes/${plane.id}/fly`, { data: { destIcao: HUB } });
|
||||
expect(res.ok()).toBeTruthy(); // repositioning needs no package (v0.12.0 manual flight)
|
||||
@@ -93,10 +86,10 @@ async function flyHomeViaApi(page: Page): Promise<void> {
|
||||
}
|
||||
|
||||
// Self-heal in CLEANUP (afterEach): the tests deliberately leave plane-starter mid-flight, so
|
||||
// fast-forward + reposition home here; then restore scale=1 / unpaused for later specs.
|
||||
// fast-forward + reposition home here; then restore the fixed world rate for later specs.
|
||||
test.afterEach(async ({ page }) => {
|
||||
await flyHomeViaApi(page);
|
||||
await postSim(page, { timeScale: 1, paused: false });
|
||||
await setScale(page, WORLD);
|
||||
});
|
||||
|
||||
test.describe.configure({ mode: 'serial' }); // shared live DB — order matters within this file
|
||||
|
||||
Reference in New Issue
Block a user