feat: v0.16.1 — ISS-007 smooth client-side sim clock with per-snapshot re-sync
CI / build + unit + e2e (pull_request) Failing after 6m42s
CI / build + unit + e2e (pull_request) Failing after 6m42s
This commit is contained in:
@@ -4,6 +4,8 @@ import { test, expect, type Page } from '@playwright/test';
|
||||
// The panes render from the shell's single /api/state poll (lib/useGameState.ts); time
|
||||
// controls POST to /api/sim and refetch immediately, so UI assertions settle within a tick.
|
||||
|
||||
const SCALE = 1000; // fastest sim speed — top of the v0.14.0 ladder (same convention as e2e/sim.spec.ts)
|
||||
|
||||
interface SimState {
|
||||
clockMs: number;
|
||||
timeScale: number;
|
||||
@@ -104,6 +106,40 @@ test('time controls: pause freezes the sim and the ladder slider sets timeScale'
|
||||
expect(after.simState.paused).toBe(false);
|
||||
});
|
||||
|
||||
test('sim clock ticks smoothly between polls — seconds advance without waiting for a snapshot (ISS-007)', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
const clock = page.getByTestId('sim-clock');
|
||||
await expect(clock).toBeVisible({ timeout: 15_000 });
|
||||
|
||||
// Fastest scale so game seconds move visibly inside the sampling window.
|
||||
const post = await page.request.post('/api/sim', { data: { timeScale: SCALE, paused: false } });
|
||||
expect(post.status()).toBe(200);
|
||||
|
||||
// "YYYY-MM-DD HH:MM:SS UTC" → epoch ms (UTC). While running there is no "(paused)" suffix.
|
||||
const sample = async () => {
|
||||
const text = ((await clock.textContent()) ?? '').trim();
|
||||
expect(text, `clock format: ${text}`).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC$/);
|
||||
return Date.parse(`${text.replace(' ', 'T')}Z`);
|
||||
};
|
||||
|
||||
// Three samples ~1.3 s apart real time: at scale 1000 each gap is ≈1300 game seconds, so the
|
||||
// displayed clock must strictly advance between CONSECUTIVE samples — with the old poll-only
|
||||
// rendering a sample pair could straddle zero snapshot updates and show no change at all.
|
||||
const t0 = await sample();
|
||||
await new Promise((r) => setTimeout(r, 1_300));
|
||||
const t1 = await sample();
|
||||
await new Promise((r) => setTimeout(r, 1_300));
|
||||
const t2 = await sample();
|
||||
|
||||
expect(t1).toBeGreaterThan(t0);
|
||||
expect(t2).toBeGreaterThan(t1);
|
||||
// Sanity: ~2.6 s real × 1000 ≈ 2.6 M game ms — generous bounds keep slow CI boxes safe while
|
||||
// still catching a frozen or wildly mis-scaled clock.
|
||||
const total = t2 - t0;
|
||||
expect(total).toBeGreaterThanOrEqual(1_000_000);
|
||||
expect(total).toBeLessThanOrEqual(6_000_000);
|
||||
});
|
||||
|
||||
test('slider commit keeps the chosen scale on screen until confirmed — no snap-back (ISS-001)', async ({ page }) => {
|
||||
test.setTimeout(60_000);
|
||||
await page.goto('/');
|
||||
|
||||
Reference in New Issue
Block a user