# 04 – Resultate & Report (Ausgabe-Dateien) > Schema-Referenz für alle Artefakte der Test-Suite und Aufbau des generierten `report.html`. > Diese Dateien werden **zur Laufzeit erzeugt** und **nicht versioniert** (→ `.gitignore`). --- ## 1. Übersicht der Artefakte | Datei | Erzeugt von | Zweck | |---|---|---| | `audit-result.json` | `tests/audit.mjs` | Raw-Reports der 3 Audits + Assertions + Page-Errors + Summary | | `selfplay-results.json` | `tests/selfplay.mjs` | Episoden-Log + Win-Rate + Aggregates | | `perf-result.json` | `tests/perf-test.mjs` | FPS, Heap, Setup-Metadaten | | `report.html` | `tests/report.mjs` | Zusammengefasster, menschlich lesbarer CI-Report | | `audit-final.png` | `tests/audit.mjs` | Finaler Screenshot des Headless-Browsers | > `report.mjs` liest die drei `*-result.json` und rendert daraus ein einzelnes `report.html`. > Fehlt eine JSON-Datei, zeigt `report.html` für die entsprechende Sektion „no data". --- ## 2. `audit-result.json` ```json { "timestamp": "2026-08-28T19:20:00.000Z", "self": { "connectivity": [ { "level": 0, "name": "…", "reachable": true } ], "attacks": [ { "id": "sniper", "projectiles": 12, "hits": 10 } ], "skills": [ { "id": "…", "rank": 4 } ], "placement": { "wall": true, "path": true }, "autoWave": true, "endlessTransition": true }, "extension": { "mortarSplashTargets": 2, "teslaAoE": { "targets": 5, "frozen": true }, "rewardDedup": true, "blockerAltPath": true, "blockerClosedPath": true }, "redesign": { "sniperPriority": true, "quantumBeam": { "aligned": 3, "offLineUnharmed": true }, "nanoSpawner": { "limit": true, "damage": true, "cleanup": true } }, "pageErrors": [], "assertions": [ { "name": "self.connectivity.allReachable", "pass": true }, { "name": "self.attacks.noZeroProjectiles", "pass": true }, { "name": "self.skills.allRank4", "pass": true } ], "summary": { "total": 12, "pass": 12, "fail": 0 } } ``` > **Exit-Code-Kopplung:** `audit.mjs` beendet sich mit `1`, sobald `summary.fail > 0` > oder `pageErrors` nicht leer ist. Ein harter Crash im Browser führt zu `2`. --- ## 3. `selfplay-results.json` ```json { "timestamp": "2026-08-28T19:30:00.000Z", "episodes": [ { "placed": 40, "towerCount": 40, "maxKills": 120, "waveReached": 8, "totalUpgrades": 64, "finalState": "victory", "finalKills": 120, "finalLeaked": 0, "finalLives": 20 } ], "summary": { "total": 10, "wins": 8, "losses": 2, "winRate": 80.0, "avgKills": 118, "avgWaves": 7.4 } } ``` **Felder:** | Feld | Bedeutung | |---|---| | `placed` | Anzahl tatsächlich platzierter Türme in der Episode | | `towerCount` | Endgültige Turm-Anzahl (inkl. Spawner) | | `maxKills` | Höchststand an Kills während der Simulation | | `waveReached` | Letzt erreichte Wave | | `totalUpgrades` | Anzahl gekaufter Skill-Upgrades | | `finalState` | `victory` \| `defeat` | | `winRate` | `wins / total × 100` | --- ## 4. `perf-result.json` ```json { "timestamp": "2026-08-28T19:45:00.000Z", "durationMs": 15000, "fps": 58, "targetFps": 55, "pass": true, "heap": { "usedMB": 48.3, "totalMB": 96.0 }, "setup": { "levelIdx": 10, "levelName": "…", "placed": 50, "enemies": 40, "state": "playing" } } ``` | Feld | Bedeutung | |---|---| | `fps` | Gemittelte Frames pro Sekunde während `durationMs` | | `targetFps` | Zielwert (Default `55`) – `pass` = `fps >= targetFps` | | `heap.usedMB` | `performance.memory.usedJSHeapSize` / 1048576 | | `heap.totalMB` | `performance.memory.totalJSHeapSize` / 1048576 | > Heap-Messung benötigt Chromium (`performance.memory`). In nicht-Chromium-Browsern ist > `heap` ggf. `null` → `report.mjs` blendet dann die Heap-Spalte aus. --- ## 5. `report.html` `report.mjs` rendert eine statische, single-file HTML-Seite: ``` ┌──────────────────────────────────────────────────────────────────┐ │ Aegis Labyrinth – Test & Audit Report │ │ Timestamp: 2026-08-28 19:45 │ ├──────────────────────────────────────────────────────────────────┤ │ ✔ AUDIT pass 12/12 self ✔ extension ✔ redesign ✔ │ │ ✔ SELF-PLAY winRate 80% (8/10) avgKills 118 │ │ ✔ PERFORMANCE 58 fps (target 55) heap 48.3 / 96.0 MB │ ├──────────────────────────────────────────────────────────────────┤ │ Assertion-Details (expandierbare Liste) │ │ Page-Errors (leer) │ └──────────────────────────────────────────────────────────────────┘ ``` **Verhalten:** - Jede Sektion hat einen Ampel-Status: grün (pass) / gelb (teilweise) / rot (fail). - Fehlende Quelldatei → Sektion wird als „no data" (grau) gerendert, statt zu crashen. - Kein externes JS/CSS → `report.html` ist vollständig offline-viewbar. --- ## 6. .gitignore (Empfehlung) ```gitignore # Test-Artefakte (werden zur Laufzeit erzeugt) audit-result.json selfplay-results.json perf-result.json report.html audit-final.png # Externe Game-Source (manuell in die Root legen) Aegis-Labyrinth.html # Node node_modules/