@rstest/browser 0.10.4 → 0.10.6
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/css/index.0521ff95b1.css +1 -0
- package/dist/browser-container/container-static/js/{3.d3d6c6e4cf.js → 854.c59f71483d.js} +5690 -5718
- package/dist/browser-container/container-static/js/854.c59f71483d.js.LICENSE.txt +1 -0
- package/dist/browser-container/container-static/js/{index.8fb1588e4a.js → index.fedc31dff3.js} +9 -9
- package/dist/browser-container/index.html +1 -1
- package/dist/browserRpcRegistry.d.ts +1 -2
- package/dist/client/api.d.ts +1 -1
- package/dist/client/dispatchTransport.d.ts +3 -5
- package/dist/client/locator.d.ts +2 -3
- package/dist/concurrency.d.ts +2 -0
- package/dist/dispatchCapabilities.d.ts +2 -2
- 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 +11 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +71 -14
- package/dist/protocol.d.ts +42 -46
- package/dist/providers/index.d.ts +11 -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 +9 -16
- 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 +2 -3
- package/dist/watchCliShortcuts.d.ts +1 -1
- package/dist/watchRerunPlanner.d.ts +2 -2
- package/package.json +8 -10
- package/src/browserRpcRegistry.ts +2 -2
- package/src/concurrency.ts +1 -1
- package/src/headedSerialTaskQueue.ts +5 -1
- package/src/hostController.ts +184 -27
- package/dist/browser-container/container-static/css/index.5c72297783.css +0 -1
- package/dist/browser-container/container-static/js/3.d3d6c6e4cf.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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! LICENSE: 854.c59f71483d.js.LICENSE.txt */
|
package/dist/browser-container/container-static/js/{index.8fb1588e4a.js → index.fedc31dff3.js}
RENAMED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
1617 (e, t, s) {
|
|
5
5
|
var l = s(9793);
|
|
6
6
|
let r = "__rstest_dispatch_response__";
|
|
7
|
-
var o = s(
|
|
7
|
+
var o = s(4472), a = s(6961), i = s(6194), 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(165), p = s(179), h = s(8753), f = s(184), x = s(5676);
|
|
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(1910), v = s(8366), y = s(4560), _ = s(4484), C = s(7527);
|
|
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(4909), S = s(7602), F = s(3106), N = s(1725), A = s(9122), P = s(1687), M = s(7046), z = s(4668);
|
|
82
82
|
let O = {
|
|
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(3401);
|
|
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(7795), q = s(7319), H = s(7752);
|
|
571
571
|
let J = (e)=>(0, l.jsxs)("svg", {
|
|
572
572
|
xmlns: "http://www.w3.org/2000/svg",
|
|
573
573
|
fill: "none",
|
|
@@ -1585,7 +1585,7 @@
|
|
|
1585
1585
|
]
|
|
1586
1586
|
});
|
|
1587
1587
|
};
|
|
1588
|
-
var X = s(
|
|
1588
|
+
var X = s(2524), K = s(4333), Y = s(3534), Q = s(5749), ee = s(1695), et = s(1255);
|
|
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(6530), eo = s(9790), ea = s(2741), ei = s(2669), en = s(6405);
|
|
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));
|
|
@@ -3045,7 +3045,7 @@
|
|
|
3045
3045
|
}, (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));
|
|
3046
3046
|
var c = n.O(void 0, [
|
|
3047
3047
|
"783",
|
|
3048
|
-
"
|
|
3048
|
+
"854"
|
|
3049
3049
|
], ()=>n(1617));
|
|
3050
3050
|
c = n.O(c);
|
|
3051
3051
|
})();
|
|
@@ -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/854.c59f71483d.js"></script><script defer src="/container-static/js/index.fedc31dff3.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>
|
|
@@ -13,6 +13,5 @@
|
|
|
13
13
|
* toHaveValues
|
|
14
14
|
* - Artifacts intentionally excluded for now: screenshot/toMatchScreenshot/
|
|
15
15
|
* trace/video
|
|
16
|
-
*/
|
|
17
|
-
export declare const supportedLocatorActions: Set<string>;
|
|
16
|
+
*/ export declare const supportedLocatorActions: Set<string>;
|
|
18
17
|
export declare const supportedExpectElementMatchers: Set<string>;
|
package/dist/client/api.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Locator, page, setTestIdAttribute } from './locator.js';
|
|
2
|
-
export type { BrowserPage, BrowserSerializable, LocatorBlurOptions, LocatorCheckOptions, LocatorClickOptions, LocatorDblclickOptions, LocatorDispatchEventInit, LocatorFillOptions, LocatorFilterOptions, LocatorFocusOptions, LocatorGetByRoleOptions, LocatorHoverOptions, LocatorKeyboardModifier, LocatorMouseButton, LocatorPosition, LocatorPressOptions, LocatorScrollIntoViewIfNeededOptions, LocatorSelectOptionOptions, LocatorSetInputFilesOptions, LocatorTextOptions, LocatorWaitForOptions
|
|
2
|
+
export type { BrowserPage, BrowserSerializable, LocatorBlurOptions, LocatorCheckOptions, LocatorClickOptions, LocatorDblclickOptions, LocatorDispatchEventInit, LocatorFillOptions, LocatorFilterOptions, LocatorFocusOptions, LocatorGetByRoleOptions, LocatorHoverOptions, LocatorKeyboardModifier, LocatorMouseButton, LocatorPosition, LocatorPressOptions, LocatorScrollIntoViewIfNeededOptions, LocatorSelectOptionOptions, LocatorSetInputFilesOptions, LocatorTextOptions, LocatorWaitForOptions } from './locator.js';
|
|
3
3
|
export { Locator, page, setTestIdAttribute };
|
|
@@ -9,8 +9,7 @@ export declare const createRequestId: (prefix: string) => string;
|
|
|
9
9
|
* {@link sendRunnerLifecycle}, so the request id only needs to be unique — it is
|
|
10
10
|
* produced by the shared {@link createRequestId} factory rather than a bespoke
|
|
11
11
|
* per-runner counter.
|
|
12
|
-
*/
|
|
13
|
-
export declare const createRunnerLifecycleRequest: (method: string, args: unknown) => BrowserDispatchRequest;
|
|
12
|
+
*/ export declare const createRunnerLifecycleRequest: (method: string, args: unknown) => BrowserDispatchRequest;
|
|
14
13
|
/**
|
|
15
14
|
* Deliver a runner-lifecycle request fire-and-forget.
|
|
16
15
|
*
|
|
@@ -18,9 +17,8 @@ export declare const createRunnerLifecycleRequest: (method: string, args: unknow
|
|
|
18
17
|
* out: the host echoes a response but the runner ignores it. Failures surface
|
|
19
18
|
* only through the optional `onError` hook (debug logging at the call site),
|
|
20
19
|
* keeping the hot test loop non-blocking.
|
|
21
|
-
*/
|
|
22
|
-
export declare const
|
|
23
|
-
export declare const dispatchRpc: <T>({ requestId, request, timeoutMs, timeoutMessage, staleMessage, }: {
|
|
20
|
+
*/ export declare const sendRunnerLifecycle: (request: BrowserDispatchRequest, onError?: (error: unknown) => void) => void;
|
|
21
|
+
export declare const dispatchRpc: <T>({ requestId, request, timeoutMs, timeoutMessage, staleMessage }: {
|
|
24
22
|
requestId: string;
|
|
25
23
|
request: BrowserDispatchRequest;
|
|
26
24
|
timeoutMs: number;
|
package/dist/client/locator.d.ts
CHANGED
|
@@ -120,6 +120,5 @@ export declare const isLocator: (value: unknown) => value is Locator;
|
|
|
120
120
|
* Forwards to the host provider (e.g. Playwright `selectors.setTestIdAttribute()`).
|
|
121
121
|
*
|
|
122
122
|
* @default 'data-testid'
|
|
123
|
-
*/
|
|
124
|
-
export
|
|
125
|
-
export {};
|
|
123
|
+
*/ export declare const setTestIdAttribute: (attribute: string) => Promise<void>;
|
|
124
|
+
export { };
|
package/dist/concurrency.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getNumCpus, parseWorkers } from '@rstest/core/internal/browser';
|
|
2
2
|
import type { Rstest } from '@rstest/core/internal/browser';
|
|
3
|
+
// Re-export the shared worker primitives so existing consumers (and unit tests
|
|
4
|
+
// importing from `../src/concurrency`) keep a stable import surface.
|
|
3
5
|
export { getNumCpus, parseWorkers };
|
|
4
6
|
type HeadlessConcurrencyContext = Pick<Rstest, 'command'> & {
|
|
5
7
|
normalizedConfig: {
|
|
@@ -30,5 +30,5 @@ type CreateHostDispatchRouterOptions = {
|
|
|
30
30
|
extensionHandlers?: Map<string, BrowserDispatchHandler>;
|
|
31
31
|
onDuplicateNamespace?: (namespace: string) => void;
|
|
32
32
|
};
|
|
33
|
-
export declare const createHostDispatchRouter: ({ routerOptions, runnerCallbacks, runSnapshotRpc, extensionHandlers, onDuplicateNamespace
|
|
34
|
-
export {};
|
|
33
|
+
export declare const createHostDispatchRouter: ({ routerOptions, runnerCallbacks, runSnapshotRpc, extensionHandlers, onDuplicateNamespace }: CreateHostDispatchRouterOptions) => HostDispatchRouter;
|
|
34
|
+
export { };
|
package/dist/dispatchRouter.d.ts
CHANGED
|
@@ -7,8 +7,7 @@ type HostDispatchRouterOptions = {
|
|
|
7
7
|
/**
|
|
8
8
|
* Host-side routing layer for dispatch envelopes.
|
|
9
9
|
* Capabilities are registered by namespace, while routing stays transport-agnostic.
|
|
10
|
-
*/
|
|
11
|
-
export declare class HostDispatchRouter {
|
|
10
|
+
*/ export declare class HostDispatchRouter {
|
|
12
11
|
private handlers;
|
|
13
12
|
private options;
|
|
14
13
|
constructor(options?: HostDispatchRouterOptions);
|
|
@@ -17,4 +16,4 @@ export declare class HostDispatchRouter {
|
|
|
17
16
|
has(namespace: string): boolean;
|
|
18
17
|
dispatch(request: BrowserDispatchRequest): Promise<BrowserDispatchResponse>;
|
|
19
18
|
}
|
|
20
|
-
export {};
|
|
19
|
+
export { };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
type HeadedSerialTask = () => Promise<void>;
|
|
2
|
+
type HeadedSerialTaskQueue = {
|
|
3
|
+
enqueue: (task: HeadedSerialTask) => Promise<void>;
|
|
4
|
+
};
|
|
2
5
|
/**
|
|
3
6
|
* Serializes headed browser file execution so only one task runs at a time.
|
|
4
7
|
* The queue keeps draining even if an earlier task rejects.
|
|
5
|
-
*/
|
|
6
|
-
export
|
|
7
|
-
enqueue: (task: HeadedSerialTask) => Promise<void>;
|
|
8
|
-
};
|
|
9
|
-
export {};
|
|
8
|
+
*/ export declare const createHeadedSerialTaskQueue: () => HeadedSerialTaskQueue;
|
|
9
|
+
export { };
|
|
@@ -14,6 +14,5 @@ type HeadlessLatestRerunSchedulerOptions<TFile, TRun> = {
|
|
|
14
14
|
/**
|
|
15
15
|
* Latest-only rerun scheduler for headless watch mode.
|
|
16
16
|
* Keeps only the newest pending payload and interrupts active run generations.
|
|
17
|
-
*/
|
|
18
|
-
export
|
|
19
|
-
export {};
|
|
17
|
+
*/ export declare const createHeadlessLatestRerunScheduler: <TFile, TRun>(options: HeadlessLatestRerunSchedulerOptions<TFile, TRun>) => HeadlessLatestRerunScheduler<TFile>;
|
|
18
|
+
export { };
|
|
@@ -7,6 +7,5 @@ type HeadlessRunnerTransportHandlers = {
|
|
|
7
7
|
/**
|
|
8
8
|
* Headless transport adapter.
|
|
9
9
|
* This only binds page bridge functions and delegates all scheduling decisions upstream.
|
|
10
|
-
*/
|
|
11
|
-
export
|
|
12
|
-
export {};
|
|
10
|
+
*/ export declare const attachHeadlessRunnerTransport: (page: BrowserProviderPage, handlers: HeadlessRunnerTransportHandlers) => Promise<void>;
|
|
11
|
+
export { };
|
package/dist/hostController.d.ts
CHANGED
|
@@ -14,8 +14,7 @@ type BrowserLazyCompilationConfig = {
|
|
|
14
14
|
* `server.port: 0` because its internal `getPort` never reads back the
|
|
15
15
|
* OS-assigned ephemeral port. This helper falls back to
|
|
16
16
|
* `httpServer.address()` to obtain the real bound port.
|
|
17
|
-
*/
|
|
18
|
-
export declare const resolveListenPort: (listenPort: number, httpServer: {
|
|
17
|
+
*/ export declare const resolveListenPort: (listenPort: number, httpServer: {
|
|
19
18
|
address: () => ReturnType<import('node:net').Server['address']>;
|
|
20
19
|
} | null) => number;
|
|
21
20
|
export declare const createBrowserLazyCompilationConfig: (setupFiles: string[]) => BrowserLazyCompilationConfig;
|
|
@@ -26,13 +25,19 @@ export declare const createBrowserRsbuildDevConfig: (_isWatchMode: boolean) => {
|
|
|
26
25
|
logLevel: 'error';
|
|
27
26
|
};
|
|
28
27
|
};
|
|
28
|
+
export declare const createBrowserContextExcludeRegExp: (patterns: string[], projectRoot: string) => RegExp | null;
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Main Entry Point
|
|
31
|
+
// ============================================================================
|
|
29
32
|
export declare const runBrowserController: (context: RstestContext, options?: BrowserTestRunOptions) => Promise<BrowserTestRunResult | void>;
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// List Browser Tests
|
|
35
|
+
// ============================================================================
|
|
30
36
|
/**
|
|
31
37
|
* Result from collecting browser tests.
|
|
32
38
|
* This is the return type for listBrowserTests, designed for future extraction
|
|
33
39
|
* to a separate browser package.
|
|
34
|
-
*/
|
|
35
|
-
export type ListBrowserTestsResult = {
|
|
40
|
+
*/ export type ListBrowserTestsResult = {
|
|
36
41
|
list: ListCommandResult[];
|
|
37
42
|
close: () => Promise<void>;
|
|
38
43
|
};
|
|
@@ -40,10 +45,9 @@ export type ListBrowserTestsResult = {
|
|
|
40
45
|
* Collect test metadata from browser mode projects without running them.
|
|
41
46
|
* This function creates a headless browser runtime, loads test files,
|
|
42
47
|
* and collects their test structure (describe/test declarations).
|
|
43
|
-
*/
|
|
44
|
-
export declare const listBrowserTests: (context: RstestContext, options?: {
|
|
48
|
+
*/ export declare const listBrowserTests: (context: RstestContext, options?: {
|
|
45
49
|
shardedEntries?: Map<string, {
|
|
46
50
|
entries: Record<string, string>;
|
|
47
51
|
}>;
|
|
48
52
|
}) => Promise<ListBrowserTestsResult>;
|
|
49
|
-
export {};
|
|
53
|
+
export { };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ import { type ListBrowserTestsResult } from './hostController.js';
|
|
|
4
4
|
export { validateBrowserConfig };
|
|
5
5
|
export declare function runBrowserTests(context: RstestContext, options?: BrowserTestRunOptions): Promise<BrowserTestRunResult | void>;
|
|
6
6
|
export declare function listBrowserTests(context: RstestContext, options?: Pick<BrowserTestRunOptions, 'shardedEntries'>): Promise<ListBrowserTestsResult>;
|
|
7
|
-
export type { BrowserTestRunOptions, BrowserTestRunResult, ListBrowserTestsResult
|
|
7
|
+
export type { BrowserTestRunOptions, BrowserTestRunResult, ListBrowserTestsResult };
|
package/dist/index.js
CHANGED
|
@@ -3002,7 +3002,8 @@ const globToRegexp = (glob)=>{
|
|
|
3002
3002
|
const regex = picomatch_default().makeRe(glob, {
|
|
3003
3003
|
fastpaths: false,
|
|
3004
3004
|
noglobstar: false,
|
|
3005
|
-
bash: false
|
|
3005
|
+
bash: false,
|
|
3006
|
+
dot: true
|
|
3006
3007
|
});
|
|
3007
3008
|
if (!regex) throw new Error(`Invalid glob pattern: ${glob}`);
|
|
3008
3009
|
if (!glob.startsWith('./')) return regex;
|
|
@@ -3022,20 +3023,76 @@ const globPatternsToRegExp = (patterns)=>{
|
|
|
3022
3023
|
});
|
|
3023
3024
|
return new RegExp(`(?:${regexParts.join('|')})$`);
|
|
3024
3025
|
};
|
|
3025
|
-
const
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3026
|
+
const REGEXP_SPECIAL_CHARACTERS = /[|\\{}()[\]^$+*?.]/g;
|
|
3027
|
+
const PATH_SEPARATOR_SOURCE = String.raw`[\\/]`;
|
|
3028
|
+
const WINDOWS_ABSOLUTE_PATH_SOURCE = String.raw`[A-Za-z]:[\\/]`;
|
|
3029
|
+
const escapeRegExp = (value)=>value.replace(REGEXP_SPECIAL_CHARACTERS, '\\$&');
|
|
3030
|
+
const normalizePathForRegExp = (value)=>normalize(value).replaceAll('\\', '/');
|
|
3031
|
+
const normalizeExcludePatternForRegExp = (value)=>value.startsWith('./') ? `./${normalizePathForRegExp(value.substring(2))}` : normalizePathForRegExp(value);
|
|
3032
|
+
const isAbsolutePatternForRegExp = (value)=>value.startsWith('/') || /^[A-Za-z]:\//.test(value);
|
|
3033
|
+
const isEscapedRegExpCharacter = (source, index)=>{
|
|
3034
|
+
let backslashCount = 0;
|
|
3035
|
+
for(let current = index - 1; current >= 0 && '\\' === source[current]; current--)backslashCount++;
|
|
3036
|
+
return backslashCount % 2 === 1;
|
|
3037
|
+
};
|
|
3038
|
+
const replacePathSeparatorsInRegExpSource = (source)=>{
|
|
3039
|
+
let result = '';
|
|
3040
|
+
let inCharacterClass = false;
|
|
3041
|
+
for(let index = 0; index < source.length; index++){
|
|
3042
|
+
const character = source[index];
|
|
3043
|
+
const isEscaped = isEscapedRegExpCharacter(source, index);
|
|
3044
|
+
if ('[' === character && !isEscaped) inCharacterClass = true;
|
|
3045
|
+
if (!inCharacterClass && '\\' === character && '/' === source[index + 1]) {
|
|
3046
|
+
result += PATH_SEPARATOR_SOURCE;
|
|
3047
|
+
index++;
|
|
3048
|
+
continue;
|
|
3035
3049
|
}
|
|
3050
|
+
result += character;
|
|
3051
|
+
if (']' === character && !isEscaped) inCharacterClass = false;
|
|
3052
|
+
}
|
|
3053
|
+
return result;
|
|
3054
|
+
};
|
|
3055
|
+
const createRelativeContextExcludeSource = (source, normalizedPattern)=>{
|
|
3056
|
+
if (normalizedPattern.startsWith('./')) return source;
|
|
3057
|
+
return normalizedPattern.startsWith('**/') ? `(?:(?:${source})|\\.(?:${source}))` : `(?:(?:${source})|\\.${PATH_SEPARATOR_SOURCE}(?:${source}))`;
|
|
3058
|
+
};
|
|
3059
|
+
const createProjectAbsoluteExcludeSource = (source, normalizedPattern)=>normalizedPattern.startsWith('./') || normalizedPattern.startsWith('**/') ? source : `${PATH_SEPARATOR_SOURCE}(?:${source})`;
|
|
3060
|
+
const excludePatternsToRegExpSources = (patterns)=>{
|
|
3061
|
+
const sources = patterns.map((pattern)=>{
|
|
3062
|
+
const normalizedPattern = normalizeExcludePatternForRegExp(pattern);
|
|
3063
|
+
const regex = globToRegexp(normalizedPattern);
|
|
3064
|
+
let source = regex.source;
|
|
3065
|
+
if (source.startsWith('^')) source = source.substring(1);
|
|
3066
|
+
if (source.endsWith('$')) source = source.substring(0, source.length - 1);
|
|
3067
|
+
source = replacePathSeparatorsInRegExpSource(source);
|
|
3068
|
+
const isAbsolute = isAbsolutePatternForRegExp(normalizedPattern);
|
|
3069
|
+
const absolute = normalizedPattern.startsWith('./') ? source.substring(2) : source;
|
|
3070
|
+
return {
|
|
3071
|
+
relative: isAbsolute ? source : createRelativeContextExcludeSource(source, normalizedPattern),
|
|
3072
|
+
absolute: isAbsolute ? absolute : createProjectAbsoluteExcludeSource(absolute, normalizedPattern),
|
|
3073
|
+
isAbsolute
|
|
3074
|
+
};
|
|
3075
|
+
});
|
|
3076
|
+
if (0 === sources.length) return null;
|
|
3077
|
+
return sources;
|
|
3078
|
+
};
|
|
3079
|
+
const createBrowserContextExcludeRegExp = (patterns, projectRoot)=>{
|
|
3080
|
+
const excludeSources = excludePatternsToRegExpSources(patterns);
|
|
3081
|
+
if (!excludeSources) return null;
|
|
3082
|
+
const normalizedProjectRoot = normalizePathForRegExp(projectRoot).replace(/[\\/]$/, '');
|
|
3083
|
+
const projectRootSource = normalizedProjectRoot.split('/').map(escapeRegExp).join(PATH_SEPARATOR_SOURCE);
|
|
3084
|
+
const relativeExcludeSources = excludeSources.filter((source)=>!source.isAbsolute);
|
|
3085
|
+
const absoluteExcludeSources = excludeSources.filter((source)=>source.isAbsolute);
|
|
3086
|
+
const sourceBranches = [];
|
|
3087
|
+
if (relativeExcludeSources.length > 0) {
|
|
3088
|
+
const relativePatternSource = `(?:${relativeExcludeSources.map((source)=>source.relative).join('|')})`;
|
|
3089
|
+
const absolutePatternSource = `(?:${relativeExcludeSources.map((source)=>source.absolute).join('|')})`;
|
|
3090
|
+
const relativeSource = `(?:${relativePatternSource})`;
|
|
3091
|
+
const absoluteSource = normalizedProjectRoot ? `${projectRootSource}(?=${PATH_SEPARATOR_SOURCE})(?:${absolutePatternSource})` : `(?:${absolutePatternSource})`;
|
|
3092
|
+
sourceBranches.push(`(?!${WINDOWS_ABSOLUTE_PATH_SOURCE}|${PATH_SEPARATOR_SOURCE})${relativeSource}`, absoluteSource);
|
|
3036
3093
|
}
|
|
3037
|
-
if (0
|
|
3038
|
-
return new RegExp(
|
|
3094
|
+
if (absoluteExcludeSources.length > 0) sourceBranches.push(`(?:${absoluteExcludeSources.map((source)=>source.relative).join('|')})`);
|
|
3095
|
+
return new RegExp(`^(?:${sourceBranches.join('|')})$`);
|
|
3039
3096
|
};
|
|
3040
3097
|
const findTestFileInModules = (modules, entryTestFiles)=>{
|
|
3041
3098
|
if (!modules) return null;
|
|
@@ -3211,7 +3268,7 @@ const generateManifestModule = ({ manifestPath, entries })=>{
|
|
|
3211
3268
|
const projectRootPosix = normalize(project.rootPath);
|
|
3212
3269
|
const includeRegExp = globPatternsToRegExp(project.normalizedConfig.include);
|
|
3213
3270
|
const excludePatterns = project.normalizedConfig.exclude.patterns;
|
|
3214
|
-
const excludeRegExp =
|
|
3271
|
+
const excludeRegExp = createBrowserContextExcludeRegExp(excludePatterns, projectRootPosix);
|
|
3215
3272
|
lines.push(`const ${varName} = import.meta.webpackContext(${JSON.stringify(projectRootPosix)}, {`);
|
|
3216
3273
|
lines.push(' recursive: true,');
|
|
3217
3274
|
lines.push(` regExp: ${includeRegExp.toString()},`);
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import type { BrowserViewport } from '@rstest/core/internal/browser';
|
|
2
2
|
import type { RuntimeConfig, TestFileResult, TestInfo, TestResult } from '@rstest/core/internal/browser-runtime';
|
|
3
3
|
import type { SnapshotUpdateState } from '@vitest/snapshot';
|
|
4
|
-
export type { BrowserLocatorIR, BrowserRpcRequest, SnapshotRpcCall, SnapshotRpcMethod, SnapshotRpcMethodArgs, SnapshotRpcRequest
|
|
4
|
+
export type { BrowserLocatorIR, BrowserRpcRequest, SnapshotRpcCall, SnapshotRpcMethod, SnapshotRpcMethodArgs, SnapshotRpcRequest } from './rpcProtocol.js';
|
|
5
5
|
export { validateBrowserRpcRequest } from './rpcProtocol.js';
|
|
6
|
-
export declare const DISPATCH_MESSAGE_TYPE =
|
|
7
|
-
export declare const DISPATCH_RESPONSE_TYPE =
|
|
8
|
-
export declare const DISPATCH_RPC_BRIDGE_NAME =
|
|
9
|
-
export declare const DISPATCH_RPC_REQUEST_TYPE =
|
|
10
|
-
export declare const RSTEST_CONFIG_MESSAGE_TYPE =
|
|
11
|
-
export declare const DISPATCH_NAMESPACE_RUNNER =
|
|
12
|
-
export declare const DISPATCH_NAMESPACE_BROWSER =
|
|
13
|
-
export declare const DISPATCH_NAMESPACE_SNAPSHOT =
|
|
14
|
-
export declare const DISPATCH_METHOD_RPC =
|
|
6
|
+
export declare const DISPATCH_MESSAGE_TYPE = '__rstest_dispatch__';
|
|
7
|
+
export declare const DISPATCH_RESPONSE_TYPE = '__rstest_dispatch_response__';
|
|
8
|
+
export declare const DISPATCH_RPC_BRIDGE_NAME = '__rstest_dispatch_rpc__';
|
|
9
|
+
export declare const DISPATCH_RPC_REQUEST_TYPE = 'dispatch-rpc-request';
|
|
10
|
+
export declare const RSTEST_CONFIG_MESSAGE_TYPE = 'RSTEST_CONFIG';
|
|
11
|
+
export declare const DISPATCH_NAMESPACE_RUNNER = 'runner';
|
|
12
|
+
export declare const DISPATCH_NAMESPACE_BROWSER = 'browser';
|
|
13
|
+
export declare const DISPATCH_NAMESPACE_SNAPSHOT = 'snapshot';
|
|
14
|
+
export declare const DISPATCH_METHOD_RPC = 'rpc';
|
|
15
15
|
export type SerializedRuntimeConfig = RuntimeConfig;
|
|
16
|
+
// `BrowserViewport` is a core config type (`@rstest/core` owns the canonical
|
|
17
|
+
// definition used by `NormalizedBrowserModeConfig`). Re-export it so the host
|
|
18
|
+
// assigns the SAME type across the seam instead of a hand-copied duplicate.
|
|
16
19
|
export type { BrowserViewport };
|
|
17
20
|
export type BrowserProjectRuntime = {
|
|
18
21
|
name: string;
|
|
@@ -24,8 +27,7 @@ export type BrowserProjectRuntime = {
|
|
|
24
27
|
/**
|
|
25
28
|
* Test file info with associated project name.
|
|
26
29
|
* Used to track which project a test file belongs to.
|
|
27
|
-
*/
|
|
28
|
-
export type TestFileInfo = {
|
|
30
|
+
*/ export type TestFileInfo = {
|
|
29
31
|
testPath: string;
|
|
30
32
|
projectName: string;
|
|
31
33
|
};
|
|
@@ -33,16 +35,14 @@ export type TestFileInfo = {
|
|
|
33
35
|
* Execution mode for browser tests.
|
|
34
36
|
* - 'run': Execute tests and report results (default)
|
|
35
37
|
* - 'collect': Only collect test metadata without running
|
|
36
|
-
*/
|
|
37
|
-
export type BrowserExecutionMode = 'run' | 'collect';
|
|
38
|
+
*/ export type BrowserExecutionMode = 'run' | 'collect';
|
|
38
39
|
/**
|
|
39
40
|
* Wire shape of a `log` client message payload. The host receives this and maps
|
|
40
41
|
* it onto core's {@link UserConsoleLog} (notably `level` → `name`); that mapper
|
|
41
42
|
* (`hostController.ts` `handleLog`) annotates its result as `UserConsoleLog`, so
|
|
42
43
|
* the map→core direction is compiler-checked. Owning the wire shape here as one
|
|
43
44
|
* named type keeps the host's input type from drifting away from the producer.
|
|
44
|
-
*/
|
|
45
|
-
export type BrowserLogPayload = {
|
|
45
|
+
*/ export type BrowserLogPayload = {
|
|
46
46
|
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
47
47
|
content: string;
|
|
48
48
|
taskId?: string;
|
|
@@ -61,31 +61,25 @@ export type BrowserHostConfig = {
|
|
|
61
61
|
};
|
|
62
62
|
testFile?: string;
|
|
63
63
|
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
runId?: string;
|
|
64
|
+
* Per-run identifier assigned by the container.
|
|
65
|
+
* Used by browser RPC calls to prevent stale requests from previous reruns.
|
|
66
|
+
*/ runId?: string;
|
|
68
67
|
/**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
runnerUrl?: string;
|
|
68
|
+
* Base URL for runner (iframe) pages.
|
|
69
|
+
*/ runnerUrl?: string;
|
|
72
70
|
/**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
wsPort?: number;
|
|
71
|
+
* WebSocket port for container RPC.
|
|
72
|
+
*/ wsPort?: number;
|
|
76
73
|
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
mode?: BrowserExecutionMode;
|
|
74
|
+
* Execution mode. Defaults to 'run'.
|
|
75
|
+
*/ mode?: BrowserExecutionMode;
|
|
80
76
|
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
debug?: boolean;
|
|
77
|
+
* Debug mode. When true, enables verbose logging in browser.
|
|
78
|
+
*/ debug?: boolean;
|
|
84
79
|
/**
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
rpcTimeout?: number;
|
|
80
|
+
* Timeout for RPC operations in milliseconds (e.g., snapshot file operations).
|
|
81
|
+
* Derived from testTimeout config.
|
|
82
|
+
*/ rpcTimeout?: number;
|
|
89
83
|
};
|
|
90
84
|
export type BrowserClientMessage = {
|
|
91
85
|
type: 'ready';
|
|
@@ -131,33 +125,36 @@ export type BrowserClientMessage = {
|
|
|
131
125
|
* {@link BrowserClientMessage} types it `send()`s). The runner client imports
|
|
132
126
|
* this instead of redeclaring the list, so the emit site cannot drift from the
|
|
133
127
|
* host router.
|
|
134
|
-
*/
|
|
135
|
-
export type RunnerLifecycleMethod = 'file-ready' | 'suite-start' | 'suite-result' | 'case-start';
|
|
128
|
+
*/ export type RunnerLifecycleMethod = 'file-ready' | 'suite-start' | 'suite-result' | 'case-start';
|
|
136
129
|
/**
|
|
137
130
|
* {@link BrowserClientMessage} types that are forwarded to the `runner`
|
|
138
131
|
* namespace (by message `type`) rather than handled at the transport layer.
|
|
139
132
|
* `Extract` keeps this a checked subset of the message union — renaming a
|
|
140
133
|
* message type drops it here, surfacing as a missing handler downstream.
|
|
141
|
-
*/
|
|
142
|
-
type RunnerMessageMethod = Extract<BrowserClientMessage['type'], 'file-start' | 'case-result' | 'file-complete' | 'log' | 'fatal'>;
|
|
134
|
+
*/ type RunnerMessageMethod = Extract<BrowserClientMessage['type'], 'file-start' | 'case-result' | 'file-complete' | 'log' | 'fatal'>;
|
|
143
135
|
/**
|
|
144
136
|
* Single source of truth for every method handled by the `runner` dispatch
|
|
145
137
|
* namespace. The host handler table is keyed by this union (a missing key is a
|
|
146
138
|
* compile error), so adding a runner method here forces a matching handler and
|
|
147
139
|
* cannot silently no-op at runtime.
|
|
148
|
-
*/
|
|
149
|
-
export type RunnerDispatchMethod = RunnerLifecycleMethod | RunnerMessageMethod;
|
|
140
|
+
*/ export type RunnerDispatchMethod = RunnerLifecycleMethod | RunnerMessageMethod;
|
|
150
141
|
/**
|
|
151
142
|
* Transport-agnostic envelope used by host routing.
|
|
152
143
|
* `namespace + method + args + target` describes an operation independent of
|
|
153
144
|
* the underlying message channel, and `runToken` provides run-level isolation.
|
|
154
|
-
*/
|
|
155
|
-
export type BrowserDispatchRequest = {
|
|
145
|
+
*/ export type BrowserDispatchRequest = {
|
|
156
146
|
requestId: string;
|
|
147
|
+
// Optional so headed/container paths can adopt the same envelope even when
|
|
148
|
+
// run-token isolation is only enforced in headless scheduling today.
|
|
157
149
|
runToken?: number;
|
|
158
150
|
namespace: string;
|
|
159
151
|
method: string;
|
|
160
152
|
args?: unknown;
|
|
153
|
+
// Routing reads `namespace`, `method`, `runToken`, and `target.sessionId`
|
|
154
|
+
// (see dispatchRouter.ts / dispatchBrowserRpcRequest). `target.testFile` and
|
|
155
|
+
// `target.projectName` are carried for diagnostics / forward-compatibility and
|
|
156
|
+
// are NOT consulted for routing today — adding a routing-relevant field here
|
|
157
|
+
// means wiring a reader on the host side, which structural typing won't force.
|
|
161
158
|
target?: {
|
|
162
159
|
testFile?: string;
|
|
163
160
|
sessionId?: string;
|
|
@@ -167,8 +164,7 @@ export type BrowserDispatchRequest = {
|
|
|
167
164
|
/**
|
|
168
165
|
* Dispatch response envelope.
|
|
169
166
|
* `stale: true` signals a safe drop from an older run generation, not a failure.
|
|
170
|
-
*/
|
|
171
|
-
export type BrowserDispatchResponse = {
|
|
167
|
+
*/ export type BrowserDispatchResponse = {
|
|
172
168
|
requestId: string;
|
|
173
169
|
runToken?: number;
|
|
174
170
|
result?: unknown;
|
|
@@ -19,10 +19,8 @@ import type { BrowserRpcRequest } from '../rpcProtocol.js';
|
|
|
19
19
|
* (peer-dependency direction). `providerImplementations` below is keyed by the
|
|
20
20
|
* re-exported union, so a provider added in core without an implementation here
|
|
21
21
|
* is a compile error.
|
|
22
|
-
*/
|
|
23
|
-
export type
|
|
24
|
-
/** Minimal console shape needed by host logging bridge. */
|
|
25
|
-
export type BrowserConsoleMessage = {
|
|
22
|
+
*/ export type { BrowserProvider };
|
|
23
|
+
/** Minimal console shape needed by host logging bridge. */ export type BrowserConsoleMessage = {
|
|
26
24
|
text: () => string;
|
|
27
25
|
};
|
|
28
26
|
/**
|
|
@@ -34,29 +32,26 @@ export type BrowserConsoleMessage = {
|
|
|
34
32
|
* (e.g. WebDriver BiDi), consider pushing page-level orchestration (goto,
|
|
35
33
|
* exposeFunction, addInitScript, event listeners) into provider-specific
|
|
36
34
|
* implementations so hostController only calls high-level semantic methods.
|
|
37
|
-
*/
|
|
38
|
-
export type BrowserProviderPage = {
|
|
35
|
+
*/ export type BrowserProviderPage = {
|
|
39
36
|
goto: (url: string, options?: {
|
|
40
37
|
waitUntil?: 'load';
|
|
41
38
|
}) => Promise<unknown>;
|
|
42
39
|
exposeFunction: (name: string, fn: (...args: any[]) => any) => Promise<void>;
|
|
43
40
|
addInitScript: (script: string) => Promise<void>;
|
|
44
41
|
on: {
|
|
45
|
-
(event: 'popup', listener: (page: BrowserProviderPage) => void): void;
|
|
46
|
-
(event: 'console', listener: (message: BrowserConsoleMessage) => void): void;
|
|
42
|
+
(event: 'popup', listener: (page: BrowserProviderPage) => void) : void;
|
|
43
|
+
(event: 'console', listener: (message: BrowserConsoleMessage) => void) : void;
|
|
47
44
|
};
|
|
48
45
|
close: () => Promise<void>;
|
|
49
46
|
[Symbol.asyncDispose]: () => Promise<void>;
|
|
50
47
|
};
|
|
51
|
-
/** Minimal browser context API surface required by hostController. */
|
|
52
|
-
export type BrowserProviderContext = {
|
|
48
|
+
/** Minimal browser context API surface required by hostController. */ export type BrowserProviderContext = {
|
|
53
49
|
newPage: () => Promise<BrowserProviderPage>;
|
|
54
50
|
on: (event: 'page', listener: (page: BrowserProviderPage) => void) => void;
|
|
55
51
|
close: () => Promise<void>;
|
|
56
52
|
[Symbol.asyncDispose]: () => Promise<void>;
|
|
57
53
|
};
|
|
58
|
-
/** Minimal browser API surface required by hostController. */
|
|
59
|
-
export type BrowserProviderBrowser = {
|
|
54
|
+
/** Minimal browser API surface required by hostController. */ export type BrowserProviderBrowser = {
|
|
60
55
|
close: () => Promise<void>;
|
|
61
56
|
[Symbol.asyncDispose]: () => Promise<void>;
|
|
62
57
|
newContext: (options: {
|
|
@@ -67,18 +62,15 @@ export type BrowserProviderBrowser = {
|
|
|
67
62
|
providerOptions?: Record<string, unknown>;
|
|
68
63
|
}) => Promise<BrowserProviderContext>;
|
|
69
64
|
};
|
|
70
|
-
/** Provider launch result consumed by hostController. */
|
|
71
|
-
export type BrowserProviderRuntime = {
|
|
65
|
+
/** Provider launch result consumed by hostController. */ export type BrowserProviderRuntime = {
|
|
72
66
|
browser: BrowserProviderBrowser;
|
|
73
67
|
};
|
|
74
|
-
/** Input contract for browser launch. */
|
|
75
|
-
export type LaunchBrowserInput = {
|
|
68
|
+
/** Input contract for browser launch. */ export type LaunchBrowserInput = {
|
|
76
69
|
browserName: 'chromium' | 'firefox' | 'webkit';
|
|
77
70
|
headless: boolean | undefined;
|
|
78
71
|
providerOptions: Record<string, unknown>;
|
|
79
72
|
};
|
|
80
|
-
/** Input contract for provider-side browser RPC dispatch. */
|
|
81
|
-
export type DispatchBrowserRpcInput = {
|
|
73
|
+
/** Input contract for provider-side browser RPC dispatch. */ export type DispatchBrowserRpcInput = {
|
|
82
74
|
containerPage?: BrowserProviderPage;
|
|
83
75
|
runnerPage?: BrowserProviderPage;
|
|
84
76
|
request: BrowserRpcRequest;
|
|
@@ -90,8 +82,7 @@ export type DispatchBrowserRpcInput = {
|
|
|
90
82
|
* Any new built-in provider must:
|
|
91
83
|
* - launch browser runtime for test execution
|
|
92
84
|
* - execute browser RPC requests (locator actions + assertions)
|
|
93
|
-
*/
|
|
94
|
-
export type BrowserProviderImplementation = {
|
|
85
|
+
*/ export type BrowserProviderImplementation = {
|
|
95
86
|
name: BrowserProvider;
|
|
96
87
|
launchRuntime: (input: LaunchBrowserInput) => Promise<BrowserProviderRuntime>;
|
|
97
88
|
dispatchRpc: (input: DispatchBrowserRpcInput) => Promise<unknown>;
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
* Contains adapted logic from Playwright matchers:
|
|
3
3
|
* https://github.com/microsoft/playwright/blob/main/packages/playwright/src/matchers/matchers.ts
|
|
4
4
|
* Copyright (c) Microsoft Corporation, Apache-2.0.
|
|
5
|
-
*/
|
|
6
|
-
import type { Page } from 'playwright';
|
|
5
|
+
*/ import type { Page } from 'playwright';
|
|
7
6
|
import type { BrowserRpcRequest } from '../../rpcProtocol.js';
|
|
8
|
-
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Public entry
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
export declare function dispatchPlaywrightBrowserRpc({ containerPage, runnerPage, request, timeoutFallbackMs }: {
|
|
9
11
|
containerPage?: Page;
|
|
10
12
|
runnerPage?: Page;
|
|
11
13
|
request: BrowserRpcRequest;
|