Restructured project from nested workspace pattern to flat single-repo layout. This eliminates redundant nesting and consolidates all project files under version control. ## Migration Summary **Before:** ``` alex/ (workspace, not versioned) ├── chess-game/ (git repo) │ ├── js/, css/, tests/ │ └── index.html └── docs/ (planning, not versioned) ``` **After:** ``` alex/ (git repo, everything versioned) ├── js/, css/, tests/ ├── index.html ├── docs/ (project documentation) ├── planning/ (historical planning docs) ├── .gitea/ (CI/CD) └── CLAUDE.md (configuration) ``` ## Changes Made ### Structure Consolidation - Moved all chess-game/ contents to root level - Removed redundant chess-game/ subdirectory - Flattened directory structure (eliminated one nesting level) ### Documentation Organization - Moved chess-game/docs/ → docs/ (project documentation) - Moved alex/docs/ → planning/ (historical planning documents) - Added CLAUDE.md (workspace configuration) - Added IMPLEMENTATION_PROMPT.md (original project prompt) ### Version Control Improvements - All project files now under version control - Planning documents preserved in planning/ folder - Merged .gitignore files (workspace + project) - Added .claude/ agent configurations ### File Updates - Updated .gitignore to include both workspace and project excludes - Moved README.md to root level - All import paths remain functional (relative paths unchanged) ## Benefits ✅ **Simpler Structure** - One level of nesting removed ✅ **Complete Versioning** - All documentation now in git ✅ **Standard Layout** - Matches open-source project conventions ✅ **Easier Navigation** - Direct access to all project files ✅ **CI/CD Compatible** - All workflows still functional ## Technical Validation - ✅ Node.js environment verified - ✅ Dependencies installed successfully - ✅ Dev server starts and responds - ✅ All core files present and accessible - ✅ Git repository functional ## Files Preserved **Implementation Files:** - js/ (3,517 lines of code) - css/ (4 stylesheets) - tests/ (87 test cases) - index.html - package.json **CI/CD Pipeline:** - .gitea/workflows/ci.yml - .gitea/workflows/release.yml **Documentation:** - docs/ (12+ documentation files) - planning/ (historical planning materials) - README.md **Configuration:** - jest.config.js, babel.config.cjs, playwright.config.js - .gitignore (merged) - CLAUDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
12 KiB
Test Scenarios (JSON Format)
This directory contains structured test scenarios in JSON format for automated testing of specific chess game behaviors.
Scenario Format
{
"id": "unique-scenario-id",
"name": "Scenario Name",
"description": "Detailed description",
"category": "category-name",
"priority": "high|medium|low",
"setup": {
"fen": "FEN string",
"description": "Setup description"
},
"steps": [
{
"action": "action-type",
"params": {},
"expected": {}
}
],
"assertions": [
{
"type": "assertion-type",
"expected": "expected-value"
}
]
}
Available Scenarios
Basic Movement Scenarios
Pawn Movement
File: pawn-movement.json
{
"id": "pawn-001",
"name": "Pawn Initial Two-Square Move",
"description": "Verify pawn can move two squares from starting position",
"category": "piece-movement",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "Initial board position"
},
"steps": [
{
"action": "selectPiece",
"params": { "square": "e2" },
"expected": { "validMoves": ["e3", "e4"] }
},
{
"action": "movePiece",
"params": { "from": "e2", "to": "e4" },
"expected": { "success": true }
}
],
"assertions": [
{ "type": "pieceAt", "square": "e4", "expected": "white-pawn" },
{ "type": "pieceAt", "square": "e2", "expected": null },
{ "type": "turn", "expected": "black" }
]
}
Knight Jump
File: knight-jump.json
{
"id": "knight-001",
"name": "Knight Jumps Over Pieces",
"description": "Verify knight can jump over blocking pieces",
"category": "piece-movement",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "Initial position with pawns blocking"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "b1", "to": "c3" },
"expected": { "success": true }
}
],
"assertions": [
{ "type": "pieceAt", "square": "c3", "expected": "white-knight" },
{ "type": "pieceAt", "square": "b1", "expected": null }
]
}
Special Moves Scenarios
En Passant
File: en-passant.json
{
"id": "special-001",
"name": "En Passant Capture",
"description": "Verify en passant capture works correctly",
"category": "special-moves",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2",
"description": "White pawn on e5, black just moved d7-d5"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "e5", "to": "d6" },
"expected": { "success": true, "captureType": "en-passant" }
}
],
"assertions": [
{ "type": "pieceAt", "square": "d6", "expected": "white-pawn" },
{ "type": "pieceAt", "square": "d5", "expected": null },
{ "type": "pieceAt", "square": "e5", "expected": null },
{ "type": "capturedPieces", "color": "black", "expected": ["pawn"] }
]
}
Castling Kingside
File: castling-kingside.json
{
"id": "castling-001",
"name": "Kingside Castling",
"description": "Verify kingside castling moves both king and rook",
"category": "special-moves",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK2R w KQkq - 0 1",
"description": "Cleared path for kingside castling"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "e1", "to": "g1" },
"expected": { "success": true, "moveType": "castling" }
}
],
"assertions": [
{ "type": "pieceAt", "square": "g1", "expected": "white-king" },
{ "type": "pieceAt", "square": "f1", "expected": "white-rook" },
{ "type": "pieceAt", "square": "e1", "expected": null },
{ "type": "pieceAt", "square": "h1", "expected": null },
{ "type": "castlingRights", "white": { "kingside": false, "queenside": true } }
]
}
Pawn Promotion
File: pawn-promotion.json
{
"id": "promotion-001",
"name": "Pawn Promotion to Queen",
"description": "Verify pawn promotes to queen on 8th rank",
"category": "special-moves",
"priority": "high",
"setup": {
"fen": "4k3/P7/8/8/8/8/8/4K3 w - - 0 1",
"description": "White pawn on a7 ready to promote"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "a7", "to": "a8", "promotion": "queen" },
"expected": { "success": true, "moveType": "promotion" }
}
],
"assertions": [
{ "type": "pieceAt", "square": "a8", "expected": "white-queen" },
{ "type": "pieceAt", "square": "a7", "expected": null }
]
}
Game State Scenarios
Check Detection
File: check-detection.json
{
"id": "gamestate-001",
"name": "Check Detection",
"description": "Verify check is detected and displayed",
"category": "game-state",
"priority": "critical",
"setup": {
"fen": "rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2",
"description": "Standard position"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "f1", "to": "c4" },
"expected": { "success": true }
},
{
"action": "movePiece",
"params": { "from": "d8", "to": "h4" },
"expected": { "success": true, "check": true }
}
],
"assertions": [
{ "type": "inCheck", "color": "white", "expected": true },
{ "type": "checkIndicator", "visible": true },
{ "type": "validMoves", "mustEscapeCheck": true }
]
}
Checkmate
File: checkmate-fools-mate.json
{
"id": "checkmate-001",
"name": "Fool's Mate Checkmate",
"description": "Verify checkmate detection in Fool's Mate",
"category": "game-state",
"priority": "critical",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "Initial position"
},
"steps": [
{ "action": "movePiece", "params": { "from": "f2", "to": "f3" } },
{ "action": "movePiece", "params": { "from": "e7", "to": "e5" } },
{ "action": "movePiece", "params": { "from": "g2", "to": "g4" } },
{
"action": "movePiece",
"params": { "from": "d8", "to": "h4" },
"expected": { "success": true, "checkmate": true }
}
],
"assertions": [
{ "type": "gameOver", "expected": true },
{ "type": "result", "expected": "black-wins" },
{ "type": "reason", "expected": "checkmate" },
{ "type": "inCheckmate", "color": "white", "expected": true }
]
}
Stalemate
File: stalemate.json
{
"id": "gamestate-003",
"name": "Stalemate Detection",
"description": "Verify stalemate results in draw",
"category": "game-state",
"priority": "high",
"setup": {
"fen": "k7/8/1Q6/8/8/8/8/7K b - - 0 1",
"description": "Black king with no legal moves, not in check"
},
"steps": [],
"assertions": [
{ "type": "gameOver", "expected": true },
{ "type": "result", "expected": "draw" },
{ "type": "reason", "expected": "stalemate" },
{ "type": "legalMoves", "color": "black", "expected": [] }
]
}
UI Interaction Scenarios
Drag and Drop
File: drag-drop-move.json
{
"id": "ui-001",
"name": "Drag and Drop Valid Move",
"description": "Verify drag-drop interaction for valid move",
"category": "ui-interaction",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "Initial position"
},
"steps": [
{
"action": "dragStart",
"params": { "square": "e2" },
"expected": { "dragActive": true, "pieceSelected": true }
},
{
"action": "dragOver",
"params": { "square": "e4" },
"expected": { "validMoveHighlight": true }
},
{
"action": "drop",
"params": { "square": "e4" },
"expected": { "success": true, "pieceAt": "e4" }
}
],
"assertions": [
{ "type": "pieceAt", "square": "e4", "expected": "white-pawn" },
{ "type": "dragActive", "expected": false }
]
}
Click to Move
File: click-to-move.json
{
"id": "ui-002",
"name": "Click-Select-Click-Move",
"description": "Verify click-based move selection",
"category": "ui-interaction",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "Initial position"
},
"steps": [
{
"action": "click",
"params": { "square": "e2" },
"expected": { "pieceSelected": true, "validMovesHighlighted": ["e3", "e4"] }
},
{
"action": "click",
"params": { "square": "e4" },
"expected": { "success": true }
}
],
"assertions": [
{ "type": "pieceAt", "square": "e4", "expected": "white-pawn" },
{ "type": "selectedSquare", "expected": null }
]
}
Error Handling Scenarios
Invalid Move
File: invalid-move.json
{
"id": "error-001",
"name": "Invalid Move Rejection",
"description": "Verify invalid moves are rejected with feedback",
"category": "error-handling",
"priority": "high",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "Initial position"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "e2", "to": "e5" },
"expected": { "success": false, "error": "Invalid move" }
}
],
"assertions": [
{ "type": "pieceAt", "square": "e2", "expected": "white-pawn" },
{ "type": "pieceAt", "square": "e5", "expected": null },
{ "type": "errorMessage", "visible": true }
]
}
Move Opponent's Piece
File: wrong-color-move.json
{
"id": "error-002",
"name": "Cannot Move Opponent's Piece",
"description": "Verify player cannot move opponent's pieces",
"category": "error-handling",
"priority": "critical",
"setup": {
"fen": "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
"description": "White to move"
},
"steps": [
{
"action": "movePiece",
"params": { "from": "e7", "to": "e5" },
"expected": { "success": false, "error": "Wrong turn" }
}
],
"assertions": [
{ "type": "pieceAt", "square": "e7", "expected": "black-pawn" },
{ "type": "turn", "expected": "white" }
]
}
Usage in Tests
import scenario from './test-data/scenarios/pawn-movement.json';
describe(scenario.name, () => {
test(scenario.description, async () => {
// Setup
const chess = new Chess(scenario.setup.fen);
// Execute steps
for (const step of scenario.steps) {
const result = executeAction(step.action, step.params);
expect(result).toMatchObject(step.expected);
}
// Verify assertions
for (const assertion of scenario.assertions) {
verifyAssertion(chess, assertion);
}
});
});
Scenario Categories
- piece-movement: Basic piece movements
- special-moves: Castling, en passant, promotion
- game-state: Check, checkmate, stalemate
- ui-interaction: Drag-drop, click-to-move
- error-handling: Invalid moves, wrong turn
- performance: Load testing, stress testing
Adding New Scenarios
- Create JSON file with proper structure
- Validate JSON syntax
- Test scenario manually
- Add to appropriate category
- Update this README
Validation
const validateScenario = (scenario) => {
return (
scenario.id &&
scenario.name &&
scenario.category &&
scenario.priority &&
scenario.setup &&
scenario.steps &&
Array.isArray(scenario.assertions)
);
};