@rstest/browser 0.11.2 → 0.11.3

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.
@@ -0,0 +1 @@
1
+ /*! LICENSE: 949.7d935e2ac9.js.LICENSE.txt */
@@ -4,7 +4,7 @@
4
4
  1086 (e, t, s) {
5
5
  var l = s(9793);
6
6
  let r = "__rstest_dispatch_response__";
7
- var o = s(9968), a = s(7311), i = s(7125), n = s(405), c = s(7541);
7
+ var o = s(9901), a = s(632), i = s(2969), n = s(405), c = s(7541);
8
8
  let d = (e)=>{
9
9
  let { message: t } = e;
10
10
  return (0, l.jsx)("div", {
@@ -15,7 +15,7 @@
15
15
  })
16
16
  });
17
17
  };
18
- var u = s(5314), p = s(4068), h = s(7708), f = s(9439), x = s(2865);
18
+ var u = s(6554), p = s(2035), h = s(393), f = s(3936), x = s(836);
19
19
  let m = (e, t)=>{
20
20
  if (!t) return e;
21
21
  let s = t.endsWith("/") ? t.slice(0, -1) : t;
@@ -32,7 +32,7 @@
32
32
  }
33
33
  }, "*"), fetch(`/__open-in-editor?file=${encodeURIComponent(e)}`).catch(()=>{});
34
34
  };
35
- var j = s(973), v = s(1061), y = s(5631), _ = s(3255), C = s(4870);
35
+ var j = s(9310), v = s(3414), y = s(4280), _ = s(8060), C = s(5759);
36
36
  let w = {
37
37
  idle: {
38
38
  label: "Idle",
@@ -78,7 +78,7 @@
78
78
  })
79
79
  }
80
80
  };
81
- var k = s(5665), S = s(9669), F = s(7707), N = s(9322), A = s(4867), P = s(2888), M = s(9365), z = s(5433);
81
+ var k = s(3965), S = s(9419), F = s(136), N = s(9237), A = s(8042), P = s(623), M = s(1614), z = s(8996);
82
82
  let R = {
83
83
  iPhoneSE: {
84
84
  width: 375,
@@ -514,7 +514,7 @@
514
514
  ]
515
515
  });
516
516
  };
517
- var D = s(2117);
517
+ var D = s(6704);
518
518
  let G = (e)=>{
519
519
  let { className: t, style: s, direction: r = "horizontal", children: o, autoSaveId: a, ...i } = e, c = n.Children.toArray(o).filter((e)=>n.isValidElement(e) && e.type === Z), d = n.useCallback(()=>{
520
520
  if (!a) return null;
@@ -567,7 +567,7 @@
567
567
  children: t
568
568
  });
569
569
  };
570
- var L = s(2004), q = s(9422), H = s(4967), J = (e)=>(0, l.jsxs)("svg", {
570
+ var L = s(5931), q = s(3103), H = s(2320), J = (e)=>(0, l.jsxs)("svg", {
571
571
  xmlns: "http://www.w3.org/2000/svg",
572
572
  fill: "none",
573
573
  viewBox: "0 0 217 200",
@@ -1585,7 +1585,7 @@
1585
1585
  ]
1586
1586
  });
1587
1587
  };
1588
- var X = s(4385), K = s(8880), Y = s(7151), Q = s(2880), ee = s(6732), et = s(4778);
1588
+ var X = s(706), K = s(2021), Y = s(9734), Q = s(4669), ee = s(9367), et = s(3346);
1589
1589
  let es = (0, n.memo)((e)=>{
1590
1590
  let { counts: t, isRunning: s } = e, r = s && 0 === t.running;
1591
1591
  return (0, l.jsx)("div", {
@@ -1725,7 +1725,7 @@
1725
1725
  ]
1726
1726
  });
1727
1727
  };
1728
- var er = s(9573), eo = s(585), ea = s(2876), ei = s(2022), en = s(3004);
1728
+ var er = s(1332), eo = s(2031), ea = s(3357), ei = s(8949), en = s(8061);
1729
1729
  let ec = (e)=>`__project__${e}`, ed = (e, t)=>`${e}::suite::${t.join("::")}`, eu = (e, t)=>{
1730
1730
  let s = e;
1731
1731
  for(let e = 1; e <= t.length; e++)s = ed(s, t.slice(0, e));
@@ -3047,7 +3047,7 @@
3047
3047
  }, (o = self.rspackChunk_rstest_browser_ui = self.rspackChunk_rstest_browser_ui || []).forEach(r.bind(null, 0)), o.push = r.bind(null, o.push.bind(o));
3048
3048
  var c = n.O(void 0, [
3049
3049
  "783",
3050
- "117"
3050
+ "949"
3051
3051
  ], ()=>n(1086));
3052
3052
  c = n.O(c);
3053
3053
  })();
@@ -12,7 +12,7 @@
12
12
  <script>
13
13
  window.__RSTEST_BROWSER_OPTIONS__ = __RSTEST_OPTIONS_PLACEHOLDER__;
14
14
  </script>
15
- <script defer src="/container-static/js/lib-react.62b27a21db.js"></script><script defer src="/container-static/js/117.3da95caa39.js"></script><script defer src="/container-static/js/index.6e4da8c9ab.js"></script><link href="/container-static/css/index.0521ff95b1.css" rel="stylesheet"></head>
15
+ <script defer src="/container-static/js/lib-react.62b27a21db.js"></script><script defer src="/container-static/js/949.7d935e2ac9.js"></script><script defer src="/container-static/js/index.492a6c2f8b.js"></script><link href="/container-static/css/index.0521ff95b1.css" rel="stylesheet"></head>
16
16
  <body>
17
17
  <div id="root"></div>
18
18
  </body>
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { DEFAULT_TEST_TIMEOUT, PhaseTracker, RSTEST_ENV_SYMBOL_KEY, browserIgnoredRuntimeConfigKeys, buildBrowserCoverageMap, color, createCoverageProvider, createRunnerEventSink, createSilentConsoleController, getNoTestFilesMessage, getNumCpus as browser_getNumCpus, getSetupFiles, getTestEntries, hasUserRstestConfigPlugins, initModifyRstestConfigHooks, isDebug, isTTY, loadCoverageProvider, logger, prepareWatchRerunState, projectRuntimeConfig, resolveProjectBuildCache, resolveShardedEntries, resolveSnapshotPathDefault, resolveWorkerCount, rsbuild, serializableConfig } from "@rstest/core/internal/browser";
1
+ import { DEFAULT_TEST_TIMEOUT, PhaseTracker, RSTEST_ENV_SYMBOL_KEY, applyWebMockRspackConfig, browserIgnoredRuntimeConfigKeys, buildBrowserCoverageMap, color, createCoverageProvider, createRunnerEventSink, createSilentConsoleController, getNoTestFilesMessage, getNumCpus as browser_getNumCpus, getPrettyConsoleName, getSetupFiles, getTestEntries, hasUserRstestConfigPlugins, importMetaRstestDefine, initModifyRstestConfigHooks, isDebug, isTTY, loadCoverageProvider, logger, pluginMockRuntime, prepareWatchRerunState, projectRuntimeConfig, resolveProjectBuildCache, resolveShardedEntries, resolveSnapshotPathDefault, resolveWorkerCount, rsbuild, serializableConfig } from "@rstest/core/internal/browser";
2
2
  import { existsSync } from "node:fs";
3
3
  import promises from "node:fs/promises";
4
4
  import { fileURLToPath } from "node:url";
@@ -3332,12 +3332,29 @@ const generateManifestModule = ({ manifestPath, entries, isWatchMode })=>{
3332
3332
  if (isWatchMode) {
3333
3333
  const includeRegExp = globPatternsToRegExp(project.normalizedConfig.include);
3334
3334
  const excludeRegExp = createBrowserContextExcludeRegExp(project.normalizedConfig.exclude.patterns, projectRootPosix);
3335
- lines.push(`const ${varName} = import.meta.webpackContext(${JSON.stringify(projectRootPosix)}, {`);
3336
- lines.push(' recursive: true,');
3337
- lines.push(` regExp: ${includeRegExp.toString()},`);
3338
- if (excludeRegExp) lines.push(` exclude: ${excludeRegExp.toString()},`);
3339
- lines.push(" mode: 'lazy',");
3340
- lines.push('});');
3335
+ const { includeSource } = project.normalizedConfig;
3336
+ const emitContext = (contextVarName, regExp)=>{
3337
+ lines.push(`const ${contextVarName} = import.meta.webpackContext(${JSON.stringify(projectRootPosix)}, {`);
3338
+ lines.push(' recursive: true,');
3339
+ lines.push(` regExp: ${regExp.toString()},`);
3340
+ if (excludeRegExp) lines.push(` exclude: ${excludeRegExp.toString()},`);
3341
+ lines.push(" mode: 'lazy',");
3342
+ lines.push('});');
3343
+ };
3344
+ if (0 === includeSource.length) emitContext(varName, includeRegExp);
3345
+ else {
3346
+ emitContext(`${varName}_include`, includeRegExp);
3347
+ emitContext(`${varName}_source`, globPatternsToRegExp(includeSource));
3348
+ const probedKeys = testFiles.map((filePath)=>toContextKey(filePath, projectRootPosix));
3349
+ lines.push(`const ${varName}_probed = ${JSON.stringify(probedKeys)};`);
3350
+ lines.push(`const ${varName}_includeKeys = new Set(${varName}_include.keys());`);
3351
+ lines.push(`const ${varName} = Object.assign(`);
3352
+ lines.push(` (key) => ${varName}_includeKeys.has(key) ? ${varName}_include(key) : ${varName}_source(key),`);
3353
+ lines.push(' {');
3354
+ lines.push(` keys: () => Array.from(new Set([...${varName}_includeKeys, ...${varName}_probed])),`);
3355
+ lines.push(' },');
3356
+ lines.push(');');
3357
+ }
3341
3358
  } else {
3342
3359
  lines.push(`const ${varName}_modules = {`);
3343
3360
  for (const filePath of testFiles){
@@ -3493,7 +3510,6 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
3493
3510
  };
3494
3511
  const browserRuntimePath = fileURLToPath(import.meta.resolve('@rstest/core/internal/browser-runtime'));
3495
3512
  const staticRstestAliases = {
3496
- '@rstest/core': resolveBrowserFile('client/public.ts'),
3497
3513
  '@rstest/browser': resolveBrowserFile('browser.ts'),
3498
3514
  '@rstest/core/internal/browser-runtime': browserRuntimePath
3499
3515
  };
@@ -3589,6 +3605,7 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
3589
3605
  appliedEnvironmentNames: appliedModifyRstestConfigEnvironments
3590
3606
  });
3591
3607
  rsbuildInstance.addPlugins([
3608
+ pluginMockRuntime,
3592
3609
  {
3593
3610
  name: 'rstest:browser-user-config',
3594
3611
  setup (api) {
@@ -3619,7 +3636,8 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
3619
3636
  source: {
3620
3637
  define: {
3621
3638
  'process.env': rstestEnvDefine,
3622
- 'import.meta.env': rstestEnvDefine
3639
+ 'import.meta.env': rstestEnvDefine,
3640
+ 'import.meta.rstest': importMetaRstestDefine('web')
3623
3641
  }
3624
3642
  },
3625
3643
  output: {
@@ -3631,6 +3649,10 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
3631
3649
  tools: {
3632
3650
  rspack: (rspackConfig)=>{
3633
3651
  rspackConfig.mode = 'development';
3652
+ applyWebMockRspackConfig(rspackConfig, {
3653
+ rspack: rspack,
3654
+ rootPath: project.rootPath
3655
+ });
3634
3656
  rspackConfig.lazyCompilation = enableHmr ? createBrowserLazyCompilationConfig(setupFiles) : false;
3635
3657
  rspackConfig.plugins = rspackConfig.plugins || [];
3636
3658
  rspackConfig.plugins.push(virtualManifestPlugin);
@@ -4272,7 +4294,7 @@ const runBrowserController = async (context, options)=>{
4272
4294
  const handleLog = async (payload)=>{
4273
4295
  const log = {
4274
4296
  content: payload.content,
4275
- name: payload.level,
4297
+ name: getPrettyConsoleName(payload.level),
4276
4298
  taskId: payload.taskId,
4277
4299
  taskName: payload.taskName,
4278
4300
  taskParentNames: payload.taskParentNames,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rstest/browser",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "Browser mode support for Rstest testing framework.",
5
5
  "keywords": [
6
6
  "rstest",
@@ -45,7 +45,7 @@
45
45
  "open-editor": "^6.0.0",
46
46
  "pathe": "^2.0.3",
47
47
  "sirv": "^3.0.2",
48
- "ws": "^8.21.0"
48
+ "ws": "^8.21.1"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@rslib/core": "0.23.2",
@@ -56,13 +56,13 @@
56
56
  "birpc": "^4.0.0",
57
57
  "picomatch": "^4.0.5",
58
58
  "playwright": "^1.61.1",
59
- "@rstest/core": "0.11.2",
60
- "@rstest/tsconfig": "0.0.1",
61
- "@rstest/browser-ui": "0.0.0"
59
+ "@rstest/core": "0.11.3",
60
+ "@rstest/browser-ui": "0.0.0",
61
+ "@rstest/tsconfig": "0.0.1"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "playwright": "^1.49.1",
65
- "@rstest/core": "^0.11.2"
65
+ "@rstest/core": "^0.11.3"
66
66
  },
67
67
  "peerDependenciesMeta": {
68
68
  "playwright": {
@@ -16,7 +16,9 @@ import type {
16
16
  import {
17
17
  createBrowserTaskContext,
18
18
  createRstestRuntime,
19
+ formatConsoleArgs,
19
20
  globalApis,
21
+ RSTEST_API_GLOBAL_KEY,
20
22
  RSTEST_ENV_SYMBOL_KEY,
21
23
  setRealTimers,
22
24
  unwrapRegex,
@@ -32,7 +34,6 @@ import {
32
34
  createRunnerLifecycleRequest,
33
35
  sendRunnerLifecycle,
34
36
  } from './dispatchTransport';
35
- import { formatConsoleArgs } from './formatConsole';
36
37
  import { BrowserSnapshotEnvironment } from './snapshot';
37
38
  import {
38
39
  findNewScriptUrl,
@@ -59,6 +60,23 @@ const debugLog = (...args: unknown[]): void => {
59
60
  type RuntimeEnvStore = Record<string, string | undefined>;
60
61
  const RSTEST_ENV_SYMBOL = Symbol.for(RSTEST_ENV_SYMBOL_KEY);
61
62
 
63
+ /**
64
+ * Publish the runtime API on the globals test modules read: the
65
+ * `@rstest/core` external and the `import.meta.rstest` define (node parity:
66
+ * `global['@rstest/core']` in runInPool), plus the `globals: true` API names.
67
+ */
68
+ const installRuntimeGlobals = (
69
+ runtime: Awaited<ReturnType<typeof createRstestRuntime>>,
70
+ runtimeConfig: RuntimeConfig,
71
+ ): void => {
72
+ (globalThis as Record<string, unknown>)[RSTEST_API_GLOBAL_KEY] = runtime.api;
73
+ if (runtimeConfig.globals) {
74
+ for (const apiKey of globalApis) {
75
+ (globalThis as any)[apiKey] = (runtime.api as any)[apiKey];
76
+ }
77
+ }
78
+ };
79
+
62
80
  type GlobalWithRuntimeEnv = typeof globalThis &
63
81
  Record<symbol, unknown> & {
64
82
  global?: typeof globalThis;
@@ -502,12 +520,7 @@ const run = async () => {
502
520
  taskContext: createBrowserTaskContext(),
503
521
  });
504
522
 
505
- // Register global APIs if globals config is enabled
506
- if (runtimeConfig.globals) {
507
- for (const apiKey of globalApis) {
508
- (globalThis as any)[apiKey] = (runtime.api as any)[apiKey];
509
- }
510
- }
523
+ installRuntimeGlobals(runtime, runtimeConfig);
511
524
 
512
525
  try {
513
526
  // Load setup files for this project after runtime is ready.
@@ -636,12 +649,7 @@ const run = async () => {
636
649
 
637
650
  const runtime = await createRstestRuntime(workerState, { taskContext });
638
651
 
639
- // Register global APIs if globals config is enabled
640
- if (runtimeConfig.globals) {
641
- for (const apiKey of globalApis) {
642
- (globalThis as any)[apiKey] = (runtime.api as any)[apiKey];
643
- }
644
- }
652
+ installRuntimeGlobals(runtime, runtimeConfig);
645
653
 
646
654
  let failedTestsCount = 0;
647
655
 
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url';
6
6
  import { isDeepStrictEqual } from 'node:util';
7
7
  import type { Rspack } from '@rstest/core';
8
8
  import {
9
+ applyWebMockRspackConfig,
9
10
  type BrowserTestRunOptions,
10
11
  type BrowserTestRunResult,
11
12
  type CoverageMapData,
@@ -17,14 +18,17 @@ import {
17
18
  DEFAULT_TEST_TIMEOUT,
18
19
  type FormattedError,
19
20
  getNoTestFilesMessage,
21
+ getPrettyConsoleName,
20
22
  getSetupFiles,
21
23
  getTestEntries,
22
24
  hasUserRstestConfigPlugins,
25
+ importMetaRstestDefine,
23
26
  initModifyRstestConfigHooks,
24
27
  isDebug,
25
28
  type ListCommandResult,
26
29
  loadCoverageProvider,
27
30
  logger,
31
+ pluginMockRuntime,
28
32
  prepareWatchRerunState,
29
33
  projectRuntimeConfig,
30
34
  PhaseTracker,
@@ -1242,16 +1246,51 @@ const generateManifestModule = ({
1242
1246
  project.normalizedConfig.exclude.patterns,
1243
1247
  projectRootPosix,
1244
1248
  );
1245
- lines.push(
1246
- `const ${varName} = import.meta.webpackContext(${JSON.stringify(projectRootPosix)}, {`,
1247
- );
1248
- lines.push(' recursive: true,');
1249
- lines.push(` regExp: ${includeRegExp.toString()},`);
1250
- if (excludeRegExp) {
1251
- lines.push(` exclude: ${excludeRegExp.toString()},`);
1249
+ const { includeSource } = project.normalizedConfig;
1250
+ const emitContext = (contextVarName: string, regExp: RegExp): void => {
1251
+ lines.push(
1252
+ `const ${contextVarName} = import.meta.webpackContext(${JSON.stringify(projectRootPosix)}, {`,
1253
+ );
1254
+ lines.push(' recursive: true,');
1255
+ lines.push(` regExp: ${regExp.toString()},`);
1256
+ if (excludeRegExp) {
1257
+ lines.push(` exclude: ${excludeRegExp.toString()},`);
1258
+ }
1259
+ lines.push(" mode: 'lazy',");
1260
+ lines.push('});');
1261
+ };
1262
+
1263
+ if (includeSource.length === 0) {
1264
+ emitContext(varName, includeRegExp);
1265
+ } else {
1266
+ // In-source test files (`includeSource`) carry an
1267
+ // `if (import.meta.rstest)` block. The include context can't see them,
1268
+ // so a second context over the `includeSource` globs backs
1269
+ // host-scheduled loads, while `keys()` only unions the entry-probed
1270
+ // in-source files (the probe does not apply inside the bundle, so raw
1271
+ // source-context keys would execute never-probed files and fail with
1272
+ // "No test suites found"). The probed list can go stale until a
1273
+ // manifest refresh; scheduled-by-path loading never does.
1274
+ emitContext(`${varName}_include`, includeRegExp);
1275
+ emitContext(`${varName}_source`, globPatternsToRegExp(includeSource));
1276
+ const probedKeys = testFiles.map((filePath) =>
1277
+ toContextKey(filePath, projectRootPosix),
1278
+ );
1279
+ lines.push(`const ${varName}_probed = ${JSON.stringify(probedKeys)};`);
1280
+ lines.push(
1281
+ `const ${varName}_includeKeys = new Set(${varName}_include.keys());`,
1282
+ );
1283
+ lines.push(`const ${varName} = Object.assign(`);
1284
+ lines.push(
1285
+ ` (key) => ${varName}_includeKeys.has(key) ? ${varName}_include(key) : ${varName}_source(key),`,
1286
+ );
1287
+ lines.push(' {');
1288
+ lines.push(
1289
+ ` keys: () => Array.from(new Set([...${varName}_includeKeys, ...${varName}_probed])),`,
1290
+ );
1291
+ lines.push(' },');
1292
+ lines.push(');');
1252
1293
  }
1253
- lines.push(" mode: 'lazy',");
1254
- lines.push('});');
1255
1294
  } else {
1256
1295
  // One-shot runs: the file set is fixed and already filtered, so emit an
1257
1296
  // explicit lazy-import map (one chunk per literal `import()`, like the
@@ -1546,11 +1585,13 @@ const createBrowserRuntime = async ({
1546
1585
  // Shared by every project — only the per-project `@rstest/browser-manifest`
1547
1586
  // alias varies (one virtual manifest per server).
1548
1587
  const staticRstestAliases = {
1549
- // User test code: import { describe, it } from '@rstest/core'
1550
- '@rstest/core': resolveBrowserFile('client/public.ts'),
1588
+ // User test code `import { describe, it } from '@rstest/core'` is NOT
1589
+ // aliased: `applyWebMockRspackConfig` keeps the request external against
1590
+ // `globalThis['@rstest/core']` (node parity), which also keeps the mock
1591
+ // hoister's provider-import ordering correct for `rs.hoisted` callbacks.
1551
1592
  // User test code: import { page } from '@rstest/browser'
1552
1593
  '@rstest/browser': resolveBrowserFile('browser.ts'),
1553
- // Browser runtime APIs for entry.ts and public.ts
1594
+ // Browser runtime APIs for entry.ts
1554
1595
  // Uses dist file with extractSourceMap to preserve sourcemap chain for inline snapshots
1555
1596
  '@rstest/core/internal/browser-runtime': browserRuntimePath,
1556
1597
  };
@@ -1712,6 +1753,9 @@ const createBrowserRuntime = async ({
1712
1753
 
1713
1754
  // Add plugin to merge user Rsbuild config with rstest required config
1714
1755
  rsbuildInstance.addPlugins([
1756
+ // Same mock runtime as the node build (importActual doppelganger rule +
1757
+ // mock webpack runtime module); order-insensitive and self-contained.
1758
+ pluginMockRuntime,
1715
1759
  {
1716
1760
  name: 'rstest:browser-user-config',
1717
1761
  setup(api) {
@@ -1766,6 +1810,10 @@ const createBrowserRuntime = async ({
1766
1810
  define: {
1767
1811
  'process.env': rstestEnvDefine,
1768
1812
  'import.meta.env': rstestEnvDefine,
1813
+ // In-source `if (import.meta.rstest)` blocks read the
1814
+ // per-file runtime API the client entry publishes on
1815
+ // `globalThis` (node parity: `global['@rstest/core']`).
1816
+ 'import.meta.rstest': importMetaRstestDefine('web'),
1769
1817
  },
1770
1818
  },
1771
1819
  output: {
@@ -1778,6 +1826,14 @@ const createBrowserRuntime = async ({
1778
1826
  tools: {
1779
1827
  rspack: (rspackConfig) => {
1780
1828
  rspackConfig.mode = 'development';
1829
+ // Web parameterization of the node mock transform:
1830
+ // RstestPlugin (hoist + path injection), the
1831
+ // `@rstest/core` global external, and
1832
+ // `exportsPresence: 'warn'`.
1833
+ applyWebMockRspackConfig(rspackConfig, {
1834
+ rspack,
1835
+ rootPath: project.rootPath,
1836
+ });
1781
1837
  // lazyCompilation's only delivery transport is the HMR
1782
1838
  // runtime, so it follows the same gate as HMR (see
1783
1839
  // `shouldEnableBrowserHmr`): headed watch only, everything
@@ -2854,7 +2910,8 @@ export const runBrowserController = async (
2854
2910
  const handleLog = async (payload: LogPayload): Promise<void> => {
2855
2911
  const log: UserConsoleLog = {
2856
2912
  content: payload.content,
2857
- name: payload.level,
2913
+ // Same colored level label as the node worker's CustomConsole.
2914
+ name: getPrettyConsoleName(payload.level),
2858
2915
  taskId: payload.taskId,
2859
2916
  taskName: payload.taskName,
2860
2917
  taskParentNames: payload.taskParentNames,
@@ -1 +0,0 @@
1
- /*! LICENSE: 117.3da95caa39.js.LICENSE.txt */
@@ -1,77 +0,0 @@
1
- /** Stringify a single console argument for terminal forwarding. */
2
- export const formatArg = (arg: unknown): string => {
3
- if (arg === null) return 'null';
4
- if (arg === undefined) return 'undefined';
5
- if (typeof arg === 'string') return arg;
6
- if (typeof arg === 'number' || typeof arg === 'boolean') return String(arg);
7
- // `JSON.stringify(symbol)` is `undefined`, so a symbol must be handled before
8
- // the JSON path or it would forward as an empty/`undefined` log.
9
- if (typeof arg === 'symbol') return arg.toString();
10
- if (arg instanceof Error) {
11
- return arg.stack || `${arg.name}: ${arg.message}`;
12
- }
13
- try {
14
- return JSON.stringify(arg, null, 2);
15
- } catch {
16
- return String(arg);
17
- }
18
- };
19
-
20
- // Format specifiers understood by the browser console. `%c` applies CSS in a
21
- // real console; forwarded to a terminal there is no styling, so it is consumed
22
- // and dropped (matching how Node's `util.format` handles it). `%%` is a literal
23
- // percent sign. Kept aligned with the browser console spec (no Node-only `%j`,
24
- // since these logs originate in the browser).
25
- // cspell:ignore sdifo WHATWG
26
- const HAS_SPECIFIER = /%[sdifoOc%]/;
27
- const SPECIFIER = /%[sdifoOc%]/g;
28
-
29
- /**
30
- * Join console arguments the way a console does. When the first argument is a
31
- * string carrying `printf`-style specifiers, substitute the following arguments
32
- * into it (consuming `%c` styles without emitting them), then append any
33
- * leftover arguments. Otherwise fall back to a plain space-join.
34
- *
35
- * Without this, `console.info('%cText', 'font-weight:bold')` (e.g. React's
36
- * DevTools notice) leaks the raw `%c` directive and its CSS argument into the
37
- * forwarded terminal output.
38
- */
39
- export const formatConsoleArgs = (args: unknown[]): string => {
40
- const first = args[0];
41
- if (typeof first !== 'string' || !HAS_SPECIFIER.test(first)) {
42
- return args.map(formatArg).join(' ');
43
- }
44
-
45
- let next = 1;
46
- const substituted = first.replace(SPECIFIER, (spec) => {
47
- if (spec === '%%') return '%';
48
- if (next >= args.length) return spec;
49
- const arg = args[next++];
50
- switch (spec) {
51
- case '%c':
52
- return ''; // CSS directive: swallow the style argument
53
- case '%s':
54
- return formatArg(arg);
55
- case '%d':
56
- case '%i': {
57
- // Match the browser console formatter (WHATWG): parseInt on the value,
58
- // so unit-suffixed strings like '42px' format as 42 (not NaN).
59
- // `String()` first keeps Symbol safe — a bare `parseInt(symbol)` throws
60
- // via ToString, whereas the spec maps a Symbol to NaN.
61
- const num = Number.parseInt(String(arg), 10);
62
- return Number.isNaN(num) ? 'NaN' : String(num);
63
- }
64
- case '%f': {
65
- const num = Number.parseFloat(String(arg));
66
- return Number.isNaN(num) ? 'NaN' : String(num);
67
- }
68
- default: // %o, %O
69
- return formatArg(arg);
70
- }
71
- });
72
-
73
- if (next >= args.length) {
74
- return substituted;
75
- }
76
- return [substituted, ...args.slice(next).map(formatArg)].join(' ');
77
- };
@@ -1,12 +0,0 @@
1
- /**
2
- * Re-export runtime API from @rstest/core/internal/browser-runtime for browser use.
3
- * This file is used as an alias target for '@rstest/core' in browser mode.
4
- *
5
- * Uses @rstest/core/internal/browser-runtime which only exports the test APIs
6
- * (describe, it, expect, etc.) without any Node.js dependencies.
7
- */
8
-
9
- // Re-export types from @rstest/core (these are compile-time only)
10
- export type { Assertion, Mock } from '@rstest/core';
11
- // Re-export all public test APIs
12
- export * from '@rstest/core/internal/browser-runtime';