4.4 KiB
Testing Twungeon
Automated gates
From a clean checkout:
npm install
npm run lint
npm run typecheck
npm test
npm run test:integration
npm run build
npm test covers deterministic domain rules and 500 generated floors.
npm run test:integration covers the HTTP/session boundary and independent
viewer authority. Tests use injected clocks, IDs, random rolls, and synthetic
Twitch identities; they do not require credentials.
Local gameplay verification
- Run
npm run devand openhttp://localhost:3000. - Confirm the exact dormant banner appears and no timer runs.
- Use Local viewer login to spawn and bind a viewer.
- Confirm 3 HP, 2 AP, no Guard, a ready heal, and a five-second phase.
- Confirm the viewer's first accepted action resets the timer to five seconds and their second accepted action does not reset it again.
- Exercise movement, invalid walls, Attack, Heal, and Pass. Invalid actions must not consume AP.
- Open a second browser/private window with a different ID. Confirm both characters share the dungeon but each controller spends only its own AP.
- Refresh during a phase. Confirm a snapshot restores the map/log and no command replays.
- Run
npm run build && npm startand repeat the smoke test against the built server.
The local-only endpoints /api/dev/spawn and /api/dev/redemption exist only while
TWITCH_ENABLED is false.
Local video-overlay verification
The production viewer path is /extension. It is safe to open directly, but it
waits for Twitch authorization when it is not inside Twitch. While running the
synthetic local backend, open:
http://localhost:3000/extension?dev=1&debug=1
dev=1 exposes the existing Local viewer login inside the overlay so the
same controller and API flow can be exercised without Twitch. debug=1 draws a
cyan control-region boundary and a pink controller boundary. Both switches are
accepted only on localhost, 127.0.0.1, or [::1], so the diagnostics cannot
be enabled on the deployed Extension origin.
Verify at 1920×1080, 1280×720, a narrower or 4:3 viewport, and a mobile-width viewport:
- the document and empty overlay canvas remain transparent;
- controls stay within the upper-left debug boundary and remain readable;
- the dungeon, log, branding, and status tiles are absent from
/extension; - only buttons (and the local-only login form) accept pointer events;
- Up, Down, Left, Right, Attack, Heal, and Pass reach the same backend routes;
- missing character, dead character, non-player phase, and zero-AP states still disable the controls; and
- loading
/still presents the full local game and controller; - mobile identity/color, HP, AP, and heal status remains visible; and
- mobile directional buttons are at least 56px and action buttons at least 52px.
Remove the query string for the production-shaped local view. Twitch-hosted testing still must cover identity sharing, player ownership, theater mode, fullscreen, embeds, ads/pauses, and Twitch player-control safe zones.
Live-channel campaign
After completing docs/twitch-setup.md, use five follower accounts and one
non-follower account. Capture redacted evidence for:
- eligible, ineligible, and duplicate
!spawnattempts; - matching and mismatched Extension identities;
- independent commands from two viewers;
- four deterministic party slots/colors and a rejected fifth viewer;
- phase expiry and AutoGuard while one viewer is disconnected;
- death and a configured Channel Points reward redemption from the same user;
- escape with the Goblin alive, complete next-floor reparty, and total-party defeat dormancy;
- refresh/reconnect during a phase and transition; and
- repeated floors and a short soak session.
Do not record tokens, JWTs, secrets, or complete authorization headers. Use the
acceptance matrix in Twungeon_MVP_Acceptance_Test_and_Build_Checklist.md for
AT-001 through AT-033 evidence. Automated passing tests do not substitute for
the clean-operator, live Twitch, first-time-viewer, or concept-validation gates.
Fault injection
Test each failure separately: expired Extension JWT, wrong channel claim, unlinked identity, invalid broadcaster token, missing follower scope, Twitch chat disconnect, wrong/duplicate Channel Points redemption, WebSocket interruption, and stale run/floor/phase command. Expected behavior is a stable rejection or a fresh snapshot without partial game-state mutation.