@rstest/browser 0.10.3 → 0.10.5
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/626.js +2 -1
- package/dist/browser-container/container-static/css/index.0521ff95b1.css +1 -0
- package/dist/browser-container/container-static/js/{27.099feaf1da.js → 854.c59f71483d.js} +5728 -5756
- package/dist/browser-container/container-static/js/854.c59f71483d.js.LICENSE.txt +1 -0
- package/dist/browser-container/container-static/js/{index.be8c8d2626.js → index.fedc31dff3.js} +109 -136
- package/dist/browser-container/container-static/js/{lib-react.5ae9b90ee5.js → lib-react.62b27a21db.js} +21 -21
- package/dist/browser-container/container-static/js/lib-react.62b27a21db.js.LICENSE.txt +1 -0
- package/dist/browser-container/index.html +1 -1
- package/dist/browser.js +4 -4
- package/dist/browserRpcRegistry.d.ts +1 -2
- package/dist/client/api.d.ts +1 -1
- package/dist/client/dispatchTransport.d.ts +18 -1
- package/dist/client/locator.d.ts +2 -3
- package/dist/concurrency.d.ts +5 -3
- package/dist/configValidation.d.ts +2 -2
- package/dist/dispatchCapabilities.d.ts +3 -3
- package/dist/dispatchRouter.d.ts +2 -3
- package/dist/headedSerialTaskQueue.d.ts +5 -5
- package/dist/headlessLatestRerunScheduler.d.ts +2 -3
- package/dist/headlessTransport.d.ts +2 -3
- package/dist/hostController.d.ts +12 -9
- package/dist/index.d.ts +6 -6
- package/dist/index.js +169 -216
- package/dist/protocol.d.ts +78 -55
- package/dist/providers/index.d.ts +18 -20
- package/dist/providers/playwright/dispatchBrowserRpc.d.ts +5 -3
- package/dist/providers/playwright/expectUtils.d.ts +2 -3
- package/dist/providers/playwright/implementation.d.ts +1 -1
- package/dist/providers/playwright/runtime.d.ts +1 -1
- package/dist/rpcProtocol.d.ts +36 -29
- package/dist/runSession.d.ts +3 -5
- package/dist/sessionRegistry.d.ts +2 -3
- package/dist/sourceMap/sourceMapLoader.d.ts +2 -2
- package/dist/viewportPresets.d.ts +7 -3
- package/dist/watchCliShortcuts.d.ts +1 -1
- package/dist/watchRerunPlanner.d.ts +2 -2
- package/package.json +7 -9
- package/src/AGENTS.md +7 -1
- package/src/browserRpcRegistry.ts +2 -2
- package/src/client/dispatchTransport.ts +63 -1
- package/src/client/entry.ts +25 -58
- package/src/client/public.ts +3 -3
- package/src/client/snapshot.ts +24 -22
- package/src/client/sourceMapSupport.ts +1 -1
- package/src/concurrency.ts +7 -21
- package/src/configValidation.ts +2 -2
- package/src/dispatchCapabilities.ts +102 -83
- package/src/env.d.ts +6 -2
- package/src/headedSerialTaskQueue.ts +5 -1
- package/src/hostController.ts +85 -43
- package/src/index.ts +22 -11
- package/src/protocol.ts +66 -22
- package/src/providers/index.ts +8 -1
- package/src/rpcProtocol.ts +34 -21
- package/src/viewportPresets.ts +5 -0
- package/src/watchCliShortcuts.ts +2 -4
- package/dist/browser-container/container-static/css/index.5c72297783.css +0 -1
- package/dist/browser-container/container-static/js/27.099feaf1da.js.LICENSE.txt +0 -1
- package/dist/browser-container/container-static/js/lib-react.5ae9b90ee5.js.LICENSE.txt +0 -1
- package/dist/client/entry.d.ts +0 -4
- package/dist/client/fakeTimersStub.d.ts +0 -25
- package/dist/client/public.d.ts +0 -9
- package/dist/client/snapshot.d.ts +0 -29
- package/dist/client/sourceMapSupport.d.ts +0 -42
package/src/hostController.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type CoverageMapData,
|
|
12
12
|
color,
|
|
13
13
|
createCoverageProvider,
|
|
14
|
+
DEFAULT_TEST_TIMEOUT,
|
|
14
15
|
type FormattedError,
|
|
15
16
|
getNoTestFilesMessage,
|
|
16
17
|
getSetupFiles,
|
|
@@ -22,16 +23,17 @@ import {
|
|
|
22
23
|
PhaseTracker,
|
|
23
24
|
type ProjectContext,
|
|
24
25
|
type Reporter,
|
|
25
|
-
type
|
|
26
|
+
type RstestContext,
|
|
26
27
|
type RuntimeConfig,
|
|
27
28
|
resolveProjectBuildCache,
|
|
29
|
+
RSTEST_ENV_SYMBOL_KEY,
|
|
28
30
|
rsbuild,
|
|
29
31
|
serializableConfig,
|
|
30
32
|
type Test,
|
|
31
33
|
type TestFileResult,
|
|
32
34
|
type TestResult,
|
|
33
35
|
type UserConsoleLog,
|
|
34
|
-
} from '@rstest/core/browser';
|
|
36
|
+
} from '@rstest/core/internal/browser';
|
|
35
37
|
import { type BirpcReturn, createBirpc } from 'birpc';
|
|
36
38
|
import openEditor from 'open-editor';
|
|
37
39
|
import { basename, dirname, join, normalize, relative, resolve } from 'pathe';
|
|
@@ -52,6 +54,7 @@ import type {
|
|
|
52
54
|
BrowserDispatchRequest,
|
|
53
55
|
BrowserDispatchResponse,
|
|
54
56
|
BrowserHostConfig,
|
|
57
|
+
BrowserLogPayload,
|
|
55
58
|
BrowserProjectRuntime,
|
|
56
59
|
BrowserRpcRequest,
|
|
57
60
|
BrowserViewport,
|
|
@@ -60,6 +63,7 @@ import type {
|
|
|
60
63
|
} from './protocol';
|
|
61
64
|
import {
|
|
62
65
|
DISPATCH_MESSAGE_TYPE,
|
|
66
|
+
DISPATCH_NAMESPACE_BROWSER,
|
|
63
67
|
DISPATCH_NAMESPACE_RUNNER,
|
|
64
68
|
validateBrowserRpcRequest,
|
|
65
69
|
} from './protocol';
|
|
@@ -97,6 +101,15 @@ type RsbuildInstance = rsbuild.RsbuildInstance;
|
|
|
97
101
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
98
102
|
const OPTIONS_PLACEHOLDER = '__RSTEST_OPTIONS_PLACEHOLDER__';
|
|
99
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Extra time added on top of a file's `testTimeout` before the host gives up
|
|
106
|
+
* waiting for that file's RPC to settle. Covers fixed per-file overhead (page
|
|
107
|
+
* navigation, runner boot) that is not part of the user's test budget. The
|
|
108
|
+
* headless and headed scheduling paths both apply this same buffer, so it lives
|
|
109
|
+
* here as one constant to keep their per-file timeout semantics identical.
|
|
110
|
+
*/
|
|
111
|
+
const PER_FILE_TIMEOUT_BUFFER_MS = 30_000;
|
|
112
|
+
|
|
100
113
|
/**
|
|
101
114
|
* Monotonic counter for synthetic per-file Perfetto `pid` values in `--trace`
|
|
102
115
|
* mode. Browser host runs every test file inside the same Node process, so
|
|
@@ -165,18 +178,8 @@ type TestFileStartPayload = {
|
|
|
165
178
|
projectName: string;
|
|
166
179
|
};
|
|
167
180
|
|
|
168
|
-
/** Payload for log event */
|
|
169
|
-
type LogPayload =
|
|
170
|
-
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
171
|
-
content: string;
|
|
172
|
-
taskId?: string;
|
|
173
|
-
taskName?: string;
|
|
174
|
-
taskParentNames?: string[];
|
|
175
|
-
taskType?: 'file' | 'suite' | 'case';
|
|
176
|
-
testPath: string;
|
|
177
|
-
type: 'stdout' | 'stderr';
|
|
178
|
-
trace?: string;
|
|
179
|
-
};
|
|
181
|
+
/** Payload for log event — single-sourced from the wire protocol. */
|
|
182
|
+
type LogPayload = BrowserLogPayload;
|
|
180
183
|
|
|
181
184
|
/** Payload for fatal error event */
|
|
182
185
|
type FatalPayload = {
|
|
@@ -597,7 +600,15 @@ export const createBrowserLazyCompilationConfig = (
|
|
|
597
600
|
};
|
|
598
601
|
};
|
|
599
602
|
|
|
600
|
-
export const createBrowserRsbuildDevConfig = (
|
|
603
|
+
export const createBrowserRsbuildDevConfig = (
|
|
604
|
+
_isWatchMode: boolean,
|
|
605
|
+
): {
|
|
606
|
+
writeToDisk: boolean;
|
|
607
|
+
hmr: boolean;
|
|
608
|
+
client: {
|
|
609
|
+
logLevel: 'error';
|
|
610
|
+
};
|
|
611
|
+
} => {
|
|
601
612
|
return {
|
|
602
613
|
writeToDisk: isDebug(),
|
|
603
614
|
// Keep HMR enabled in browser mode even for one-shot runs.
|
|
@@ -830,11 +841,16 @@ const getRuntimeConfigFromProject = (
|
|
|
830
841
|
} = project.normalizedConfig;
|
|
831
842
|
|
|
832
843
|
return {
|
|
833
|
-
// Propagate NODE_ENV from the host so
|
|
834
|
-
//
|
|
835
|
-
//
|
|
844
|
+
// Propagate NODE_ENV and the RSTEST flag from the host so
|
|
845
|
+
// `process.env.NODE_ENV` / `process.env.RSTEST` (rewritten to the
|
|
846
|
+
// `RSTEST_ENV_SYMBOL_KEY` symbol store) resolve in browser tests the same
|
|
847
|
+
// way they do in Node mode, where `prepare.ts` sets them on the real
|
|
848
|
+
// `process.env`.
|
|
849
|
+
// User-supplied `env` wins so explicit overrides still take effect.
|
|
850
|
+
// See https://github.com/web-infra-dev/rstest/issues/1351
|
|
836
851
|
env: {
|
|
837
852
|
NODE_ENV: process.env.NODE_ENV,
|
|
853
|
+
RSTEST: 'true',
|
|
838
854
|
...env,
|
|
839
855
|
},
|
|
840
856
|
testNamePattern,
|
|
@@ -864,7 +880,7 @@ const getRuntimeConfigFromProject = (
|
|
|
864
880
|
};
|
|
865
881
|
};
|
|
866
882
|
|
|
867
|
-
const getBrowserProjects = (context:
|
|
883
|
+
const getBrowserProjects = (context: RstestContext): ProjectContext[] => {
|
|
868
884
|
return context.projects.filter(
|
|
869
885
|
(project) => project.normalizedConfig.browser.enabled,
|
|
870
886
|
);
|
|
@@ -936,7 +952,7 @@ const resolveProviderForTestPath = ({
|
|
|
936
952
|
};
|
|
937
953
|
|
|
938
954
|
const collectProjectEntries = async (
|
|
939
|
-
context:
|
|
955
|
+
context: RstestContext,
|
|
940
956
|
): Promise<BrowserProjectEntries[]> => {
|
|
941
957
|
// Only collect entries for browser mode projects
|
|
942
958
|
const browserProjects = getBrowserProjects(context);
|
|
@@ -1211,7 +1227,7 @@ const createBrowserRuntime = async ({
|
|
|
1211
1227
|
containerDevServer,
|
|
1212
1228
|
forceHeadless,
|
|
1213
1229
|
}: {
|
|
1214
|
-
context:
|
|
1230
|
+
context: RstestContext;
|
|
1215
1231
|
manifestPath: string;
|
|
1216
1232
|
manifestSource: string;
|
|
1217
1233
|
tempDir: string;
|
|
@@ -1257,7 +1273,7 @@ const createBrowserRuntime = async ({
|
|
|
1257
1273
|
|
|
1258
1274
|
// Rstest internal aliases that must not be overridden by user config
|
|
1259
1275
|
const browserRuntimePath = fileURLToPath(
|
|
1260
|
-
import.meta.resolve('@rstest/core/browser-runtime'),
|
|
1276
|
+
import.meta.resolve('@rstest/core/internal/browser-runtime'),
|
|
1261
1277
|
);
|
|
1262
1278
|
|
|
1263
1279
|
const rstestInternalAliases = {
|
|
@@ -1268,7 +1284,7 @@ const createBrowserRuntime = async ({
|
|
|
1268
1284
|
'@rstest/browser': resolveBrowserFile('browser.ts'),
|
|
1269
1285
|
// Browser runtime APIs for entry.ts and public.ts
|
|
1270
1286
|
// Uses dist file with extractSourceMap to preserve sourcemap chain for inline snapshots
|
|
1271
|
-
'@rstest/core/browser-runtime': browserRuntimePath,
|
|
1287
|
+
'@rstest/core/internal/browser-runtime': browserRuntimePath,
|
|
1272
1288
|
'@sinonjs/fake-timers': resolveBrowserFile('client/fakeTimersStub.ts'),
|
|
1273
1289
|
};
|
|
1274
1290
|
|
|
@@ -1329,6 +1345,13 @@ const createBrowserRuntime = async ({
|
|
|
1329
1345
|
project.rootPath,
|
|
1330
1346
|
),
|
|
1331
1347
|
);
|
|
1348
|
+
// rspack `define` replaces `process.env` / `import.meta.env` with
|
|
1349
|
+
// this literal expression. JSON.stringify reproduces the exact
|
|
1350
|
+
// double-quoted `"rstest.env"` text, so the owned key can never
|
|
1351
|
+
// drift from the runtime `Symbol.for(RSTEST_ENV_SYMBOL_KEY)` sites.
|
|
1352
|
+
const rstestEnvDefine = `globalThis[Symbol.for(${JSON.stringify(
|
|
1353
|
+
RSTEST_ENV_SYMBOL_KEY,
|
|
1354
|
+
)})]`;
|
|
1332
1355
|
// Merge order: current config -> userConfig -> rstest required config (highest priority)
|
|
1333
1356
|
const merged = mergeEnvironmentConfig(
|
|
1334
1357
|
config,
|
|
@@ -1347,8 +1370,8 @@ const createBrowserRuntime = async ({
|
|
|
1347
1370
|
},
|
|
1348
1371
|
source: {
|
|
1349
1372
|
define: {
|
|
1350
|
-
'process.env':
|
|
1351
|
-
'import.meta.env':
|
|
1373
|
+
'process.env': rstestEnvDefine,
|
|
1374
|
+
'import.meta.env': rstestEnvDefine,
|
|
1352
1375
|
},
|
|
1353
1376
|
},
|
|
1354
1377
|
output: {
|
|
@@ -1677,7 +1700,7 @@ const createBrowserRuntime = async ({
|
|
|
1677
1700
|
};
|
|
1678
1701
|
|
|
1679
1702
|
async function resolveProjectEntries(
|
|
1680
|
-
context:
|
|
1703
|
+
context: RstestContext,
|
|
1681
1704
|
shardedEntries?: Map<string, { entries: Record<string, string> }>,
|
|
1682
1705
|
): Promise<BrowserProjectEntries[]> {
|
|
1683
1706
|
if (shardedEntries) {
|
|
@@ -1707,7 +1730,7 @@ async function resolveProjectEntries(
|
|
|
1707
1730
|
// ============================================================================
|
|
1708
1731
|
|
|
1709
1732
|
export const runBrowserController = async (
|
|
1710
|
-
context:
|
|
1733
|
+
context: RstestContext,
|
|
1711
1734
|
options?: BrowserTestRunOptions,
|
|
1712
1735
|
): Promise<BrowserTestRunResult | void> => {
|
|
1713
1736
|
const {
|
|
@@ -2073,7 +2096,9 @@ export const runBrowserController = async (
|
|
|
2073
2096
|
|
|
2074
2097
|
// Get max testTimeout from all browser projects for RPC timeout
|
|
2075
2098
|
const maxTestTimeoutForRpc = Math.max(
|
|
2076
|
-
...browserProjects.map(
|
|
2099
|
+
...browserProjects.map(
|
|
2100
|
+
(p) => p.normalizedConfig.testTimeout ?? DEFAULT_TEST_TIMEOUT,
|
|
2101
|
+
),
|
|
2077
2102
|
);
|
|
2078
2103
|
|
|
2079
2104
|
const hostOptions: BrowserHostConfig = {
|
|
@@ -2161,13 +2186,16 @@ export const runBrowserController = async (
|
|
|
2161
2186
|
}
|
|
2162
2187
|
};
|
|
2163
2188
|
|
|
2164
|
-
runtime.dispatchHandlers.set(
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
request
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2189
|
+
runtime.dispatchHandlers.set(
|
|
2190
|
+
DISPATCH_NAMESPACE_BROWSER,
|
|
2191
|
+
async (dispatchRequest) => {
|
|
2192
|
+
const request = validateBrowserRpcRequest(dispatchRequest.args);
|
|
2193
|
+
return dispatchBrowserRpcRequest({
|
|
2194
|
+
request,
|
|
2195
|
+
target: dispatchRequest.target,
|
|
2196
|
+
});
|
|
2197
|
+
},
|
|
2198
|
+
);
|
|
2171
2199
|
|
|
2172
2200
|
runtime.setContainerOptions(hostOptions);
|
|
2173
2201
|
|
|
@@ -2397,7 +2425,9 @@ export const runBrowserController = async (
|
|
|
2397
2425
|
};
|
|
2398
2426
|
|
|
2399
2427
|
const shouldEmitUserConsoleLog = (log: UserConsoleLog): boolean => {
|
|
2400
|
-
return
|
|
2428
|
+
return (
|
|
2429
|
+
context.normalizedConfig.onConsoleLog?.(log.content, log.type) !== false
|
|
2430
|
+
);
|
|
2401
2431
|
};
|
|
2402
2432
|
|
|
2403
2433
|
const emitUserConsoleLog = async (log: UserConsoleLog): Promise<void> => {
|
|
@@ -2505,8 +2535,12 @@ export const runBrowserController = async (
|
|
|
2505
2535
|
);
|
|
2506
2536
|
case 'removeSnapshotFile':
|
|
2507
2537
|
return snapshotRpcMethods.removeSnapshotFile(request.args.filepath);
|
|
2508
|
-
default:
|
|
2509
|
-
|
|
2538
|
+
default: {
|
|
2539
|
+
// Exhaustiveness guard: a new SnapshotRpcRequest method without a case
|
|
2540
|
+
// here fails to compile rather than silently returning undefined.
|
|
2541
|
+
const _exhaustive: never = request;
|
|
2542
|
+
return _exhaustive;
|
|
2543
|
+
}
|
|
2510
2544
|
}
|
|
2511
2545
|
};
|
|
2512
2546
|
|
|
@@ -2596,7 +2630,7 @@ export const runBrowserController = async (
|
|
|
2596
2630
|
message: BrowserClientMessage,
|
|
2597
2631
|
): Promise<void> => {
|
|
2598
2632
|
const response = await dispatchRouter.dispatch({
|
|
2599
|
-
requestId: nextDispatchRequestId(
|
|
2633
|
+
requestId: nextDispatchRequestId(DISPATCH_NAMESPACE_RUNNER),
|
|
2600
2634
|
runToken: run.token,
|
|
2601
2635
|
namespace: DISPATCH_NAMESPACE_RUNNER,
|
|
2602
2636
|
method: message.type,
|
|
@@ -2653,7 +2687,7 @@ export const runBrowserController = async (
|
|
|
2653
2687
|
);
|
|
2654
2688
|
const perFileTimeoutMs =
|
|
2655
2689
|
(projectRuntime?.runtimeConfig.testTimeout ?? maxTestTimeoutForRpc) +
|
|
2656
|
-
|
|
2690
|
+
PER_FILE_TIMEOUT_BUFFER_MS;
|
|
2657
2691
|
|
|
2658
2692
|
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
2659
2693
|
|
|
@@ -3052,6 +3086,12 @@ export const runBrowserController = async (
|
|
|
3052
3086
|
}
|
|
3053
3087
|
|
|
3054
3088
|
let currentTestFiles = allTestFiles;
|
|
3089
|
+
// Coincidentally equal to the runner-side CONFIG_WAIT_TIMEOUT_MS and
|
|
3090
|
+
// DEFAULT_RPC_TIMEOUT_MS (client/entry.ts, client/dispatchTransport.ts) but
|
|
3091
|
+
// semantically distinct and in a different runtime, so deliberately NOT shared
|
|
3092
|
+
// with them. Invariant worth preserving: a runner must be able to receive its
|
|
3093
|
+
// config (config-wait) before the host declares its frames un-ready, i.e.
|
|
3094
|
+
// CONFIG_WAIT_TIMEOUT_MS <= RUNNER_FRAMES_READY_TIMEOUT_MS.
|
|
3055
3095
|
const RUNNER_FRAMES_READY_TIMEOUT_MS = 30_000;
|
|
3056
3096
|
let currentRunnerFramesSignature: string | null = null;
|
|
3057
3097
|
const runnerFramesWaiters = new Map<string, Set<() => void>>();
|
|
@@ -3139,7 +3179,7 @@ export const runBrowserController = async (
|
|
|
3139
3179
|
);
|
|
3140
3180
|
return (
|
|
3141
3181
|
(projectRuntime?.runtimeConfig.testTimeout ?? maxTestTimeoutForRpc) +
|
|
3142
|
-
|
|
3182
|
+
PER_FILE_TIMEOUT_BUFFER_MS
|
|
3143
3183
|
);
|
|
3144
3184
|
};
|
|
3145
3185
|
|
|
@@ -3602,7 +3642,7 @@ export type ListBrowserTestsResult = {
|
|
|
3602
3642
|
* and collects their test structure (describe/test declarations).
|
|
3603
3643
|
*/
|
|
3604
3644
|
export const listBrowserTests = async (
|
|
3605
|
-
context:
|
|
3645
|
+
context: RstestContext,
|
|
3606
3646
|
options?: {
|
|
3607
3647
|
shardedEntries?: Map<string, { entries: Record<string, string> }>;
|
|
3608
3648
|
},
|
|
@@ -3681,7 +3721,9 @@ export const listBrowserTests = async (
|
|
|
3681
3721
|
|
|
3682
3722
|
// Get max testTimeout from all browser projects for RPC timeout
|
|
3683
3723
|
const maxTestTimeoutForRpc = Math.max(
|
|
3684
|
-
...browserProjects.map(
|
|
3724
|
+
...browserProjects.map(
|
|
3725
|
+
(p) => p.normalizedConfig.testTimeout ?? DEFAULT_TEST_TIMEOUT,
|
|
3726
|
+
),
|
|
3685
3727
|
);
|
|
3686
3728
|
|
|
3687
3729
|
const hostOptions: BrowserHostConfig = {
|
package/src/index.ts
CHANGED
|
@@ -1,34 +1,45 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
BrowserHostModule,
|
|
2
3
|
BrowserTestRunOptions,
|
|
3
4
|
BrowserTestRunResult,
|
|
4
|
-
|
|
5
|
-
} from '@rstest/core/browser';
|
|
5
|
+
RstestContext,
|
|
6
|
+
} from '@rstest/core/internal/browser';
|
|
7
|
+
import { validateBrowserConfig } from './configValidation';
|
|
6
8
|
import {
|
|
7
9
|
type ListBrowserTestsResult,
|
|
8
10
|
listBrowserTests as listBrowserTestsImpl,
|
|
9
11
|
runBrowserController,
|
|
10
12
|
} from './hostController';
|
|
11
13
|
|
|
12
|
-
export { validateBrowserConfig }
|
|
13
|
-
export {
|
|
14
|
-
BROWSER_VIEWPORT_PRESET_DIMENSIONS,
|
|
15
|
-
BROWSER_VIEWPORT_PRESET_IDS,
|
|
16
|
-
resolveBrowserViewportPreset,
|
|
17
|
-
} from './viewportPresets';
|
|
14
|
+
export { validateBrowserConfig };
|
|
18
15
|
|
|
19
16
|
export async function runBrowserTests(
|
|
20
|
-
context:
|
|
17
|
+
context: RstestContext,
|
|
21
18
|
options?: BrowserTestRunOptions,
|
|
22
19
|
): Promise<BrowserTestRunResult | void> {
|
|
23
20
|
return runBrowserController(context, options);
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
export async function listBrowserTests(
|
|
27
|
-
context:
|
|
24
|
+
context: RstestContext,
|
|
25
|
+
options?: Pick<BrowserTestRunOptions, 'shardedEntries'>,
|
|
28
26
|
): Promise<ListBrowserTestsResult> {
|
|
29
|
-
|
|
27
|
+
// Forward `options` (e.g. `shardedEntries`) so `rstest list --shard` lists
|
|
28
|
+
// only the current shard's browser test files, matching the run path.
|
|
29
|
+
return listBrowserTestsImpl(context, options);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Compile-time guard: ensure the public host exports satisfy the core-owned
|
|
34
|
+
* {@link BrowserHostModule} contract. This catches drift such as a dropped
|
|
35
|
+
* `options` argument at the load boundary. No runtime side effect.
|
|
36
|
+
*/
|
|
37
|
+
void ({
|
|
38
|
+
validateBrowserConfig,
|
|
39
|
+
runBrowserTests,
|
|
40
|
+
listBrowserTests,
|
|
41
|
+
} satisfies BrowserHostModule);
|
|
42
|
+
|
|
32
43
|
export type {
|
|
33
44
|
BrowserTestRunOptions,
|
|
34
45
|
BrowserTestRunResult,
|
package/src/protocol.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BrowserViewport } from '@rstest/core/internal/browser';
|
|
2
2
|
import type {
|
|
3
3
|
RuntimeConfig,
|
|
4
4
|
TestFileResult,
|
|
5
5
|
TestInfo,
|
|
6
6
|
TestResult,
|
|
7
|
-
} from '@rstest/core/browser-runtime';
|
|
7
|
+
} from '@rstest/core/internal/browser-runtime';
|
|
8
8
|
import type { SnapshotUpdateState } from '@vitest/snapshot';
|
|
9
9
|
|
|
10
10
|
export type {
|
|
11
11
|
BrowserLocatorIR,
|
|
12
12
|
BrowserRpcRequest,
|
|
13
|
+
SnapshotRpcCall,
|
|
14
|
+
SnapshotRpcMethod,
|
|
15
|
+
SnapshotRpcMethodArgs,
|
|
13
16
|
SnapshotRpcRequest,
|
|
14
17
|
} from './rpcProtocol';
|
|
15
18
|
export { validateBrowserRpcRequest } from './rpcProtocol';
|
|
@@ -27,12 +30,10 @@ export const DISPATCH_METHOD_RPC = 'rpc';
|
|
|
27
30
|
|
|
28
31
|
export type SerializedRuntimeConfig = RuntimeConfig;
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
| DevicePreset;
|
|
33
|
+
// `BrowserViewport` is a core config type (`@rstest/core` owns the canonical
|
|
34
|
+
// definition used by `NormalizedBrowserModeConfig`). Re-export it so the host
|
|
35
|
+
// assigns the SAME type across the seam instead of a hand-copied duplicate.
|
|
36
|
+
export type { BrowserViewport };
|
|
36
37
|
|
|
37
38
|
export type BrowserProjectRuntime = {
|
|
38
39
|
name: string;
|
|
@@ -58,6 +59,25 @@ export type TestFileInfo = {
|
|
|
58
59
|
*/
|
|
59
60
|
export type BrowserExecutionMode = 'run' | 'collect';
|
|
60
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Wire shape of a `log` client message payload. The host receives this and maps
|
|
64
|
+
* it onto core's {@link UserConsoleLog} (notably `level` → `name`); that mapper
|
|
65
|
+
* (`hostController.ts` `handleLog`) annotates its result as `UserConsoleLog`, so
|
|
66
|
+
* the map→core direction is compiler-checked. Owning the wire shape here as one
|
|
67
|
+
* named type keeps the host's input type from drifting away from the producer.
|
|
68
|
+
*/
|
|
69
|
+
export type BrowserLogPayload = {
|
|
70
|
+
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
71
|
+
content: string;
|
|
72
|
+
taskId?: string;
|
|
73
|
+
taskName?: string;
|
|
74
|
+
taskParentNames?: string[];
|
|
75
|
+
taskType?: 'file' | 'suite' | 'case';
|
|
76
|
+
testPath: string;
|
|
77
|
+
type: 'stdout' | 'stderr';
|
|
78
|
+
trace?: string;
|
|
79
|
+
};
|
|
80
|
+
|
|
61
81
|
export type BrowserHostConfig = {
|
|
62
82
|
rootPath: string;
|
|
63
83
|
projects: BrowserProjectRuntime[];
|
|
@@ -101,20 +121,7 @@ export type BrowserClientMessage =
|
|
|
101
121
|
}
|
|
102
122
|
| { type: 'case-result'; payload: TestResult }
|
|
103
123
|
| { type: 'file-complete'; payload: TestFileResult }
|
|
104
|
-
| {
|
|
105
|
-
type: 'log';
|
|
106
|
-
payload: {
|
|
107
|
-
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
108
|
-
content: string;
|
|
109
|
-
taskId?: string;
|
|
110
|
-
taskName?: string;
|
|
111
|
-
taskParentNames?: string[];
|
|
112
|
-
taskType?: 'file' | 'suite' | 'case';
|
|
113
|
-
testPath: string;
|
|
114
|
-
type: 'stdout' | 'stderr';
|
|
115
|
-
trace?: string;
|
|
116
|
-
};
|
|
117
|
-
}
|
|
124
|
+
| { type: 'log'; payload: BrowserLogPayload }
|
|
118
125
|
| {
|
|
119
126
|
type: 'fatal';
|
|
120
127
|
payload: { message: string; stack?: string };
|
|
@@ -134,6 +141,38 @@ export type BrowserClientMessage =
|
|
|
134
141
|
payload: BrowserDispatchRequest;
|
|
135
142
|
};
|
|
136
143
|
|
|
144
|
+
/**
|
|
145
|
+
* Lifecycle methods the runner emits via `dispatchRunnerLifecycle()` as
|
|
146
|
+
* dispatch-rpc-requests on the `runner` namespace (as opposed to the
|
|
147
|
+
* {@link BrowserClientMessage} types it `send()`s). The runner client imports
|
|
148
|
+
* this instead of redeclaring the list, so the emit site cannot drift from the
|
|
149
|
+
* host router.
|
|
150
|
+
*/
|
|
151
|
+
export type RunnerLifecycleMethod =
|
|
152
|
+
| 'file-ready'
|
|
153
|
+
| 'suite-start'
|
|
154
|
+
| 'suite-result'
|
|
155
|
+
| 'case-start';
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* {@link BrowserClientMessage} types that are forwarded to the `runner`
|
|
159
|
+
* namespace (by message `type`) rather than handled at the transport layer.
|
|
160
|
+
* `Extract` keeps this a checked subset of the message union — renaming a
|
|
161
|
+
* message type drops it here, surfacing as a missing handler downstream.
|
|
162
|
+
*/
|
|
163
|
+
type RunnerMessageMethod = Extract<
|
|
164
|
+
BrowserClientMessage['type'],
|
|
165
|
+
'file-start' | 'case-result' | 'file-complete' | 'log' | 'fatal'
|
|
166
|
+
>;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Single source of truth for every method handled by the `runner` dispatch
|
|
170
|
+
* namespace. The host handler table is keyed by this union (a missing key is a
|
|
171
|
+
* compile error), so adding a runner method here forces a matching handler and
|
|
172
|
+
* cannot silently no-op at runtime.
|
|
173
|
+
*/
|
|
174
|
+
export type RunnerDispatchMethod = RunnerLifecycleMethod | RunnerMessageMethod;
|
|
175
|
+
|
|
137
176
|
/**
|
|
138
177
|
* Transport-agnostic envelope used by host routing.
|
|
139
178
|
* `namespace + method + args + target` describes an operation independent of
|
|
@@ -147,6 +186,11 @@ export type BrowserDispatchRequest = {
|
|
|
147
186
|
namespace: string;
|
|
148
187
|
method: string;
|
|
149
188
|
args?: unknown;
|
|
189
|
+
// Routing reads `namespace`, `method`, `runToken`, and `target.sessionId`
|
|
190
|
+
// (see dispatchRouter.ts / dispatchBrowserRpcRequest). `target.testFile` and
|
|
191
|
+
// `target.projectName` are carried for diagnostics / forward-compatibility and
|
|
192
|
+
// are NOT consulted for routing today — adding a routing-relevant field here
|
|
193
|
+
// means wiring a reader on the host side, which structural typing won't force.
|
|
150
194
|
target?: {
|
|
151
195
|
testFile?: string;
|
|
152
196
|
sessionId?: string;
|
package/src/providers/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BrowserProvider } from '@rstest/core/internal/browser';
|
|
1
2
|
import type { BrowserRpcRequest } from '../rpcProtocol';
|
|
2
3
|
import { playwrightProviderImplementation } from './playwright';
|
|
3
4
|
|
|
@@ -14,8 +15,14 @@ import { playwrightProviderImplementation } from './playwright';
|
|
|
14
15
|
* - do not reference optional peer provider types from public declarations
|
|
15
16
|
* - keep provider-specific behavior and config decoding inside provider implementations
|
|
16
17
|
* - prefer direct passthrough to provider APIs over provider-specific translation
|
|
18
|
+
*
|
|
19
|
+
* The provider-name union is owned by `@rstest/core` (see `BROWSER_PROVIDERS`)
|
|
20
|
+
* because core's CLI `init` templates need it but cannot import this package
|
|
21
|
+
* (peer-dependency direction). `providerImplementations` below is keyed by the
|
|
22
|
+
* re-exported union, so a provider added in core without an implementation here
|
|
23
|
+
* is a compile error.
|
|
17
24
|
*/
|
|
18
|
-
export type BrowserProvider
|
|
25
|
+
export type { BrowserProvider };
|
|
19
26
|
|
|
20
27
|
/** Minimal console shape needed by host logging bridge. */
|
|
21
28
|
export type BrowserConsoleMessage = {
|
package/src/rpcProtocol.ts
CHANGED
|
@@ -178,28 +178,41 @@ export const validateBrowserRpcRequest = (
|
|
|
178
178
|
return request;
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Single source of truth for snapshot RPC methods and their argument shapes.
|
|
183
|
+
* The request union, the client sender, both host-side mappers, and every
|
|
184
|
+
* exhaustiveness check derive from this map — adding or renaming a method here
|
|
185
|
+
* forces a compile error at every site that has not been updated.
|
|
186
|
+
*/
|
|
187
|
+
export type SnapshotRpcMethodArgs = {
|
|
188
|
+
resolveSnapshotPath: { testPath: string };
|
|
189
|
+
readSnapshotFile: { filepath: string };
|
|
190
|
+
saveSnapshotFile: { filepath: string; content: string };
|
|
191
|
+
removeSnapshotFile: { filepath: string };
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export type SnapshotRpcMethod = keyof SnapshotRpcMethodArgs;
|
|
195
|
+
|
|
181
196
|
/**
|
|
182
197
|
* Snapshot RPC request from runner iframe.
|
|
183
198
|
* The container will forward these to the host via WebSocket RPC.
|
|
184
199
|
*/
|
|
185
|
-
export type SnapshotRpcRequest =
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
args: { filepath: string };
|
|
205
|
-
};
|
|
200
|
+
export type SnapshotRpcRequest = {
|
|
201
|
+
[M in SnapshotRpcMethod]: {
|
|
202
|
+
id: string;
|
|
203
|
+
method: M;
|
|
204
|
+
args: SnapshotRpcMethodArgs[M];
|
|
205
|
+
};
|
|
206
|
+
}[SnapshotRpcMethod];
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Client-side snapshot RPC call (request without the transport `id`).
|
|
210
|
+
* Distributive over {@link SnapshotRpcMethod} so `method` and `args` stay paired
|
|
211
|
+
* at the call site — a mismatched pair fails to compile.
|
|
212
|
+
*/
|
|
213
|
+
export type SnapshotRpcCall = {
|
|
214
|
+
[M in SnapshotRpcMethod]: {
|
|
215
|
+
method: M;
|
|
216
|
+
args: SnapshotRpcMethodArgs[M];
|
|
217
|
+
};
|
|
218
|
+
}[SnapshotRpcMethod];
|
package/src/viewportPresets.ts
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* IMPORTANT: Keep this list/map in sync with `DevicePreset` typing in
|
|
5
5
|
* `@rstest/core` (`packages/core/src/types/config.ts`) so `defineConfig`
|
|
6
6
|
* autocomplete and runtime validation stay consistent.
|
|
7
|
+
*
|
|
8
|
+
* Upstream source of truth for ids/dimensions is the Chrome DevTools emulated
|
|
9
|
+
* device list — mirror each device's `screen.vertical` `{ width, height }`:
|
|
10
|
+
* https://github.com/ChromeDevTools/devtools-frontend/blob/main/front_end/models/emulation/EmulatedDevices.ts
|
|
11
|
+
* Last verified in sync (all 17): 2026-04-22, devtools-frontend commit abaac05e.
|
|
7
12
|
*/
|
|
8
13
|
export const BROWSER_VIEWPORT_PRESET_IDS = [
|
|
9
14
|
'iPhoneSE',
|
package/src/watchCliShortcuts.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { color, logger } from '@rstest/core/browser';
|
|
1
|
+
import { color, isTTY, logger } from '@rstest/core/internal/browser';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
export const isBrowserWatchCliShortcutsEnabled = (): boolean => isTTY();
|
|
3
|
+
export const isBrowserWatchCliShortcutsEnabled = (): boolean => isTTY('stdin');
|
|
6
4
|
|
|
7
5
|
export const getBrowserWatchCliShortcutsHintMessage = (): string => {
|
|
8
6
|
return ` ${color.dim('press')} ${color.bold('q')} ${color.dim('to quit')}\n`;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-zinc-950:#09090b;--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-light:300;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--tracking-widest:.1em;--radius-md:.375rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}@supports (color:lab(0% 0 0)){:root,:host{--color-zinc-950:lab(2.51107% .242703 -.886115)}}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.bottom-0{bottom:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.mt-3{margin-top:calc(var(--spacing) * 3)}.ml-1{margin-left:calc(var(--spacing) * 1)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-\[1px\]{height:1px}.h-\[48px\]{height:48px}.h-full{height:100%}.h-screen{height:100vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-2{width:calc(var(--spacing) * 2)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-\[16px\]{width:16px}.w-\[120px\]{width:120px}.w-\[280px\]{width:280px}.w-full{width:100%}.max-w-\[400px\]{max-width:400px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.resize{resize:both}.grid-cols-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-columns:auto minmax(0,1fr) auto}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.bg-black\/\[0\.02\]{background-color:#00000005}@supports (color:color-mix(in lab, red, red)){.bg-black\/\[0\.02\]{background-color:color-mix(in oklab, var(--color-black) 2%, transparent)}}.bg-transparent{background-color:#0000}.bg-zinc-950{background-color:var(--color-zinc-950)}.p-0{padding:calc(var(--spacing) * 0)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-\(--accents-3\){color:var(--accents-3)}.text-\(--accents-4\){color:var(--accents-4)}.text-\(--accents-5\){color:var(--accents-5)}.text-\(--accents-6\){color:var(--accents-6)}.text-\(--accents-7\){color:var(--accents-7)}.text-\(--muted-foreground\){color:var(--muted-foreground)}.text-\(--warning\){color:var(--warning)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-\[cubic-bezier\(0\.4\,0\,0\.2\,1\)\]{--tw-ease:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:bg-\(--accents-1\):hover{background-color:var(--accents-1)}.hover\:text-\(--accents-6\):hover{color:var(--accents-6)}}}.ant-typography.font-mono{font-family:var(--font-mono)}:root{--font-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--background:#fff;--foreground:#000;--ds-gray-100:#fafafa;--ds-gray-200:#eaeaea;--ds-gray-300:#999;--ds-gray-400:#888;--ds-gray-500:#666;--ds-gray-600:#444;--ds-gray-700:#333;--ds-gray-800:#111;--ds-gray-900:#000;--ds-gray-1000:#000;--ds-red-100:#fff0f0;--ds-red-200:#ffebeb;--ds-red-300:#ffe6e6;--ds-red-700:#e5484d;--ds-red-800:#da2f35;--ds-red-900:#cb2a2f;--ds-green-100:#effbef;--ds-green-200:#ebfaeb;--ds-green-300:#daf6da;--ds-green-700:#45a557;--ds-green-800:#398e4a;--ds-green-900:#297a3a;--ds-amber-100:#fff6e6;--ds-amber-200:#fff4d6;--ds-amber-300:#fef0cd;--ds-amber-700:#ffb224;--ds-amber-800:#ff990a;--ds-amber-900:#a35200;--ds-blue-700:#0070f3;--accents-1:var(--ds-gray-100);--accents-2:var(--ds-gray-200);--accents-3:var(--ds-gray-300);--accents-4:var(--ds-gray-400);--accents-5:var(--ds-gray-500);--accents-6:var(--ds-gray-600);--accents-7:var(--ds-gray-700);--accents-8:var(--ds-gray-800);--border:var(--accents-2);--muted:var(--accents-1);--muted-foreground:var(--accents-5);--primary:var(--foreground);--success:var(--ds-green-700);--error:var(--ds-red-800);--warning:var(--ds-amber-700);--lightningcss-light:initial;--lightningcss-dark: ;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}[data-theme=dark]{--background:#000;--foreground:#fff;--ds-gray-100:#111;--ds-gray-200:#333;--ds-gray-300:#444;--ds-gray-400:#666;--ds-gray-500:#888;--ds-gray-600:#999;--ds-gray-700:#eaeaea;--ds-gray-800:#fafafa;--ds-gray-900:#fff;--ds-gray-1000:#fff;--ds-red-100:#2a1314;--ds-red-200:#3c1618;--ds-red-300:#561a1e;--ds-red-700:#e5484d;--ds-red-800:#d93036;--ds-red-900:#ff6166;--ds-green-100:#0b2212;--ds-green-200:#0f2e18;--ds-green-300:#12361b;--ds-green-700:#45a557;--ds-green-800:#398e4a;--ds-green-900:#62c073;--ds-amber-100:#291800;--ds-amber-200:#331b00;--ds-amber-300:#4d2a00;--ds-amber-700:#ffb224;--ds-amber-800:#ff990a;--ds-amber-900:#f2a20d;--ds-blue-700:#0070f3;--accents-1:var(--ds-gray-100);--accents-2:var(--ds-gray-200);--accents-3:var(--ds-gray-300);--accents-4:var(--ds-gray-400);--accents-5:var(--ds-gray-500);--accents-6:var(--ds-gray-600);--accents-7:var(--ds-gray-700);--accents-8:var(--ds-gray-800);--border:var(--accents-2);--muted:var(--accents-1);--muted-foreground:var(--accents-5);--primary:var(--foreground);--success:var(--ds-green-700);--error:var(--ds-red-800);--warning:var(--ds-amber-700);--lightningcss-light: ;--lightningcss-dark:initial;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}body{background:var(--background);min-height:100vh;color:var(--foreground);margin:0;font-family:Inter,system-ui,-apple-system,sans-serif;overflow:hidden}.ant-input-affix-wrapper:focus,.ant-input-affix-wrapper-focused{border-color:var(--foreground);box-shadow:0 0 0 1px var(--foreground)}.ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected{transition:none}@keyframes status-flash{0%{filter:brightness()}5%{filter:brightness(2.5)}15%{filter:brightness(1.8)}40%{filter:brightness(1.3)}to{filter:brightness()}}.status-icon-flash{animation:1.5s ease-out status-flash}@keyframes progress-segment-flash{0%{filter:brightness();box-shadow:none}10%{filter:brightness(2.5);box-shadow:0 0 8px 1px}to{filter:brightness();box-shadow:none}}.progress-flash-active{animation:1s cubic-bezier(.4,0,.2,1) progress-segment-flash}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! LICENSE: 27.099feaf1da.js.LICENSE.txt */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! LICENSE: lib-react.5ae9b90ee5.js.LICENSE.txt */
|
package/dist/client/entry.d.ts
DELETED