Skip to content

Commit 703093b

Browse files
xenobiasoftclaude
andcommitted
Fix flaky and broken tests across E2E and unit suites
- E2E cell interaction tests used a near-solved board with one empty cell, so any move completed the puzzle and triggered the victory display before the assertion could run; introduce two-empty-cell factories so filling cell (0,0) leaves isSolved() false and the board stays visible - GameTimerTests.OnTick_ShouldFireAtInterval waited only 5x the interval, giving insufficient headroom under CI scheduling jitter; double the wait to 10x so the tick count reliably reaches the >=3 threshold Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4ac223f commit 703093b

3 files changed

Lines changed: 51 additions & 5 deletions

File tree

Tests/E2E/fixtures/game-data.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,26 @@ function makeNearSolvedCells(emptyRow = 0, emptyCol = 0): CellModel[] {
9898
return cells;
9999
}
100100

101+
/**
102+
* Builds 81 cells with TWO empty user-editable cells.
103+
* Filling only one of them won't solve the board, so isSolved() stays false.
104+
*/
105+
function makeNearSolvedCellsWith2Empty(
106+
emptyRow1 = 0, emptyCol1 = 0,
107+
emptyRow2 = 0, emptyCol2 = 1,
108+
): CellModel[] {
109+
const cells: CellModel[] = [];
110+
for (let r = 0; r < 9; r++) {
111+
for (let c = 0; c < 9; c++) {
112+
const isEmpty =
113+
(r === emptyRow1 && c === emptyCol1) ||
114+
(r === emptyRow2 && c === emptyCol2);
115+
cells.push(isEmpty ? makeEmptyCell(r, c) : makeCell(r, c, SOLVED_BOARD[r][c], true));
116+
}
117+
}
118+
return cells;
119+
}
120+
101121
/**
102122
* Builds a fully solved 81-cell board.
103123
* Cell (0,0) is user-placed (isFixed=false) to reflect that the user filled it in.
@@ -178,6 +198,30 @@ export function makeSolvedGame(): GameModel {
178198
});
179199
}
180200

201+
/**
202+
* A game with TWO empty cells — cell (0,0) and cell (0,1) — so that filling
203+
* cell (0,0) does NOT complete the board and isSolved() stays false.
204+
* Use this as `initialGame` in cell-interaction tests.
205+
*/
206+
export function makeTestGameForInteraction(): GameModel {
207+
return makeTestGame({
208+
cells: makeNearSolvedCellsWith2Empty(EMPTY_CELL_ROW, EMPTY_CELL_COL, 0, 1),
209+
});
210+
}
211+
212+
/**
213+
* State after the user places EMPTY_CELL_VALUE in cell (0,0) while cell (0,1)
214+
* is still empty. isSolved() returns false so no victory display is triggered.
215+
* Use as `gameAfterMove` in cell-interaction tests.
216+
*/
217+
export function makeTestGameAfterInteractionMove(): GameModel {
218+
const cells = makeNearSolvedCellsWith2Empty(EMPTY_CELL_ROW, EMPTY_CELL_COL, 0, 1);
219+
const cell = cells.find(c => c.row === EMPTY_CELL_ROW && c.column === EMPTY_CELL_COL)!;
220+
cell.value = EMPTY_CELL_VALUE;
221+
cell.hasValue = true;
222+
return makeTestGame({ cells });
223+
}
224+
181225
/**
182226
* A lightweight saved game for populating the home-page load-game list.
183227
*/

Tests/E2E/tests/game.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
makeTestGameWithMove,
1010
makeTestGameWithStats,
1111
makeSolvedGame,
12+
makeTestGameForInteraction,
13+
makeTestGameAfterInteractionMove,
1214
} from '../fixtures/game-data';
1315

1416
// ────────────────────────────────────────────────────────────────────────────
@@ -58,8 +60,8 @@ test.describe('Game Page – Board', () => {
5860
test.describe('Game Page – Cell Interaction', () => {
5961
test('clicking a number button places a value in the selected cell', async ({ page, gamePage }) => {
6062
await setupApiMocks(page, {
61-
initialGame: makeTestGame(),
62-
gameAfterMove: makeTestGameWithMove(),
63+
initialGame: makeTestGameForInteraction(),
64+
gameAfterMove: makeTestGameAfterInteractionMove(),
6365
});
6466
await gamePage.goto(TEST_GAME_ID);
6567

@@ -72,8 +74,8 @@ test.describe('Game Page – Cell Interaction', () => {
7274

7375
test('pressing a number key on the keyboard places a value in the selected cell', async ({ page, gamePage }) => {
7476
await setupApiMocks(page, {
75-
initialGame: makeTestGame(),
76-
gameAfterMove: makeTestGameWithMove(),
77+
initialGame: makeTestGameForInteraction(),
78+
gameAfterMove: makeTestGameAfterInteractionMove(),
7779
});
7880
await gamePage.goto(TEST_GAME_ID);
7981

src/backend/Tests/Blazor/Services/GameTimerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public async Task OnTick_ShouldFireAtInterval()
118118

119119
// Act
120120
_timer.Start();
121-
await Task.Delay(_interval * 5);
121+
await Task.Delay(_interval * 10);
122122
_timer.Pause();
123123

124124
// Assert

0 commit comments

Comments
 (0)