feat(e2e): add window.__FERROUS_DEBUG__ bridge to /play for automation
play.html now loads solitaire_wasm.js alongside the Bevy canvas and
exposes the same window.__FERROUS_DEBUG__ object as /play-classic.
The bridge runs an independent SolitaireGame (WASM logic layer) seeded
from ?seed= / ?draw3= URL params; Bevy renders the visual game in
parallel without coupling.
Methods exposed: seed, state, legalMoves, moveHistory, snapshot,
applyLegalMove, applyMove, draw, undo, serialize, fromSaved, newGame,
failureReport, replayPayload, runAutoplay — matching the /play-classic
contract so the shared Playwright harness targets either route without
modification.
cycle_metrics.js: add --route play-classic|play flag (default
play-classic). Routes to /${route}?seed=N. The resume-overlay clear
step is skipped for /play since the Bevy build uses localStorage-backed
WasmStorage, not a #resume-overlay element.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -103,6 +103,9 @@ async function main() {
|
||||
const policyArg = readArg("--policy", "loop_aware");
|
||||
const policy = policyArg === "baseline" ? "baseline" : "loop_aware";
|
||||
const outPath = readArg("--out", "/tmp/playwright-cycle-metrics.json");
|
||||
// --route play-classic (default) or --route play
|
||||
const routeArg = readArg("--route", "play-classic");
|
||||
const route = routeArg === "play" ? "play" : "play-classic";
|
||||
const maxCycleRateAll = parseOptionalNumber("--max-cycle-rate-all");
|
||||
const maxCycleRateDraw1 = parseOptionalNumber("--max-cycle-rate-draw1");
|
||||
const maxCycleRateDraw3 = parseOptionalNumber("--max-cycle-rate-draw3");
|
||||
@@ -155,17 +158,19 @@ async function main() {
|
||||
}
|
||||
});
|
||||
|
||||
await page.goto(`${baseUrl}/play-classic?seed=${seed}${suffix}`, {
|
||||
await page.goto(`${baseUrl}/${route}?seed=${seed}${suffix}`, {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
|
||||
const resumeVisible = await page
|
||||
.locator("#resume-overlay:not(.hidden)")
|
||||
.isVisible()
|
||||
.catch(() => false);
|
||||
if (resumeVisible) {
|
||||
await page.evaluate(() => localStorage.removeItem("fs_game_save"));
|
||||
await page.reload({ waitUntil: "domcontentloaded" });
|
||||
if (route === "play-classic") {
|
||||
const resumeVisible = await page
|
||||
.locator("#resume-overlay:not(.hidden)")
|
||||
.isVisible()
|
||||
.catch(() => false);
|
||||
if (resumeVisible) {
|
||||
await page.evaluate(() => localStorage.removeItem("fs_game_save"));
|
||||
await page.reload({ waitUntil: "domcontentloaded" });
|
||||
}
|
||||
}
|
||||
|
||||
await page.waitForFunction(
|
||||
|
||||
Reference in New Issue
Block a user