fd98f46267
Test / test (pull_request) Successful in 37m24s
PR #170 changed the web replay payload (moves list -> embedded session recording) but missed these Playwright specs, which only run on master pushes and so failed post-merge. Assertions now match the v4 shape: schema_version 4, recording.initial_state present, moves at recording.instructions. Verified locally against a real server with freshly built wasm bundles: full suite 18/18 green, including the five play_canvas specs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
94 lines
3.6 KiB
JavaScript
94 lines
3.6 KiB
JavaScript
const { test, expect } = require("@playwright/test");
|
|
|
|
async function gotoReadyGame(page, seed = 42) {
|
|
await page.goto(`/play-classic?seed=${seed}`);
|
|
const resumeOverlay = page.locator("#resume-overlay:not(.hidden)");
|
|
if (await resumeOverlay.isVisible().catch(() => false)) {
|
|
await page.evaluate(() => localStorage.removeItem("fs_game_save"));
|
|
await page.reload();
|
|
}
|
|
await page.waitForFunction(
|
|
() =>
|
|
typeof window.__FERROUS_DEBUG__ === "object" &&
|
|
window.__FERROUS_DEBUG__.seed() !== null
|
|
);
|
|
}
|
|
|
|
test("hud and core controls render for gameplay", async ({ page }) => {
|
|
await gotoReadyGame(page, 42);
|
|
|
|
await expect(page.locator("#hud-score")).toHaveText(/Score:\s*\d+/);
|
|
await expect(page.locator("#hud-moves")).toHaveText(/Moves:\s*\d+/);
|
|
await expect(page.locator("#hud-timer")).toHaveText(/\d+:\d{2}/);
|
|
await expect(page.locator("#hud-stock")).toHaveText(/Stock:\s*\d+/);
|
|
|
|
await expect(page.locator("#btn-undo")).toBeVisible();
|
|
await expect(page.locator("#btn-new")).toBeVisible();
|
|
await expect(page.locator("#chk-draw3")).toBeVisible();
|
|
await expect(page.locator("#btn-theme")).toBeVisible();
|
|
await expect(page.locator("#board")).toBeVisible();
|
|
await expect(page.locator("#card-area .slot[data-pile='stock']")).toBeVisible();
|
|
});
|
|
|
|
test("stock click + undo button behaves like player flow", async ({ page }) => {
|
|
await gotoReadyGame(page, 42);
|
|
|
|
const baselineHistoryLen = await page.evaluate(
|
|
() => window.__FERROUS_DEBUG__.moveHistory().length
|
|
);
|
|
|
|
const stockBox = await page.locator("#card-area .slot[data-pile='stock']").boundingBox();
|
|
expect(stockBox).not.toBeNull();
|
|
await page.mouse.click(
|
|
stockBox.x + stockBox.width / 2,
|
|
stockBox.y + stockBox.height / 2
|
|
);
|
|
await expect
|
|
.poll(async () => await page.evaluate(() => window.__FERROUS_DEBUG__.moveHistory().length))
|
|
.toBe(baselineHistoryLen + 1);
|
|
|
|
await page.locator("#btn-undo").click();
|
|
await expect
|
|
.poll(async () => await page.evaluate(() => window.__FERROUS_DEBUG__.moveHistory().length))
|
|
.toBe(baselineHistoryLen);
|
|
});
|
|
|
|
test("draw-mode toggle affects replay payload draw_mode", async ({ page }) => {
|
|
await gotoReadyGame(page, 123);
|
|
|
|
await page.locator("#chk-draw3").check();
|
|
await expect(page.locator("#chk-draw3")).toBeChecked();
|
|
|
|
const applyResult = await page.evaluate(() =>
|
|
window.__FERROUS_DEBUG__.applyMove({ kind: "stock_click" })
|
|
);
|
|
expect(applyResult?.ok).toBeTruthy();
|
|
await expect
|
|
.poll(async () => await page.evaluate(() => window.__FERROUS_DEBUG__.replayPayload() !== null))
|
|
.toBe(true);
|
|
|
|
const payload = await page.evaluate(() => window.__FERROUS_DEBUG__.replayPayload());
|
|
expect(payload.draw_mode).toBe("DrawThree");
|
|
expect(payload.schema_version).toBe(4);
|
|
expect(Array.isArray(payload.recording?.instructions)).toBeTruthy();
|
|
expect(payload.recording.instructions.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("autonomous play keeps invariants stable across seed batch", async ({ page }) => {
|
|
test.setTimeout(120_000);
|
|
const seeds = [0, 1, 2, 3, 4, 5, 7, 11, 13, 17, 23, 29, 31, 42, 77, 99];
|
|
|
|
for (const seed of seeds) {
|
|
await gotoReadyGame(page, seed);
|
|
const run = await page.evaluate(() =>
|
|
window.__FERROUS_DEBUG__.runAutoplay({
|
|
maxSteps: 220,
|
|
maxVisitsPerState: 2,
|
|
policy: "loop_aware",
|
|
})
|
|
);
|
|
|
|
expect(run.ok, `seed ${seed} failed: ${JSON.stringify(run)}`).toBeTruthy();
|
|
}
|
|
});
|