Christoph Wagner 5ad0700b41 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>
2025-11-23 10:05:26 +01:00

484 lines
12 KiB
Markdown

# 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)
);
};
```