@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.
- package/dist/browser-container/container-static/js/{117.3da95caa39.js → 949.7d935e2ac9.js} +917 -891
- package/dist/browser-container/container-static/js/949.7d935e2ac9.js.LICENSE.txt +1 -0
- package/dist/browser-container/container-static/js/{index.6e4da8c9ab.js → index.492a6c2f8b.js} +9 -9
- package/dist/browser-container/index.html +1 -1
- package/dist/index.js +32 -10
- package/package.json +6 -6
- package/src/client/entry.ts +21 -13
- package/src/hostController.ts +70 -13
- package/dist/browser-container/container-static/js/117.3da95caa39.js.LICENSE.txt +0 -1
- package/src/client/formatConsole.ts +0 -77
- package/src/client/public.ts +0 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! LICENSE: 949.7d935e2ac9.js.LICENSE.txt */
|
package/dist/browser-container/container-static/js/{index.6e4da8c9ab.js → index.492a6c2f8b.js}
RENAMED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
"
|
|
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/
|
|
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
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
60
|
-
"@rstest/
|
|
61
|
-
"@rstest/
|
|
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.
|
|
65
|
+
"@rstest/core": "^0.11.3"
|
|
66
66
|
},
|
|
67
67
|
"peerDependenciesMeta": {
|
|
68
68
|
"playwright": {
|
package/src/client/entry.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
package/src/hostController.ts
CHANGED
|
@@ -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
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
lines.push(`
|
|
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
|
|
1550
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
};
|
package/src/client/public.ts
DELETED
|
@@ -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';
|