game-harness 1.1.2 → 1.3.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.
- package/CHANGELOG.md +14 -0
- package/README.md +8 -2
- package/dist/cjs/browser-config.js +15 -1
- package/dist/cjs/chromium-launch.js +1 -0
- package/dist/cjs/vitest-major.js +16 -0
- package/dist/esm/browser-config.js +15 -1
- package/dist/esm/chromium-launch.js +1 -0
- package/dist/esm/vitest-major.js +13 -0
- package/dist/types/browser-config.d.cts +20 -1
- package/dist/types/browser-config.d.ts +20 -1
- package/dist/types/chromium-launch.d.cts +7 -3
- package/dist/types/chromium-launch.d.ts +7 -3
- package/dist/types/vitest-major.d.cts +7 -0
- package/dist/types/vitest-major.d.ts +7 -0
- package/docs/guides/chromium-and-silent-qa.md +5 -2
- package/docs/guides/playwright.md +5 -1
- package/docs/guides/vitest.md +15 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes are recorded here. Releases follow
|
|
|
4
4
|
[Semantic Versioning](https://semver.org/) and are generated from Conventional
|
|
5
5
|
Commits by release-please.
|
|
6
6
|
|
|
7
|
+
## [1.3.0](https://github.com/jbcom/game-harness/compare/game-harness-v1.2.0...game-harness-v1.3.0) (2026-10-10)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **chromium:** add the macos-hardware-metal gpu mode ([008f277](https://github.com/jbcom/game-harness/commit/008f2770886e73a2d323b65bb3f6373ea21be426))
|
|
13
|
+
|
|
14
|
+
## [1.2.0](https://github.com/jbcom/game-harness/compare/game-harness-v1.1.2...game-harness-v1.2.0) (2026-10-10)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **vitest:** pass the browser server's api, custom commands, failure screenshots and isolation through ([29c6d2d](https://github.com/jbcom/game-harness/commit/29c6d2dbaf099b7dcdf8a9cd2b1ffa621e9d9059))
|
|
20
|
+
|
|
7
21
|
## [1.1.2](https://github.com/jbcom/game-harness/compare/game-harness-v1.1.1...game-harness-v1.1.2) (2026-10-07)
|
|
8
22
|
|
|
9
23
|
|
package/README.md
CHANGED
|
@@ -180,6 +180,11 @@ make WebGL start. The default `auto` profile lets Chromium select the native
|
|
|
180
180
|
renderer (including Metal on macOS). `software` is an explicit SwiftShader
|
|
181
181
|
fallback. `linux-hardware-vulkan` applies the reviewed Mesa/ANGLE flags and
|
|
182
182
|
`EGL_PLATFORM=surfaceless` for a runner that exposes `/dev/dri/renderD128`.
|
|
183
|
+
`macos-hardware-metal` asks ANGLE for its Metal backend (`--use-angle=metal
|
|
184
|
+
--ignore-gpu-blocklist`); it is the profile for an Apple Silicon Mac with no
|
|
185
|
+
window session, where `headless: true` still reaches the real GPU (no display
|
|
186
|
+
server or Xvfb is involved), so a render host does not fall back to
|
|
187
|
+
SwiftShader.
|
|
183
188
|
|
|
184
189
|
Vitest's interactive UI is disabled by default even though the Chromium window
|
|
185
190
|
remains visible. This gives Playwright a fixed viewport and a deterministic
|
|
@@ -252,11 +257,12 @@ const browser = await chromium.launch({ args, env, headless: false });
|
|
|
252
257
|
`createChromiumLaunchProfile()` is the peer-free primitive behind both
|
|
253
258
|
`definePlaywrightConfig()` and `defineBrowserTestConfig()` — use it directly
|
|
254
259
|
when driving Chromium yourself (a custom launch script, `production-runtime`'s
|
|
255
|
-
own internals, or a non-Playwright automation layer). It resolves one of
|
|
260
|
+
own internals, or a non-Playwright automation layer). It resolves one of four
|
|
256
261
|
renderer policies (`auto` leaves selection to Chromium; `software` opts into
|
|
257
262
|
SwiftShader explicitly; `linux-hardware-vulkan` applies the reviewed
|
|
258
263
|
Mesa/ANGLE flags plus `EGL_PLATFORM=surfaceless` for a runner exposing
|
|
259
|
-
`/dev/dri/renderD128`
|
|
264
|
+
`/dev/dri/renderD128`; `macos-hardware-metal` asks ANGLE for its Metal backend
|
|
265
|
+
with `--use-angle=metal --ignore-gpu-blocklist`) and always de-duplicates and appends `--mute-audio`
|
|
260
266
|
last, so a caller-supplied arg list can never accidentally drop the silence
|
|
261
267
|
guard. Every profile also carries `CHROMIUM_ANTI_THROTTLING_ARGS`
|
|
262
268
|
(`--disable-background-timer-throttling`, `--disable-renderer-backgrounding`,
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.defineBrowserTestConfig = defineBrowserTestConfig;
|
|
4
4
|
const browser_playwright_1 = require("@vitest/browser-playwright");
|
|
5
5
|
const chromium_launch_js_1 = require("./chromium-launch.js");
|
|
6
|
+
const vitest_major_js_1 = require("./vitest-major.js");
|
|
6
7
|
function resolveHeadless(headless) {
|
|
7
8
|
if (typeof headless === 'boolean')
|
|
8
9
|
return headless;
|
|
@@ -40,7 +41,7 @@ function resolveHeadless(headless) {
|
|
|
40
41
|
* one, wrap the test command in `xvfb-run` rather than forcing headless here.
|
|
41
42
|
*/
|
|
42
43
|
function defineBrowserTestConfig(opts = {}) {
|
|
43
|
-
const { contextOptions = {}, gpuArgs = [], gpuMode = 'auto', headless = false, ui = false, instances = [{ browser: 'chromium' }], optimizeDeps = [], setupFiles, name = 'browser', include = ['tests/browser/**/*.browser.test.{ts,tsx}'], fileParallelism = false, } = opts;
|
|
44
|
+
const { contextOptions = {}, gpuArgs = [], gpuMode = 'auto', headless = false, ui = false, instances = [{ browser: 'chromium' }], optimizeDeps = [], setupFiles, name = 'browser', include = ['tests/browser/**/*.browser.test.{ts,tsx}'], fileParallelism = false, api, commands, screenshotFailures, isolate, } = opts;
|
|
44
45
|
if (!name.trim())
|
|
45
46
|
throw new TypeError('browser project name must not be empty');
|
|
46
47
|
if (instances.length === 0) {
|
|
@@ -73,6 +74,19 @@ function defineBrowserTestConfig(opts = {}) {
|
|
|
73
74
|
if (setupFiles) {
|
|
74
75
|
test.setupFiles = [...setupFiles];
|
|
75
76
|
}
|
|
77
|
+
if (api) {
|
|
78
|
+
if ((0, vitest_major_js_1.vitestMajor)() >= 5)
|
|
79
|
+
test.api = { ...api };
|
|
80
|
+
// Vitest 4's browser server reads its own `api`; Vitest 5's types no longer carry it.
|
|
81
|
+
else
|
|
82
|
+
test.browser.api = { ...api };
|
|
83
|
+
}
|
|
84
|
+
if (commands)
|
|
85
|
+
test.browser = { ...test.browser, commands: { ...commands } };
|
|
86
|
+
if (screenshotFailures !== undefined)
|
|
87
|
+
test.browser = { ...test.browser, screenshotFailures };
|
|
88
|
+
if (isolate !== undefined)
|
|
89
|
+
test.isolate = isolate;
|
|
76
90
|
if (optimizeDeps.length > 0) {
|
|
77
91
|
// Vitest's `test` fragment has no `optimizeDeps` field (that lives at
|
|
78
92
|
// the top-level Vite config) — surface the caller's list here so a
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vitestMajor = vitestMajor;
|
|
4
|
+
const node_1 = require("vitest/node");
|
|
5
|
+
/**
|
|
6
|
+
* The major version of the Vitest the consumer installed. The peer range spans
|
|
7
|
+
* Vitest 4 and 5, which disagree about where some browser-mode options live
|
|
8
|
+
* (Vitest 5 moved the browser server's port from `browser.api` to the
|
|
9
|
+
* top-level `api`, and ignores the old one).
|
|
10
|
+
*/
|
|
11
|
+
function vitestMajor() {
|
|
12
|
+
const major = Number.parseInt(node_1.version, 10);
|
|
13
|
+
if (!Number.isFinite(major))
|
|
14
|
+
throw new Error(`unrecognised Vitest version: ${node_1.version}`);
|
|
15
|
+
return major;
|
|
16
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { playwright } from '@vitest/browser-playwright';
|
|
2
2
|
import { createChromiumLaunchProfile } from './chromium-launch.js';
|
|
3
|
+
import { vitestMajor } from './vitest-major.js';
|
|
3
4
|
function resolveHeadless(headless) {
|
|
4
5
|
if (typeof headless === 'boolean')
|
|
5
6
|
return headless;
|
|
@@ -37,7 +38,7 @@ function resolveHeadless(headless) {
|
|
|
37
38
|
* one, wrap the test command in `xvfb-run` rather than forcing headless here.
|
|
38
39
|
*/
|
|
39
40
|
export function defineBrowserTestConfig(opts = {}) {
|
|
40
|
-
const { contextOptions = {}, gpuArgs = [], gpuMode = 'auto', headless = false, ui = false, instances = [{ browser: 'chromium' }], optimizeDeps = [], setupFiles, name = 'browser', include = ['tests/browser/**/*.browser.test.{ts,tsx}'], fileParallelism = false, } = opts;
|
|
41
|
+
const { contextOptions = {}, gpuArgs = [], gpuMode = 'auto', headless = false, ui = false, instances = [{ browser: 'chromium' }], optimizeDeps = [], setupFiles, name = 'browser', include = ['tests/browser/**/*.browser.test.{ts,tsx}'], fileParallelism = false, api, commands, screenshotFailures, isolate, } = opts;
|
|
41
42
|
if (!name.trim())
|
|
42
43
|
throw new TypeError('browser project name must not be empty');
|
|
43
44
|
if (instances.length === 0) {
|
|
@@ -70,6 +71,19 @@ export function defineBrowserTestConfig(opts = {}) {
|
|
|
70
71
|
if (setupFiles) {
|
|
71
72
|
test.setupFiles = [...setupFiles];
|
|
72
73
|
}
|
|
74
|
+
if (api) {
|
|
75
|
+
if (vitestMajor() >= 5)
|
|
76
|
+
test.api = { ...api };
|
|
77
|
+
// Vitest 4's browser server reads its own `api`; Vitest 5's types no longer carry it.
|
|
78
|
+
else
|
|
79
|
+
test.browser.api = { ...api };
|
|
80
|
+
}
|
|
81
|
+
if (commands)
|
|
82
|
+
test.browser = { ...test.browser, commands: { ...commands } };
|
|
83
|
+
if (screenshotFailures !== undefined)
|
|
84
|
+
test.browser = { ...test.browser, screenshotFailures };
|
|
85
|
+
if (isolate !== undefined)
|
|
86
|
+
test.isolate = isolate;
|
|
73
87
|
if (optimizeDeps.length > 0) {
|
|
74
88
|
// Vitest's `test` fragment has no `optimizeDeps` field (that lives at
|
|
75
89
|
// the top-level Vite config) — surface the caller's list here so a
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { version } from 'vitest/node';
|
|
2
|
+
/**
|
|
3
|
+
* The major version of the Vitest the consumer installed. The peer range spans
|
|
4
|
+
* Vitest 4 and 5, which disagree about where some browser-mode options live
|
|
5
|
+
* (Vitest 5 moved the browser server's port from `browser.api` to the
|
|
6
|
+
* top-level `api`, and ignores the old one).
|
|
7
|
+
*/
|
|
8
|
+
export function vitestMajor() {
|
|
9
|
+
const major = Number.parseInt(version, 10);
|
|
10
|
+
if (!Number.isFinite(major))
|
|
11
|
+
throw new Error(`unrecognised Vitest version: ${version}`);
|
|
12
|
+
return major;
|
|
13
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PlaywrightProviderOptions } from '@vitest/browser-playwright';
|
|
2
|
-
import type { TestUserConfig } from 'vitest/node';
|
|
2
|
+
import type { BrowserConfigOptions, TestUserConfig } from 'vitest/node';
|
|
3
3
|
import { type ChromiumGpuMode } from './chromium-launch.js';
|
|
4
4
|
/**
|
|
5
5
|
* A single browser instance entry, as accepted by Vitest Browser Mode's
|
|
@@ -64,6 +64,25 @@ export interface BrowserTestConfigOptions {
|
|
|
64
64
|
* verified your suite tolerates concurrent browser contexts.
|
|
65
65
|
*/
|
|
66
66
|
fileParallelism?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* The browser server's address, such as the port a CI slot or a local
|
|
69
|
+
* port allocator assigned (`{ port, strictPort: true }`). Placed where the
|
|
70
|
+
* installed Vitest reads it: the top-level `api` on Vitest 5, `browser.api`
|
|
71
|
+
* on Vitest 4. Omitted, Vitest's default port is used.
|
|
72
|
+
*/
|
|
73
|
+
api?: BrowserApiConfig;
|
|
74
|
+
/** Custom browser commands (`browser.commands`), e.g. a pointer drawn along a path. */
|
|
75
|
+
commands?: NonNullable<BrowserConfigOptions['commands']>;
|
|
76
|
+
/** `browser.screenshotFailures`. Omitted, Vitest's default applies. */
|
|
77
|
+
screenshotFailures?: boolean;
|
|
78
|
+
/** The top-level `isolate` (Vitest 5 retired `browser.isolate` for it). Omitted, Vitest's default applies. */
|
|
79
|
+
isolate?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/** The browser server's address options: the subset Vitest 4's `browser.api` and Vitest 5's `api` share. */
|
|
82
|
+
export interface BrowserApiConfig {
|
|
83
|
+
port?: number;
|
|
84
|
+
strictPort?: boolean;
|
|
85
|
+
host?: string;
|
|
67
86
|
}
|
|
68
87
|
/**
|
|
69
88
|
* Builds a `test` fragment for a Vitest Browser Mode project, wired for
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PlaywrightProviderOptions } from '@vitest/browser-playwright';
|
|
2
|
-
import type { TestUserConfig } from 'vitest/node';
|
|
2
|
+
import type { BrowserConfigOptions, TestUserConfig } from 'vitest/node';
|
|
3
3
|
import { type ChromiumGpuMode } from './chromium-launch.js';
|
|
4
4
|
/**
|
|
5
5
|
* A single browser instance entry, as accepted by Vitest Browser Mode's
|
|
@@ -64,6 +64,25 @@ export interface BrowserTestConfigOptions {
|
|
|
64
64
|
* verified your suite tolerates concurrent browser contexts.
|
|
65
65
|
*/
|
|
66
66
|
fileParallelism?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* The browser server's address, such as the port a CI slot or a local
|
|
69
|
+
* port allocator assigned (`{ port, strictPort: true }`). Placed where the
|
|
70
|
+
* installed Vitest reads it: the top-level `api` on Vitest 5, `browser.api`
|
|
71
|
+
* on Vitest 4. Omitted, Vitest's default port is used.
|
|
72
|
+
*/
|
|
73
|
+
api?: BrowserApiConfig;
|
|
74
|
+
/** Custom browser commands (`browser.commands`), e.g. a pointer drawn along a path. */
|
|
75
|
+
commands?: NonNullable<BrowserConfigOptions['commands']>;
|
|
76
|
+
/** `browser.screenshotFailures`. Omitted, Vitest's default applies. */
|
|
77
|
+
screenshotFailures?: boolean;
|
|
78
|
+
/** The top-level `isolate` (Vitest 5 retired `browser.isolate` for it). Omitted, Vitest's default applies. */
|
|
79
|
+
isolate?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/** The browser server's address options: the subset Vitest 4's `browser.api` and Vitest 5's `api` share. */
|
|
82
|
+
export interface BrowserApiConfig {
|
|
83
|
+
port?: number;
|
|
84
|
+
strictPort?: boolean;
|
|
85
|
+
host?: string;
|
|
67
86
|
}
|
|
68
87
|
/**
|
|
69
88
|
* Builds a `test` fragment for a Vitest Browser Mode project, wired for
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/** Browser renderer policy for agent-controlled Chromium sessions. */
|
|
2
|
-
export type ChromiumGpuMode = 'auto' | 'software' | 'linux-hardware-vulkan';
|
|
2
|
+
export type ChromiumGpuMode = 'auto' | 'software' | 'linux-hardware-vulkan' | 'macos-hardware-metal';
|
|
3
3
|
export type ChromiumEnvironment = Record<string, string | undefined>;
|
|
4
4
|
export interface ChromiumLaunchProfileOptions {
|
|
5
5
|
/**
|
|
6
|
-
* `auto` leaves renderer selection to Chromium (Metal on macOS
|
|
7
|
-
* desktop stack elsewhere). `software` opts into
|
|
6
|
+
* `auto` leaves renderer selection to Chromium (Metal on macOS in a headed
|
|
7
|
+
* window, the native desktop stack elsewhere). `software` opts into
|
|
8
|
+
* SwiftShader explicitly.
|
|
8
9
|
* `linux-hardware-vulkan` is a proven Mesa/ANGLE profile for a
|
|
9
10
|
* Linux runner with `/dev/dri/renderD128` passed through.
|
|
11
|
+
* `macos-hardware-metal` asks ANGLE for its Metal backend, which gives a
|
|
12
|
+
* headless Chromium on an Apple Silicon Mac (no window session needed) the
|
|
13
|
+
* real GPU instead of SwiftShader.
|
|
10
14
|
*/
|
|
11
15
|
gpuMode?: ChromiumGpuMode;
|
|
12
16
|
/** Additional Chromium arguments, de-duplicated ahead of `--mute-audio`. */
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/** Browser renderer policy for agent-controlled Chromium sessions. */
|
|
2
|
-
export type ChromiumGpuMode = 'auto' | 'software' | 'linux-hardware-vulkan';
|
|
2
|
+
export type ChromiumGpuMode = 'auto' | 'software' | 'linux-hardware-vulkan' | 'macos-hardware-metal';
|
|
3
3
|
export type ChromiumEnvironment = Record<string, string | undefined>;
|
|
4
4
|
export interface ChromiumLaunchProfileOptions {
|
|
5
5
|
/**
|
|
6
|
-
* `auto` leaves renderer selection to Chromium (Metal on macOS
|
|
7
|
-
* desktop stack elsewhere). `software` opts into
|
|
6
|
+
* `auto` leaves renderer selection to Chromium (Metal on macOS in a headed
|
|
7
|
+
* window, the native desktop stack elsewhere). `software` opts into
|
|
8
|
+
* SwiftShader explicitly.
|
|
8
9
|
* `linux-hardware-vulkan` is a proven Mesa/ANGLE profile for a
|
|
9
10
|
* Linux runner with `/dev/dri/renderD128` passed through.
|
|
11
|
+
* `macos-hardware-metal` asks ANGLE for its Metal backend, which gives a
|
|
12
|
+
* headless Chromium on an Apple Silicon Mac (no window session needed) the
|
|
13
|
+
* real GPU instead of SwiftShader.
|
|
10
14
|
*/
|
|
11
15
|
gpuMode?: ChromiumGpuMode;
|
|
12
16
|
/** Additional Chromium arguments, de-duplicated ahead of `--mute-audio`. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The major version of the Vitest the consumer installed. The peer range spans
|
|
3
|
+
* Vitest 4 and 5, which disagree about where some browser-mode options live
|
|
4
|
+
* (Vitest 5 moved the browser server's port from `browser.api` to the
|
|
5
|
+
* top-level `api`, and ignores the old one).
|
|
6
|
+
*/
|
|
7
|
+
export declare function vitestMajor(): number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The major version of the Vitest the consumer installed. The peer range spans
|
|
3
|
+
* Vitest 4 and 5, which disagree about where some browser-mode options live
|
|
4
|
+
* (Vitest 5 moved the browser server's port from `browser.api` to the
|
|
5
|
+
* top-level `api`, and ignores the old one).
|
|
6
|
+
*/
|
|
7
|
+
export declare function vitestMajor(): number;
|
|
@@ -17,10 +17,13 @@ const browser = await chromium.launch({ args, env, headless: false });
|
|
|
17
17
|
`definePlaywrightConfig()` and `defineBrowserTestConfig()` — use it directly
|
|
18
18
|
when driving Chromium yourself (a custom launch script, `production-runtime`'s
|
|
19
19
|
own internals, or a non-Playwright automation layer). It resolves one of
|
|
20
|
-
|
|
20
|
+
four renderer policies (`auto` leaves selection to Chromium; `software`
|
|
21
21
|
opts into SwiftShader explicitly; `linux-hardware-vulkan` applies the
|
|
22
22
|
reviewed Mesa/ANGLE flags plus `EGL_PLATFORM=surfaceless` for a runner
|
|
23
|
-
exposing `/dev/dri/renderD128`
|
|
23
|
+
exposing `/dev/dri/renderD128`; `macos-hardware-metal` asks ANGLE for its
|
|
24
|
+
Metal backend with `--use-angle=metal --ignore-gpu-blocklist`, which a
|
|
25
|
+
headless Chromium on an Apple Silicon Mac with no window session honours by
|
|
26
|
+
using the real GPU) and always de-duplicates and appends
|
|
24
27
|
`--mute-audio` last, so a caller-supplied arg list can never accidentally
|
|
25
28
|
drop the silence guard.
|
|
26
29
|
|
|
@@ -43,7 +43,11 @@ to make WebGL start. The default `auto` profile lets Chromium select the
|
|
|
43
43
|
native renderer (including Metal on macOS). `software` is an explicit
|
|
44
44
|
SwiftShader fallback. `linux-hardware-vulkan` applies the reviewed
|
|
45
45
|
Mesa/ANGLE flags and `EGL_PLATFORM=surfaceless` for a runner that exposes
|
|
46
|
-
`/dev/dri/renderD128`.
|
|
46
|
+
`/dev/dri/renderD128`. `macos-hardware-metal` asks ANGLE for its Metal backend
|
|
47
|
+
(`--use-angle=metal --ignore-gpu-blocklist`); it is the profile for an Apple
|
|
48
|
+
Silicon Mac with no window session, where `headless: true` still reaches the
|
|
49
|
+
real GPU (no display server or Xvfb is involved), so a render host does not
|
|
50
|
+
fall back to SwiftShader.
|
|
47
51
|
|
|
48
52
|
A Gitea runner job using the hardware profile must install
|
|
49
53
|
`mesa-vulkan-drivers` and `xvfb`, require the render device with
|
package/docs/guides/vitest.md
CHANGED
|
@@ -39,3 +39,18 @@ discover on its own) that must also be merged into your top-level
|
|
|
39
39
|
`vite.config.ts`'s `optimizeDeps.include` — read them off the returned
|
|
40
40
|
fragment's `__optimizeDepsInclude` field, since Vitest's `test` block has no
|
|
41
41
|
`optimizeDeps` field of its own.
|
|
42
|
+
|
|
43
|
+
A game whose suite needs more of Vitest's browser options passes them through
|
|
44
|
+
rather than spreading over the fragment:
|
|
45
|
+
|
|
46
|
+
- `api` is the browser server's address, such as the port a CI slot or a
|
|
47
|
+
local port allocator assigned, with `strictPort: true` so a taken port
|
|
48
|
+
fails rather than drifting. It is placed where the installed Vitest reads
|
|
49
|
+
it: the top-level `api` on Vitest 5 (which ignores `browser.api`),
|
|
50
|
+
`browser.api` on Vitest 4.
|
|
51
|
+
- `commands` registers custom browser commands (`browser.commands`), such as
|
|
52
|
+
a pointer drawn along a path that `userEvent` cannot draw.
|
|
53
|
+
- `screenshotFailures` sets `browser.screenshotFailures`.
|
|
54
|
+
- `isolate` sets the top-level `isolate`, which replaced `browser.isolate`.
|
|
55
|
+
|
|
56
|
+
Each is left to Vitest's default when it is not given.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "game-harness",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Release-grade browser QA primitives for TypeScript games: silent Playwright/Vitest sessions, deterministic screenshots, runtime proof, and Lighthouse gates.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|