Fix e2e specs for fixed world clock: idle-pause expiry window, scale-1 motion settle, self-heal (ISS-117)
CI / build + unit + e2e (pull_request) Successful in 12m44s
CI / build + unit + e2e (pull_request) Successful in 12m44s
This commit is contained in:
+42
-7
@@ -87,6 +87,31 @@ async function setScale(page: Page, scale: number): Promise<void> {
|
||||
expect(body.timeScale, `timeScale should be ${scale} after POST /api/test/set-timescale`).toBe(scale);
|
||||
}
|
||||
|
||||
// Test hook (FLIGHT_TEST_HOOKS=1): force a plane's health and/or repair gate — same shape as e2e/sim.spec.ts.
|
||||
async function setHealth(page: Page, planeId: string, fields: Record<string, unknown>): Promise<void> {
|
||||
const res = await page.request.post('/api/test/set-health', { data: { planeId, ...fields } });
|
||||
expect(res.status()).toBe(200);
|
||||
}
|
||||
|
||||
// Idle-pause (ISS-117) freezes a fully grounded fleet — put the starter in repair so the clock
|
||||
// advances for tests that need it. The €1.5k repair cost is why the expiry test captures its
|
||||
// cash/rep baseline AFTER deactivateWorld; deactivateWorld restores full health and no gate afterwards.
|
||||
async function activateWorld(page: Page): Promise<void> {
|
||||
await setHealth(page, 'plane-starter', { health: 50 });
|
||||
expect((await page.request.post('/api/planes/plane-starter/repair')).status()).toBe(200);
|
||||
}
|
||||
|
||||
// Shorten the repair gate to "now" — the next advancing tick flips the plane back to available.
|
||||
async function deactivateWorld(page: Page): Promise<void> {
|
||||
await setHealth(page, 'plane-starter', { health: 100, repairUntilMs: 0 });
|
||||
await expect
|
||||
.poll(async () => (await getState(page)).planes.find((p) => p.id === 'plane-starter')?.status ?? '', {
|
||||
timeout: 30_000,
|
||||
message: 'waiting for the starter to flip back to available',
|
||||
})
|
||||
.toBe('available');
|
||||
}
|
||||
|
||||
// Closest airport to the hub from /api/airports → shortest possible flight. Returns both
|
||||
// endpoints' coordinates so exact-km assertions (rep/fuel) can mirror lib/geo.ts.
|
||||
async function nearestToHub(page: Page): Promise<{ icao: string; lat: number; lon: number; hubLat: number; hubLon: number }> {
|
||||
@@ -296,7 +321,6 @@ test('abandon while grounded deducts exactly the formula penalty', async ({ page
|
||||
test('expired packages deliver and abandon with no reward and no penalty', async ({ page }) => {
|
||||
test.setTimeout(480_000); // two ~10 s real-time legs at 1000× (HUB↔LEMD) plus expiry wait
|
||||
await flyHomeViaApi(page);
|
||||
const before = await getState(page);
|
||||
|
||||
// A: load, let it expire while loaded, then FLY to its destination — arrival must
|
||||
// unbind it WITHOUT paying out. B: load, let it expire, abandon for free. B's
|
||||
@@ -310,12 +334,23 @@ test('expired packages deliver and abandon with no reward and no penalty', async
|
||||
expect(res.ok()).toBeTruthy();
|
||||
}
|
||||
|
||||
// Fast-forward past both deadlines — the tick flips loaded → expired (slot kept).
|
||||
await setScale(page, SCALE);
|
||||
let s = await getState(page);
|
||||
await expect.poll(async () => ((await getState(page)).packages.find((p) => p.id === pkgA.id)!.status), { timeout: 30_000 }).toBe('expired');
|
||||
s = await getState(page);
|
||||
expect(s.packages.find((p) => p.id === pkgB.id)!.status).toBe('expired');
|
||||
// Idle-pause (ISS-117): a fully grounded fleet freezes the clock, so expirePackages never runs —
|
||||
// put the starter in repair for the expiry window only. The €1.5k repair cost is why the cash/rep
|
||||
// baseline below is captured AFTER deactivateWorld, not before it.
|
||||
await activateWorld(page);
|
||||
try {
|
||||
// Fast-forward past both deadlines — the tick flips loaded → expired (slot kept).
|
||||
await setScale(page, SCALE);
|
||||
let s = await getState(page);
|
||||
await expect.poll(async () => ((await getState(page)).packages.find((p) => p.id === pkgA.id)!.status), { timeout: 30_000 }).toBe('expired');
|
||||
s = await getState(page);
|
||||
expect(s.packages.find((p) => p.id === pkgB.id)!.status).toBe('expired');
|
||||
} finally {
|
||||
await deactivateWorld(page);
|
||||
}
|
||||
|
||||
const before = await getState(page); // baseline AFTER the repair cost — no-reward assertions compare against this
|
||||
let s = before;
|
||||
|
||||
// Fly to the destination — arrival unbinds A for free (no reward, no rep).
|
||||
const flyRes = await page.request.post('/api/planes/plane-starter/fly', { data: { destIcao: 'LEMD' } });
|
||||
|
||||
Reference in New Issue
Block a user