# Testing The project uses Node's built-in test runner, Python's `unittest`, and browser-based visual QA. Runtime code has no third-party packages, so a clean checkout can run both automated suites without installing dependencies. ## Automated checks Run all JavaScript and Python unit and contract tests: ```bash npm test ``` Run CSS-bundle, JavaScript-syntax, asset-reference, and release-hygiene checks: ```bash npm run check ``` Run every automated check and test together: ```bash npm run verify ``` Documentation dependencies are isolated from the runtime. After installing `docs/requirements.txt` in a virtual environment, build the complete site with warnings treated as errors: ```bash npm run docs:build ``` The dedicated documentation workflow runs that strict build for relevant pull requests and `main` updates, then stores the generated HTML as a private workflow artifact. The check command also confirms that `styles/app.css` matches its ordered sources, local assets resolve, and generated review output or private workspace paths have not entered the release tree. `npm test` runs `test:js` first and then `test:feedback`; a failure in either suite fails `npm run verify`. Run one suite while developing a focused change: ```bash node --test tests/chess.test.js node --test tests/hints.test.js node --test tests/hints-css.test.js node --test tests/board-input.test.js node --test tests/endgame-choreography.test.js node --test tests/feedback.test.js python3 -m unittest discover -s feedback/tests -p 'test_*.py' ``` ## Coverage by suite - `tests/chess.test.js`: FEN parsing, legal move generation, standard move-tree counts, king safety, clocks, history, defensive snapshots, castling, en passant, promotion, terminal states, deterministic hint analysis, legal principal variations, search, and undo. - `tests/hints.test.js`: factual hint wording, searched-line notation, score perspective, terminal continuations, and themed vocabulary. - `tests/hints-css.test.js`: 3D-safe FROM/TO markers, distinct source and destination treatment, and untruncated counsel layout. - `tests/board-input.test.js`: SVG event delegation, piece overhangs, perspective seams, enlarged legal targets, touch slop, and focus restoration. - `tests/pieces.test.js`: public renderer fallbacks and unique role output. - `tests/readability.test.js`: large-scale silhouette markers and geometric distinction. - `tests/structural-live.test.js`: structural SVG hooks, unique paint identifiers, articulation, and weapon-contact contracts. - `tests/endgame-choreography.test.js`: pure outcome descriptions for wins, losses, local games, stalemate, and non-terminal positions. - `tests/feedback.test.js`: client normalization, request shape, validation, rate-limit copy, focus, cancellation, duplicate-submit protection, error recovery, accessible markup, and nonintrusive placement. - `tests/documentation.test.js`: complete Sphinx source, mixed Markdown/reStructuredText configuration, pinned dependencies, strict local and CI entry points, private artifact handling, and generated-output exclusions. - `feedback/tests/test_server.py`: strict HTTP and JSON contracts, Unicode sanitization, private database files, privacy-preserving storage, retention, real storage limits, deduplication, multi-window rate limits, health, and periodic maintenance. - `feedback/tests/test_manage.py`: counts, privacy-safe JSON Lines export, scrubbed online backups, integrity failures, and retention pruning. - `tests/deployment*.test.js`: private routing, immutable deployment, isolated networkless backup jobs, read-only live-data access during backup, rollback safety, and container hardening. The markup tests intentionally verify stable classes and data attributes used by CSS and animation code. If a structural hook changes, update the renderer, every consumer, and the relevant contract assertion together. ## Manual browser checklist Start the app with `npm start`, then check the following before publishing a visual or interaction change: 1. Begin a computer duel as Ivory and as Obsidian; confirm the arrival starts only after **Begin the duel**. 2. Start a local two-player duel and verify board orientation, rail labels, move status, and Undo. 3. Select and move each role in 3D and flat views. Confirm source and destination targets remain easy to activate. 4. Trigger a melee capture and a magical capture. Check approach, weapon contact, defender reaction, matchup text, and **Skip duel**. 5. Skip movement and combat with Escape and with the visible button; verify the final engine position and keyboard focus. 6. Exercise castling, en passant, and each promotion choice. 7. Reveal a hint and confirm distinct FROM/TO markers, a three-ply explanation, and unchanged 3D piece structure. Select FROM, flip the board, and toggle flat view; the roles and persistent counsel must remain. A different selection or move attempt must clear them. 8. Reach check, checkmate, and stalemate positions; verify announcements and closing-scene skip behavior. 9. Fill both captured-piece courts beyond eight pieces and check that the pieces remain inside the board frame. 10. Resize during movement and inspect desktop, tablet, and 320-pixel-wide phone layouts for clipping or overlap. 11. Enable the operating system's reduced-motion preference and confirm long cinematics are bypassed or settled. 12. Find **Provide feedback** in the footer at desktop and 320-pixel phone widths; confirm it never floats over the board, combat controls, or toast. 13. Open the feedback dialog with a keyboard, move through every labeled control, then close it with both the close button and Escape. Confirm focus returns to the footer trigger and an active game animation is not skipped behind the dialog. 14. Exercise the category choices, live character count, too-short input, 2,000-character boundary, slow submit, duplicate click, and offline failure. Errors must keep the draft and remain announced without rendering server response content. 15. Against a disposable local API or controlled test deployment, submit successfully and confirm the dialog resets, closes, and announces success. Do not use production feedback data as a manual test fixture. ## Visual QA script `scripts/visual-qa.mjs` runs the responsive browser checks, captures representative combat phases, and records layout and depth diagnostics in the chosen output directory. It requires Node.js 22 or newer and Google Chrome, and talks to Chrome DevTools directly without a browser-automation package: ```bash npm start node scripts/visual-qa.mjs --out /tmp/enchanted-board-qa --viewport all --combat --hud-stress node scripts/visual-qa.mjs --out /tmp/enchanted-board-hints --viewport all --hint ``` The `--hint` pass asserts exact d2-to-d4 endpoints, stable structural source nodes, visible and accessible FROM/TO roles, untruncated explanatory counsel, source-selection persistence, board-flip persistence, and flat-view persistence. If Chrome is installed somewhere other than `/usr/bin/google-chrome`, pass its executable path with `--chrome`. Run `node scripts/visual-qa.mjs --help` for viewport, intro, hint, casualty, and stress options. Screenshots are review artifacts, not assertions by themselves. Pair them with the JSON metrics and inspect representative approach, parry, impact, and aftermath frames. Keep generated output outside the repository. ## Adding tests - Prefer an externally observable result over a private method assertion. - Assert that rejected operations do not mutate FEN, history, or focus state. - Cover both colors for asymmetric chess rules such as pawn movement and castling. - Verify undo whenever a move touches more than its source and destination squares. - Keep DOM-free logic in pure functions where practical so it can run under Node without a simulated browser. - Treat any feedback schema change as a client, service, SQLite constraint, test, and documentation change. - Test feedback suppression without asserting a distinguishable public response; honeypot, duplicate, and rate-limit no-ops intentionally share the generic `202` response. - Name regressions after the behavior a user relies on, not after implementation details.