playwright

This commit is contained in:
Stefan
2025-12-06 17:37:44 +01:00
parent 743bda02bf
commit 9ebca615c7
17 changed files with 32333 additions and 193 deletions
+28 -20
View File
@@ -1,9 +1,8 @@
import { Chess } from "chess.js";
import {
Color,
GeneratedTacticPosition,
TacticalPatternType,
detectTacticsForSide,
findTacticalOpportunitiesForSide,
generateBackRankWeaknessPosition,
generateDiscoveredCheckPosition,
generateDoubleAttackPosition,
@@ -27,32 +26,41 @@ const generators: GeneratorEntry[] = [
{ patternType: "DISCOVERED_CHECK", side: "white", generator: () => generateDiscoveredCheckPosition({ side: "white" }) },
{ patternType: "DOUBLE_ATTACK", side: "white", generator: () => generateDoubleAttackPosition({ side: "white" }) },
{ patternType: "OVERLOADING", side: "white", generator: () => generateOverloadingPosition({ side: "white" }) },
{ patternType: "BACK_RANK_WEAKNESS", side: "black", generator: () => generateBackRankWeaknessPosition({ side: "black" }) },
{ patternType: "TRAPPED_PIECE", side: "black", generator: () => generateTrappedPiecePosition({ side: "black" }) },
{ patternType: "BACK_RANK_WEAKNESS", side: "white", generator: () => generateBackRankWeaknessPosition({ side: "white" }) },
{ patternType: "TRAPPED_PIECE", side: "white", generator: () => generateTrappedPiecePosition({ side: "white" }) },
];
describe("tactic generators", () => {
it.each(generators)(
"creates scenarios where opportunities expose %s",
"generates valid %s tactical puzzles from Lichess database",
({ patternType, side, generator }) => {
const scenario = generator();
const opportunities = findTacticalOpportunitiesForSide(scenario.initialPosition, side);
const opportunity = opportunities.find(
(o) =>
o.move.from === scenario.creatingMove.from &&
o.move.to === scenario.creatingMove.to &&
o.pattern.type === patternType,
);
expect(opportunity).toBeDefined();
expect(opportunity?.pattern).toMatchObject({ type: patternType });
const resultingPatterns = detectTacticsForSide(scenario.resultingPosition, side);
const directMatch = resultingPatterns.find((p) => p.type === patternType);
expect(directMatch).toBeDefined();
// Verify the scenario has all required fields
expect(scenario.initialPosition.fen).toBeTruthy();
expect(scenario.creatingMove).toBeDefined();
expect(scenario.creatingMove.from).toBeTruthy();
expect(scenario.creatingMove.to).toBeTruthy();
expect(scenario.resultingPosition.fen).toBeTruthy();
expect(scenario.expectedPattern.type).toBe(patternType);
expect(scenario.side).toBe(side);
// Verify the first move (bestMove) is legal in the initial position
const chess = new Chess(scenario.initialPosition.fen);
const firstMove = chess.move({
from: scenario.creatingMove.from,
to: scenario.creatingMove.to,
promotion: scenario.creatingMove.promotion,
});
expect(firstMove).toBeTruthy();
expect(firstMove).toMatchObject({
from: scenario.creatingMove.from,
to: scenario.creatingMove.to,
});
// Verify it's the correct side's turn
const turnColor = scenario.initialPosition.fen.split(' ')[1];
expect(turnColor).toBe(side === 'white' ? 'w' : 'b');
},
);
});