game-harness 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/AGENTS.md +140 -0
  2. package/CHANGELOG.md +69 -0
  3. package/LICENSE +21 -0
  4. package/README.md +568 -0
  5. package/bin/test-harness-visual-battery.mjs +6 -0
  6. package/dist/cjs/bin/visual-battery.js +43 -0
  7. package/dist/cjs/browser-config.js +83 -0
  8. package/dist/cjs/chromium-launch.js +37 -0
  9. package/dist/cjs/index.js +10 -0
  10. package/dist/cjs/lighthouse.js +73 -0
  11. package/dist/cjs/package.json +3 -0
  12. package/dist/cjs/playwright-config.js +303 -0
  13. package/dist/cjs/production-runtime.js +315 -0
  14. package/dist/cjs/release-ladder.js +40 -0
  15. package/dist/cjs/silent-qa.js +75 -0
  16. package/dist/cjs/visual-battery.js +247 -0
  17. package/dist/esm/bin/visual-battery.js +41 -0
  18. package/dist/esm/browser-config.js +80 -0
  19. package/dist/esm/chromium-launch.js +34 -0
  20. package/dist/esm/index.js +3 -0
  21. package/dist/esm/lighthouse.js +70 -0
  22. package/dist/esm/playwright-config.js +292 -0
  23. package/dist/esm/production-runtime.js +304 -0
  24. package/dist/esm/release-ladder.js +37 -0
  25. package/dist/esm/silent-qa.js +67 -0
  26. package/dist/esm/visual-battery.js +239 -0
  27. package/dist/types/bin/visual-battery.d.cts +2 -0
  28. package/dist/types/bin/visual-battery.d.ts +2 -0
  29. package/dist/types/browser-config.d.cts +100 -0
  30. package/dist/types/browser-config.d.ts +100 -0
  31. package/dist/types/chromium-launch.d.cts +27 -0
  32. package/dist/types/chromium-launch.d.ts +27 -0
  33. package/dist/types/index.d.cts +3 -0
  34. package/dist/types/index.d.ts +3 -0
  35. package/dist/types/lighthouse.d.cts +44 -0
  36. package/dist/types/lighthouse.d.ts +44 -0
  37. package/dist/types/playwright-config.d.cts +122 -0
  38. package/dist/types/playwright-config.d.ts +122 -0
  39. package/dist/types/production-runtime.d.cts +105 -0
  40. package/dist/types/production-runtime.d.ts +105 -0
  41. package/dist/types/release-ladder.d.cts +38 -0
  42. package/dist/types/release-ladder.d.ts +38 -0
  43. package/dist/types/silent-qa.d.cts +47 -0
  44. package/dist/types/silent-qa.d.ts +47 -0
  45. package/dist/types/visual-battery.d.cts +69 -0
  46. package/dist/types/visual-battery.d.ts +69 -0
  47. package/docs/404.md +17 -0
  48. package/docs/agent-guide.md +10 -0
  49. package/docs/architecture.md +81 -0
  50. package/docs/assets/game-harness-hero.webp +0 -0
  51. package/docs/changelog.md +9 -0
  52. package/docs/contributing.md +21 -0
  53. package/docs/entry-points.md +41 -0
  54. package/docs/getting-started.md +42 -0
  55. package/docs/guides/chromium-and-silent-qa.md +72 -0
  56. package/docs/guides/lighthouse-and-release-ladder.md +62 -0
  57. package/docs/guides/playwright.md +58 -0
  58. package/docs/guides/production-runtime.md +61 -0
  59. package/docs/guides/visual-battery.md +58 -0
  60. package/docs/guides/vitest.md +41 -0
  61. package/docs/introduction.md +29 -0
  62. package/docs/package.json +13 -0
  63. package/docs/quick-start.md +47 -0
  64. package/docs/reference/troubleshooting.md +33 -0
  65. package/docs/security.md +15 -0
  66. package/docs/sourcey.config.ts +79 -0
  67. package/llms.txt +32 -0
  68. package/maestro/smoke.template.yaml +11 -0
  69. package/package.json +196 -0
package/AGENTS.md ADDED
@@ -0,0 +1,140 @@
1
+ # AGENTS.md
2
+
3
+ This file has two audiences: an agent **consuming** `game-harness`
4
+ as a dependency in a game repository, and an agent **contributing** to this
5
+ repository itself. Read the section that matches your task.
6
+
7
+ ## Consuming this package
8
+
9
+ Game Harness is release-grade browser QA primitives for TypeScript games —
10
+ silent Playwright/Vitest sessions, deterministic screenshots, production-runtime
11
+ proof, and Lighthouse gates. It is a focused library, not a test framework:
12
+ the game keeps its own journeys, assertions, art direction, and audio engine.
13
+
14
+ Full guides live at [jonbogaty.com/game-harness](https://jonbogaty.com/game-harness/);
15
+ [llms.txt](llms.txt) indexes every page. The rules below are the ones an
16
+ agent gets wrong most often.
17
+
18
+ ### Install only what you use
19
+
20
+ The package root is peer-free and never loads Playwright or Vitest. Install
21
+ only the peer family for the entry point you import:
22
+
23
+ ```sh
24
+ # Playwright config and production-runtime verification
25
+ pnpm add -D game-harness @playwright/test
26
+ pnpm exec playwright install chromium
27
+
28
+ # Vitest Browser Mode instead
29
+ pnpm add -D game-harness vitest @vitest/browser-playwright playwright
30
+ pnpm exec playwright install chromium
31
+
32
+ # Peer-free Lighthouse, release-ladder, or visual-battery utilities only
33
+ pnpm add -D game-harness
34
+ ```
35
+
36
+ Node 22 or newer is required.
37
+
38
+ ### Entry points
39
+
40
+ Import only the subpath a task needs — never import a framework subpath from
41
+ code that must stay peer-free.
42
+
43
+ | Entry point | Use for | Requires |
44
+ | --------------------- | ------------------------------------------------------------ | -------------------------------------- |
45
+ | `game-harness` (root) | Lighthouse presets, release ladder, visual battery | nothing |
46
+ | `/chromium` | Renderer + mandatory `--mute-audio` launch profile | nothing |
47
+ | `/silent-qa` | Application-side runtime mute adapter and readiness marker | nothing |
48
+ | `/playwright` | Device tiers, isolated ports, strict-port preview server | `@playwright/test` |
49
+ | `/production-runtime` | Fresh server/browser lifecycle, fail-closed runtime evidence | `@playwright/test` |
50
+ | `/vitest` | Vitest Browser Mode config fragment | `vitest`, `@vitest/browser-playwright` |
51
+
52
+ Full detail: [Entry points](https://jonbogaty.com/game-harness/entry-points/).
53
+
54
+ ### The silence contract is not optional
55
+
56
+ Every browser this package launches gets `--mute-audio` appended last,
57
+ regardless of caller-supplied args. That is defense in depth, not the whole
58
+ contract — the application must also call `activateSilentQa()` (or
59
+ `activateSilentQaAsync()` if muting is async) before the audio engine
60
+ initializes, so it can publish `<html data-audio-mode="muted-test">`.
61
+ `openSilentGame()` will not resolve until that marker exists. Do not add an
62
+ "audible debug mode" escape hatch; verify audio state through mocks,
63
+ analyser assertions, or programmatic engine state instead. See
64
+ [Chromium launch profile & Silent QA](https://jonbogaty.com/game-harness/guides/chromium-and-silent-qa/).
65
+
66
+ ### Never hard-code a preview/dev-server port
67
+
68
+ Use `definePlaywrightConfig({ port, webServerCommand })` (or
69
+ `findAvailableProductionPort()` for `production-runtime`) instead of a
70
+ literal port in `playwright.config.ts` or a server command. On CI the
71
+ factory derives a deterministic port from repository/run/job identity so
72
+ concurrent workflows can't collide; a hard-coded port bypasses that
73
+ isolation and is not valid release evidence. See
74
+ [Playwright](https://jonbogaty.com/game-harness/guides/playwright/) and
75
+ [Production runtime verification](https://jonbogaty.com/game-harness/guides/production-runtime/).
76
+
77
+ ### Screenshot baselines have one canonical location
78
+
79
+ `runVisualBattery()` requires `__screenshots__/` directly under the harness
80
+ directory a test file lives in (Vitest resolves screenshot paths relative to
81
+ the test file). A second `__screenshots__` directory anywhere else in the
82
+ harness tree is rejected — it would let a screenshot escape the Git diff
83
+ gate. See [Visual battery](https://jonbogaty.com/game-harness/guides/visual-battery/).
84
+
85
+ ### Before claiming a change works
86
+
87
+ Run the same gate CI runs: `pnpm verify` (formatting, lint, types, coverage,
88
+ build, `publint`/`@arethetypeswrong/cli`, and clean packed-consumer smoke
89
+ tests) in the _consuming_ repo, not just `pnpm test`. A green `pnpm test`
90
+ with a broken export or a headless-mode regression is not release evidence.
91
+
92
+ ## Contributing to this repository
93
+
94
+ This is a pnpm workspace: the library at the repo root
95
+ (`game-harness`) and its private Sourcey documentation workspace
96
+ under `docs/` (`game-harness-docs`, never published). Sourcey is the only
97
+ documentation renderer. Its Markdown source and `sourcey.config.ts` live in
98
+ that directory; `docs/dist/` is generated and ignored.
99
+
100
+ ### Setup
101
+
102
+ ```sh
103
+ mise install # or: nvm use && corepack enable
104
+ pnpm install --frozen-lockfile
105
+ pnpm verify
106
+ ```
107
+
108
+ `mise.toml` is local-only. CI reads the Node version from `.nvmrc` and the
109
+ pnpm version from `package.json`'s `packageManager` field via the official
110
+ `actions/setup-node` and `pnpm/action-setup` actions — never edit a
111
+ hardcoded version string into a workflow file.
112
+
113
+ ### Commands
114
+
115
+ - `pnpm verify` — the full gate: format check, Oxlint, strict typecheck,
116
+ 100%-coverage test run, ESM+CJS+types build, `publint`/attw, and
117
+ clean-tarball consumer smoke tests. This is what CI runs; run it before
118
+ every commit.
119
+ - `pnpm test` — unit and contract tests only, for fast iteration.
120
+ - `pnpm --filter game-harness-docs validate` / `pnpm --filter
121
+ game-harness-docs dev` — build or preview the Sourcey docs site in isolation.
122
+ - `pnpm format` — apply Prettier.
123
+
124
+ ### Conventions
125
+
126
+ - Conventional Commits (`fix:`, `feat:`, `docs:`, `refactor:`, `test:`,
127
+ `chore:`). release-please derives the changelog and next version from
128
+ these — never hand-edit `CHANGELOG.md` or the version field.
129
+ - `docs/architecture.md` is packed into the npm tarball (see `package.json`
130
+ `files`) and is also the Sourcey architecture page. Do not create a parallel
131
+ documentation renderer or a second architecture copy.
132
+ - Every GitHub Actions step is pinned to an exact commit SHA (resolved via
133
+ `gh api repos/<owner>/<repo>/releases/latest`, never guessed from
134
+ training data), with a `# vX.Y.Z` comment. The repository also requires
135
+ SHA pinning (`sha_pinning_required: true`) at the Actions-settings level.
136
+ - Branch protection on `main` requires the named `dependency-review` and
137
+ `repository-policy` checks, automated quality checks, and resolved review
138
+ threads, but no human approval. Merge commits preserve the topic branch
139
+ history; squash, rebase, direct default-branch pushes, and force pushes are
140
+ not part of the trusted-agent path.
package/CHANGELOG.md ADDED
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ All notable changes are recorded here. Releases follow
4
+ [Semantic Versioning](https://semver.org/) and are generated from Conventional
5
+ Commits by release-please.
6
+
7
+ ## [1.0.0](https://github.com/jbcom/game-harness/compare/game-harness-v0.5.0...game-harness-v1.0.0) (2026-08-24)
8
+
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+
12
+ * publish unscoped game-harness package
13
+
14
+ ### Features
15
+
16
+ * publish unscoped game-harness package ([db71974](https://github.com/jbcom/game-harness/commit/db71974fb5082ae6fb8870016f004338d85a3bc9))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * use bound SonarQube Cloud analysis ([914a271](https://github.com/jbcom/game-harness/commit/914a271d70b95df816fca3f8366a8670a39a6f7d))
22
+
23
+ ## [0.5.0](https://github.com/jbcom/game-harness/compare/game-harness-v0.4.3...game-harness-v0.5.0) (2026-08-24)
24
+
25
+
26
+ ### Features
27
+
28
+ * complete production-ready OSS release ([90ed8e9](https://github.com/jbcom/game-harness/commit/90ed8e9939c6a176c686a068ab03fe3378d7fee8))
29
+ * **docs:** migrate site to Sourcey ([06d8beb](https://github.com/jbcom/game-harness/commit/06d8beb87581c1bed77c0ad8e25c31c10f6faae8))
30
+ * **docs:** scaffold Astro + Starlight documentation site ([76eb557](https://github.com/jbcom/game-harness/commit/76eb557aaf0ebc548a8c7a4a21f4eb9eef769910))
31
+ * harden release proof and production runtime verification ([#9](https://github.com/jbcom/game-harness/issues/9)) ([b0b8659](https://github.com/jbcom/game-harness/commit/b0b8659cb78c0faeaf3ceb6f72a770fd43894fe3))
32
+ * **persistence:** align Capacitor 8.5 and release contracts ([#41](https://github.com/jbcom/game-harness/issues/41)) ([f49f6bf](https://github.com/jbcom/game-harness/commit/f49f6bf1b2ec340a980d5f791de19827afa14598))
33
+ * publish game-harness as a production-ready OSS package ([02e50b1](https://github.com/jbcom/game-harness/commit/02e50b1567700e7873c627977233fd4ed76eb6bd))
34
+ * **test-harness:** extract vitest-browser+playwright+visual-battery harness to @arcade-cabinet/test-harness ([#1](https://github.com/jbcom/game-harness/issues/1)) ([1609226](https://github.com/jbcom/game-harness/commit/1609226b0f6e464abf0ca2e6cea51bf7e18dcac2))
35
+ * **test-harness:** isolate concurrent Playwright ports ([5703743](https://github.com/jbcom/game-harness/commit/57037437427c03247142e1c81ee5c09fe87733d8))
36
+ * **test-harness:** share silent QA runtime adapter ([#15](https://github.com/jbcom/game-harness/issues/15)) ([78f1b23](https://github.com/jbcom/game-harness/commit/78f1b233ea705b58ca1f2b9f309eb9810d791dab))
37
+ * **test-harness:** standardize headed hardware WebGL proof ([#12](https://github.com/jbcom/game-harness/issues/12)) ([ebd1eca](https://github.com/jbcom/game-harness/commit/ebd1ecaac9e606d63d7a4f4cfdb2315390fedc6a))
38
+
39
+
40
+ ### Bug Fixes
41
+
42
+ * address CodeRabbit review findings on PR [#1](https://github.com/jbcom/game-harness/issues/1) ([a82790c](https://github.com/jbcom/game-harness/commit/a82790c80ef5034987ff9c2edd1c48520c6dc404))
43
+ * **ci:** keep browser evidence deterministic ([6e2f889](https://github.com/jbcom/game-harness/commit/6e2f889f6dde4e3e20c94a74b4c920ac941e1c27))
44
+ * harden portable harness execution ([0d84800](https://github.com/jbcom/game-harness/commit/0d848001e0ba4c82ab1ef9af5c7db4c3a9b3ee47))
45
+ * harden visual and base-path validation ([682061f](https://github.com/jbcom/game-harness/commit/682061fa331c3c72ffcefa70208d845636c56ba5))
46
+ * make release checks portable ([4d3a4c7](https://github.com/jbcom/game-harness/commit/4d3a4c7f6fb2bdf6613c093fbc517ea009941a60))
47
+ * remove leading ./ from bin paths, npm publish silently strips it ([162d687](https://github.com/jbcom/game-harness/commit/162d687b97a42663026c3d5e79e25dc18e4bba37))
48
+ * require named repository policy gates ([ba23f17](https://github.com/jbcom/game-harness/commit/ba23f17595fb6f402342dbc77452043f85e96dd4))
49
+ * require named repository policy gates ([23922f8](https://github.com/jbcom/game-harness/commit/23922f8d1f2517d15103a423cdee3b2627759a7d))
50
+ * resolve release review findings ([c76b4ec](https://github.com/jbcom/game-harness/commit/c76b4ec64b211d0cf69ba5939b3dfa8c1c48b959))
51
+ * split release.yml into release-please + cd workflows, fix npm token secret ([83ca25d](https://github.com/jbcom/game-harness/commit/83ca25d91d62eb085e06340030a8dfe30fc735db))
52
+ * **test-harness:** gate deterministic canvas baselines ([8cd458a](https://github.com/jbcom/game-harness/commit/8cd458adf583733da7a04a29f08d05772f73015c))
53
+ * **test-harness:** harden 0.4.3 release proof ([#49](https://github.com/jbcom/game-harness/issues/49)) ([4fae4c6](https://github.com/jbcom/game-harness/commit/4fae4c653c85bb7161ee60e2d15a74d72b5c04a7))
54
+ * **test-harness:** isolate WebGL visual baselines ([48d02bb](https://github.com/jbcom/game-harness/commit/48d02bb87cef8e09bf1f3a074ee5cae5ff2a2ed3))
55
+ * **test-harness:** keep cleanup guard outside finally ([29d23e8](https://github.com/jbcom/game-harness/commit/29d23e8e2c298f563cbcb85f350288a8b1fc80cb))
56
+ * **test-harness:** make framework peers entrypoint-optional ([#4](https://github.com/jbcom/game-harness/issues/4)) ([cfc726a](https://github.com/jbcom/game-harness/commit/cfc726a0dc8e33d263f40c46e128e6f11ee90ed0))
57
+ * **test-harness:** ship a workspace-safe visual battery CLI ([71b90f3](https://github.com/jbcom/game-harness/commit/71b90f30f51f9915fbd2e4a57faad915177e5f1d))
58
+ * the release verifier was genuinely broken, plus package.json metadata ([6dc40ef](https://github.com/jbcom/game-harness/commit/6dc40effb60dbbcb48f300fee2079040789fe22c))
59
+ * validate Sourcey output and visual cwd ([2ddbcd9](https://github.com/jbcom/game-harness/commit/2ddbcd9edd77f142580cbe8cda58a66bb2ffd97c))
60
+
61
+ ## 0.4.3 - 2026-08-24
62
+
63
+ ### Added
64
+
65
+ - Initial standalone public package extracted from the production browser-game
66
+ verification harness.
67
+ - Peer-isolated Playwright and Vitest Browser Mode configuration entry points.
68
+ - Fail-closed silent-QA, production-runtime, visual-regression, Lighthouse, and
69
+ release-ladder primitives.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jon Bogaty
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.