@testspectra/react 1.1.8-rc.2 → 1.1.8-rc.20
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/LICENSE.md +48 -0
- package/bin/testspectra-react.js +7 -7
- package/dist/cli.js +34 -7
- package/dist/index.js +45 -8
- package/package.json +17 -15
- package/vitest.config.ts +117 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# TestSpectra Commercial Software License Agreement
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TestSpectra. All rights reserved.
|
|
4
|
+
|
|
5
|
+
IMPORTANT NOTICE: This software is NOT open-source. Although distribution archives,
|
|
6
|
+
npm packages, and editor extensions are publicly downloadable, installation,
|
|
7
|
+
execution, and use of the Software are strictly conditioned upon obtaining a valid
|
|
8
|
+
Commercial License or an authorized Evaluation/Trial License from TestSpectra.
|
|
9
|
+
|
|
10
|
+
1. GRANT OF LICENSE
|
|
11
|
+
Subject to payment of applicable license fees or an active authorized evaluation
|
|
12
|
+
period, TestSpectra grants you a non-exclusive, non-transferable, revocable license
|
|
13
|
+
to install and execute the Software solely for authoring, debugging, and executing
|
|
14
|
+
automated software tests.
|
|
15
|
+
|
|
16
|
+
2. LICENSE ACTIVATION & ENFORCEMENT
|
|
17
|
+
- Use of the Software requires activation via a valid License Key, authorized CI token,
|
|
18
|
+
or active TestSpectra Cloud account.
|
|
19
|
+
- Any attempt to circumvent, disable, modify, reverse engineer, or tamper with the
|
|
20
|
+
license verification mechanisms, cryptographic signatures, or binary checks is
|
|
21
|
+
a material breach of this Agreement and automatically terminates your license.
|
|
22
|
+
|
|
23
|
+
3. RESTRICTIONS
|
|
24
|
+
You shall not, and shall not permit any third party to:
|
|
25
|
+
- Decompile, disassemble, reverse engineer, or derive source code from the binaries,
|
|
26
|
+
compiled scripts, or libraries of the Software.
|
|
27
|
+
- Sublicense, sell, rent, lease, distribute, or host the Software as a service for third parties.
|
|
28
|
+
- Re-brand, white-label, or package the Software or any of its components as part of a
|
|
29
|
+
competing commercial QA, testing, or developer tooling product.
|
|
30
|
+
- Modify, alter, or remove any proprietary notices, copyright labels, or license headers.
|
|
31
|
+
|
|
32
|
+
4. INTELLECTUAL PROPERTY
|
|
33
|
+
The Software, including its source code, architecture, Rust core engine, algorithms,
|
|
34
|
+
matchers, extensions, interfaces, and documentation, represents valuable intellectual
|
|
35
|
+
property and trade secrets of TestSpectra.
|
|
36
|
+
|
|
37
|
+
5. TERMINATION
|
|
38
|
+
This license is effective until terminated. Your rights under this license will terminate
|
|
39
|
+
automatically without notice if you fail to comply with any of its terms, or upon expiration
|
|
40
|
+
of your active subscription or trial term. Upon termination, you must cease all use of
|
|
41
|
+
the Software and delete all copies in your possession.
|
|
42
|
+
|
|
43
|
+
6. DISCLAIMER OF WARRANTY & LIMITATION OF LIABILITY
|
|
44
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
45
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
46
|
+
PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
47
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
48
|
+
ARISING FROM THE USE OF OR INABILITY TO USE THE SOFTWARE.
|
package/bin/testspectra-react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { runCli } from '../dist/cli.js';
|
|
3
|
-
|
|
4
|
-
runCli().catch((err) => {
|
|
5
|
-
console.error(err);
|
|
6
|
-
process.exit(1);
|
|
7
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCli } from '../dist/cli.js';
|
|
3
|
+
|
|
4
|
+
runCli().catch((err) => {
|
|
5
|
+
console.error(err);
|
|
6
|
+
process.exit(1);
|
|
7
|
+
});
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
|
-
import
|
|
2
|
+
import spawn from "cross-spawn";
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
async function runComponentTests(options = {}) {
|
|
5
|
-
const
|
|
6
|
+
const rawCwd = options.cwd ?? process.cwd();
|
|
7
|
+
const cwd = path.resolve(rawCwd);
|
|
6
8
|
const configPath = fileURLToPath(new URL("../vitest.config.ts", import.meta.url));
|
|
7
9
|
const ext = process.platform === "win32" ? ".cmd" : "";
|
|
8
10
|
const vitestBin = fileURLToPath(new URL(`../node_modules/.bin/vitest${ext}`, import.meta.url));
|
|
@@ -11,7 +13,11 @@ async function runComponentTests(options = {}) {
|
|
|
11
13
|
args.push("--reporter=default", "--reporter=json", `--outputFile.json=${options.outputFile}`);
|
|
12
14
|
}
|
|
13
15
|
if (options.spec) {
|
|
14
|
-
|
|
16
|
+
let specPattern = options.spec.replace(/\\/g, "/");
|
|
17
|
+
if (path.isAbsolute(options.spec)) {
|
|
18
|
+
specPattern = path.relative(cwd, options.spec).replace(/\\/g, "/");
|
|
19
|
+
}
|
|
20
|
+
args.push(specPattern);
|
|
15
21
|
}
|
|
16
22
|
const semanticReporter = Boolean(options.onLine);
|
|
17
23
|
return new Promise((resolve) => {
|
|
@@ -20,14 +26,13 @@ async function runComponentTests(options = {}) {
|
|
|
20
26
|
cwd,
|
|
21
27
|
env: {
|
|
22
28
|
...process.env,
|
|
23
|
-
TESTSPECTRA_TEST_ROOT: cwd,
|
|
29
|
+
TESTSPECTRA_TEST_ROOT: cwd.replace(/\\/g, "/"),
|
|
24
30
|
TESTSPECTRA_HEADLESS: options.headless === false ? "false" : "true",
|
|
25
31
|
TESTSPECTRA_STEP_DELAY: String(options.stepDelayMs ?? 0),
|
|
26
32
|
TESTSPECTRA_FILE_PARALLELISM: options.concurrency === 1 ? "false" : "true",
|
|
27
33
|
...options.browserExecutablePath ? { TESTSPECTRA_BROWSER_EXECUTABLE: options.browserExecutablePath } : {},
|
|
28
34
|
TESTSPECTRA_SEMANTIC_REPORTER: semanticReporter ? "1" : "0"
|
|
29
|
-
}
|
|
30
|
-
shell: process.platform === "win32"
|
|
35
|
+
}
|
|
31
36
|
});
|
|
32
37
|
if (semanticReporter) {
|
|
33
38
|
const handleData = (buf) => {
|
|
@@ -64,7 +69,29 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
64
69
|
const parsed = parseInt(String(rawDelay), 10);
|
|
65
70
|
if (!isNaN(parsed) && parsed >= 0) stepDelayMs = parsed;
|
|
66
71
|
}
|
|
67
|
-
|
|
72
|
+
let spec = getFlagValue(argv, "--spec", "-s");
|
|
73
|
+
if (!spec) {
|
|
74
|
+
const flagsWithValues = /* @__PURE__ */ new Set([
|
|
75
|
+
"--step-delay",
|
|
76
|
+
"--delay",
|
|
77
|
+
"--spec",
|
|
78
|
+
"-s",
|
|
79
|
+
"--output",
|
|
80
|
+
"-o",
|
|
81
|
+
"--concurrency",
|
|
82
|
+
"-c",
|
|
83
|
+
"--browser-executable"
|
|
84
|
+
]);
|
|
85
|
+
for (let i = 1; i < argv.length; i++) {
|
|
86
|
+
const arg = argv[i];
|
|
87
|
+
if (arg.startsWith("-")) {
|
|
88
|
+
if (flagsWithValues.has(arg)) i++;
|
|
89
|
+
} else {
|
|
90
|
+
spec = arg;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
68
95
|
const outputFile = getFlagValue(argv, "--output", "-o");
|
|
69
96
|
const rawConcurrency = getFlagValue(argv, "--concurrency", "-c");
|
|
70
97
|
let concurrency;
|
package/dist/index.js
CHANGED
|
@@ -51,6 +51,14 @@ var DomDriverBridge = class {
|
|
|
51
51
|
"Spectra.navigate() is not supported in component testing mode. Use Spectra.mount(<Component />) to render a component tree instead of navigating a URL."
|
|
52
52
|
);
|
|
53
53
|
}
|
|
54
|
+
async setCookies(setCookieHeaders, _url) {
|
|
55
|
+
const headers = Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders];
|
|
56
|
+
for (const header of headers) {
|
|
57
|
+
if (typeof document !== "undefined") {
|
|
58
|
+
document.cookie = header;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
54
62
|
async back() {
|
|
55
63
|
throw new Error("Spectra.back() is not supported in component testing mode.");
|
|
56
64
|
}
|
|
@@ -284,7 +292,9 @@ var DomDriverBridge = class {
|
|
|
284
292
|
}
|
|
285
293
|
async shouldHaveNoConsoleErrors() {
|
|
286
294
|
if (this.consoleErrors.length > 0) {
|
|
287
|
-
throw new Error(
|
|
295
|
+
throw new Error(
|
|
296
|
+
`Expected no console errors, but found ${this.consoleErrors.length}: ${this.consoleErrors.join("; ")}`
|
|
297
|
+
);
|
|
288
298
|
}
|
|
289
299
|
}
|
|
290
300
|
async clearCookies() {
|
|
@@ -337,10 +347,12 @@ async function mount(element) {
|
|
|
337
347
|
}
|
|
338
348
|
|
|
339
349
|
// src/cli.ts
|
|
340
|
-
import
|
|
350
|
+
import spawn from "cross-spawn";
|
|
351
|
+
import path from "node:path";
|
|
341
352
|
import { fileURLToPath } from "node:url";
|
|
342
353
|
async function runComponentTests(options = {}) {
|
|
343
|
-
const
|
|
354
|
+
const rawCwd = options.cwd ?? process.cwd();
|
|
355
|
+
const cwd = path.resolve(rawCwd);
|
|
344
356
|
const configPath = fileURLToPath(new URL("../vitest.config.ts", import.meta.url));
|
|
345
357
|
const ext = process.platform === "win32" ? ".cmd" : "";
|
|
346
358
|
const vitestBin = fileURLToPath(new URL(`../node_modules/.bin/vitest${ext}`, import.meta.url));
|
|
@@ -349,7 +361,11 @@ async function runComponentTests(options = {}) {
|
|
|
349
361
|
args.push("--reporter=default", "--reporter=json", `--outputFile.json=${options.outputFile}`);
|
|
350
362
|
}
|
|
351
363
|
if (options.spec) {
|
|
352
|
-
|
|
364
|
+
let specPattern = options.spec.replace(/\\/g, "/");
|
|
365
|
+
if (path.isAbsolute(options.spec)) {
|
|
366
|
+
specPattern = path.relative(cwd, options.spec).replace(/\\/g, "/");
|
|
367
|
+
}
|
|
368
|
+
args.push(specPattern);
|
|
353
369
|
}
|
|
354
370
|
const semanticReporter = Boolean(options.onLine);
|
|
355
371
|
return new Promise((resolve) => {
|
|
@@ -358,14 +374,13 @@ async function runComponentTests(options = {}) {
|
|
|
358
374
|
cwd,
|
|
359
375
|
env: {
|
|
360
376
|
...process.env,
|
|
361
|
-
TESTSPECTRA_TEST_ROOT: cwd,
|
|
377
|
+
TESTSPECTRA_TEST_ROOT: cwd.replace(/\\/g, "/"),
|
|
362
378
|
TESTSPECTRA_HEADLESS: options.headless === false ? "false" : "true",
|
|
363
379
|
TESTSPECTRA_STEP_DELAY: String(options.stepDelayMs ?? 0),
|
|
364
380
|
TESTSPECTRA_FILE_PARALLELISM: options.concurrency === 1 ? "false" : "true",
|
|
365
381
|
...options.browserExecutablePath ? { TESTSPECTRA_BROWSER_EXECUTABLE: options.browserExecutablePath } : {},
|
|
366
382
|
TESTSPECTRA_SEMANTIC_REPORTER: semanticReporter ? "1" : "0"
|
|
367
|
-
}
|
|
368
|
-
shell: process.platform === "win32"
|
|
383
|
+
}
|
|
369
384
|
});
|
|
370
385
|
if (semanticReporter) {
|
|
371
386
|
const handleData = (buf) => {
|
|
@@ -402,7 +417,29 @@ async function runCli(argv = process.argv.slice(2)) {
|
|
|
402
417
|
const parsed = parseInt(String(rawDelay), 10);
|
|
403
418
|
if (!isNaN(parsed) && parsed >= 0) stepDelayMs = parsed;
|
|
404
419
|
}
|
|
405
|
-
|
|
420
|
+
let spec = getFlagValue(argv, "--spec", "-s");
|
|
421
|
+
if (!spec) {
|
|
422
|
+
const flagsWithValues = /* @__PURE__ */ new Set([
|
|
423
|
+
"--step-delay",
|
|
424
|
+
"--delay",
|
|
425
|
+
"--spec",
|
|
426
|
+
"-s",
|
|
427
|
+
"--output",
|
|
428
|
+
"-o",
|
|
429
|
+
"--concurrency",
|
|
430
|
+
"-c",
|
|
431
|
+
"--browser-executable"
|
|
432
|
+
]);
|
|
433
|
+
for (let i = 1; i < argv.length; i++) {
|
|
434
|
+
const arg = argv[i];
|
|
435
|
+
if (arg.startsWith("-")) {
|
|
436
|
+
if (flagsWithValues.has(arg)) i++;
|
|
437
|
+
} else {
|
|
438
|
+
spec = arg;
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
406
443
|
const outputFile = getFlagValue(argv, "--output", "-o");
|
|
407
444
|
const rawConcurrency = getFlagValue(argv, "--concurrency", "-c");
|
|
408
445
|
let concurrency;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testspectra/react",
|
|
3
|
-
"version": "1.1.8-rc.
|
|
3
|
+
"version": "1.1.8-rc.20",
|
|
4
4
|
"description": "Bundled Vitest browser-mode runner for React component testing with the TestSpectra Spectra.* DSL",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"testspectra",
|
|
@@ -31,33 +31,35 @@
|
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
34
|
-
"bin"
|
|
34
|
+
"bin",
|
|
35
|
+
"vitest.config.ts"
|
|
35
36
|
],
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "node scripts/build.js",
|
|
38
|
-
"typecheck": "tsc --noEmit",
|
|
39
|
-
"test": "vitest run --config ./vitest.config.ts",
|
|
40
|
-
"prepublishOnly": "npm run build"
|
|
41
|
-
},
|
|
42
37
|
"dependencies": {
|
|
43
|
-
"@testspectra/matchers": "workspace:*",
|
|
44
38
|
"@testing-library/react": "^16.0.0",
|
|
45
39
|
"@testing-library/user-event": "^14.5.2",
|
|
46
40
|
"@vitejs/plugin-react": "^4.3.1",
|
|
47
41
|
"@vitest/browser": "^2.1.8",
|
|
42
|
+
"cross-spawn": "^7.0.6",
|
|
48
43
|
"playwright": "^1.48.0",
|
|
49
|
-
"vitest": "
|
|
44
|
+
"vitest": "^2.1.8",
|
|
45
|
+
"@testspectra/matchers": "1.1.8-rc.20"
|
|
50
46
|
},
|
|
51
47
|
"peerDependencies": {
|
|
52
48
|
"react": ">=18.0.0",
|
|
53
49
|
"react-dom": ">=18.0.0"
|
|
54
50
|
},
|
|
55
51
|
"devDependencies": {
|
|
56
|
-
"@types/
|
|
52
|
+
"@types/cross-spawn": "^6.0.6",
|
|
53
|
+
"@types/node": "^20.14.0",
|
|
57
54
|
"@types/react": "^18.3.3",
|
|
58
55
|
"@types/react-dom": "^18.3.0",
|
|
59
|
-
"esbuild": "
|
|
60
|
-
"typescript": "
|
|
56
|
+
"esbuild": "^0.28.2",
|
|
57
|
+
"typescript": "^5.6.3"
|
|
61
58
|
},
|
|
62
|
-
"license": "SEE LICENSE IN LICENSE.md"
|
|
63
|
-
|
|
59
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "node scripts/build.js",
|
|
62
|
+
"typecheck": "tsc --noEmit",
|
|
63
|
+
"test": "vitest run --config ./vitest.config.ts"
|
|
64
|
+
}
|
|
65
|
+
}
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundled Vitest browser-mode configuration for @testspectra/react.
|
|
3
|
+
*
|
|
4
|
+
* Consumers never author this file themselves — `spectra test` / `testspectra-react test` loads
|
|
5
|
+
* it programmatically (see src/cli.ts). `root` is deliberately kept fixed at THIS package's own
|
|
6
|
+
* directory (not the consumer's project) — `@vitest/browser`'s transitive dependencies
|
|
7
|
+
* (`@testing-library/dom`, `@testing-library/user-event`) live under this package's own
|
|
8
|
+
* `node_modules` under pnpm's strict per-package isolation, and Vite's dependency optimizer
|
|
9
|
+
* fails to resolve them if `root` points elsewhere. Test discovery and auto-import instead use
|
|
10
|
+
* absolute paths built from `TESTSPECTRA_TEST_ROOT` (see auto_import.ts and cli.ts).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readdirSync, existsSync } from 'node:fs';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { fileURLToPath } from 'node:url';
|
|
16
|
+
|
|
17
|
+
import react from '@vitejs/plugin-react';
|
|
18
|
+
import { defineConfig } from 'vitest/config';
|
|
19
|
+
|
|
20
|
+
const packageDir = fileURLToPath(new URL('.', import.meta.url));
|
|
21
|
+
const setupFile = path.join(packageDir, 'src/setup.ts');
|
|
22
|
+
const testRoot = (process.env.TESTSPECTRA_TEST_ROOT || process.cwd()).replace(/\\/g, '/');
|
|
23
|
+
|
|
24
|
+
/** Scans <testRoot>/page-objects, /support/steps, /fixtures — mirrors the Rust orchestrator's
|
|
25
|
+
* AutoImportManifest scan for E2E (docs/v2/cli/ambient-types-generator.md), reimplemented here
|
|
26
|
+
* in Node (this config file), since there is no Rust orchestrator in this mode. */
|
|
27
|
+
function buildAutoImportManifest(root: string) {
|
|
28
|
+
function scanEntityDir(subdir: string, filePattern: (platform: string) => string) {
|
|
29
|
+
const dir = path.join(root, subdir);
|
|
30
|
+
if (!existsSync(dir)) return [] as Array<{ name: string; path: string }>;
|
|
31
|
+
const entries: Array<{ name: string; path: string }> = [];
|
|
32
|
+
for (const name of readdirSync(dir, { withFileTypes: true })) {
|
|
33
|
+
if (!name.isDirectory()) continue;
|
|
34
|
+
for (const platform of ['web', 'common']) {
|
|
35
|
+
for (const ext of ['tsx', 'ts']) {
|
|
36
|
+
const candidate = path.join(dir, name.name, filePattern(platform).replace(/\.tsx?$/, `.${ext}`));
|
|
37
|
+
if (existsSync(candidate)) {
|
|
38
|
+
entries.push({ name: name.name, path: candidate.replace(/\\/g, '/') });
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (entries.at(-1)?.name === name.name) break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return entries;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function scanFixtures(): Array<{ name: string; path: string }> {
|
|
49
|
+
const dir = path.join(root, 'fixtures');
|
|
50
|
+
if (!existsSync(dir)) return [];
|
|
51
|
+
return readdirSync(dir)
|
|
52
|
+
.filter((f) => f.endsWith('.json'))
|
|
53
|
+
.map((f) => ({ name: f.replace(/\.json$/, ''), path: path.join(dir, f).replace(/\\/g, '/') }));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
pageObjects: scanEntityDir('page-objects', (p) => `${p}.tsx`),
|
|
58
|
+
steps: scanEntityDir('support/steps', (p) => `${p}.step.tsx`),
|
|
59
|
+
fixtures: scanFixtures(),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default defineConfig({
|
|
64
|
+
root: packageDir,
|
|
65
|
+
plugins: [react()],
|
|
66
|
+
define: {
|
|
67
|
+
__TESTSPECTRA_AUTO_IMPORT_MANIFEST__: JSON.stringify(buildAutoImportManifest(testRoot)),
|
|
68
|
+
__TESTSPECTRA_STEP_DELAY_MS__: JSON.stringify(Number(process.env.TESTSPECTRA_STEP_DELAY) || 0),
|
|
69
|
+
__TESTSPECTRA_SEMANTIC_REPORTER__: JSON.stringify(process.env.TESTSPECTRA_SEMANTIC_REPORTER === '1'),
|
|
70
|
+
},
|
|
71
|
+
server: {
|
|
72
|
+
fs: { allow: [packageDir, testRoot] },
|
|
73
|
+
},
|
|
74
|
+
test: {
|
|
75
|
+
globals: true,
|
|
76
|
+
setupFiles: [setupFile],
|
|
77
|
+
// When spectra test drives this run, @testspectra/cli's own Reporter (the same semantic,
|
|
78
|
+
// natural-English reporter E2E uses) owns 100% of the terminal output, fed by the
|
|
79
|
+
// [TESTSPECTRA_*] lines emitEvent() now prints (see prelude.ts) — Vitest's own console
|
|
80
|
+
// reporter would just double/clutter that output, so it's silenced here. Standalone
|
|
81
|
+
// `pnpm test` / `testspectra-react test` (this env var unset) keeps Vitest's normal reporter.
|
|
82
|
+
reporters: process.env.TESTSPECTRA_SEMANTIC_REPORTER === '1' ? [] : 'default',
|
|
83
|
+
// When TESTSPECTRA_TEST_ROOT is unset, this is the package's own `pnpm test` run (no consumer
|
|
84
|
+
// spawning it) — discover its own smoke test instead of a nonexistent specs/ under packageDir.
|
|
85
|
+
// When set (spawned by cli.ts for a real consumer), only that consumer's specs/ are included —
|
|
86
|
+
// deliberately NOT this package's own src/__tests__/**, so a consumer's `spectra test` output
|
|
87
|
+
// never shows this package's internal smoke test mixed in.
|
|
88
|
+
dir: process.env.TESTSPECTRA_TEST_ROOT ? testRoot : undefined,
|
|
89
|
+
include: process.env.TESTSPECTRA_TEST_ROOT
|
|
90
|
+
? ['specs/**/web.test.tsx', 'specs/**/*.test.tsx']
|
|
91
|
+
: ['src/**/*.test.tsx'],
|
|
92
|
+
browser: {
|
|
93
|
+
enabled: true,
|
|
94
|
+
provider: 'playwright',
|
|
95
|
+
name: 'chromium',
|
|
96
|
+
// Vitest's CLI does NOT reliably override a `browser.headless` value already set here by
|
|
97
|
+
// `--browser.headless=false` (verified empirically: the spawned Chromium process still
|
|
98
|
+
// carried `--headless` even with the CLI flag passed) — so headed/headless is threaded
|
|
99
|
+
// through as an env var (set by cli.ts) that this config file, which we fully control,
|
|
100
|
+
// reads directly, instead of depending on Vitest's CLI/config-file merge semantics.
|
|
101
|
+
headless: process.env.TESTSPECTRA_HEADLESS !== 'false',
|
|
102
|
+
// Vitest 2.x browser mode has no numeric worker-count knob (unlike the E2E Rust orchestrator's
|
|
103
|
+
// WorkerSizingEngine) — only this parallel/sequential switch. `spectra test --concurrency 1`
|
|
104
|
+
// maps to sequential; any other value (or omitted) keeps Vitest's own parallel default.
|
|
105
|
+
fileParallelism: process.env.TESTSPECTRA_FILE_PARALLELISM !== 'false',
|
|
106
|
+
// Zero browser-discovery logic lives in this package (see cli.ts's RunComponentTestsOptions
|
|
107
|
+
// comment) — `spectra test` locates the Chrome-for-Testing binary `spectra doctor` already
|
|
108
|
+
// manages for the E2E CDP driver and passes it in via this env var, so component testing
|
|
109
|
+
// reuses that install instead of requiring a separate `playwright install` download. Omitted
|
|
110
|
+
// when run standalone (e.g. this package's own `pnpm test`), where Playwright falls back to
|
|
111
|
+
// its own bundled/downloaded browser.
|
|
112
|
+
providerOptions: process.env.TESTSPECTRA_BROWSER_EXECUTABLE
|
|
113
|
+
? { launch: { executablePath: process.env.TESTSPECTRA_BROWSER_EXECUTABLE } }
|
|
114
|
+
: undefined,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|