Step 7 - Testing, quality and deployment

4 min czytania

Testing, quality and deployment

Close the loop: prove the thing works, then ship it as static files.

Test layers

Unit — engine and AI. Already specified in steps 2 and 3. These are the deepest tests and must stay fast: the whole suite runs in under 30 seconds, including the exhaustive never-lose search.

Unit — state and storage. Transitions, alternating starters, score counting, and the corrupt / unavailable / throwing storage cases from step 5.

Integration — DOM. With jsdom, mount the whole app into a detached document and drive it through simulated events:

  • Clicking three cells in a winning pattern ends the round, marks the winning cells and increments the right counter.
  • A full board with no line reports a draw and increments draws.
  • Clicking an occupied cell changes nothing — no state change, no counter movement.
  • Clicking any cell after the game ends changes nothing.
  • Keyboard-only play: focus the board, navigate with arrows, place with Enter, and complete a whole game without a single synthetic click.
  • Switching to human-vs-computer with humanMark: 'O' and a fixed opening of X results in the computer having moved before the player interacts.
  • Setting difficulty to hard and playing a scripted human sequence never ends in a human win.

Use fake timers for the cosmetic AI delay so integration tests do not sleep.

Accessibility. Run axe-core against the rendered document in three states — fresh board, mid-game, and finished game — and assert zero violations at the wcag2a and wcag2aa levels. axe-core is permitted as a dev dependency for this purpose.

Manual checklist

Run before release, and record the result in the repository README:

  • Play a full game with the mouse, the keyboard and a touchscreen.
  • Play with a screen reader (VoiceOver or NVDA): the board position, each cell's content and the outcome are all announced, and nothing is announced twice.
  • Verify in current Chrome, Firefox and Safari, desktop and mobile.
  • Toggle the OS between light and dark, and reduced motion on and off.
  • Zoom the browser to 200% and confirm nothing is clipped or overlapping.
  • Reload mid-game: settings and scores return, a fresh board appears.
  • Disable localStorage in browser settings and confirm the game still plays.
  • Go offline after the first load and confirm the game still plays.
  • Lose ten times in a row to Hard — or rather, fail to win once.

Performance budget

Metric Budget
Total transferred (gzipped) < 30 kB
JavaScript (uncompressed) < 60 kB
CSS (uncompressed) < 12 kB
Time to interactive on a mid-range phone < 1 s
Hard AI decision, worst case < 100 ms
Cumulative layout shift 0
Lighthouse Performance / Accessibility / Best Practices 100 / 100 / 100

Layout shift of exactly zero is achievable here and is worth insisting on: the board is a fixed grid and the status line must reserve its height so a longer message does not push the board down.

Build and deployment

npm run build produces a fully static dist/ — HTML, one JS bundle, one CSS file, one SVG. It has no server requirement, so it can be hosted anywhere: Firebase Hosting, GitHub Pages, Netlify, Cloudflare Pages, or a plain directory behind nginx. Document one path in the README and mention that the others need no code change.

Set Vite's base to './' so the build also works from a subdirectory and from file://.

Recommended headers where the host allows them: the same CSP as the meta tag, X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer. Hashed asset filenames get a long Cache-Control; index.html must not be cached aggressively.

Optionally add a minimal service worker that pre-caches the four build artefacts for offline play. If included, it must not be a network proxy — cache-first for its own assets and nothing else — and it must be registerable but not required for the game to work.

Acceptance criteria

  • npm run test passes with zero failures and zero skipped tests, in under 30 seconds.
  • Overall statement coverage is at least 85%, and at least 95% for src/engine/.
  • The jsdom integration suite covers win, draw, occupied-cell, post-game click, keyboard-only play and computer-moves-first, and all pass.
  • axe-core reports zero wcag2a / wcag2aa violations in fresh, mid-game and finished states.
  • npm run build succeeds, npm run preview serves a working game, and the same dist/ also works when opened directly from the filesystem.
  • Every performance budget figure above is met and recorded.
  • Lighthouse scores 100 for Performance, Accessibility and Best Practices on the production build.
  • The manual checklist has been completed and its result recorded in the repository README.
  • dist/ requests nothing from a third-party origin, verified in the network panel.
  • The game plays correctly with the network disconnected after first load.
  • npm run verify passes on a clean checkout after npm ci.

Dyskusja

Komentarze: 0

Brak komentarzy. Rozpocznij dyskusję.