refactor: Consolidate repository structure - flatten from workspace pattern

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>
This commit is contained in:
Christoph Wagner
2025-11-23 10:05:26 +01:00
co-authored by Claude
parent 1fd28d10b4
commit 5ad0700b41
326 changed files with 107368 additions and 281 deletions
+389
View File
@@ -0,0 +1,389 @@
# Chess Game Test Data (PGN Format)
This directory contains PGN (Portable Game Notation) files of complete chess games for testing game replay, move validation, and analysis features.
## PGN Format
PGN includes:
- Game metadata (Event, Site, Date, Round, White, Black, Result)
- Move sequences in standard algebraic notation
- Optional annotations and variations
## Available Games
### Famous Short Games
#### Fool's Mate
**File**: `fools-mate.pgn`
```pgn
[Event "Fool's Mate Example"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "0-1"]
1. f3 e5 2. g4 Qh4# 0-1
```
**Description**: Shortest possible checkmate (2 moves)
**Moves**: 2
**Result**: Black wins
---
#### Scholar's Mate
**File**: `scholars-mate.pgn`
```pgn
[Event "Scholar's Mate Example"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "1-0"]
1. e4 e5 2. Bc4 Nc6 3. Qh5 Nf6 4. Qxf7# 1-0
```
**Description**: Four-move checkmate
**Moves**: 4
**Result**: White wins
---
### Historic Masterpieces
#### The Immortal Game
**File**: `immortal-game.pgn`
```pgn
[Event "Casual Game"]
[Site "London"]
[Date "1851.06.21"]
[Round "?"]
[White "Adolf Anderssen"]
[Black "Lionel Kieseritzky"]
[Result "1-0"]
1. e4 e5 2. f4 exf4 3. Bc4 Qh4+ 4. Kf1 b5 5. Bxb5 Nf6 6. Nf3 Qh6
7. d3 Nh5 8. Nh4 Qg5 9. Nf5 c6 10. g4 Nf6 11. Rg1 cxb5 12. h4 Qg6
13. h5 Qg5 14. Qf3 Ng8 15. Bxf4 Qf6 16. Nc3 Bc5 17. Nd5 Qxb2
18. Bd6 Bxg1 19. e5 Qxa1+ 20. Ke2 Na6 21. Nxg7+ Kd8 22. Qf6+ Nxf6
23. Be7# 1-0
```
**Description**: Famous 1851 game with brilliant sacrifices
**Moves**: 23
**Result**: White wins
**Notable**: Multiple piece sacrifices leading to checkmate
---
#### The Opera Game
**File**: `opera-game.pgn`
```pgn
[Event "Paris Opera"]
[Site "Paris"]
[Date "1858.??.??"]
[Round "?"]
[White "Paul Morphy"]
[Black "Duke of Brunswick and Count Isouard"]
[Result "1-0"]
1. e4 e5 2. Nf3 d6 3. d4 Bg4 4. dxe5 Bxf3 5. Qxf3 dxe5 6. Bc4 Nf6
7. Qb3 Qe7 8. Nc3 c6 9. Bg5 b5 10. Nxb5 cxb5 11. Bxb5+ Nbd7
12. O-O-O Rd8 13. Rxd7 Rxd7 14. Rd1 Qe6 15. Bxd7+ Nxd7 16. Qb8+ Nxb8
17. Rd8# 1-0
```
**Description**: Morphy's famous game at the Paris Opera
**Moves**: 17
**Result**: White wins
**Notable**: Brilliant tactical play, queen sacrifice
---
### Test Cases for Special Moves
#### En Passant Capture
**File**: `en-passant-game.pgn`
```pgn
[Event "En Passant Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
1. e4 a6 2. e5 d5 3. exd6 *
```
**Description**: Demonstrates en passant capture
**Moves**: 3
**Result**: Unfinished
**Test**: En passant on move 3
---
#### Castling Both Sides
**File**: `castling-game.pgn`
```pgn
[Event "Castling Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. O-O Nf6 5. d3 d6 6. Nc3 O-O *
```
**Description**: Both sides castle kingside
**Moves**: 6
**Result**: Unfinished
**Test**: Castling validation
---
#### Pawn Promotion
**File**: `pawn-promotion-game.pgn`
```pgn
[Event "Promotion Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
1. e4 d5 2. exd5 Qxd5 3. Nc3 Qe6+ 4. Be2 Qg6 5. Nf3 Qxg2 6. Rg1 Qh3
7. Rg3 Qh6 8. Rg8+ Qf8 9. Rxf8# *
```
**Description**: Game with pawn promotion scenario
**Moves**: 9
**Result**: Unfinished
---
### Draw Test Cases
#### Stalemate
**File**: `stalemate-game.pgn`
```pgn
[Event "Stalemate Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "1/2-1/2"]
1. e3 a5 2. Qh5 Ra6 3. Qxa5 h5 4. Qxc7 Rah6 5. h4 f6 6. Qxd7+ Kf7
7. Qxb7 Qd3 8. Qxb8 Qh7 9. Qxc8 Kg6 10. Qe6 1/2-1/2
```
**Description**: Game ending in stalemate
**Moves**: 10
**Result**: Draw
**Test**: Stalemate detection
---
#### Insufficient Material
**File**: `insufficient-material.pgn`
```pgn
[Event "Insufficient Material Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "1/2-1/2"]
1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 4. Bxc6 dxc6 5. Nxe5 Qd4 6. Nxf7 Qxe4+
7. Qe2 Qxe2# 1/2-1/2
```
**Description**: Game ending with insufficient material
**Result**: Draw
---
#### Threefold Repetition
**File**: `threefold-repetition.pgn`
```pgn
[Event "Threefold Repetition Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "1/2-1/2"]
1. Nf3 Nf6 2. Ng1 Ng8 3. Nf3 Nf6 4. Ng1 Ng8 5. Nf3 1/2-1/2
```
**Description**: Threefold repetition draw
**Moves**: 5
**Result**: Draw
**Test**: Repetition detection
---
### Opening Repertoire
#### Italian Game
**File**: `italian-game.pgn`
```pgn
[Event "Italian Opening"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+
7. Nc3 Nxe4 8. O-O Bxc3 9. d5 *
```
**Description**: Italian Game main line
**Moves**: 9
---
#### Sicilian Defense
**File**: `sicilian-defense.pgn`
```pgn
[Event "Sicilian Defense"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
1. e4 c5 2. Nf3 d6 3. d4 cxd4 4. Nxd4 Nf6 5. Nc3 a6 6. Be3 e5
7. Nb3 Be6 8. f3 *
```
**Description**: Sicilian Defense, Najdorf Variation
**Moves**: 8
---
#### Queen's Gambit
**File**: `queens-gambit.pgn`
```pgn
[Event "Queen's Gambit"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
1. d4 d5 2. c4 e6 3. Nc3 Nf6 4. Bg5 Be7 5. e3 O-O 6. Nf3 h6
7. Bh4 b6 8. cxd5 *
```
**Description**: Queen's Gambit Declined
**Moves**: 8
---
### Edge Case Games
#### Maximum Moves (Longest Game)
**File**: `long-game.pgn`
```
[Event "Long Game Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
[100+ moves for endurance testing]
```
**Description**: Very long game for stress testing
**Moves**: 100+
---
#### All Piece Types Promoted
**File**: `all-promotions.pgn`
```pgn
[Event "All Promotions Test"]
[Site "?"]
[Date "????.??.??"]
[Round "?"]
[White "White"]
[Black "Black"]
[Result "*"]
[Game demonstrating promotion to Q, R, B, N]
```
**Description**: Tests all promotion piece types
---
## Usage in Tests
```javascript
import { loadPGN } from '../utils/fixtures';
import { Chess } from 'chess.js';
test('Replay Immortal Game', () => {
const pgn = loadPGN('immortal-game');
const chess = new Chess();
chess.loadPgn(pgn);
expect(chess.isCheckmate()).toBe(true);
});
test('Validate all moves in Opera Game', () => {
const pgn = loadPGN('opera-game');
const chess = new Chess();
const result = chess.loadPgn(pgn);
expect(result).toBe(true); // All moves valid
});
```
## Test Categories
### Functional Tests
- `fools-mate.pgn`, `scholars-mate.pgn` - Basic checkmate
- `en-passant-game.pgn` - Special moves
- `castling-game.pgn` - Castling validation
- `pawn-promotion-game.pgn` - Pawn promotion
### Edge Cases
- `stalemate-game.pgn` - Draw by stalemate
- `threefold-repetition.pgn` - Draw by repetition
- `insufficient-material.pgn` - Draw by insufficient material
- `long-game.pgn` - Endurance testing
### Historic Games
- `immortal-game.pgn` - Tactics and sacrifices
- `opera-game.pgn` - Brilliant play
- Famous games for regression testing
## Adding New Games
1. Create `.pgn` file with proper metadata
2. Validate PGN using chess.js
3. Add description to this README
4. Categorize appropriately
5. Create corresponding test cases
## PGN Validation
```javascript
import { Chess } from 'chess.js';
const isValidPGN = (pgn) => {
const chess = new Chess();
return chess.loadPgn(pgn);
};
```
## Resources
- PGN Specification: https://www.chessclub.com/help/PGN-spec
- Chess.js: https://github.com/jhlywa/chess.js
- Online PGN Viewer: https://www.chess.com/analysis
- Game Database: https://www.pgnmentor.com/
@@ -0,0 +1,295 @@
# Chess Position Test Data
This directory contains FEN (Forsyth-Edwards Notation) strings for various chess positions used in testing.
## FEN Format
FEN notation describes a chess position using 6 fields:
1. Piece placement (from white's perspective, rank 8 to rank 1)
2. Active color (w = white, b = black)
3. Castling availability (KQkq)
4. En passant target square
5. Halfmove clock (for 50-move rule)
6. Fullmove number
Example: `rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1`
## Available Positions
### Initial Position
**File**: `initial-position.fen`
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
```
**Description**: Standard starting position
---
### Checkmate Positions
#### Fool's Mate
**File**: `fools-mate.fen`
```
rnb1kbnr/pppp1ppp/8/4p3/6Pq/5P2/PPPPP2P/RNBQKBNR w KQkq - 1 3
```
**Description**: Shortest possible checkmate (2 moves)
#### Scholar's Mate
**File**: `scholars-mate.fen`
```
r1bqkb1r/pppp1Qpp/2n2n2/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQkq - 0 4
```
**Description**: Four-move checkmate pattern
#### Back Rank Mate
**File**: `back-rank-mate.fen`
```
6k1/5ppp/8/8/8/8/5PPP/4R1K1 b - - 0 1
```
**Description**: Classic back rank mate pattern
#### Smothered Mate
**File**: `smothered-mate.fen`
```
5rk1/5ppp/8/8/8/8/5PPP/4R1K1 b - - 0 1
```
**Description**: King trapped by own pieces
---
### Stalemate Positions
#### Basic Stalemate
**File**: `basic-stalemate.fen`
```
k7/8/1Q6/8/8/8/8/7K b - - 0 1
```
**Description**: Black king has no legal moves but not in check
#### Pawn Stalemate
**File**: `pawn-stalemate.fen`
```
7k/5K2/6P1/8/8/8/8/8 b - - 0 1
```
**Description**: Stalemate with pawn blockage
---
### Special Move Positions
#### En Passant Available
**File**: `en-passant-available.fen`
```
rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2
```
**Description**: White can capture en passant on d6
#### Castling Positions
**File**: `castling-kingside.fen`
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK2R w KQkq - 0 1
```
**Description**: White can castle kingside
**File**: `castling-queenside.fen`
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/R3KBNR w KQkq - 0 1
```
**Description**: White can castle queenside
**File**: `castling-both.fen`
```
r3k2r/pppppppp/8/8/8/8/PPPPPPPP/R3K2R w KQkq - 0 1
```
**Description**: Both sides can castle both ways
#### Pawn Promotion
**File**: `pawn-promotion.fen`
```
4k3/P7/8/8/8/8/8/4K3 w - - 0 1
```
**Description**: White pawn ready to promote
---
### Complex Middlegame Positions
#### Italian Game
**File**: `italian-game.fen`
```
r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3
```
**Description**: Classic Italian opening position
#### Sicilian Defense
**File**: `sicilian-defense.fen`
```
rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2
```
**Description**: Sicilian Defense after 1.e4 c5
#### Queen's Gambit
**File**: `queens-gambit.fen`
```
rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq c3 0 2
```
**Description**: Queen's Gambit position
---
### Endgame Positions
#### King and Queen vs King
**File**: `kq-vs-k.fen`
```
8/8/8/8/8/3k4/3Q4/3K4 w - - 0 1
```
**Description**: Basic queen endgame
#### King and Rook vs King
**File**: `kr-vs-k.fen`
```
8/8/8/8/8/3k4/3R4/3K4 w - - 0 1
```
**Description**: Basic rook endgame
#### Pawn Endgame
**File**: `pawn-endgame.fen`
```
8/5k2/5P2/5K2/8/8/8/8 w - - 0 1
```
**Description**: King and pawn vs king
#### Opposite Color Bishops
**File**: `opposite-bishops.fen`
```
8/5k2/8/3b4/8/8/3B4/5K2 w - - 0 1
```
**Description**: Bishops on opposite colors (often drawn)
---
### Edge Cases
#### Three-Fold Repetition Setup
**File**: `threefold-setup.fen`
```
r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4
```
**Description**: Position for testing threefold repetition
#### Fifty-Move Rule
**File**: `fifty-move-rule.fen`
```
8/8/8/8/8/3k4/3Q4/3K4 w - - 99 100
```
**Description**: Near fifty-move rule threshold
#### Insufficient Material (KB vs K)
**File**: `insufficient-kb-vs-k.fen`
```
8/8/8/8/8/3k4/3B4/3K4 w - - 0 1
```
**Description**: Draw due to insufficient material
#### Insufficient Material (KN vs K)
**File**: `insufficient-kn-vs-k.fen`
```
8/8/8/8/8/3k4/3N4/3K4 w - - 0 1
```
**Description**: Draw due to insufficient material
---
### Famous Game Positions
#### Immortal Game (Anderssen vs Kieseritzky, 1851)
**File**: `immortal-game-final.fen`
```
r1b1kb1r/p2pqppp/5n2/1p2p3/2B1P3/1Q6/PPPPNPPP/RNB1K2R w KQkq - 0 1
```
**Description**: Position before the famous sacrifice
#### Opera Game (Morphy vs Duke of Brunswick, 1858)
**File**: `opera-game-final.fen`
```
2kr4/ppp2pp1/4p3/4b3/2B5/2P2Q2/P4PPP/2KR4 b - - 0 1
```
**Description**: Famous tactical position
---
### Test-Specific Positions
#### All Pieces Present
**File**: `all-pieces.fen`
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
```
**Description**: For testing piece rendering
#### Empty Board (only kings)
**File**: `empty-board.fen`
```
4k3/8/8/8/8/8/8/4K3 w - - 0 1
```
**Description**: Minimal valid position
#### Maximum Pieces
**File**: `max-pieces.fen`
```
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
```
**Description**: All 32 pieces on board
#### Piece Movement Tests
**File**: `piece-movement-test.fen`
```
8/8/8/3p1p2/2pNPp2/3p1p2/8/8 w - - 0 1
```
**Description**: Knight surrounded by enemy pawns
---
## Usage in Tests
```javascript
import { loadFEN } from '../utils/fixtures';
test('Fool\'s Mate detection', () => {
const position = loadFEN('fools-mate');
const chess = new Chess(position);
expect(chess.isCheckmate()).toBe(true);
});
```
## Adding New Positions
1. Create a new `.fen` file
2. Validate FEN using chess.js or online validator
3. Add description to this README
4. Create corresponding test cases
5. Document expected behavior
## FEN Validation
To validate FEN strings:
```javascript
import { Chess } from 'chess.js';
const isValidFEN = (fen) => {
try {
const chess = new Chess(fen);
return chess.fen() === fen;
} catch {
return false;
}
};
```
## Resources
- FEN Notation: https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
- Chess.js Library: https://github.com/jhlywa/chess.js
- FEN Validator: https://www.chess.com/analysis
@@ -0,0 +1,483 @@
# Test Scenarios (JSON Format)
This directory contains structured test scenarios in JSON format for automated testing of specific chess game behaviors.
## Scenario Format
```json
{
"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`
```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`
```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`
```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`
```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`
```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`
```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`
```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`
```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`
```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`
```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`
```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`
```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
```javascript
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
1. Create JSON file with proper structure
2. Validate JSON syntax
3. Test scenario manually
4. Add to appropriate category
5. Update this README
## Validation
```javascript
const validateScenario = (scenario) => {
return (
scenario.id &&
scenario.name &&
scenario.category &&
scenario.priority &&
scenario.setup &&
scenario.steps &&
Array.isArray(scenario.assertions)
);
};
```