Skip to content

Commit 1926fcb

Browse files
committed
Tests: Overhaul e2e testing infrastructure with a TypeScript runner
1 parent 4c40503 commit 1926fcb

9 files changed

Lines changed: 393 additions & 59 deletions

File tree

client/src/Index.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { assetList } from "./Assets";
2+
import { ScenarioRegistry } from "./testing/ScenarioRegistry";
23
import { Game } from "./Game";
34
import { InGameScene } from "./scene/type/InGameScene";
45
import { JoinGameScene } from "./scene/type/JoinGameScene";
@@ -16,11 +17,18 @@ Game.createInstance({ assetList: assetList, canvasColor: "gray" }, () => {
1617

1718
const urlParams = new URLSearchParams(window.location.search);
1819
if (urlParams.get("test") === "true") {
19-
import("./testing/scenarios/CitySettlement.test").then(module => {
20-
setTimeout(() => {
21-
const runner = module.setupCitySettlementTest(Game.getInstance());
22-
runner.run();
23-
}, 1000);
24-
});
20+
const scenarioName = urlParams.get("scenario") || "CitySettlement";
21+
const loader = ScenarioRegistry.get(scenarioName);
22+
23+
if (loader) {
24+
loader().then(setup => {
25+
setTimeout(() => {
26+
const runner = setup(Game.getInstance());
27+
runner.run();
28+
}, 1000);
29+
});
30+
} else {
31+
console.error(`Scenario '${scenarioName}' not found. Available: ${ScenarioRegistry.getAvailableScenarios().join(", ")}`);
32+
}
2533
}
2634
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Game } from "../Game";
2+
import { TestRunner } from "./TestRunner";
3+
4+
export type ScenarioSetup = (game: Game) => TestRunner;
5+
6+
type ScenarioLoader = () => Promise<ScenarioSetup>;
7+
8+
export class ScenarioRegistry {
9+
private static scenarios: Map<string, ScenarioLoader> = new Map();
10+
11+
public static register(name: string, loader: ScenarioLoader) {
12+
this.scenarios.set(name, loader);
13+
}
14+
15+
public static get(name: string): ScenarioLoader | undefined {
16+
return this.scenarios.get(name);
17+
}
18+
19+
public static getAvailableScenarios(): string[] {
20+
return Array.from(this.scenarios.keys());
21+
}
22+
}
23+
24+
// Register default scenarios
25+
ScenarioRegistry.register("CitySettlement", async () => {
26+
const module = await import("./scenarios/CitySettlement.test");
27+
return module.setupCitySettlementTest;
28+
});

client/src/testing/TestRunner.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ export interface TestStep {
99
export class TestRunner {
1010
private steps: TestStep[] = [];
1111
private game: Game;
12+
private scenarioName: string;
1213

13-
constructor(game: Game) {
14+
constructor(game: Game, scenarioName: string) {
1415
this.game = game;
16+
this.scenarioName = scenarioName;
1517
}
1618

1719
public addStep(step: TestStep) {
1820
this.steps.push(step);
1921
}
2022

2123
public async run() {
22-
console.log("Starting Test Runner...");
24+
console.log(`Starting Test Runner for Scenario: ${this.scenarioName}...`);
2325
const resultsProxy = document.createElement("div");
2426
resultsProxy.id = "test-results";
2527
resultsProxy.style.position = "absolute";
@@ -29,6 +31,13 @@ export class TestRunner {
2931
resultsProxy.style.color = "white";
3032
resultsProxy.style.padding = "10px";
3133
resultsProxy.style.fontFamily = "monospace";
34+
35+
const title = document.createElement("h3");
36+
title.textContent = `Scenario: ${this.scenarioName}`;
37+
title.style.margin = "0 0 10px 0";
38+
title.style.borderBottom = "1px solid white";
39+
resultsProxy.appendChild(title);
40+
3241
document.body.appendChild(resultsProxy);
3342

3443
const log = (msg: string, color: string = "white") => {

client/src/testing/scenarios/CitySettlement.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { InGameScene } from "../../scene/type/InGameScene";
55
import { Unit } from "../../Unit";
66

77
export function setupCitySettlementTest(game: Game) {
8-
const runner = new TestRunner(game);
8+
const runner = new TestRunner(game, "CitySettlement");
99
let settlerUnit: Unit | undefined;
1010

1111
runner.addStep({
@@ -166,7 +166,7 @@ export function setupCitySettlementTest(game: Game) {
166166
runner.addStep({
167167
name: "Check Food Output",
168168
action: async () => {
169-
await new Promise(r => setTimeout(r, 4000)); // Wait for city to settle
169+
await new Promise(r => setTimeout(r, 2000)); // Wait for city to settle
170170
},
171171
verification: async () => {
172172
console.log("[Test] Verification: Checking City Food via GameMap...");

0 commit comments

Comments
 (0)