@vitest/browser 4.1.7 → 4.1.9
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/client/.vite/manifest.json +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-B-wB8WWP.js → orchestrator-KVYrTcFi.js} +38 -6
- package/dist/client/__vitest_browser__/{tester-DQAp97S5.js → tester-BJtsJFpD.js} +4 -0
- package/dist/client/orchestrator.html +1 -1
- package/dist/client/tester/tester.html +1 -1
- package/dist/index.js +36 -5
- package/dist/types.d.ts +1 -0
- package/package.json +6 -6
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "utils"
|
|
5
5
|
},
|
|
6
6
|
"orchestrator.html": {
|
|
7
|
-
"file": "__vitest_browser__/orchestrator-
|
|
7
|
+
"file": "__vitest_browser__/orchestrator-KVYrTcFi.js",
|
|
8
8
|
"name": "orchestrator",
|
|
9
9
|
"src": "orchestrator.html",
|
|
10
10
|
"isEntry": true,
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
]
|
|
14
14
|
},
|
|
15
15
|
"tester/tester.html": {
|
|
16
|
-
"file": "__vitest_browser__/tester-
|
|
16
|
+
"file": "__vitest_browser__/tester-BJtsJFpD.js",
|
|
17
17
|
"name": "tester",
|
|
18
18
|
"src": "tester/tester.html",
|
|
19
19
|
"isEntry": true,
|
package/dist/client/__vitest_browser__/{orchestrator-B-wB8WWP.js → orchestrator-KVYrTcFi.js}
RENAMED
|
@@ -10,6 +10,8 @@ class IframeOrchestrator {
|
|
|
10
10
|
cancelled = false;
|
|
11
11
|
recreateNonIsolatedIframe = false;
|
|
12
12
|
iframes = /* @__PURE__ */ new Map();
|
|
13
|
+
readyIframes = /* @__PURE__ */ new Set();
|
|
14
|
+
readyWaiters = /* @__PURE__ */ new Map();
|
|
13
15
|
eventTarget = new EventTarget();
|
|
14
16
|
traces;
|
|
15
17
|
constructor() {
|
|
@@ -27,6 +29,9 @@ class IframeOrchestrator {
|
|
|
27
29
|
"message",
|
|
28
30
|
(e) => this.onGlobalChannelEvent(e)
|
|
29
31
|
);
|
|
32
|
+
void client.waitForConnection().then(() => client.rpc.onOrchestratorReady()).catch((error) => {
|
|
33
|
+
debug("failed to notify orchestrator readiness", error);
|
|
34
|
+
});
|
|
30
35
|
}
|
|
31
36
|
async createTesters(options) {
|
|
32
37
|
await this.traces.waitInit();
|
|
@@ -63,6 +68,8 @@ class IframeOrchestrator {
|
|
|
63
68
|
}
|
|
64
69
|
this.iframes.forEach((iframe) => iframe.remove());
|
|
65
70
|
this.iframes.clear();
|
|
71
|
+
this.readyIframes.clear();
|
|
72
|
+
this.readyWaiters.clear();
|
|
66
73
|
for (let i = 0; i < options.files.length; i++) {
|
|
67
74
|
if (this.cancelled) {
|
|
68
75
|
await endSpan();
|
|
@@ -104,8 +111,7 @@ class IframeOrchestrator {
|
|
|
104
111
|
async runNonIsolatedTests(container, options, startTime, otelContext) {
|
|
105
112
|
if (this.recreateNonIsolatedIframe) {
|
|
106
113
|
this.recreateNonIsolatedIframe = false;
|
|
107
|
-
this.
|
|
108
|
-
this.iframes.delete(ID_ALL);
|
|
114
|
+
this.removeIframe(ID_ALL);
|
|
109
115
|
debug("recreate non-isolated iframe");
|
|
110
116
|
}
|
|
111
117
|
if (!this.iframes.has(ID_ALL)) {
|
|
@@ -131,8 +137,7 @@ class IframeOrchestrator {
|
|
|
131
137
|
const { width, height } = config.browser.viewport;
|
|
132
138
|
const file = spec.filepath;
|
|
133
139
|
if (this.iframes.has(file)) {
|
|
134
|
-
this.
|
|
135
|
-
this.iframes.delete(file);
|
|
140
|
+
this.removeIframe(file);
|
|
136
141
|
}
|
|
137
142
|
const iframe = await this.prepareIframe(
|
|
138
143
|
container,
|
|
@@ -181,12 +186,12 @@ Expected: ${iframe.src}`
|
|
|
181
186
|
}
|
|
182
187
|
} else {
|
|
183
188
|
this.iframes.set(iframeId, iframe);
|
|
184
|
-
this.sendEventToIframe({
|
|
189
|
+
this.waitForReady(iframeId).then(() => this.sendEventToIframe({
|
|
185
190
|
event: "prepare",
|
|
186
191
|
iframeId,
|
|
187
192
|
startTime,
|
|
188
193
|
otelCarrier: this.traces.getContextCarrier(otelContext)
|
|
189
|
-
}).then(resolve, (error) => reject(this.dispatchIframeError(error)));
|
|
194
|
+
})).then(resolve, (error) => reject(this.dispatchIframeError(error)));
|
|
190
195
|
}
|
|
191
196
|
};
|
|
192
197
|
iframe.onerror = (e) => {
|
|
@@ -201,6 +206,29 @@ Expected: ${iframe.src}`
|
|
|
201
206
|
});
|
|
202
207
|
return iframe;
|
|
203
208
|
}
|
|
209
|
+
markReady(iframeId) {
|
|
210
|
+
this.readyIframes.add(iframeId);
|
|
211
|
+
const waiter = this.readyWaiters.get(iframeId);
|
|
212
|
+
if (waiter) {
|
|
213
|
+
this.readyWaiters.delete(iframeId);
|
|
214
|
+
waiter();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
waitForReady(iframeId) {
|
|
218
|
+
if (this.readyIframes.has(iframeId)) {
|
|
219
|
+
return Promise.resolve();
|
|
220
|
+
}
|
|
221
|
+
return new Promise((resolve) => {
|
|
222
|
+
this.readyWaiters.set(iframeId, resolve);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
removeIframe(iframeId) {
|
|
226
|
+
const iframe = this.iframes.get(iframeId);
|
|
227
|
+
this.iframes.delete(iframeId);
|
|
228
|
+
this.readyIframes.delete(iframeId);
|
|
229
|
+
this.readyWaiters.delete(iframeId);
|
|
230
|
+
iframe == null ? void 0 : iframe.remove();
|
|
231
|
+
}
|
|
204
232
|
loggedIframe = /* @__PURE__ */ new WeakSet();
|
|
205
233
|
createWarningMessage(iframeId, location) {
|
|
206
234
|
return `The iframe${iframeId === ID_ALL ? "" : ` for "${iframeId}"`} was reloaded ${location}. This can lead to unexpected behavior during tests, duplicated test results or tests hanging.
|
|
@@ -257,6 +285,10 @@ If you are using a framework that manipulates browser history (like React Router
|
|
|
257
285
|
async onIframeEvent(e) {
|
|
258
286
|
debug("iframe event", JSON.stringify(e.data));
|
|
259
287
|
switch (e.data.event) {
|
|
288
|
+
case "ready": {
|
|
289
|
+
this.markReady(e.data.iframeId);
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
260
292
|
case "viewport": {
|
|
261
293
|
const { width, height, iframeId: id } = e.data;
|
|
262
294
|
const iframe = this.iframes.get(id);
|
|
@@ -2151,6 +2151,10 @@ const commands = new CommandsManager();
|
|
|
2151
2151
|
getBrowserState().commands = commands;
|
|
2152
2152
|
getBrowserState().activeTraceTaskIds = /* @__PURE__ */ new Set();
|
|
2153
2153
|
getBrowserState().iframeId = iframeId;
|
|
2154
|
+
channel.postMessage({
|
|
2155
|
+
event: "ready",
|
|
2156
|
+
iframeId
|
|
2157
|
+
});
|
|
2154
2158
|
let contextSwitched = false;
|
|
2155
2159
|
async function prepareTestEnvironment(options) {
|
|
2156
2160
|
debug == null ? void 0 : debug("trying to resolve the runner");
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
{__VITEST_INJECTOR__}
|
|
27
27
|
{__VITEST_ERROR_CATCHER__}
|
|
28
28
|
{__VITEST_SCRIPTS__}
|
|
29
|
-
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-
|
|
29
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-KVYrTcFi.js"></script>
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-BsFW67Gk.js">
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Vitest Browser Tester</title>
|
|
8
|
-
<script type="module" crossorigin src="/__vitest_browser__/tester-
|
|
8
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-BJtsJFpD.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-BsFW67Gk.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { PNG } from 'pngjs';
|
|
|
18
18
|
import { diff } from '@blazediff/core';
|
|
19
19
|
import { WebSocketServer } from 'ws';
|
|
20
20
|
|
|
21
|
-
var version = "4.1.
|
|
21
|
+
var version = "4.1.9";
|
|
22
22
|
|
|
23
23
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
24
24
|
function normalizeWindowsPath(input = "") {
|
|
@@ -1431,6 +1431,19 @@ class BrowserServerCDPHandler {
|
|
|
1431
1431
|
}
|
|
1432
1432
|
}
|
|
1433
1433
|
|
|
1434
|
+
const _startV8Coverage = async (context) => {
|
|
1435
|
+
const session = await context.__ensureCDPHandler();
|
|
1436
|
+
await session.send("Profiler.enable");
|
|
1437
|
+
await session.send("Profiler.startPreciseCoverage", {
|
|
1438
|
+
callCount: true,
|
|
1439
|
+
detailed: true
|
|
1440
|
+
});
|
|
1441
|
+
};
|
|
1442
|
+
const _takeV8Coverage = async (context) => {
|
|
1443
|
+
const session = await context.__ensureCDPHandler();
|
|
1444
|
+
return session.send("Profiler.takePreciseCoverage");
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1434
1447
|
const types = {
|
|
1435
1448
|
'application/andrew-inset': ['ez'],
|
|
1436
1449
|
'application/appinstaller': ['appinstaller'],
|
|
@@ -2495,6 +2508,8 @@ var builtinCommands = {
|
|
|
2495
2508
|
readFile,
|
|
2496
2509
|
removeFile,
|
|
2497
2510
|
writeFile,
|
|
2511
|
+
__vitest_startV8Coverage: _startV8Coverage,
|
|
2512
|
+
__vitest_takeV8Coverage: _takeV8Coverage,
|
|
2498
2513
|
__vitest_markTrace: _markTrace,
|
|
2499
2514
|
__vitest_groupTraceStart: _groupTraceStart,
|
|
2500
2515
|
__vitest_groupTraceEnd: _groupTraceEnd,
|
|
@@ -3009,7 +3024,8 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3009
3024
|
}
|
|
3010
3025
|
if (type === "orchestrator") {
|
|
3011
3026
|
const session = sessions.getSession(sessionId);
|
|
3012
|
-
// it's possible the session was already resolved by the preview provider
|
|
3027
|
+
// it's possible the session was already resolved by the preview provider,
|
|
3028
|
+
// but we still mark the websocket connection when the page reconnects
|
|
3013
3029
|
session?.connected();
|
|
3014
3030
|
}
|
|
3015
3031
|
const project = vitest.getProjectByName(projectName);
|
|
@@ -3018,7 +3034,7 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3018
3034
|
}
|
|
3019
3035
|
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
3020
3036
|
wss.emit("connection", ws, request);
|
|
3021
|
-
const { rpc, offCancel } = setupClient(project, rpcId, ws);
|
|
3037
|
+
const { rpc, offCancel } = setupClient(project, rpcId, ws, { sessionId });
|
|
3022
3038
|
const state = project.browser.state;
|
|
3023
3039
|
const clients = type === "tester" ? state.testers : state.orchestrators;
|
|
3024
3040
|
clients.set(rpcId, rpc);
|
|
@@ -3049,10 +3065,22 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3049
3065
|
function canWrite(project) {
|
|
3050
3066
|
return project.config.browser.api.allowWrite && project.vitest.config.browser.api.allowWrite && project.config.api.allowWrite && project.vitest.config.api.allowWrite;
|
|
3051
3067
|
}
|
|
3052
|
-
function
|
|
3068
|
+
function isCdpAllowed(project) {
|
|
3069
|
+
return project.config.api.allowExec && project.config.browser.api.allowExec && project.vitest.config.api.allowExec && project.vitest.config.browser.api.allowExec && project.config.api.allowWrite && project.config.browser.api.allowWrite && project.vitest.config.api.allowWrite && project.vitest.config.browser.api.allowWrite;
|
|
3070
|
+
}
|
|
3071
|
+
function assertCdpAllowed(project) {
|
|
3072
|
+
if (!isCdpAllowed(project)) {
|
|
3073
|
+
throw new Error(`Cannot use CDP because browser API write or exec operations are disabled. See https://vitest.dev/config/browser/api.`);
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
function setupClient(project, rpcId, ws, options) {
|
|
3053
3077
|
const mockResolver = new ServerMockResolver(globalServer.vite, { moduleDirectories: project.config?.deps?.moduleDirectories });
|
|
3054
3078
|
const mocker = project.browser?.provider.mocker;
|
|
3055
3079
|
const rpc = createBirpc({
|
|
3080
|
+
onOrchestratorReady() {
|
|
3081
|
+
const sessions = vitest._browserSessions;
|
|
3082
|
+
sessions.getSession(options.sessionId)?.ready();
|
|
3083
|
+
},
|
|
3056
3084
|
async onUnhandledError(error, type) {
|
|
3057
3085
|
if (error && typeof error === "object") {
|
|
3058
3086
|
const _error = error;
|
|
@@ -3193,7 +3221,8 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3193
3221
|
sessionId,
|
|
3194
3222
|
triggerCommand: (name, ...args) => {
|
|
3195
3223
|
return project.browser.triggerCommand(name, context, ...args);
|
|
3196
|
-
}
|
|
3224
|
+
},
|
|
3225
|
+
__ensureCDPHandler: () => globalServer.ensureCDPHandler(sessionId, rpcId)
|
|
3197
3226
|
}, provider.getCommandsContext(sessionId));
|
|
3198
3227
|
return await project.browser.triggerCommand(command, context, ...payload);
|
|
3199
3228
|
},
|
|
@@ -3255,10 +3284,12 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3255
3284
|
return mocker.delete(sessionId, id);
|
|
3256
3285
|
},
|
|
3257
3286
|
async sendCdpEvent(sessionId, event, payload) {
|
|
3287
|
+
assertCdpAllowed(project);
|
|
3258
3288
|
const cdp = await globalServer.ensureCDPHandler(sessionId, rpcId);
|
|
3259
3289
|
return cdp.send(event, payload);
|
|
3260
3290
|
},
|
|
3261
3291
|
async trackCdpEvent(sessionId, type, event, listenerId) {
|
|
3292
|
+
assertCdpAllowed(project);
|
|
3262
3293
|
const cdp = await globalServer.ensureCDPHandler(sessionId, rpcId);
|
|
3263
3294
|
cdp[type](event, listenerId);
|
|
3264
3295
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface WebSocketBrowserHandlers {
|
|
|
11
11
|
onTaskArtifactRecord: <Artifact extends TestArtifact>(testId: string, artifact: Artifact) => Promise<Artifact>;
|
|
12
12
|
onTaskUpdate: (method: TestExecutionMethod, packs: TaskResultPack[], events: TaskEventPack[]) => void;
|
|
13
13
|
onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void;
|
|
14
|
+
onOrchestratorReady: () => void;
|
|
14
15
|
cancelCurrentRun: (reason: CancelReason) => void;
|
|
15
16
|
getCountOfFailedTests: () => number;
|
|
16
17
|
readSnapshotFile: (id: string) => Promise<string | null>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest/browser",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.1.
|
|
4
|
+
"version": "4.1.9",
|
|
5
5
|
"description": "Browser running for Vitest",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"providers"
|
|
58
58
|
],
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"vitest": "4.1.
|
|
60
|
+
"vitest": "4.1.9"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@blazediff/core": "1.9.1",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"sirv": "^3.0.2",
|
|
67
67
|
"tinyrainbow": "^3.1.0",
|
|
68
68
|
"ws": "^8.19.0",
|
|
69
|
-
"@vitest/
|
|
70
|
-
"@vitest/
|
|
69
|
+
"@vitest/utils": "4.1.9",
|
|
70
|
+
"@vitest/mocker": "4.1.9"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@opentelemetry/api": "^1.9.0",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"ivya": "^1.8.0",
|
|
80
80
|
"mime": "^4.1.0",
|
|
81
81
|
"pathe": "^2.0.3",
|
|
82
|
-
"
|
|
83
|
-
"vitest": "4.1.
|
|
82
|
+
"vitest": "4.1.9",
|
|
83
|
+
"@vitest/runner": "4.1.9"
|
|
84
84
|
},
|
|
85
85
|
"scripts": {
|
|
86
86
|
"typecheck": "tsc -p ./src/client/tsconfig.json --noEmit",
|