@testspectra/react 1.1.8-rc.24 → 1.1.8-rc.28

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/dist/cli.js CHANGED
@@ -10,6 +10,11 @@ import { createRequire } from "node:module";
10
10
  import os from "node:os";
11
11
  import path from "node:path";
12
12
  import { pathToFileURL } from "node:url";
13
+ function resolveEsmUrl(specifier, packageDir) {
14
+ const cjsPath = createRequire(path.join(packageDir, "package.json")).resolve(specifier);
15
+ const esmPath = cjsPath.replace(/\.cjs$/, ".js");
16
+ return pathToFileURL(existsSync(esmPath) ? esmPath : cjsPath).href;
17
+ }
13
18
  function buildAutoImportManifest(root) {
14
19
  function scanEntityDir(subdir, filePattern) {
15
20
  const dir = path.join(root, subdir);
@@ -42,15 +47,17 @@ function buildAutoImportManifest(root) {
42
47
  };
43
48
  }
44
49
  function generateVitestConfig(opts) {
45
- const req = createRequire(path.join(opts.packageDir, "package.json"));
46
- const reactPluginUrl = pathToFileURL(req.resolve("@vitejs/plugin-react")).href;
47
- const vitestConfigUrl = pathToFileURL(req.resolve("vitest/config")).href;
50
+ const reactPluginUrl = resolveEsmUrl("@vitejs/plugin-react", opts.packageDir);
51
+ const vitestConfigUrl = resolveEsmUrl("vitest/config", opts.packageDir);
48
52
  const manifest = buildAutoImportManifest(opts.testRoot);
49
53
  const setupFile = path.join(opts.packageDir, "dist/setup.js").replace(/\\/g, "/");
54
+ const reporterFile = path.join(opts.packageDir, "dist/vitest_reporter.js").replace(/\\/g, "/");
55
+ const reporterUrl = pathToFileURL(reporterFile).href;
50
56
  const normalizedPackageDir = opts.packageDir.replace(/\\/g, "/");
51
57
  const normalizedTestRoot = opts.testRoot.replace(/\\/g, "/");
52
58
  const configContent = `import react from '${reactPluginUrl}';
53
59
  import { defineConfig } from '${vitestConfigUrl}';
60
+ ${opts.semanticReporter ? `import { SpectraVitestReporter } from '${reporterUrl}';` : ""}
54
61
 
55
62
  export default defineConfig({
56
63
  root: ${JSON.stringify(normalizedPackageDir)},
@@ -80,7 +87,10 @@ export default defineConfig({
80
87
  test: {
81
88
  globals: true,
82
89
  setupFiles: [${JSON.stringify(setupFile)}],
83
- reporters: ${opts.semanticReporter ? "[]" : "'default'"},
90
+ reporters: ${opts.semanticReporter ? `[
91
+ new SpectraVitestReporter({ testRoot: ${JSON.stringify(normalizedTestRoot)} }),
92
+ ${opts.outputFile ? `['json', { outputFile: ${JSON.stringify(opts.outputFile)} }],` : ""}
93
+ ]` : opts.outputFile ? `['default', ['json', { outputFile: ${JSON.stringify(opts.outputFile)} }]]` : "'default'"},
84
94
  dir: ${JSON.stringify(normalizedTestRoot)},
85
95
  include: ['specs/**/web.test.tsx', 'specs/**/*.test.tsx'],
86
96
  browser: {
@@ -110,6 +120,12 @@ export default defineConfig({
110
120
 
111
121
  // src/cli.ts
112
122
  async function runComponentTests(options = {}) {
123
+ const runner = options.runner ?? "vitest";
124
+ if (runner === "spectra") {
125
+ console.log("TestSpectra native component testing is orchestrated by the Rust Core Engine.");
126
+ console.log("Use `spectra test` to run tests with full parallel CDP orchestration.");
127
+ return true;
128
+ }
113
129
  const rawCwd = options.cwd ?? process.cwd();
114
130
  const cwd = path2.resolve(rawCwd);
115
131
  const packageDir = fileURLToPath(new URL("..", import.meta.url));
@@ -125,12 +141,10 @@ async function runComponentTests(options = {}) {
125
141
  stepDelayMs: options.stepDelayMs ?? 0,
126
142
  semanticReporter,
127
143
  fileParallelism: options.concurrency !== 1,
128
- browserExecutable: options.browserExecutablePath
144
+ browserExecutable: options.browserExecutablePath,
145
+ outputFile: options.outputFile
129
146
  });
130
147
  const args = ["run", "--config", configPath];
131
- if (options.outputFile) {
132
- args.push("--reporter=default", "--reporter=json", `--outputFile.json=${options.outputFile}`);
133
- }
134
148
  if (options.spec) {
135
149
  let specPattern = options.spec.replace(/\\/g, "/");
136
150
  if (path2.isAbsolute(options.spec)) {
@@ -167,8 +181,18 @@ async function runComponentTests(options = {}) {
167
181
  });
168
182
  }
169
183
  function getFlagValue(argv, ...names) {
170
- const index = argv.findIndex((a) => names.includes(a));
171
- return index !== -1 ? argv[index + 1] : void 0;
184
+ for (let i = 0; i < argv.length; i++) {
185
+ const arg = argv[i];
186
+ for (const name of names) {
187
+ if (arg === name) {
188
+ return argv[i + 1];
189
+ }
190
+ if (arg.startsWith(`${name}=`)) {
191
+ return arg.slice(name.length + 1);
192
+ }
193
+ }
194
+ }
195
+ return void 0;
172
196
  }
173
197
  async function runCli(argv = process.argv.slice(2)) {
174
198
  const [command] = argv;
@@ -179,7 +203,9 @@ async function runCli(argv = process.argv.slice(2)) {
179
203
  let headless = true;
180
204
  if (argv.includes("--headed") || argv.includes("--no-headless")) headless = false;
181
205
  else if (argv.includes("--headless")) headless = true;
182
- const rawDelay = getFlagValue(argv, "--step-delay", "--delay");
206
+ const rawRunner = getFlagValue(argv, "--runner", "-r");
207
+ const runner = rawRunner === "vitest" ? "vitest" : "spectra";
208
+ const rawDelay = getFlagValue(argv, "--step-delay", "--delay", "-d");
183
209
  let stepDelayMs;
184
210
  if (rawDelay !== void 0) {
185
211
  const parsed = parseInt(String(rawDelay), 10);
@@ -188,8 +214,11 @@ async function runCli(argv = process.argv.slice(2)) {
188
214
  let spec = getFlagValue(argv, "--spec", "-s");
189
215
  if (!spec) {
190
216
  const flagsWithValues = /* @__PURE__ */ new Set([
217
+ "--runner",
218
+ "-r",
191
219
  "--step-delay",
192
220
  "--delay",
221
+ "-d",
193
222
  "--spec",
194
223
  "-s",
195
224
  "--output",
@@ -216,7 +245,15 @@ async function runCli(argv = process.argv.slice(2)) {
216
245
  if (!isNaN(parsed) && parsed >= 1) concurrency = parsed;
217
246
  }
218
247
  const browserExecutablePath = getFlagValue(argv, "--browser-executable");
219
- const ok = await runComponentTests({ headless, stepDelayMs, spec, outputFile, concurrency, browserExecutablePath });
248
+ const ok = await runComponentTests({
249
+ runner,
250
+ headless,
251
+ stepDelayMs,
252
+ spec,
253
+ outputFile,
254
+ concurrency,
255
+ browserExecutablePath
256
+ });
220
257
  process.exit(ok ? 0 : 1);
221
258
  }
222
259
  export {
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export declare class DomDriverBridge implements PlatformDriverBridge {
7
7
  export declare function mount<P = any>(element: any): Promise<any>;
8
8
 
9
9
  export interface RunComponentTestsOptions {
10
+ runner?: 'spectra' | 'vitest';
10
11
  cwd?: string;
11
12
  headless?: boolean;
12
13
  stepDelayMs?: number;
@@ -17,6 +18,37 @@ export interface RunComponentTestsOptions {
17
18
  onLine?: (line: string) => void;
18
19
  }
19
20
 
21
+ export interface BundleServer {
22
+ url: string;
23
+ stop(): void;
24
+ }
25
+
26
+ export interface BundleServerOptions {
27
+ testRoot?: string;
28
+ packageDir?: string;
29
+ manifest?: any;
30
+ stepDelayMs?: number;
31
+ }
32
+
33
+ export declare function startBundleServer(opts?: BundleServerOptions): Promise<BundleServer>;
20
34
  export declare function runComponentTests(options?: RunComponentTestsOptions): Promise<boolean>;
21
35
  export declare function runCli(argv?: string[]): Promise<void>;
22
- export type { ExpectStatic } from 'vitest';
36
+ export declare function sanitizeError(err: unknown): string;
37
+ export declare function sanitizeErrorMessage(msg: string): string;
38
+ export declare function sanitizeViteUrl(text: string): string;
39
+ export declare function sanitizeStackTrace(stack: string): string;
40
+ export declare function isVitestNoise(line: string): boolean;
41
+
42
+ export interface AssertionMatchers<T = unknown> {
43
+ toBe(expected: T): void;
44
+ toEqual(expected: unknown): void;
45
+ toBeTruthy(): void;
46
+ toBeFalsy(): void;
47
+ toBeNull(): void;
48
+ toBeUndefined(): void;
49
+ toBeDefined(): void;
50
+ toContain(item: unknown): void;
51
+ not: AssertionMatchers<T>;
52
+ }
53
+
54
+ export type ExpectStatic = <T = unknown>(actual: T) => AssertionMatchers<T>;