@vitest/browser 5.0.0-beta.4 → 5.0.0-beta.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/client/.vite/manifest.json +6 -6
- package/dist/client/__vitest_browser__/{defineProperty-C3k2g8Sk.js → defineProperty-WHpdAQXR.js} +44 -1
- package/dist/client/__vitest_browser__/{orchestrator-B44yH1M4.js → orchestrator-bDJB3Bid.js} +44 -31
- package/dist/client/__vitest_browser__/tester-C1kIlbPd.js +2099 -0
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/tester.html +2 -2
- package/dist/client/tester/trace.d.ts +1 -1
- package/dist/index.js +22 -22
- package/dist/state.js +1 -0
- package/dist/types.d.ts +2 -2
- package/package.json +6 -6
- package/dist/client/__vitest__/assets/index-B2jbgabi.js +0 -139
- package/dist/client/__vitest__/assets/index-CEyXAB_I.css +0 -1
- package/dist/client/__vitest__/favicon.ico +0 -0
- package/dist/client/__vitest__/favicon.svg +0 -50
- package/dist/client/__vitest__/index.html +0 -32
- package/dist/client/__vitest_browser__/tester-kAU8uxhk.js +0 -5086
|
@@ -0,0 +1,2099 @@
|
|
|
1
|
+
import { a as moduleRunner, d as resolve, i as getWorkerState, l as getTestName, n as getBrowserState, o as now$1, r as getConfig, s as __vitePreload, t as _defineProperty } from "./defineProperty-WHpdAQXR.js";
|
|
2
|
+
import { channel, client, globalChannel, onCancel, registerPageMarkHandler } from "@vitest/browser/client";
|
|
3
|
+
import { Traces } from "vitest/internal/traces";
|
|
4
|
+
import { page, server, userEvent } from "vitest/browser";
|
|
5
|
+
import { DecodedMap, SpyModule, collectTests, format, getOriginalPosition, getSafeTimers, loadDiffConfig, loadSnapshotSerializers, setupCommonEnv, startCoverageInsideWorker, startTests, stopCoverageInsideWorker, takeCoverageInsideWorker } from "vitest/internal/browser";
|
|
6
|
+
import { TestRunner, recordArtifact } from "vitest";
|
|
7
|
+
|
|
8
|
+
//#region \0rolldown/runtime.js
|
|
9
|
+
var __create = Object.create;
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
14
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
19
|
+
key = keys[i];
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
21
|
+
__defProp(to, key, {
|
|
22
|
+
get: ((k) => from[k]).bind(null, key),
|
|
23
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return to;
|
|
29
|
+
};
|
|
30
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
31
|
+
value: mod,
|
|
32
|
+
enumerable: true
|
|
33
|
+
}) : target, mod));
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region ../../node_modules/.pnpm/flatted@3.4.2/node_modules/flatted/esm/index.js
|
|
37
|
+
var { parse: $parse, stringify: $stringify } = JSON;
|
|
38
|
+
var { keys } = Object;
|
|
39
|
+
var Primitive = String;
|
|
40
|
+
var primitive = "string";
|
|
41
|
+
var ignore = {};
|
|
42
|
+
var object = "object";
|
|
43
|
+
var noop = (_, value) => value;
|
|
44
|
+
var primitives = (value) => value instanceof Primitive ? Primitive(value) : value;
|
|
45
|
+
var Primitives = (_, value) => typeof value === primitive ? new Primitive(value) : value;
|
|
46
|
+
var resolver = (input, lazy, parsed, $) => (output) => {
|
|
47
|
+
for (let ke = keys(output), { length } = ke, y = 0; y < length; y++) {
|
|
48
|
+
const k = ke[y];
|
|
49
|
+
const value = output[k];
|
|
50
|
+
if (value instanceof Primitive) {
|
|
51
|
+
const tmp = input[+value];
|
|
52
|
+
if (typeof tmp === object && !parsed.has(tmp)) {
|
|
53
|
+
parsed.add(tmp);
|
|
54
|
+
output[k] = ignore;
|
|
55
|
+
lazy.push({
|
|
56
|
+
o: output,
|
|
57
|
+
k,
|
|
58
|
+
r: tmp
|
|
59
|
+
});
|
|
60
|
+
} else output[k] = $.call(output, k, tmp);
|
|
61
|
+
} else if (output[k] !== ignore) output[k] = $.call(output, k, value);
|
|
62
|
+
}
|
|
63
|
+
return output;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Converts a specialized flatted string into a JS value.
|
|
67
|
+
* @param {string} text
|
|
68
|
+
* @param {(this: any, key: string, value: any) => any} [reviver]
|
|
69
|
+
* @returns {any}
|
|
70
|
+
*/
|
|
71
|
+
var parse = (text, reviver) => {
|
|
72
|
+
const input = $parse(text, Primitives).map(primitives);
|
|
73
|
+
const $ = reviver || noop;
|
|
74
|
+
let value = input[0];
|
|
75
|
+
if (typeof value === object && value) {
|
|
76
|
+
const lazy = [];
|
|
77
|
+
const revive = resolver(input, lazy, /* @__PURE__ */ new Set(), $);
|
|
78
|
+
value = revive(value);
|
|
79
|
+
let i = 0;
|
|
80
|
+
while (i < lazy.length) {
|
|
81
|
+
const { o, k, r } = lazy[i++];
|
|
82
|
+
o[k] = $.call(o, k, revive(r));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return $.call({ "": value }, "", value);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/client/tester/dialog.ts
|
|
90
|
+
function showPopupWarning(name, value, defaultValue) {
|
|
91
|
+
return (...params) => {
|
|
92
|
+
const formattedParams = params.map((p) => JSON.stringify(p)).join(", ");
|
|
93
|
+
console.warn(`Vitest encountered a \`${name}(${formattedParams})\` call that it cannot handle by default, so it returned \`${value}\`. Read more in https://vitest.dev/guide/browser/#thread-blocking-dialogs.
|
|
94
|
+
If needed, mock the \`${name}\` call manually like:
|
|
95
|
+
|
|
96
|
+
\`\`\`
|
|
97
|
+
import { expect, vi } from "vitest"
|
|
98
|
+
|
|
99
|
+
vi.spyOn(window, "${name}")${defaultValue ? `.mockReturnValue(${JSON.stringify(defaultValue)})` : ""}
|
|
100
|
+
${name}(${formattedParams})
|
|
101
|
+
expect(${name}).toHaveBeenCalledWith(${formattedParams})
|
|
102
|
+
\`\`\``);
|
|
103
|
+
return value;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function setupDialogsSpy() {
|
|
107
|
+
globalThis.alert = showPopupWarning("alert", void 0);
|
|
108
|
+
globalThis.confirm = showPopupWarning("confirm", false, true);
|
|
109
|
+
globalThis.prompt = showPopupWarning("prompt", null, "your value");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/client/tester/rpc.ts
|
|
114
|
+
var { get } = Reflect;
|
|
115
|
+
function withSafeTimers(getTimers, fn) {
|
|
116
|
+
const { setTimeout, clearTimeout } = getTimers();
|
|
117
|
+
const currentSetTimeout = globalThis.setTimeout;
|
|
118
|
+
const currentClearTimeout = globalThis.clearTimeout;
|
|
119
|
+
try {
|
|
120
|
+
globalThis.setTimeout = setTimeout;
|
|
121
|
+
globalThis.clearTimeout = clearTimeout;
|
|
122
|
+
return fn();
|
|
123
|
+
} finally {
|
|
124
|
+
globalThis.setTimeout = currentSetTimeout;
|
|
125
|
+
globalThis.clearTimeout = currentClearTimeout;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
var promises = /* @__PURE__ */ new Set();
|
|
129
|
+
function createSafeRpc(client) {
|
|
130
|
+
return new Proxy(client.rpc, { get(target, p, handler) {
|
|
131
|
+
if (p === "then") return;
|
|
132
|
+
const sendCall = get(target, p, handler);
|
|
133
|
+
const safeSendCall = (...args) => withSafeTimers(getSafeTimers, async () => {
|
|
134
|
+
const result = sendCall(...args);
|
|
135
|
+
promises.add(result);
|
|
136
|
+
try {
|
|
137
|
+
return await result;
|
|
138
|
+
} finally {
|
|
139
|
+
promises.delete(result);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
safeSendCall.asEvent = sendCall.asEvent;
|
|
143
|
+
return safeSendCall;
|
|
144
|
+
} });
|
|
145
|
+
}
|
|
146
|
+
function rpc$2() {
|
|
147
|
+
return globalThis.__vitest_worker__.rpc;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
|
|
152
|
+
var comma = ",".charCodeAt(0);
|
|
153
|
+
var semicolon = ";".charCodeAt(0);
|
|
154
|
+
var chars$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
155
|
+
var intToChar$1 = new Uint8Array(64);
|
|
156
|
+
var charToInt$1 = new Uint8Array(128);
|
|
157
|
+
for (let i = 0; i < chars$1.length; i++) {
|
|
158
|
+
const c = chars$1.charCodeAt(i);
|
|
159
|
+
intToChar$1[i] = c;
|
|
160
|
+
charToInt$1[c] = i;
|
|
161
|
+
}
|
|
162
|
+
function decodeInteger(reader, relative) {
|
|
163
|
+
let value = 0;
|
|
164
|
+
let shift = 0;
|
|
165
|
+
let integer = 0;
|
|
166
|
+
do {
|
|
167
|
+
integer = charToInt$1[reader.next()];
|
|
168
|
+
value |= (integer & 31) << shift;
|
|
169
|
+
shift += 5;
|
|
170
|
+
} while (integer & 32);
|
|
171
|
+
const shouldNegate = value & 1;
|
|
172
|
+
value >>>= 1;
|
|
173
|
+
if (shouldNegate) value = -2147483648 | -value;
|
|
174
|
+
return relative + value;
|
|
175
|
+
}
|
|
176
|
+
function hasMoreVlq(reader, max) {
|
|
177
|
+
if (reader.pos >= max) return false;
|
|
178
|
+
return reader.peek() !== comma;
|
|
179
|
+
}
|
|
180
|
+
var StringReader = class {
|
|
181
|
+
constructor(buffer) {
|
|
182
|
+
this.pos = 0;
|
|
183
|
+
this.buffer = buffer;
|
|
184
|
+
}
|
|
185
|
+
next() {
|
|
186
|
+
return this.buffer.charCodeAt(this.pos++);
|
|
187
|
+
}
|
|
188
|
+
peek() {
|
|
189
|
+
return this.buffer.charCodeAt(this.pos);
|
|
190
|
+
}
|
|
191
|
+
indexOf(char) {
|
|
192
|
+
const { buffer, pos } = this;
|
|
193
|
+
const idx = buffer.indexOf(char, pos);
|
|
194
|
+
return idx === -1 ? buffer.length : idx;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
function decode(mappings) {
|
|
198
|
+
const { length } = mappings;
|
|
199
|
+
const reader = new StringReader(mappings);
|
|
200
|
+
const decoded = [];
|
|
201
|
+
let genColumn = 0;
|
|
202
|
+
let sourcesIndex = 0;
|
|
203
|
+
let sourceLine = 0;
|
|
204
|
+
let sourceColumn = 0;
|
|
205
|
+
let namesIndex = 0;
|
|
206
|
+
do {
|
|
207
|
+
const semi = reader.indexOf(";");
|
|
208
|
+
const line = [];
|
|
209
|
+
let sorted = true;
|
|
210
|
+
let lastCol = 0;
|
|
211
|
+
genColumn = 0;
|
|
212
|
+
while (reader.pos < semi) {
|
|
213
|
+
let seg;
|
|
214
|
+
genColumn = decodeInteger(reader, genColumn);
|
|
215
|
+
if (genColumn < lastCol) sorted = false;
|
|
216
|
+
lastCol = genColumn;
|
|
217
|
+
if (hasMoreVlq(reader, semi)) {
|
|
218
|
+
sourcesIndex = decodeInteger(reader, sourcesIndex);
|
|
219
|
+
sourceLine = decodeInteger(reader, sourceLine);
|
|
220
|
+
sourceColumn = decodeInteger(reader, sourceColumn);
|
|
221
|
+
if (hasMoreVlq(reader, semi)) {
|
|
222
|
+
namesIndex = decodeInteger(reader, namesIndex);
|
|
223
|
+
seg = [
|
|
224
|
+
genColumn,
|
|
225
|
+
sourcesIndex,
|
|
226
|
+
sourceLine,
|
|
227
|
+
sourceColumn,
|
|
228
|
+
namesIndex
|
|
229
|
+
];
|
|
230
|
+
} else seg = [
|
|
231
|
+
genColumn,
|
|
232
|
+
sourcesIndex,
|
|
233
|
+
sourceLine,
|
|
234
|
+
sourceColumn
|
|
235
|
+
];
|
|
236
|
+
} else seg = [genColumn];
|
|
237
|
+
line.push(seg);
|
|
238
|
+
reader.pos++;
|
|
239
|
+
}
|
|
240
|
+
if (!sorted) sort(line);
|
|
241
|
+
decoded.push(line);
|
|
242
|
+
reader.pos = semi + 1;
|
|
243
|
+
} while (reader.pos <= length);
|
|
244
|
+
return decoded;
|
|
245
|
+
}
|
|
246
|
+
function sort(line) {
|
|
247
|
+
line.sort(sortComparator);
|
|
248
|
+
}
|
|
249
|
+
function sortComparator(a, b) {
|
|
250
|
+
return a[0] - b[0];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region ../../node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js
|
|
255
|
+
var require_resolve_uri_umd = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
256
|
+
(function(global, factory) {
|
|
257
|
+
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.resolveURI = factory());
|
|
258
|
+
})(exports, (function() {
|
|
259
|
+
"use strict";
|
|
260
|
+
const schemeRegex = /^[\w+.-]+:\/\//;
|
|
261
|
+
/**
|
|
262
|
+
* Matches the parts of a URL:
|
|
263
|
+
* 1. Scheme, including ":", guaranteed.
|
|
264
|
+
* 2. User/password, including "@", optional.
|
|
265
|
+
* 3. Host, guaranteed.
|
|
266
|
+
* 4. Port, including ":", optional.
|
|
267
|
+
* 5. Path, including "/", optional.
|
|
268
|
+
* 6. Query, including "?", optional.
|
|
269
|
+
* 7. Hash, including "#", optional.
|
|
270
|
+
*/
|
|
271
|
+
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
|
|
272
|
+
/**
|
|
273
|
+
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
|
|
274
|
+
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
|
|
275
|
+
*
|
|
276
|
+
* 1. Host, optional.
|
|
277
|
+
* 2. Path, which may include "/", guaranteed.
|
|
278
|
+
* 3. Query, including "?", optional.
|
|
279
|
+
* 4. Hash, including "#", optional.
|
|
280
|
+
*/
|
|
281
|
+
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
|
|
282
|
+
function isAbsoluteUrl(input) {
|
|
283
|
+
return schemeRegex.test(input);
|
|
284
|
+
}
|
|
285
|
+
function isSchemeRelativeUrl(input) {
|
|
286
|
+
return input.startsWith("//");
|
|
287
|
+
}
|
|
288
|
+
function isAbsolutePath(input) {
|
|
289
|
+
return input.startsWith("/");
|
|
290
|
+
}
|
|
291
|
+
function isFileUrl(input) {
|
|
292
|
+
return input.startsWith("file:");
|
|
293
|
+
}
|
|
294
|
+
function isRelative(input) {
|
|
295
|
+
return /^[.?#]/.test(input);
|
|
296
|
+
}
|
|
297
|
+
function parseAbsoluteUrl(input) {
|
|
298
|
+
const match = urlRegex.exec(input);
|
|
299
|
+
return makeUrl(match[1], match[2] || "", match[3], match[4] || "", match[5] || "/", match[6] || "", match[7] || "");
|
|
300
|
+
}
|
|
301
|
+
function parseFileUrl(input) {
|
|
302
|
+
const match = fileRegex.exec(input);
|
|
303
|
+
const path = match[2];
|
|
304
|
+
return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path) ? path : "/" + path, match[3] || "", match[4] || "");
|
|
305
|
+
}
|
|
306
|
+
function makeUrl(scheme, user, host, port, path, query, hash) {
|
|
307
|
+
return {
|
|
308
|
+
scheme,
|
|
309
|
+
user,
|
|
310
|
+
host,
|
|
311
|
+
port,
|
|
312
|
+
path,
|
|
313
|
+
query,
|
|
314
|
+
hash,
|
|
315
|
+
type: 7
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function parseUrl(input) {
|
|
319
|
+
if (isSchemeRelativeUrl(input)) {
|
|
320
|
+
const url = parseAbsoluteUrl("http:" + input);
|
|
321
|
+
url.scheme = "";
|
|
322
|
+
url.type = 6;
|
|
323
|
+
return url;
|
|
324
|
+
}
|
|
325
|
+
if (isAbsolutePath(input)) {
|
|
326
|
+
const url = parseAbsoluteUrl("http://foo.com" + input);
|
|
327
|
+
url.scheme = "";
|
|
328
|
+
url.host = "";
|
|
329
|
+
url.type = 5;
|
|
330
|
+
return url;
|
|
331
|
+
}
|
|
332
|
+
if (isFileUrl(input)) return parseFileUrl(input);
|
|
333
|
+
if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);
|
|
334
|
+
const url = parseAbsoluteUrl("http://foo.com/" + input);
|
|
335
|
+
url.scheme = "";
|
|
336
|
+
url.host = "";
|
|
337
|
+
url.type = input ? input.startsWith("?") ? 3 : input.startsWith("#") ? 2 : 4 : 1;
|
|
338
|
+
return url;
|
|
339
|
+
}
|
|
340
|
+
function stripPathFilename(path) {
|
|
341
|
+
if (path.endsWith("/..")) return path;
|
|
342
|
+
const index = path.lastIndexOf("/");
|
|
343
|
+
return path.slice(0, index + 1);
|
|
344
|
+
}
|
|
345
|
+
function mergePaths(url, base) {
|
|
346
|
+
normalizePath(base, base.type);
|
|
347
|
+
if (url.path === "/") url.path = base.path;
|
|
348
|
+
else url.path = stripPathFilename(base.path) + url.path;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
|
|
352
|
+
* "foo/.". We need to normalize to a standard representation.
|
|
353
|
+
*/
|
|
354
|
+
function normalizePath(url, type) {
|
|
355
|
+
const rel = type <= 4;
|
|
356
|
+
const pieces = url.path.split("/");
|
|
357
|
+
let pointer = 1;
|
|
358
|
+
let positive = 0;
|
|
359
|
+
let addTrailingSlash = false;
|
|
360
|
+
for (let i = 1; i < pieces.length; i++) {
|
|
361
|
+
const piece = pieces[i];
|
|
362
|
+
if (!piece) {
|
|
363
|
+
addTrailingSlash = true;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
addTrailingSlash = false;
|
|
367
|
+
if (piece === ".") continue;
|
|
368
|
+
if (piece === "..") {
|
|
369
|
+
if (positive) {
|
|
370
|
+
addTrailingSlash = true;
|
|
371
|
+
positive--;
|
|
372
|
+
pointer--;
|
|
373
|
+
} else if (rel) pieces[pointer++] = piece;
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
pieces[pointer++] = piece;
|
|
377
|
+
positive++;
|
|
378
|
+
}
|
|
379
|
+
let path = "";
|
|
380
|
+
for (let i = 1; i < pointer; i++) path += "/" + pieces[i];
|
|
381
|
+
if (!path || addTrailingSlash && !path.endsWith("/..")) path += "/";
|
|
382
|
+
url.path = path;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Attempts to resolve `input` URL/path relative to `base`.
|
|
386
|
+
*/
|
|
387
|
+
function resolve(input, base) {
|
|
388
|
+
if (!input && !base) return "";
|
|
389
|
+
const url = parseUrl(input);
|
|
390
|
+
let inputType = url.type;
|
|
391
|
+
if (base && inputType !== 7) {
|
|
392
|
+
const baseUrl = parseUrl(base);
|
|
393
|
+
const baseType = baseUrl.type;
|
|
394
|
+
switch (inputType) {
|
|
395
|
+
case 1: url.hash = baseUrl.hash;
|
|
396
|
+
case 2: url.query = baseUrl.query;
|
|
397
|
+
case 3:
|
|
398
|
+
case 4: mergePaths(url, baseUrl);
|
|
399
|
+
case 5:
|
|
400
|
+
url.user = baseUrl.user;
|
|
401
|
+
url.host = baseUrl.host;
|
|
402
|
+
url.port = baseUrl.port;
|
|
403
|
+
case 6: url.scheme = baseUrl.scheme;
|
|
404
|
+
}
|
|
405
|
+
if (baseType > inputType) inputType = baseType;
|
|
406
|
+
}
|
|
407
|
+
normalizePath(url, inputType);
|
|
408
|
+
const queryHash = url.query + url.hash;
|
|
409
|
+
switch (inputType) {
|
|
410
|
+
case 2:
|
|
411
|
+
case 3: return queryHash;
|
|
412
|
+
case 4: {
|
|
413
|
+
const path = url.path.slice(1);
|
|
414
|
+
if (!path) return queryHash || ".";
|
|
415
|
+
if (isRelative(base || input) && !isRelative(path)) return "./" + path + queryHash;
|
|
416
|
+
return path + queryHash;
|
|
417
|
+
}
|
|
418
|
+
case 5: return url.path + queryHash;
|
|
419
|
+
default: return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return resolve;
|
|
423
|
+
}));
|
|
424
|
+
}));
|
|
425
|
+
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
|
|
428
|
+
var import_resolve_uri_umd = /* @__PURE__ */ __toESM(require_resolve_uri_umd(), 1);
|
|
429
|
+
var COLUMN = 0;
|
|
430
|
+
var SOURCES_INDEX = 1;
|
|
431
|
+
var SOURCE_LINE = 2;
|
|
432
|
+
var SOURCE_COLUMN = 3;
|
|
433
|
+
var NAMES_INDEX = 4;
|
|
434
|
+
var found = false;
|
|
435
|
+
function binarySearch(haystack, needle, low, high) {
|
|
436
|
+
while (low <= high) {
|
|
437
|
+
const mid = low + (high - low >> 1);
|
|
438
|
+
const cmp = haystack[mid][COLUMN] - needle;
|
|
439
|
+
if (cmp === 0) {
|
|
440
|
+
found = true;
|
|
441
|
+
return mid;
|
|
442
|
+
}
|
|
443
|
+
if (cmp < 0) low = mid + 1;
|
|
444
|
+
else high = mid - 1;
|
|
445
|
+
}
|
|
446
|
+
found = false;
|
|
447
|
+
return low - 1;
|
|
448
|
+
}
|
|
449
|
+
function upperBound(haystack, needle, index) {
|
|
450
|
+
for (let i = index + 1; i < haystack.length; index = i++) if (haystack[i][COLUMN] !== needle) break;
|
|
451
|
+
return index;
|
|
452
|
+
}
|
|
453
|
+
function lowerBound(haystack, needle, index) {
|
|
454
|
+
for (let i = index - 1; i >= 0; index = i--) if (haystack[i][COLUMN] !== needle) break;
|
|
455
|
+
return index;
|
|
456
|
+
}
|
|
457
|
+
function memoizedBinarySearch(haystack, needle, state, key) {
|
|
458
|
+
const { lastKey, lastNeedle, lastIndex } = state;
|
|
459
|
+
let low = 0;
|
|
460
|
+
let high = haystack.length - 1;
|
|
461
|
+
if (key === lastKey) {
|
|
462
|
+
if (needle === lastNeedle) {
|
|
463
|
+
found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
|
|
464
|
+
return lastIndex;
|
|
465
|
+
}
|
|
466
|
+
if (needle >= lastNeedle) low = lastIndex === -1 ? 0 : lastIndex;
|
|
467
|
+
else high = lastIndex;
|
|
468
|
+
}
|
|
469
|
+
state.lastKey = key;
|
|
470
|
+
state.lastNeedle = needle;
|
|
471
|
+
return state.lastIndex = binarySearch(haystack, needle, low, high);
|
|
472
|
+
}
|
|
473
|
+
var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)";
|
|
474
|
+
var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)";
|
|
475
|
+
var LEAST_UPPER_BOUND = -1;
|
|
476
|
+
var GREATEST_LOWER_BOUND = 1;
|
|
477
|
+
function cast(map) {
|
|
478
|
+
return map;
|
|
479
|
+
}
|
|
480
|
+
function decodedMappings(map) {
|
|
481
|
+
var _a;
|
|
482
|
+
return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded));
|
|
483
|
+
}
|
|
484
|
+
function originalPositionFor(map, needle) {
|
|
485
|
+
let { line, column, bias } = needle;
|
|
486
|
+
line--;
|
|
487
|
+
if (line < 0) throw new Error(LINE_GTR_ZERO);
|
|
488
|
+
if (column < 0) throw new Error(COL_GTR_EQ_ZERO);
|
|
489
|
+
const decoded = decodedMappings(map);
|
|
490
|
+
if (line >= decoded.length) return OMapping(null, null, null, null);
|
|
491
|
+
const segments = decoded[line];
|
|
492
|
+
const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || 1);
|
|
493
|
+
if (index === -1) return OMapping(null, null, null, null);
|
|
494
|
+
const segment = segments[index];
|
|
495
|
+
if (segment.length === 1) return OMapping(null, null, null, null);
|
|
496
|
+
const { names, resolvedSources } = map;
|
|
497
|
+
return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
|
|
498
|
+
}
|
|
499
|
+
function OMapping(source, line, column, name) {
|
|
500
|
+
return {
|
|
501
|
+
source,
|
|
502
|
+
line,
|
|
503
|
+
column,
|
|
504
|
+
name
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
function traceSegmentInternal(segments, memo, line, column, bias) {
|
|
508
|
+
let index = memoizedBinarySearch(segments, column, memo, line);
|
|
509
|
+
if (found) index = (bias === -1 ? upperBound : lowerBound)(segments, column, index);
|
|
510
|
+
else if (bias === -1) index++;
|
|
511
|
+
if (index === -1 || index === segments.length) return -1;
|
|
512
|
+
return index;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region ../utils/src/helpers.ts
|
|
517
|
+
function notNullish(v) {
|
|
518
|
+
return v != null;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
//#endregion
|
|
522
|
+
//#region ../utils/src/source-map.ts
|
|
523
|
+
var CHROME_IE_STACK_REGEXP = /^\s*at .*(?:\S:\d+|\(native\))/m;
|
|
524
|
+
var SAFARI_NATIVE_CODE_REGEXP = /^(?:eval@)?(?:\[native code\])?$/;
|
|
525
|
+
var stackIgnorePatterns = [
|
|
526
|
+
"node:internal",
|
|
527
|
+
/\/packages\/\w+\/dist\//,
|
|
528
|
+
/\/@vitest\/\w+\/dist\//,
|
|
529
|
+
"/vitest/dist/",
|
|
530
|
+
"/vitest/src/",
|
|
531
|
+
"/packages/expect/src/",
|
|
532
|
+
"/packages/snapshot/src/",
|
|
533
|
+
"/node_modules/chai/",
|
|
534
|
+
"/node_modules/tinyspy/",
|
|
535
|
+
"/vite/dist/node/module-runner",
|
|
536
|
+
"/rolldown-vite/dist/node/module-runner",
|
|
537
|
+
"/deps/chunk-",
|
|
538
|
+
"/deps/@vitest",
|
|
539
|
+
"/deps/loupe",
|
|
540
|
+
"/deps/chai",
|
|
541
|
+
"/browser-playwright/dist/locators.js",
|
|
542
|
+
"/browser-webdriverio/dist/locators.js",
|
|
543
|
+
"/browser-preview/dist/locators.js",
|
|
544
|
+
/node:\w+/,
|
|
545
|
+
/__vitest_test__/,
|
|
546
|
+
/__vitest_browser__/,
|
|
547
|
+
"/@id/__x00__vitest/browser",
|
|
548
|
+
/\/deps\/vitest_/
|
|
549
|
+
];
|
|
550
|
+
var NOW_LENGTH$1 = Date.now().toString().length;
|
|
551
|
+
var REGEXP_VITEST$1 = new RegExp(`vitest=\\d{${NOW_LENGTH$1}}`);
|
|
552
|
+
function extractLocation(urlLike) {
|
|
553
|
+
if (!urlLike.includes(":")) return [urlLike];
|
|
554
|
+
const parts = /(.+?)(?::(\d+))?(?::(\d+))?$/.exec(urlLike.replace(/^\(|\)$/g, ""));
|
|
555
|
+
if (!parts) return [urlLike];
|
|
556
|
+
let url = parts[1];
|
|
557
|
+
if (url.startsWith("async ")) url = url.slice(6);
|
|
558
|
+
if (url.startsWith("http:") || url.startsWith("https:")) {
|
|
559
|
+
const urlObj = new URL(url);
|
|
560
|
+
urlObj.searchParams.delete("import");
|
|
561
|
+
urlObj.searchParams.delete("browserv");
|
|
562
|
+
url = urlObj.pathname + urlObj.hash + urlObj.search;
|
|
563
|
+
}
|
|
564
|
+
if (url.startsWith("/@fs/")) {
|
|
565
|
+
const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url);
|
|
566
|
+
url = url.slice(isWindows ? 5 : 4);
|
|
567
|
+
}
|
|
568
|
+
if (url.includes("vitest=")) url = url.replace(REGEXP_VITEST$1, "").replace(/[?&]$/, "");
|
|
569
|
+
return [
|
|
570
|
+
url,
|
|
571
|
+
parts[2] || void 0,
|
|
572
|
+
parts[3] || void 0
|
|
573
|
+
];
|
|
574
|
+
}
|
|
575
|
+
function parseSingleFFOrSafariStack(raw) {
|
|
576
|
+
let line = raw.trim();
|
|
577
|
+
if (SAFARI_NATIVE_CODE_REGEXP.test(line)) return null;
|
|
578
|
+
if (line.includes(" > eval")) line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1");
|
|
579
|
+
if (!line.includes("@")) return null;
|
|
580
|
+
let atIndex = -1;
|
|
581
|
+
let locationPart = "";
|
|
582
|
+
let functionName;
|
|
583
|
+
for (let i = 0; i < line.length; i++) if (line[i] === "@") {
|
|
584
|
+
const candidateLocation = line.slice(i + 1);
|
|
585
|
+
if (candidateLocation.includes(":") && candidateLocation.length >= 3) {
|
|
586
|
+
atIndex = i;
|
|
587
|
+
locationPart = candidateLocation;
|
|
588
|
+
functionName = i > 0 ? line.slice(0, i) : void 0;
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
if (atIndex === -1 || !locationPart.includes(":") || locationPart.length < 3) return null;
|
|
593
|
+
const [url, lineNumber, columnNumber] = extractLocation(locationPart);
|
|
594
|
+
if (!url || !lineNumber || !columnNumber) return null;
|
|
595
|
+
return {
|
|
596
|
+
file: url,
|
|
597
|
+
method: functionName || "",
|
|
598
|
+
line: Number.parseInt(lineNumber),
|
|
599
|
+
column: Number.parseInt(columnNumber)
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
function parseSingleV8Stack(raw) {
|
|
603
|
+
let line = raw.trim();
|
|
604
|
+
if (!CHROME_IE_STACK_REGEXP.test(line)) return null;
|
|
605
|
+
if (line.includes("(eval ")) line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(,.*$)/g, "");
|
|
606
|
+
let sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(").replace(/^.*?\s+/, "");
|
|
607
|
+
const location = sanitizedLine.match(/ (\(.+\)$)/);
|
|
608
|
+
sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine;
|
|
609
|
+
const [url, lineNumber, columnNumber] = extractLocation(location ? location[1] : sanitizedLine);
|
|
610
|
+
let method = location && sanitizedLine || "";
|
|
611
|
+
let file = url && ["eval", "<anonymous>"].includes(url) ? void 0 : url;
|
|
612
|
+
if (!file || !lineNumber || !columnNumber) return null;
|
|
613
|
+
if (method.startsWith("async ")) method = method.slice(6);
|
|
614
|
+
if (file.startsWith("file://")) file = file.slice(7);
|
|
615
|
+
file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve(file);
|
|
616
|
+
if (method) method = method.replace(/\(0\s?,\s?__vite_ssr_import_\d+__.(\w+)\)/g, "$1").replace(/__(vite_ssr_import|vi_import)_\d+__\./g, "").replace(/(Object\.)?__vite_ssr_export_default__\s?/g, "");
|
|
617
|
+
return {
|
|
618
|
+
method,
|
|
619
|
+
file,
|
|
620
|
+
line: Number.parseInt(lineNumber),
|
|
621
|
+
column: Number.parseInt(columnNumber)
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
function createStackString(stacks) {
|
|
625
|
+
return stacks.map((stack) => {
|
|
626
|
+
const line = `${stack.file}:${stack.line}:${stack.column}`;
|
|
627
|
+
if (stack.method) return ` at ${stack.method}(${line})`;
|
|
628
|
+
return ` at ${line}`;
|
|
629
|
+
}).join("\n");
|
|
630
|
+
}
|
|
631
|
+
function parseStacktrace(stack, options = {}) {
|
|
632
|
+
const { ignoreStackEntries = stackIgnorePatterns } = options;
|
|
633
|
+
let stacks = !CHROME_IE_STACK_REGEXP.test(stack) ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack);
|
|
634
|
+
const helperIndex = stacks.findLastIndex((s) => s.method.includes("__VITEST_HELPER__"));
|
|
635
|
+
if (helperIndex >= 0) stacks = stacks.slice(helperIndex + 1);
|
|
636
|
+
return stacks.map((stack) => {
|
|
637
|
+
var _options$getSourceMap;
|
|
638
|
+
if (options.getUrlId) stack.file = options.getUrlId(stack.file);
|
|
639
|
+
const map = (_options$getSourceMap = options.getSourceMap) === null || _options$getSourceMap === void 0 ? void 0 : _options$getSourceMap.call(options, stack.file);
|
|
640
|
+
if (!map || typeof map !== "object" || !map.version) return shouldFilter(ignoreStackEntries, stack.file) ? null : stack;
|
|
641
|
+
const position = getOriginalPosition$1(new DecodedMap$1(map, stack.file), stack);
|
|
642
|
+
if (!position) return stack;
|
|
643
|
+
const { line, column, source, name } = position;
|
|
644
|
+
let file = source || stack.file;
|
|
645
|
+
if (file.match(/\/\w:\//)) file = file.slice(1);
|
|
646
|
+
if (shouldFilter(ignoreStackEntries, file)) return null;
|
|
647
|
+
if (line != null && column != null) return {
|
|
648
|
+
line,
|
|
649
|
+
column,
|
|
650
|
+
file,
|
|
651
|
+
method: name || stack.method
|
|
652
|
+
};
|
|
653
|
+
return stack;
|
|
654
|
+
}).filter((s) => s != null);
|
|
655
|
+
}
|
|
656
|
+
function shouldFilter(ignoreStackEntries, file) {
|
|
657
|
+
return ignoreStackEntries.some((p) => file.match(p));
|
|
658
|
+
}
|
|
659
|
+
function parseFFOrSafariStackTrace(stack) {
|
|
660
|
+
return stack.split("\n").map((line) => parseSingleFFOrSafariStack(line)).filter(notNullish);
|
|
661
|
+
}
|
|
662
|
+
function parseV8Stacktrace(stack) {
|
|
663
|
+
return stack.split("\n").map((line) => parseSingleV8Stack(line)).filter(notNullish);
|
|
664
|
+
}
|
|
665
|
+
var DecodedMap$1 = class {
|
|
666
|
+
constructor(map, from) {
|
|
667
|
+
_defineProperty(this, "_encoded", void 0);
|
|
668
|
+
_defineProperty(this, "_decoded", void 0);
|
|
669
|
+
_defineProperty(this, "_decodedMemo", void 0);
|
|
670
|
+
_defineProperty(this, "url", void 0);
|
|
671
|
+
_defineProperty(this, "version", void 0);
|
|
672
|
+
_defineProperty(this, "names", []);
|
|
673
|
+
_defineProperty(this, "resolvedSources", void 0);
|
|
674
|
+
this.map = map;
|
|
675
|
+
const { mappings, names, sources } = map;
|
|
676
|
+
this.version = map.version;
|
|
677
|
+
this.names = names || [];
|
|
678
|
+
this._encoded = mappings || "";
|
|
679
|
+
this._decodedMemo = memoizedState();
|
|
680
|
+
this.url = from;
|
|
681
|
+
this.resolvedSources = (sources || []).map((s) => resolve(from, "..", s || ""));
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
function memoizedState() {
|
|
685
|
+
return {
|
|
686
|
+
lastKey: -1,
|
|
687
|
+
lastNeedle: -1,
|
|
688
|
+
lastIndex: -1
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
function getOriginalPosition$1(map, needle) {
|
|
692
|
+
const result = originalPositionFor(map, needle);
|
|
693
|
+
if (result.column == null) return null;
|
|
694
|
+
return result;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
//#endregion
|
|
698
|
+
//#region src/client/tester/snapshot.ts
|
|
699
|
+
var VitestBrowserSnapshotEnvironment = class {
|
|
700
|
+
constructor() {
|
|
701
|
+
_defineProperty(this, "sourceMaps", /* @__PURE__ */ new Map());
|
|
702
|
+
_defineProperty(this, "traceMaps", /* @__PURE__ */ new Map());
|
|
703
|
+
}
|
|
704
|
+
addSourceMap(filepath, map) {
|
|
705
|
+
this.sourceMaps.set(filepath, map);
|
|
706
|
+
}
|
|
707
|
+
getVersion() {
|
|
708
|
+
return "1";
|
|
709
|
+
}
|
|
710
|
+
getHeader() {
|
|
711
|
+
return `// Vitest Snapshot v${this.getVersion()}, https://vitest.dev/guide/snapshot.html`;
|
|
712
|
+
}
|
|
713
|
+
readSnapshotFile(filepath) {
|
|
714
|
+
return rpc$1().readSnapshotFile(filepath);
|
|
715
|
+
}
|
|
716
|
+
saveSnapshotFile(filepath, snapshot) {
|
|
717
|
+
return rpc$1().saveSnapshotFile(filepath, snapshot);
|
|
718
|
+
}
|
|
719
|
+
resolvePath(filepath) {
|
|
720
|
+
return rpc$1().resolveSnapshotPath(filepath);
|
|
721
|
+
}
|
|
722
|
+
resolveRawPath(testPath, rawPath) {
|
|
723
|
+
return rpc$1().resolveSnapshotRawPath(testPath, rawPath);
|
|
724
|
+
}
|
|
725
|
+
removeSnapshotFile(filepath) {
|
|
726
|
+
return rpc$1().removeSnapshotFile(filepath);
|
|
727
|
+
}
|
|
728
|
+
processStackTrace(stack) {
|
|
729
|
+
const map = this.sourceMaps.get(stack.file);
|
|
730
|
+
if (!map) return stack;
|
|
731
|
+
let traceMap = this.traceMaps.get(stack.file);
|
|
732
|
+
if (!traceMap) {
|
|
733
|
+
traceMap = new DecodedMap(map, stack.file);
|
|
734
|
+
this.traceMaps.set(stack.file, traceMap);
|
|
735
|
+
}
|
|
736
|
+
const position = getOriginalPosition(traceMap, stack);
|
|
737
|
+
if (position) return {
|
|
738
|
+
...stack,
|
|
739
|
+
line: position.line,
|
|
740
|
+
column: position.column
|
|
741
|
+
};
|
|
742
|
+
return stack;
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
function rpc$1() {
|
|
746
|
+
return globalThis.__vitest_worker__.rpc;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
//#endregion
|
|
750
|
+
//#region src/client/tester/trace.ts
|
|
751
|
+
var PSEUDO_CLASS_NAMES = [
|
|
752
|
+
":hover",
|
|
753
|
+
":active",
|
|
754
|
+
":focus",
|
|
755
|
+
":focus-visible",
|
|
756
|
+
":focus-within"
|
|
757
|
+
];
|
|
758
|
+
function createBrowserTraceRangeId() {
|
|
759
|
+
return Math.random().toString(36).slice(2);
|
|
760
|
+
}
|
|
761
|
+
async function recordBrowserTraceEntry(task, options) {
|
|
762
|
+
const attemptInfo = (/* @__PURE__ */ getBrowserState()).browserTraceAttempts.get(task.id);
|
|
763
|
+
const relativeStartTime = now$1() - attemptInfo.startTime;
|
|
764
|
+
const snapshot = takeSnapshot(options.element);
|
|
765
|
+
const entry = {
|
|
766
|
+
...options,
|
|
767
|
+
startTime: relativeStartTime,
|
|
768
|
+
snapshot
|
|
769
|
+
};
|
|
770
|
+
const { retry, repeats } = attemptInfo;
|
|
771
|
+
const { recordCanvas } = (/* @__PURE__ */ getBrowserState()).config.browser.traceView;
|
|
772
|
+
const data = {
|
|
773
|
+
retry,
|
|
774
|
+
repeats,
|
|
775
|
+
recordCanvas,
|
|
776
|
+
entries: [entry]
|
|
777
|
+
};
|
|
778
|
+
await (/* @__PURE__ */ getWorkerState()).rpc.triggerCommand((/* @__PURE__ */ getBrowserState()).sessionId, "__vitest_recordBrowserTrace", void 0, [{
|
|
779
|
+
testId: task.id,
|
|
780
|
+
data
|
|
781
|
+
}]);
|
|
782
|
+
}
|
|
783
|
+
function takeSnapshot(serializedLocator) {
|
|
784
|
+
const { snapshot, createMirror } = (/* @__PURE__ */ getBrowserState()).browserTraceDomSnapshot;
|
|
785
|
+
const traceView = (/* @__PURE__ */ getBrowserState()).config.browser.traceView;
|
|
786
|
+
const engine = (/* @__PURE__ */ getBrowserState()).selectorEngine;
|
|
787
|
+
const mirror = createMirror();
|
|
788
|
+
const result = {
|
|
789
|
+
serialized: snapshot(document, {
|
|
790
|
+
mirror,
|
|
791
|
+
inlineImages: traceView.inlineImages,
|
|
792
|
+
recordCanvas: traceView.recordCanvas
|
|
793
|
+
}),
|
|
794
|
+
viewport: {
|
|
795
|
+
width: window.innerWidth,
|
|
796
|
+
height: window.innerHeight
|
|
797
|
+
},
|
|
798
|
+
scroll: {
|
|
799
|
+
x: window.scrollX,
|
|
800
|
+
y: window.scrollY
|
|
801
|
+
},
|
|
802
|
+
pseudoClassIds: {}
|
|
803
|
+
};
|
|
804
|
+
for (const className of PSEUDO_CLASS_NAMES) {
|
|
805
|
+
const elements = document.querySelectorAll(className);
|
|
806
|
+
const ids = Array.from(elements, (el) => mirror.getId(el)).filter((id) => id !== -1);
|
|
807
|
+
result.pseudoClassIds[className] = ids;
|
|
808
|
+
}
|
|
809
|
+
if (serializedLocator) try {
|
|
810
|
+
const el = engine.querySelector(engine.parseSelector(serializedLocator._pwSelector ?? serializedLocator.selector), document.documentElement, false);
|
|
811
|
+
if (!el) result.selectorResolution = "missing";
|
|
812
|
+
else {
|
|
813
|
+
const id = mirror.getId(el);
|
|
814
|
+
if (id !== -1) {
|
|
815
|
+
result.selectorId = id;
|
|
816
|
+
result.selectorResolution = "matched";
|
|
817
|
+
} else result.selectorResolution = "missing";
|
|
818
|
+
}
|
|
819
|
+
} catch (error) {
|
|
820
|
+
result.selectorResolution = "error";
|
|
821
|
+
result.selectorError = error instanceof Error ? error.message : String(error);
|
|
822
|
+
}
|
|
823
|
+
return result;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
//#endregion
|
|
827
|
+
//#region src/client/tester/runner.ts
|
|
828
|
+
var browserHashMap = /* @__PURE__ */ new Map();
|
|
829
|
+
function createBrowserRunner(mocker, state, coverageModule) {
|
|
830
|
+
return class BrowserTestRunner extends TestRunner {
|
|
831
|
+
constructor(options) {
|
|
832
|
+
super(options.config);
|
|
833
|
+
_defineProperty(this, "config", void 0);
|
|
834
|
+
_defineProperty(this, "hashMap", browserHashMap);
|
|
835
|
+
_defineProperty(this, "sourceMapCache", /* @__PURE__ */ new Map());
|
|
836
|
+
_defineProperty(this, "method", "run");
|
|
837
|
+
_defineProperty(this, "commands", void 0);
|
|
838
|
+
_defineProperty(this, "traces", /* @__PURE__ */ new Map());
|
|
839
|
+
_defineProperty(this, "onAfterRetryTask", async (test, { retry, repeats }) => {
|
|
840
|
+
var _test$result3, _test$result4;
|
|
841
|
+
if ((/* @__PURE__ */ getBrowserState()).browserTraceAttempts.has(test.id)) {
|
|
842
|
+
var _test$result, _test$result2;
|
|
843
|
+
const status = (_test$result = test.result) === null || _test$result === void 0 ? void 0 : _test$result.state;
|
|
844
|
+
const stack = status === "fail" ? (_test$result2 = test.result) === null || _test$result2 === void 0 || (_test$result2 = _test$result2.errors) === null || _test$result2 === void 0 ? void 0 : _test$result2[0].stack : void 0;
|
|
845
|
+
const location = test.location ? {
|
|
846
|
+
...test.location,
|
|
847
|
+
file: test.file.filepath
|
|
848
|
+
} : void 0;
|
|
849
|
+
await recordBrowserTraceEntry(test, {
|
|
850
|
+
name: `vitest:onAfterRetryTask`,
|
|
851
|
+
kind: "lifecycle",
|
|
852
|
+
...status === "pass" || status === "fail" ? { status } : {},
|
|
853
|
+
...stack ? { stack } : location ? { location } : {}
|
|
854
|
+
});
|
|
855
|
+
(/* @__PURE__ */ getBrowserState()).browserTraceAttempts.delete(test.id);
|
|
856
|
+
}
|
|
857
|
+
if (!(/* @__PURE__ */ getBrowserState()).activeTraceTaskIds.has(test.id)) return;
|
|
858
|
+
await this.commands.triggerCommand("__vitest_markTrace", [{
|
|
859
|
+
name: `onAfterRetryTask [${(_test$result3 = test.result) === null || _test$result3 === void 0 ? void 0 : _test$result3.state}]`,
|
|
860
|
+
stack: (_test$result4 = test.result) === null || _test$result4 === void 0 || (_test$result4 = _test$result4.errors) === null || _test$result4 === void 0 ? void 0 : _test$result4[0].stack
|
|
861
|
+
}]);
|
|
862
|
+
const name = getTraceName(test, retry, repeats);
|
|
863
|
+
if (!this.traces.has(test.id)) this.traces.set(test.id, []);
|
|
864
|
+
const traces = this.traces.get(test.id);
|
|
865
|
+
const { tracePath } = await this.commands.triggerCommand("__vitest_stopChunkTrace", [{ name }]);
|
|
866
|
+
traces.push(tracePath);
|
|
867
|
+
});
|
|
868
|
+
_defineProperty(this, "onAfterRunTask", async (task) => {
|
|
869
|
+
var _super$onAfterRunTask, _task$result2;
|
|
870
|
+
(_super$onAfterRunTask = super.onAfterRunTask) === null || _super$onAfterRunTask === void 0 || _super$onAfterRunTask.call(this, task);
|
|
871
|
+
const trace = this.config.browser.trace;
|
|
872
|
+
const traces = this.traces.get(task.id) || [];
|
|
873
|
+
if (traces.length) {
|
|
874
|
+
var _task$result;
|
|
875
|
+
if (trace === "retain-on-failure" && ((_task$result = task.result) === null || _task$result === void 0 ? void 0 : _task$result.state) === "pass") await this.commands.triggerCommand("__vitest_deleteTracing", [{ traces }]);
|
|
876
|
+
else await this.commands.triggerCommand("__vitest_annotateTraces", [{
|
|
877
|
+
testId: task.id,
|
|
878
|
+
traces
|
|
879
|
+
}]);
|
|
880
|
+
}
|
|
881
|
+
if (this.config.bail && ((_task$result2 = task.result) === null || _task$result2 === void 0 ? void 0 : _task$result2.state) === "fail") {
|
|
882
|
+
if (1 + await rpc$2().getCountOfFailedTests() >= this.config.bail) {
|
|
883
|
+
rpc$2().cancelCurrentRun("test-failure");
|
|
884
|
+
this.cancel("test-failure");
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
_defineProperty(this, "onTaskFinished", async (task) => {
|
|
889
|
+
var _task$result3, _task$result4, _Reflect$get;
|
|
890
|
+
const lastErrorContext = (_task$result3 = task.result) === null || _task$result3 === void 0 || (_task$result3 = _task$result3.errors) === null || _task$result3 === void 0 || (_task$result3 = _task$result3.at(-1)) === null || _task$result3 === void 0 ? void 0 : _task$result3.__vitest_error_context__;
|
|
891
|
+
if (this.config.browser.screenshotFailures && document.body.clientHeight > 0 && ((_task$result4 = task.result) === null || _task$result4 === void 0 ? void 0 : _task$result4.state) === "fail" && task.type === "test" && !(lastErrorContext && Reflect.get(lastErrorContext, "assertionName") === "toMatchScreenshot" && ((_Reflect$get = Reflect.get(lastErrorContext, "meta")) === null || _Reflect$get === void 0 ? void 0 : _Reflect$get.outcome) !== "unstable-screenshot")) {
|
|
892
|
+
var _this$config$browser$;
|
|
893
|
+
const screenshot = await page.screenshot(
|
|
894
|
+
{ timeout: ((_this$config$browser$ = this.config.browser.providerOptions) === null || _this$config$browser$ === void 0 ? void 0 : _this$config$browser$.actionTimeout) ?? 5e3 }
|
|
895
|
+
/** TODO */
|
|
896
|
+
).catch((err) => {
|
|
897
|
+
console.error("[vitest] Failed to take a screenshot", err);
|
|
898
|
+
});
|
|
899
|
+
if (screenshot) await recordArtifact(task, {
|
|
900
|
+
type: "internal:failureScreenshot",
|
|
901
|
+
attachments: [{
|
|
902
|
+
contentType: "image/png",
|
|
903
|
+
path: screenshot,
|
|
904
|
+
originalPath: screenshot
|
|
905
|
+
}]
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
_defineProperty(this, "cancel", (reason) => {
|
|
910
|
+
var _super$cancel;
|
|
911
|
+
(_super$cancel = super.cancel) === null || _super$cancel === void 0 || _super$cancel.call(this, reason);
|
|
912
|
+
globalChannel.postMessage({
|
|
913
|
+
type: "cancel",
|
|
914
|
+
reason
|
|
915
|
+
});
|
|
916
|
+
});
|
|
917
|
+
_defineProperty(this, "onBeforeRunSuite", async (suite) => {
|
|
918
|
+
var _super$onBeforeRunSui;
|
|
919
|
+
await Promise.all([(_super$onBeforeRunSui = super.onBeforeRunSuite) === null || _super$onBeforeRunSui === void 0 ? void 0 : _super$onBeforeRunSui.call(this, suite), (async () => {
|
|
920
|
+
if (!("filepath" in suite)) return;
|
|
921
|
+
const map = await rpc$2().getBrowserFileSourceMap(suite.filepath);
|
|
922
|
+
this.sourceMapCache.set(suite.filepath, map);
|
|
923
|
+
const snapshotEnvironment = this.config.snapshotOptions.snapshotEnvironment;
|
|
924
|
+
if (snapshotEnvironment instanceof VitestBrowserSnapshotEnvironment) snapshotEnvironment.addSourceMap(suite.filepath, map);
|
|
925
|
+
})()]);
|
|
926
|
+
});
|
|
927
|
+
_defineProperty(this, "onAfterRunFiles", async (files) => {
|
|
928
|
+
super.onAfterRunFiles(files);
|
|
929
|
+
const [coverage] = await Promise.all([coverageModule.takeCoverage(), mocker.invalidate()]);
|
|
930
|
+
if (coverage) await rpc$2().onAfterSuiteRun({
|
|
931
|
+
coverage,
|
|
932
|
+
testFiles: files.map((file) => file.name),
|
|
933
|
+
environment: "__browser__",
|
|
934
|
+
projectName: this.config.name
|
|
935
|
+
});
|
|
936
|
+
});
|
|
937
|
+
_defineProperty(this, "onCollectStart", (file) => {
|
|
938
|
+
return rpc$2().onQueued(this.method, file);
|
|
939
|
+
});
|
|
940
|
+
_defineProperty(this, "onCollected", async (files) => {
|
|
941
|
+
files.forEach((file) => {
|
|
942
|
+
file.prepareDuration = state.durations.prepare;
|
|
943
|
+
file.environmentLoad = state.durations.environment;
|
|
944
|
+
state.durations.prepare = 0;
|
|
945
|
+
state.durations.environment = 0;
|
|
946
|
+
});
|
|
947
|
+
if (this.config.includeTaskLocation) try {
|
|
948
|
+
await updateTestFilesLocations(files, this.sourceMapCache);
|
|
949
|
+
} catch {}
|
|
950
|
+
return rpc$2().onCollected(this.method, files);
|
|
951
|
+
});
|
|
952
|
+
_defineProperty(this, "onTestAnnotate", (test, annotation) => {
|
|
953
|
+
const artifact = {
|
|
954
|
+
type: "internal:annotation",
|
|
955
|
+
annotation,
|
|
956
|
+
location: annotation.location
|
|
957
|
+
};
|
|
958
|
+
return this.onTestArtifactRecord(test, artifact).then(({ annotation }) => annotation);
|
|
959
|
+
});
|
|
960
|
+
_defineProperty(this, "onTestArtifactRecord", (test, artifact) => {
|
|
961
|
+
if (artifact.location) {
|
|
962
|
+
const map = this.sourceMapCache.get(artifact.location.file);
|
|
963
|
+
if (!map) return rpc$2().onTaskArtifactRecord(test.id, artifact);
|
|
964
|
+
const position = getOriginalPosition(new DecodedMap(map, artifact.location.file), artifact.location);
|
|
965
|
+
if (position) {
|
|
966
|
+
const { source, column, line } = position;
|
|
967
|
+
const file = source || artifact.location.file;
|
|
968
|
+
artifact.location = {
|
|
969
|
+
line,
|
|
970
|
+
column: column + 1,
|
|
971
|
+
file: file.match(/\/\w:\//) ? file.slice(1) : file
|
|
972
|
+
};
|
|
973
|
+
if (artifact.type === "internal:annotation") artifact.annotation.location = artifact.location;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return rpc$2().onTaskArtifactRecord(test.id, artifact);
|
|
977
|
+
});
|
|
978
|
+
_defineProperty(this, "onTaskUpdate", (task, events) => {
|
|
979
|
+
return rpc$2().onTaskUpdate(this.method, task, events);
|
|
980
|
+
});
|
|
981
|
+
_defineProperty(this, "importFile", async (filepath, mode) => {
|
|
982
|
+
let hash = this.hashMap.get(filepath);
|
|
983
|
+
if (mode === "setup" || !hash) {
|
|
984
|
+
hash = Date.now().toString();
|
|
985
|
+
this.hashMap.set(filepath, hash);
|
|
986
|
+
}
|
|
987
|
+
const importpath = `${`/${/^\w:/.test(filepath) ? "@fs/" : ""}`}${filepath}?${`browserv=${hash}`}`.replace(/\/+/g, "/");
|
|
988
|
+
const trace = this.config.browser.trace;
|
|
989
|
+
if (mode === "collect" && trace !== "off") await this.commands.triggerCommand("__vitest_startTracing", []);
|
|
990
|
+
try {
|
|
991
|
+
await __vitePreload(() => import(
|
|
992
|
+
/* @vite-ignore */
|
|
993
|
+
importpath
|
|
994
|
+
), []);
|
|
995
|
+
} catch (err) {
|
|
996
|
+
throw new Error(`Failed to import test file ${filepath}`, { cause: err });
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
_defineProperty(this, "trace", (name, attributes, cb) => {
|
|
1000
|
+
const options = typeof attributes === "object" ? { attributes } : {};
|
|
1001
|
+
return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes);
|
|
1002
|
+
});
|
|
1003
|
+
this.config = options.config;
|
|
1004
|
+
this.commands = (/* @__PURE__ */ getBrowserState()).commands;
|
|
1005
|
+
this.viteEnvironment = "__browser__";
|
|
1006
|
+
this._otel = (/* @__PURE__ */ getBrowserState()).traces;
|
|
1007
|
+
}
|
|
1008
|
+
setMethod(method) {
|
|
1009
|
+
this.method = method;
|
|
1010
|
+
}
|
|
1011
|
+
async onBeforeTryTask(test, options) {
|
|
1012
|
+
var _super$onBeforeTryTas;
|
|
1013
|
+
await userEvent.cleanup();
|
|
1014
|
+
(_super$onBeforeTryTas = super.onBeforeTryTask) === null || _super$onBeforeTryTas === void 0 || _super$onBeforeTryTas.call(this, test, options);
|
|
1015
|
+
const trace = this.config.browser.trace;
|
|
1016
|
+
const { retry, repeats } = options;
|
|
1017
|
+
const shouldTrace = trace !== "off" && !(trace === "on-all-retries" && retry === 0) && !(trace === "on-first-retry" && retry !== 1);
|
|
1018
|
+
const shouldTraceView = this.config.browser.traceView.enabled;
|
|
1019
|
+
if (!shouldTraceView && !shouldTrace) {
|
|
1020
|
+
(/* @__PURE__ */ getBrowserState()).activeTraceTaskIds.delete(test.id);
|
|
1021
|
+
(/* @__PURE__ */ getBrowserState()).browserTraceAttempts.delete(test.id);
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
if (shouldTraceView) {
|
|
1025
|
+
(/* @__PURE__ */ getBrowserState()).browserTraceDomSnapshot = await __vitePreload(() => import("./rrweb-snapshot-iZCFA2to.js"), []);
|
|
1026
|
+
(/* @__PURE__ */ getBrowserState()).browserTraceAttempts.set(test.id, {
|
|
1027
|
+
retry,
|
|
1028
|
+
repeats,
|
|
1029
|
+
startTime: now$1()
|
|
1030
|
+
});
|
|
1031
|
+
} else (/* @__PURE__ */ getBrowserState()).browserTraceAttempts.delete(test.id);
|
|
1032
|
+
if (!shouldTrace) {
|
|
1033
|
+
(/* @__PURE__ */ getBrowserState()).activeTraceTaskIds.delete(test.id);
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
(/* @__PURE__ */ getBrowserState()).activeTraceTaskIds.add(test.id);
|
|
1037
|
+
let title = /* @__PURE__ */ getTestName(test);
|
|
1038
|
+
if (retry) title += ` (retry x${retry})`;
|
|
1039
|
+
if (repeats) title += ` (repeat x${repeats})`;
|
|
1040
|
+
const name = getTraceName(test, retry, repeats);
|
|
1041
|
+
await this.commands.triggerCommand("__vitest_startChunkTrace", [{
|
|
1042
|
+
name,
|
|
1043
|
+
title
|
|
1044
|
+
}]);
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
var cachedRunner = null;
|
|
1049
|
+
function getBrowserRunner() {
|
|
1050
|
+
return cachedRunner;
|
|
1051
|
+
}
|
|
1052
|
+
async function initiateRunner(state, mocker, config) {
|
|
1053
|
+
if (cachedRunner) return cachedRunner;
|
|
1054
|
+
const BrowserRunner = createBrowserRunner(mocker, state, { takeCoverage: () => takeCoverageInsideWorker(config.coverage, moduleRunner) });
|
|
1055
|
+
if (!config.snapshotOptions.snapshotEnvironment) config.snapshotOptions.snapshotEnvironment = new VitestBrowserSnapshotEnvironment();
|
|
1056
|
+
const runner = new BrowserRunner({ config });
|
|
1057
|
+
cachedRunner = runner;
|
|
1058
|
+
onCancel((reason) => {
|
|
1059
|
+
var _runner$cancel;
|
|
1060
|
+
(_runner$cancel = runner.cancel) === null || _runner$cancel === void 0 || _runner$cancel.call(runner, reason);
|
|
1061
|
+
});
|
|
1062
|
+
const [diffOptions] = await Promise.all([loadDiffConfig(config, moduleRunner), loadSnapshotSerializers(config, moduleRunner)]);
|
|
1063
|
+
runner.config._diffOptions = diffOptions;
|
|
1064
|
+
(/* @__PURE__ */ getWorkerState()).onFilterStackTrace = (stack) => {
|
|
1065
|
+
return createStackString(parseStacktrace(stack, { getSourceMap(file) {
|
|
1066
|
+
return runner.sourceMapCache.get(file);
|
|
1067
|
+
} }));
|
|
1068
|
+
};
|
|
1069
|
+
return runner;
|
|
1070
|
+
}
|
|
1071
|
+
async function getTraceMap(file, sourceMaps) {
|
|
1072
|
+
const result = sourceMaps.get(file) || await rpc$2().getBrowserFileSourceMap(file).then((map) => {
|
|
1073
|
+
sourceMaps.set(file, map);
|
|
1074
|
+
return map;
|
|
1075
|
+
});
|
|
1076
|
+
if (!result) return null;
|
|
1077
|
+
return new DecodedMap(result, file);
|
|
1078
|
+
}
|
|
1079
|
+
async function updateTestFilesLocations(files, sourceMaps) {
|
|
1080
|
+
const promises = files.map(async (file) => {
|
|
1081
|
+
const traceMap = await getTraceMap(file.filepath, sourceMaps);
|
|
1082
|
+
if (!traceMap) return null;
|
|
1083
|
+
const updateLocation = (task) => {
|
|
1084
|
+
if (task.location) {
|
|
1085
|
+
const position = getOriginalPosition(traceMap, task.location);
|
|
1086
|
+
if (position) {
|
|
1087
|
+
const { line, column } = position;
|
|
1088
|
+
task.location = {
|
|
1089
|
+
line,
|
|
1090
|
+
column: task.each ? column : column + 1
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
if ("tasks" in task) task.tasks.forEach(updateLocation);
|
|
1095
|
+
};
|
|
1096
|
+
file.tasks.forEach(updateLocation);
|
|
1097
|
+
return null;
|
|
1098
|
+
});
|
|
1099
|
+
await Promise.all(promises);
|
|
1100
|
+
}
|
|
1101
|
+
function getTraceName(task, retryCount, repeatsCount) {
|
|
1102
|
+
return `${(/* @__PURE__ */ getTestName(task, "-")).replace(/[^a-z0-9]/gi, "-")}-${repeatsCount}-${retryCount}`;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
//#endregion
|
|
1106
|
+
//#region src/client/tester/logger.ts
|
|
1107
|
+
var { Date: Date$1, console: console$1, performance: performance$1 } = globalThis;
|
|
1108
|
+
function setupConsoleLogSpy() {
|
|
1109
|
+
const { log, info, error, dir, dirxml, trace, time, timeEnd, timeLog, warn, debug, count, countReset } = console$1;
|
|
1110
|
+
console$1.log = stdout(log);
|
|
1111
|
+
console$1.debug = stdout(debug);
|
|
1112
|
+
console$1.info = stdout(info);
|
|
1113
|
+
console$1.error = stderr(error);
|
|
1114
|
+
console$1.warn = stderr(warn);
|
|
1115
|
+
console$1.dir = (item, options) => {
|
|
1116
|
+
dir(item, options);
|
|
1117
|
+
sendLog("stdout", processLog([item]));
|
|
1118
|
+
};
|
|
1119
|
+
console$1.dirxml = (...args) => {
|
|
1120
|
+
dirxml(...args);
|
|
1121
|
+
sendLog("stdout", processLog(args));
|
|
1122
|
+
};
|
|
1123
|
+
console$1.trace = (...args) => {
|
|
1124
|
+
var _globalThis$__vitest_;
|
|
1125
|
+
trace(...args);
|
|
1126
|
+
const content = processLog(args);
|
|
1127
|
+
const error = /* @__PURE__ */ new Error("$$Trace");
|
|
1128
|
+
sendLog("stderr", `${content}\n${(((_globalThis$__vitest_ = globalThis.__vitest_worker__) === null || _globalThis$__vitest_ === void 0 ? void 0 : _globalThis$__vitest_.onFilterStackTrace) || ((s) => s || ""))(error.stack || "")}`, true);
|
|
1129
|
+
};
|
|
1130
|
+
const timeLabels = {};
|
|
1131
|
+
console$1.time = (label = "default") => {
|
|
1132
|
+
time(label);
|
|
1133
|
+
timeLabels[label] = performance$1.now();
|
|
1134
|
+
};
|
|
1135
|
+
console$1.timeLog = (label = "default") => {
|
|
1136
|
+
timeLog(label);
|
|
1137
|
+
if (!(label in timeLabels)) sendLog("stderr", `Timer "${label}" does not exist`);
|
|
1138
|
+
else sendLog("stdout", `${label}: ${timeLabels[label]} ms`);
|
|
1139
|
+
};
|
|
1140
|
+
console$1.timeEnd = (label = "default") => {
|
|
1141
|
+
timeEnd(label);
|
|
1142
|
+
const end = performance$1.now();
|
|
1143
|
+
const start = timeLabels[label];
|
|
1144
|
+
if (!(label in timeLabels)) sendLog("stderr", `Timer "${label}" does not exist`);
|
|
1145
|
+
else if (typeof start !== "undefined") sendLog("stdout", `${label}: ${end - start} ms`);
|
|
1146
|
+
};
|
|
1147
|
+
const countLabels = {};
|
|
1148
|
+
console$1.count = (label = "default") => {
|
|
1149
|
+
count(label);
|
|
1150
|
+
const counter = (countLabels[label] ?? 0) + 1;
|
|
1151
|
+
countLabels[label] = counter;
|
|
1152
|
+
sendLog("stdout", `${label}: ${counter}`);
|
|
1153
|
+
};
|
|
1154
|
+
console$1.countReset = (label = "default") => {
|
|
1155
|
+
countReset(label);
|
|
1156
|
+
countLabels[label] = 0;
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
function stdout(base) {
|
|
1160
|
+
return (...args) => {
|
|
1161
|
+
base(...args);
|
|
1162
|
+
if (args[0] === "[WDIO]") {
|
|
1163
|
+
if (args[1] === "newShadowRoot" || args[1] === "removeShadowRoot") return;
|
|
1164
|
+
}
|
|
1165
|
+
sendLog("stdout", processLog(args));
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
function stderr(base) {
|
|
1169
|
+
return (...args) => {
|
|
1170
|
+
base(...args);
|
|
1171
|
+
sendLog("stderr", processLog(args));
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
function processLog(args) {
|
|
1175
|
+
return format(args, { multiline: true });
|
|
1176
|
+
}
|
|
1177
|
+
function sendLog(type, content, disableStack) {
|
|
1178
|
+
var _globalThis$__vitest_2, _Error$stack;
|
|
1179
|
+
if (content.startsWith("[vite]")) return;
|
|
1180
|
+
const taskId = ((_globalThis$__vitest_2 = globalThis.__vitest_worker__) === null || _globalThis$__vitest_2 === void 0 || (_globalThis$__vitest_2 = _globalThis$__vitest_2.current) === null || _globalThis$__vitest_2 === void 0 ? void 0 : _globalThis$__vitest_2.id) ?? "__vitest__unknown_test__";
|
|
1181
|
+
const origin = getConfig().printConsoleTrace && !disableStack ? (_Error$stack = (/* @__PURE__ */ new Error("STACK_TRACE")).stack) === null || _Error$stack === void 0 ? void 0 : _Error$stack.split("\n").slice(1).join("\n") : void 0;
|
|
1182
|
+
const runner = getBrowserRunner();
|
|
1183
|
+
rpc$2().sendLog((runner === null || runner === void 0 ? void 0 : runner.method) || "run", {
|
|
1184
|
+
origin,
|
|
1185
|
+
content,
|
|
1186
|
+
browser: true,
|
|
1187
|
+
time: Date$1.now(),
|
|
1188
|
+
taskId,
|
|
1189
|
+
type,
|
|
1190
|
+
size: content.length
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
//#endregion
|
|
1195
|
+
//#region ../mocker/dist/chunk-registry.js
|
|
1196
|
+
var MockerRegistry = class {
|
|
1197
|
+
constructor() {
|
|
1198
|
+
_defineProperty(this, "registryByUrl", /* @__PURE__ */ new Map());
|
|
1199
|
+
_defineProperty(this, "registryById", /* @__PURE__ */ new Map());
|
|
1200
|
+
}
|
|
1201
|
+
clear() {
|
|
1202
|
+
this.registryByUrl.clear();
|
|
1203
|
+
this.registryById.clear();
|
|
1204
|
+
}
|
|
1205
|
+
keys() {
|
|
1206
|
+
return this.registryByUrl.keys();
|
|
1207
|
+
}
|
|
1208
|
+
add(mock) {
|
|
1209
|
+
this.registryByUrl.set(mock.url, mock);
|
|
1210
|
+
this.registryById.set(mock.id, mock);
|
|
1211
|
+
}
|
|
1212
|
+
register(typeOrEvent, raw, id, url, factoryOrRedirect) {
|
|
1213
|
+
const type = typeof typeOrEvent === "object" ? typeOrEvent.type : typeOrEvent;
|
|
1214
|
+
if (typeof typeOrEvent === "object") {
|
|
1215
|
+
const event = typeOrEvent;
|
|
1216
|
+
if (event instanceof AutomockedModule || event instanceof AutospiedModule || event instanceof ManualMockedModule || event instanceof RedirectedModule) throw new TypeError(`[vitest] Cannot register a mock that is already defined. Expected a JSON representation from \`MockedModule.toJSON\`, instead got "${event.type}". Use "registry.add()" to update a mock instead.`);
|
|
1217
|
+
if (event.type === "automock") {
|
|
1218
|
+
const module = AutomockedModule.fromJSON(event);
|
|
1219
|
+
this.add(module);
|
|
1220
|
+
return module;
|
|
1221
|
+
} else if (event.type === "autospy") {
|
|
1222
|
+
const module = AutospiedModule.fromJSON(event);
|
|
1223
|
+
this.add(module);
|
|
1224
|
+
return module;
|
|
1225
|
+
} else if (event.type === "redirect") {
|
|
1226
|
+
const module = RedirectedModule.fromJSON(event);
|
|
1227
|
+
this.add(module);
|
|
1228
|
+
return module;
|
|
1229
|
+
} else if (event.type === "manual") throw new Error(`Cannot set serialized manual mock. Define a factory function manually with \`ManualMockedModule.fromJSON()\`.`);
|
|
1230
|
+
else throw new Error(`Unknown mock type: ${event.type}`);
|
|
1231
|
+
}
|
|
1232
|
+
if (typeof raw !== "string") throw new TypeError("[vitest] Mocks require a raw string.");
|
|
1233
|
+
if (typeof url !== "string") throw new TypeError("[vitest] Mocks require a url string.");
|
|
1234
|
+
if (typeof id !== "string") throw new TypeError("[vitest] Mocks require an id string.");
|
|
1235
|
+
if (type === "manual") {
|
|
1236
|
+
if (typeof factoryOrRedirect !== "function") throw new TypeError("[vitest] Manual mocks require a factory function.");
|
|
1237
|
+
const mock = new ManualMockedModule(raw, id, url, factoryOrRedirect);
|
|
1238
|
+
this.add(mock);
|
|
1239
|
+
return mock;
|
|
1240
|
+
} else if (type === "automock" || type === "autospy") {
|
|
1241
|
+
const mock = type === "automock" ? new AutomockedModule(raw, id, url) : new AutospiedModule(raw, id, url);
|
|
1242
|
+
this.add(mock);
|
|
1243
|
+
return mock;
|
|
1244
|
+
} else if (type === "redirect") {
|
|
1245
|
+
if (typeof factoryOrRedirect !== "string") throw new TypeError("[vitest] Redirect mocks require a redirect string.");
|
|
1246
|
+
const mock = new RedirectedModule(raw, id, url, factoryOrRedirect);
|
|
1247
|
+
this.add(mock);
|
|
1248
|
+
return mock;
|
|
1249
|
+
} else throw new Error(`[vitest] Unknown mock type: ${type}`);
|
|
1250
|
+
}
|
|
1251
|
+
delete(id) {
|
|
1252
|
+
this.registryByUrl.delete(id);
|
|
1253
|
+
}
|
|
1254
|
+
deleteById(id) {
|
|
1255
|
+
this.registryById.delete(id);
|
|
1256
|
+
}
|
|
1257
|
+
get(id) {
|
|
1258
|
+
return this.registryByUrl.get(id);
|
|
1259
|
+
}
|
|
1260
|
+
getById(id) {
|
|
1261
|
+
return this.registryById.get(id);
|
|
1262
|
+
}
|
|
1263
|
+
has(id) {
|
|
1264
|
+
return this.registryByUrl.has(id);
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
var AutomockedModule = class AutomockedModule {
|
|
1268
|
+
constructor(raw, id, url) {
|
|
1269
|
+
_defineProperty(this, "type", "automock");
|
|
1270
|
+
this.raw = raw;
|
|
1271
|
+
this.id = id;
|
|
1272
|
+
this.url = url;
|
|
1273
|
+
}
|
|
1274
|
+
static fromJSON(data) {
|
|
1275
|
+
return new AutomockedModule(data.raw, data.id, data.url);
|
|
1276
|
+
}
|
|
1277
|
+
toJSON() {
|
|
1278
|
+
return {
|
|
1279
|
+
type: this.type,
|
|
1280
|
+
url: this.url,
|
|
1281
|
+
raw: this.raw,
|
|
1282
|
+
id: this.id
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
var AutospiedModule = class AutospiedModule {
|
|
1287
|
+
constructor(raw, id, url) {
|
|
1288
|
+
_defineProperty(this, "type", "autospy");
|
|
1289
|
+
this.raw = raw;
|
|
1290
|
+
this.id = id;
|
|
1291
|
+
this.url = url;
|
|
1292
|
+
}
|
|
1293
|
+
static fromJSON(data) {
|
|
1294
|
+
return new AutospiedModule(data.raw, data.id, data.url);
|
|
1295
|
+
}
|
|
1296
|
+
toJSON() {
|
|
1297
|
+
return {
|
|
1298
|
+
type: this.type,
|
|
1299
|
+
url: this.url,
|
|
1300
|
+
id: this.id,
|
|
1301
|
+
raw: this.raw
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
var RedirectedModule = class RedirectedModule {
|
|
1306
|
+
constructor(raw, id, url, redirect) {
|
|
1307
|
+
_defineProperty(this, "type", "redirect");
|
|
1308
|
+
this.raw = raw;
|
|
1309
|
+
this.id = id;
|
|
1310
|
+
this.url = url;
|
|
1311
|
+
this.redirect = redirect;
|
|
1312
|
+
}
|
|
1313
|
+
static fromJSON(data) {
|
|
1314
|
+
return new RedirectedModule(data.raw, data.id, data.url, data.redirect);
|
|
1315
|
+
}
|
|
1316
|
+
toJSON() {
|
|
1317
|
+
return {
|
|
1318
|
+
type: this.type,
|
|
1319
|
+
url: this.url,
|
|
1320
|
+
raw: this.raw,
|
|
1321
|
+
id: this.id,
|
|
1322
|
+
redirect: this.redirect
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
var ManualMockedModule = class ManualMockedModule {
|
|
1327
|
+
constructor(raw, id, url, factory) {
|
|
1328
|
+
_defineProperty(this, "cache", void 0);
|
|
1329
|
+
_defineProperty(this, "type", "manual");
|
|
1330
|
+
this.raw = raw;
|
|
1331
|
+
this.id = id;
|
|
1332
|
+
this.url = url;
|
|
1333
|
+
this.factory = factory;
|
|
1334
|
+
}
|
|
1335
|
+
resolve() {
|
|
1336
|
+
if (this.cache) return this.cache;
|
|
1337
|
+
let exports$1;
|
|
1338
|
+
try {
|
|
1339
|
+
exports$1 = this.factory();
|
|
1340
|
+
} catch (err) {
|
|
1341
|
+
throw createHelpfulError(err);
|
|
1342
|
+
}
|
|
1343
|
+
if (typeof exports$1 === "object" && typeof (exports$1 === null || exports$1 === void 0 ? void 0 : exports$1.then) === "function") return exports$1.then((result) => {
|
|
1344
|
+
assertValidExports(this.raw, result);
|
|
1345
|
+
return this.cache = result;
|
|
1346
|
+
}, (error) => {
|
|
1347
|
+
throw createHelpfulError(error);
|
|
1348
|
+
});
|
|
1349
|
+
assertValidExports(this.raw, exports$1);
|
|
1350
|
+
return this.cache = exports$1;
|
|
1351
|
+
}
|
|
1352
|
+
static fromJSON(data, factory) {
|
|
1353
|
+
return new ManualMockedModule(data.raw, data.id, data.url, factory);
|
|
1354
|
+
}
|
|
1355
|
+
toJSON() {
|
|
1356
|
+
return {
|
|
1357
|
+
type: this.type,
|
|
1358
|
+
url: this.url,
|
|
1359
|
+
id: this.id,
|
|
1360
|
+
raw: this.raw
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
function createHelpfulError(cause) {
|
|
1365
|
+
const error = /* @__PURE__ */ new Error("[vitest] There was an error when mocking a module. If you are using \"vi.mock\" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://vitest.dev/api/vi.html#vi-mock");
|
|
1366
|
+
error.cause = cause;
|
|
1367
|
+
return error;
|
|
1368
|
+
}
|
|
1369
|
+
function assertValidExports(raw, exports$1) {
|
|
1370
|
+
if (exports$1 === null || typeof exports$1 !== "object" || Array.isArray(exports$1)) throw new TypeError(`[vitest] vi.mock("${raw}", factory?: () => unknown) is not returning an object. Did you mean to return an object with a "default" key?`);
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
//#endregion
|
|
1374
|
+
//#region ../mocker/dist/index.js
|
|
1375
|
+
function mockObject(options, object, mockExports = {}) {
|
|
1376
|
+
const finalizers = new Array();
|
|
1377
|
+
const refs = new RefTracker();
|
|
1378
|
+
const define = (container, key, value) => {
|
|
1379
|
+
try {
|
|
1380
|
+
container[key] = value;
|
|
1381
|
+
return true;
|
|
1382
|
+
} catch {
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
1386
|
+
const createMock = (currentValue) => {
|
|
1387
|
+
if (!options.createMockInstance) throw new Error("[@vitest/mocker] `createMockInstance` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
|
|
1388
|
+
const createMockInstance = options.createMockInstance;
|
|
1389
|
+
const prototypeMembers = currentValue.prototype ? collectFunctionProperties(currentValue.prototype) : [];
|
|
1390
|
+
return createMockInstance({
|
|
1391
|
+
name: currentValue.name,
|
|
1392
|
+
prototypeMembers,
|
|
1393
|
+
originalImplementation: options.type === "autospy" ? currentValue : void 0,
|
|
1394
|
+
keepMembersImplementation: options.type === "autospy"
|
|
1395
|
+
});
|
|
1396
|
+
};
|
|
1397
|
+
const mockPropertiesOf = (container, newContainer) => {
|
|
1398
|
+
const isModule = getType(container) === "Module" || !!container.__esModule;
|
|
1399
|
+
for (const { key: property, descriptor } of getAllMockableProperties(container, isModule, options.globalConstructors)) {
|
|
1400
|
+
if (!isModule && descriptor.get) {
|
|
1401
|
+
try {
|
|
1402
|
+
if (options.type === "autospy") Object.defineProperty(newContainer, property, descriptor);
|
|
1403
|
+
else Object.defineProperty(newContainer, property, {
|
|
1404
|
+
configurable: descriptor.configurable,
|
|
1405
|
+
enumerable: descriptor.enumerable,
|
|
1406
|
+
get: () => {},
|
|
1407
|
+
set: descriptor.set ? () => {} : void 0
|
|
1408
|
+
});
|
|
1409
|
+
} catch {}
|
|
1410
|
+
continue;
|
|
1411
|
+
}
|
|
1412
|
+
if (isReadonlyProp(container[property], property)) continue;
|
|
1413
|
+
const value = container[property];
|
|
1414
|
+
const refId = refs.getId(value);
|
|
1415
|
+
if (refId !== void 0) {
|
|
1416
|
+
finalizers.push(() => define(newContainer, property, refs.getMockedValue(refId)));
|
|
1417
|
+
continue;
|
|
1418
|
+
}
|
|
1419
|
+
const type = getType(value);
|
|
1420
|
+
if (Array.isArray(value)) {
|
|
1421
|
+
if (options.type === "automock") define(newContainer, property, []);
|
|
1422
|
+
else define(newContainer, property, value.map((value) => {
|
|
1423
|
+
if (value && typeof value === "object") {
|
|
1424
|
+
const newObject = {};
|
|
1425
|
+
mockPropertiesOf(value, newObject);
|
|
1426
|
+
return newObject;
|
|
1427
|
+
}
|
|
1428
|
+
if (typeof value === "function") return createMock(value);
|
|
1429
|
+
return value;
|
|
1430
|
+
}));
|
|
1431
|
+
continue;
|
|
1432
|
+
}
|
|
1433
|
+
const isFunction = type.includes("Function") && typeof value === "function";
|
|
1434
|
+
if ((!isFunction || value._isMockFunction) && type !== "Object" && type !== "Module") {
|
|
1435
|
+
define(newContainer, property, value);
|
|
1436
|
+
continue;
|
|
1437
|
+
}
|
|
1438
|
+
if (options.type === "autospy" && type === "Module") {
|
|
1439
|
+
const exports$1 = Object.create(null);
|
|
1440
|
+
Object.defineProperty(exports$1, Symbol.toStringTag, {
|
|
1441
|
+
value: "Module",
|
|
1442
|
+
configurable: true,
|
|
1443
|
+
writable: true
|
|
1444
|
+
});
|
|
1445
|
+
try {
|
|
1446
|
+
newContainer[property] = exports$1;
|
|
1447
|
+
} catch {
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
} else if (!define(newContainer, property, isFunction || options.type === "autospy" ? value : {})) continue;
|
|
1451
|
+
if (isFunction) newContainer[property] = createMock(newContainer[property]);
|
|
1452
|
+
refs.track(value, newContainer[property]);
|
|
1453
|
+
mockPropertiesOf(value, newContainer[property]);
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1456
|
+
const mockedObject = mockExports;
|
|
1457
|
+
mockPropertiesOf(object, mockedObject);
|
|
1458
|
+
for (const finalizer of finalizers) finalizer();
|
|
1459
|
+
return mockedObject;
|
|
1460
|
+
}
|
|
1461
|
+
var RefTracker = class {
|
|
1462
|
+
constructor() {
|
|
1463
|
+
_defineProperty(this, "idMap", /* @__PURE__ */ new Map());
|
|
1464
|
+
_defineProperty(this, "mockedValueMap", /* @__PURE__ */ new Map());
|
|
1465
|
+
}
|
|
1466
|
+
getId(value) {
|
|
1467
|
+
return this.idMap.get(value);
|
|
1468
|
+
}
|
|
1469
|
+
getMockedValue(id) {
|
|
1470
|
+
return this.mockedValueMap.get(id);
|
|
1471
|
+
}
|
|
1472
|
+
track(originalValue, mockedValue) {
|
|
1473
|
+
const newId = this.idMap.size;
|
|
1474
|
+
this.idMap.set(originalValue, newId);
|
|
1475
|
+
this.mockedValueMap.set(newId, mockedValue);
|
|
1476
|
+
return newId;
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
function getType(value) {
|
|
1480
|
+
return Object.prototype.toString.apply(value).slice(8, -1);
|
|
1481
|
+
}
|
|
1482
|
+
function isReadonlyProp(object, prop) {
|
|
1483
|
+
if (prop === "arguments" || prop === "caller" || prop === "callee" || prop === "name" || prop === "length") {
|
|
1484
|
+
const typeName = getType(object);
|
|
1485
|
+
return typeName === "Function" || typeName === "AsyncFunction" || typeName === "GeneratorFunction" || typeName === "AsyncGeneratorFunction";
|
|
1486
|
+
}
|
|
1487
|
+
if (prop === "source" || prop === "global" || prop === "ignoreCase" || prop === "multiline") return getType(object) === "RegExp";
|
|
1488
|
+
return false;
|
|
1489
|
+
}
|
|
1490
|
+
function getAllMockableProperties(obj, isModule, constructors) {
|
|
1491
|
+
const { Map, Object, Function, RegExp, Array } = constructors;
|
|
1492
|
+
const allProps = new Map();
|
|
1493
|
+
let curr = obj;
|
|
1494
|
+
do {
|
|
1495
|
+
if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype) break;
|
|
1496
|
+
collectOwnProperties(curr, (key) => {
|
|
1497
|
+
const descriptor = Object.getOwnPropertyDescriptor(curr, key);
|
|
1498
|
+
if (descriptor) allProps.set(key, {
|
|
1499
|
+
key,
|
|
1500
|
+
descriptor
|
|
1501
|
+
});
|
|
1502
|
+
});
|
|
1503
|
+
} while (curr = Object.getPrototypeOf(curr));
|
|
1504
|
+
if (isModule && !allProps.has("default") && "default" in obj) {
|
|
1505
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, "default");
|
|
1506
|
+
if (descriptor) allProps.set("default", {
|
|
1507
|
+
key: "default",
|
|
1508
|
+
descriptor
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
return Array.from(allProps.values());
|
|
1512
|
+
}
|
|
1513
|
+
function collectOwnProperties(obj, collector) {
|
|
1514
|
+
const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
|
|
1515
|
+
Object.getOwnPropertyNames(obj).forEach(collect);
|
|
1516
|
+
Object.getOwnPropertySymbols(obj).forEach(collect);
|
|
1517
|
+
}
|
|
1518
|
+
function collectFunctionProperties(prototype) {
|
|
1519
|
+
const properties = /* @__PURE__ */ new Set();
|
|
1520
|
+
collectOwnProperties(prototype, (prop) => {
|
|
1521
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, prop);
|
|
1522
|
+
if (!descriptor || descriptor.get) return;
|
|
1523
|
+
if (getType(descriptor.value).includes("Function") && !isReadonlyProp(descriptor.value, prop)) properties.add(prop);
|
|
1524
|
+
});
|
|
1525
|
+
return Array.from(properties);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
//#endregion
|
|
1529
|
+
//#region ../mocker/dist/chunk-pathe.M-eThtNZ.js
|
|
1530
|
+
var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
1531
|
+
function normalizeWindowsPath(input = "") {
|
|
1532
|
+
if (!input) return input;
|
|
1533
|
+
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
1534
|
+
}
|
|
1535
|
+
var _UNC_REGEX = /^[/\\]{2}/;
|
|
1536
|
+
var _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
1537
|
+
var _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
|
|
1538
|
+
var _EXTNAME_RE = /.(\.[^./]+|\.)$/;
|
|
1539
|
+
var normalize = function(path) {
|
|
1540
|
+
if (path.length === 0) return ".";
|
|
1541
|
+
path = normalizeWindowsPath(path);
|
|
1542
|
+
const isUNCPath = path.match(_UNC_REGEX);
|
|
1543
|
+
const isPathAbsolute = isAbsolute(path);
|
|
1544
|
+
const trailingSeparator = path[path.length - 1] === "/";
|
|
1545
|
+
path = normalizeString(path, !isPathAbsolute);
|
|
1546
|
+
if (path.length === 0) {
|
|
1547
|
+
if (isPathAbsolute) return "/";
|
|
1548
|
+
return trailingSeparator ? "./" : ".";
|
|
1549
|
+
}
|
|
1550
|
+
if (trailingSeparator) path += "/";
|
|
1551
|
+
if (_DRIVE_LETTER_RE.test(path)) path += "/";
|
|
1552
|
+
if (isUNCPath) {
|
|
1553
|
+
if (!isPathAbsolute) return `//./${path}`;
|
|
1554
|
+
return `//${path}`;
|
|
1555
|
+
}
|
|
1556
|
+
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
|
|
1557
|
+
};
|
|
1558
|
+
var join = function(...segments) {
|
|
1559
|
+
let path = "";
|
|
1560
|
+
for (const seg of segments) {
|
|
1561
|
+
if (!seg) continue;
|
|
1562
|
+
if (path.length > 0) {
|
|
1563
|
+
const pathTrailing = path[path.length - 1] === "/";
|
|
1564
|
+
const segLeading = seg[0] === "/";
|
|
1565
|
+
if (pathTrailing && segLeading) path += seg.slice(1);
|
|
1566
|
+
else path += pathTrailing || segLeading ? seg : `/${seg}`;
|
|
1567
|
+
} else path += seg;
|
|
1568
|
+
}
|
|
1569
|
+
return normalize(path);
|
|
1570
|
+
};
|
|
1571
|
+
function normalizeString(path, allowAboveRoot) {
|
|
1572
|
+
let res = "";
|
|
1573
|
+
let lastSegmentLength = 0;
|
|
1574
|
+
let lastSlash = -1;
|
|
1575
|
+
let dots = 0;
|
|
1576
|
+
let char = null;
|
|
1577
|
+
for (let index = 0; index <= path.length; ++index) {
|
|
1578
|
+
if (index < path.length) char = path[index];
|
|
1579
|
+
else if (char === "/") break;
|
|
1580
|
+
else char = "/";
|
|
1581
|
+
if (char === "/") {
|
|
1582
|
+
if (lastSlash === index - 1 || dots === 1);
|
|
1583
|
+
else if (dots === 2) {
|
|
1584
|
+
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
|
1585
|
+
if (res.length > 2) {
|
|
1586
|
+
const lastSlashIndex = res.lastIndexOf("/");
|
|
1587
|
+
if (lastSlashIndex === -1) {
|
|
1588
|
+
res = "";
|
|
1589
|
+
lastSegmentLength = 0;
|
|
1590
|
+
} else {
|
|
1591
|
+
res = res.slice(0, lastSlashIndex);
|
|
1592
|
+
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
1593
|
+
}
|
|
1594
|
+
lastSlash = index;
|
|
1595
|
+
dots = 0;
|
|
1596
|
+
continue;
|
|
1597
|
+
} else if (res.length > 0) {
|
|
1598
|
+
res = "";
|
|
1599
|
+
lastSegmentLength = 0;
|
|
1600
|
+
lastSlash = index;
|
|
1601
|
+
dots = 0;
|
|
1602
|
+
continue;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
if (allowAboveRoot) {
|
|
1606
|
+
res += res.length > 0 ? "/.." : "..";
|
|
1607
|
+
lastSegmentLength = 2;
|
|
1608
|
+
}
|
|
1609
|
+
} else {
|
|
1610
|
+
if (res.length > 0) res += `/${path.slice(lastSlash + 1, index)}`;
|
|
1611
|
+
else res = path.slice(lastSlash + 1, index);
|
|
1612
|
+
lastSegmentLength = index - lastSlash - 1;
|
|
1613
|
+
}
|
|
1614
|
+
lastSlash = index;
|
|
1615
|
+
dots = 0;
|
|
1616
|
+
} else if (char === "." && dots !== -1) ++dots;
|
|
1617
|
+
else dots = -1;
|
|
1618
|
+
}
|
|
1619
|
+
return res;
|
|
1620
|
+
}
|
|
1621
|
+
var isAbsolute = function(p) {
|
|
1622
|
+
return _IS_ABSOLUTE_RE.test(p);
|
|
1623
|
+
};
|
|
1624
|
+
var extname = function(p) {
|
|
1625
|
+
if (p === "..") return "";
|
|
1626
|
+
const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
|
|
1627
|
+
return match && match[1] || "";
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
//#endregion
|
|
1631
|
+
//#region ../mocker/dist/chunk-mocker.js
|
|
1632
|
+
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1633
|
+
var intToChar = new Uint8Array(64);
|
|
1634
|
+
var charToInt = new Uint8Array(128);
|
|
1635
|
+
for (let i = 0; i < chars.length; i++) {
|
|
1636
|
+
const c = chars.charCodeAt(i);
|
|
1637
|
+
intToChar[i] = c;
|
|
1638
|
+
charToInt[c] = i;
|
|
1639
|
+
}
|
|
1640
|
+
var NOW_LENGTH = Date.now().toString().length;
|
|
1641
|
+
var REGEXP_VITEST = new RegExp(`vitest=\\d{${NOW_LENGTH}}`);
|
|
1642
|
+
var { now } = Date;
|
|
1643
|
+
var ModuleMocker = class {
|
|
1644
|
+
constructor(interceptor, rpc, createMockInstance, config) {
|
|
1645
|
+
_defineProperty(this, "registry", new MockerRegistry());
|
|
1646
|
+
_defineProperty(this, "queue", /* @__PURE__ */ new Set());
|
|
1647
|
+
_defineProperty(this, "mockedIds", /* @__PURE__ */ new Set());
|
|
1648
|
+
this.interceptor = interceptor;
|
|
1649
|
+
this.rpc = rpc;
|
|
1650
|
+
this.createMockInstance = createMockInstance;
|
|
1651
|
+
this.config = config;
|
|
1652
|
+
}
|
|
1653
|
+
async prepare() {
|
|
1654
|
+
if (!this.queue.size) return;
|
|
1655
|
+
await Promise.all([...this.queue.values()]);
|
|
1656
|
+
}
|
|
1657
|
+
async resolveFactoryModule(id) {
|
|
1658
|
+
const mock = this.registry.get(id);
|
|
1659
|
+
if (!mock || mock.type !== "manual") throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`);
|
|
1660
|
+
return await mock.resolve();
|
|
1661
|
+
}
|
|
1662
|
+
getFactoryModule(id) {
|
|
1663
|
+
const mock = this.registry.get(id);
|
|
1664
|
+
if (!mock || mock.type !== "manual") throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`);
|
|
1665
|
+
if (!mock.cache) throw new Error(`Mock ${id} wasn't resolved. This is probably a Vitest error. Please, open a new issue with reproduction.`);
|
|
1666
|
+
return mock.cache;
|
|
1667
|
+
}
|
|
1668
|
+
async invalidate() {
|
|
1669
|
+
const ids = Array.from(this.mockedIds);
|
|
1670
|
+
if (!ids.length) return;
|
|
1671
|
+
await this.rpc.invalidate(ids);
|
|
1672
|
+
await this.interceptor.invalidate();
|
|
1673
|
+
this.registry.clear();
|
|
1674
|
+
}
|
|
1675
|
+
async importActual(id, importer) {
|
|
1676
|
+
const resolved = await this.rpc.resolveId(id, importer);
|
|
1677
|
+
if (resolved == null) throw new Error(`[vitest] Cannot resolve "${id}" imported from "${importer}"`);
|
|
1678
|
+
const ext = extname(resolved.id);
|
|
1679
|
+
const url = new URL(resolved.url, this.getBaseUrl());
|
|
1680
|
+
const query = `_vitest_original&ext${ext}`;
|
|
1681
|
+
const actualUrl = `${url.pathname}${url.search ? `${url.search}&${query}` : `?${query}`}${url.hash}`;
|
|
1682
|
+
return this.wrapDynamicImport(() => __vitePreload(() => import(
|
|
1683
|
+
/* @vite-ignore */
|
|
1684
|
+
actualUrl
|
|
1685
|
+
), [])).then((mod) => {
|
|
1686
|
+
if (!resolved.optimized || typeof mod.default === "undefined") return mod;
|
|
1687
|
+
const m = mod.default;
|
|
1688
|
+
return (m === null || m === void 0 ? void 0 : m.__esModule) ? m : {
|
|
1689
|
+
...typeof m === "object" && !Array.isArray(m) || typeof m === "function" ? m : {},
|
|
1690
|
+
default: m
|
|
1691
|
+
};
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
getBaseUrl() {
|
|
1695
|
+
return location.href;
|
|
1696
|
+
}
|
|
1697
|
+
async importMock(rawId, importer) {
|
|
1698
|
+
await this.prepare();
|
|
1699
|
+
const { resolvedId, resolvedUrl, redirectUrl } = await this.rpc.resolveMock(rawId, importer, { mock: "auto" });
|
|
1700
|
+
const mockUrl = this.resolveMockPath(cleanVersion(resolvedUrl));
|
|
1701
|
+
let mock = this.registry.get(mockUrl);
|
|
1702
|
+
if (!mock) if (redirectUrl) mock = new RedirectedModule(rawId, resolvedId, mockUrl, new URL(this.resolveMockPath(cleanVersion(redirectUrl)), this.getBaseUrl()).toString());
|
|
1703
|
+
else mock = new AutomockedModule(rawId, resolvedId, mockUrl);
|
|
1704
|
+
if (mock.type === "manual") return await mock.resolve();
|
|
1705
|
+
if (mock.type === "automock" || mock.type === "autospy") {
|
|
1706
|
+
const url = new URL(`/@id/${resolvedId}`, this.getBaseUrl());
|
|
1707
|
+
const query = url.search ? `${url.search}&t=${now()}` : `?t=${now()}`;
|
|
1708
|
+
const moduleObject = await __vitePreload(() => import(
|
|
1709
|
+
/* @vite-ignore */
|
|
1710
|
+
`${url.pathname}${query}&mock=${mock.type}${url.hash}`
|
|
1711
|
+
), []);
|
|
1712
|
+
return this.mockObject(moduleObject, mock.type);
|
|
1713
|
+
}
|
|
1714
|
+
return __vitePreload(() => import(
|
|
1715
|
+
/* @vite-ignore */
|
|
1716
|
+
mock.redirect
|
|
1717
|
+
), []);
|
|
1718
|
+
}
|
|
1719
|
+
mockObject(object, mockExportsOrModuleType, moduleType) {
|
|
1720
|
+
let mockExports;
|
|
1721
|
+
if (mockExportsOrModuleType === "automock" || mockExportsOrModuleType === "autospy") {
|
|
1722
|
+
moduleType = mockExportsOrModuleType;
|
|
1723
|
+
mockExports = void 0;
|
|
1724
|
+
} else mockExports = mockExportsOrModuleType;
|
|
1725
|
+
moduleType ?? (moduleType = "automock");
|
|
1726
|
+
return mockObject({
|
|
1727
|
+
globalConstructors: {
|
|
1728
|
+
Object,
|
|
1729
|
+
Function,
|
|
1730
|
+
Array,
|
|
1731
|
+
Map,
|
|
1732
|
+
RegExp
|
|
1733
|
+
},
|
|
1734
|
+
createMockInstance: this.createMockInstance,
|
|
1735
|
+
type: moduleType
|
|
1736
|
+
}, object, mockExports);
|
|
1737
|
+
}
|
|
1738
|
+
getMockContext() {
|
|
1739
|
+
return { callstack: null };
|
|
1740
|
+
}
|
|
1741
|
+
queueMock(rawId, importer, factoryOrOptions) {
|
|
1742
|
+
const promise = this.rpc.resolveMock(rawId, importer, { mock: typeof factoryOrOptions === "function" ? "factory" : (factoryOrOptions === null || factoryOrOptions === void 0 ? void 0 : factoryOrOptions.spy) ? "spy" : "auto" }).then(async ({ redirectUrl, resolvedId, resolvedUrl, needsInterop, mockType }) => {
|
|
1743
|
+
const mockUrl = this.resolveMockPath(cleanVersion(resolvedUrl));
|
|
1744
|
+
this.mockedIds.add(resolvedId);
|
|
1745
|
+
const factory = typeof factoryOrOptions === "function" ? async () => {
|
|
1746
|
+
const data = await factoryOrOptions();
|
|
1747
|
+
return needsInterop ? { default: data } : data;
|
|
1748
|
+
} : void 0;
|
|
1749
|
+
const mockRedirect = typeof redirectUrl === "string" ? new URL(this.resolveMockPath(cleanVersion(redirectUrl)), this.getBaseUrl()).toString() : null;
|
|
1750
|
+
let module;
|
|
1751
|
+
if (mockType === "manual") module = this.registry.register("manual", rawId, resolvedId, mockUrl, factory);
|
|
1752
|
+
else if (mockType === "autospy") module = this.registry.register("autospy", rawId, resolvedId, mockUrl);
|
|
1753
|
+
else if (mockType === "redirect") module = this.registry.register("redirect", rawId, resolvedId, mockUrl, mockRedirect);
|
|
1754
|
+
else module = this.registry.register("automock", rawId, resolvedId, mockUrl);
|
|
1755
|
+
await this.interceptor.register(module);
|
|
1756
|
+
}).finally(() => {
|
|
1757
|
+
this.queue.delete(promise);
|
|
1758
|
+
});
|
|
1759
|
+
this.queue.add(promise);
|
|
1760
|
+
}
|
|
1761
|
+
queueUnmock(id, importer) {
|
|
1762
|
+
const promise = this.rpc.resolveId(id, importer).then(async (resolved) => {
|
|
1763
|
+
if (!resolved) return;
|
|
1764
|
+
const mockUrl = this.resolveMockPath(cleanVersion(resolved.url));
|
|
1765
|
+
this.mockedIds.add(resolved.id);
|
|
1766
|
+
this.registry.delete(mockUrl);
|
|
1767
|
+
await this.interceptor.delete(mockUrl);
|
|
1768
|
+
}).finally(() => {
|
|
1769
|
+
this.queue.delete(promise);
|
|
1770
|
+
});
|
|
1771
|
+
this.queue.add(promise);
|
|
1772
|
+
}
|
|
1773
|
+
wrapDynamicImport(moduleFactory) {
|
|
1774
|
+
if (typeof moduleFactory === "function") return new Promise((resolve, reject) => {
|
|
1775
|
+
this.prepare().finally(() => {
|
|
1776
|
+
moduleFactory().then(resolve, reject);
|
|
1777
|
+
});
|
|
1778
|
+
});
|
|
1779
|
+
return moduleFactory;
|
|
1780
|
+
}
|
|
1781
|
+
getMockedModuleById(id) {
|
|
1782
|
+
return this.registry.getById(id);
|
|
1783
|
+
}
|
|
1784
|
+
reset() {
|
|
1785
|
+
this.registry.clear();
|
|
1786
|
+
this.mockedIds.clear();
|
|
1787
|
+
this.queue.clear();
|
|
1788
|
+
}
|
|
1789
|
+
resolveMockPath(path) {
|
|
1790
|
+
const config = this.config;
|
|
1791
|
+
const fsRoot = join("/@fs/", config.root);
|
|
1792
|
+
if (path.startsWith(config.root)) return path.slice(config.root.length);
|
|
1793
|
+
if (path.startsWith(fsRoot)) return path.slice(fsRoot.length);
|
|
1794
|
+
return path;
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
var versionRegexp = /(\?|&)v=\w{8}/;
|
|
1798
|
+
function cleanVersion(url) {
|
|
1799
|
+
return url.replace(versionRegexp, "");
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
//#endregion
|
|
1803
|
+
//#region src/client/tester/mocker.ts
|
|
1804
|
+
var VitestBrowserClientMocker = class extends ModuleMocker {
|
|
1805
|
+
getMockContext() {
|
|
1806
|
+
return { callstack: null };
|
|
1807
|
+
}
|
|
1808
|
+
wrapDynamicImport(moduleFactory) {
|
|
1809
|
+
return (/* @__PURE__ */ getBrowserState()).wrapModule(moduleFactory);
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1812
|
+
|
|
1813
|
+
//#endregion
|
|
1814
|
+
//#region src/client/tester/mocker-interceptor.ts
|
|
1815
|
+
function createModuleMockerInterceptor() {
|
|
1816
|
+
return {
|
|
1817
|
+
async register(module) {
|
|
1818
|
+
const state = /* @__PURE__ */ getBrowserState();
|
|
1819
|
+
await rpc().registerMock(state.sessionId, module.toJSON());
|
|
1820
|
+
},
|
|
1821
|
+
async delete(id) {
|
|
1822
|
+
const state = /* @__PURE__ */ getBrowserState();
|
|
1823
|
+
await rpc().unregisterMock(state.sessionId, id);
|
|
1824
|
+
},
|
|
1825
|
+
async invalidate() {
|
|
1826
|
+
const state = /* @__PURE__ */ getBrowserState();
|
|
1827
|
+
await rpc().clearMocks(state.sessionId);
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
function rpc() {
|
|
1832
|
+
return (/* @__PURE__ */ getWorkerState()).rpc;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
//#endregion
|
|
1836
|
+
//#region src/client/tester/tester-utils.ts
|
|
1837
|
+
var ACTION_TRACE_COMMANDS = new Set([
|
|
1838
|
+
"__vitest_click",
|
|
1839
|
+
"__vitest_dblClick",
|
|
1840
|
+
"__vitest_tripleClick",
|
|
1841
|
+
"__vitest_wheel",
|
|
1842
|
+
"__vitest_type",
|
|
1843
|
+
"__vitest_clear",
|
|
1844
|
+
"__vitest_fill",
|
|
1845
|
+
"__vitest_selectOptions",
|
|
1846
|
+
"__vitest_dragAndDrop",
|
|
1847
|
+
"__vitest_hover",
|
|
1848
|
+
"__vitest_upload",
|
|
1849
|
+
"__vitest_tab",
|
|
1850
|
+
"__vitest_keyboard",
|
|
1851
|
+
"__vitest_takeScreenshot"
|
|
1852
|
+
]);
|
|
1853
|
+
var CommandsManager = class {
|
|
1854
|
+
constructor() {
|
|
1855
|
+
_defineProperty(this, "_listeners", []);
|
|
1856
|
+
}
|
|
1857
|
+
onCommand(listener) {
|
|
1858
|
+
this._listeners.push(listener);
|
|
1859
|
+
}
|
|
1860
|
+
async triggerCommand(command, args, clientError = /* @__PURE__ */ new Error("empty")) {
|
|
1861
|
+
var _state$current;
|
|
1862
|
+
const state = /* @__PURE__ */ getWorkerState();
|
|
1863
|
+
const rpc = state.rpc;
|
|
1864
|
+
const { sessionId, traces } = /* @__PURE__ */ getBrowserState();
|
|
1865
|
+
const filepath = state.filepath || ((_state$current = state.current) === null || _state$current === void 0 || (_state$current = _state$current.file) === null || _state$current === void 0 ? void 0 : _state$current.filepath);
|
|
1866
|
+
args = args.filter((arg) => arg !== void 0);
|
|
1867
|
+
const actionTraceGroupName = ACTION_TRACE_COMMANDS.has(command) ? `vitest:${command.slice(9)}` : void 0;
|
|
1868
|
+
const currentTest = (/* @__PURE__ */ getWorkerState()).current;
|
|
1869
|
+
const hasActiveTrace = !!actionTraceGroupName && !!currentTest && (/* @__PURE__ */ getBrowserState()).activeTraceTaskIds.has(currentTest.id);
|
|
1870
|
+
const hasActiveTraceView = !!actionTraceGroupName && !!currentTest && (/* @__PURE__ */ getBrowserState()).browserTraceAttempts.has(currentTest.id);
|
|
1871
|
+
if (this._listeners.length) await Promise.all(this._listeners.map((listener) => listener(command, args)));
|
|
1872
|
+
return traces.$("vitest.browser.tester.command", { attributes: {
|
|
1873
|
+
"vitest.browser.command": command,
|
|
1874
|
+
"code.file.path": filepath
|
|
1875
|
+
} }, async () => {
|
|
1876
|
+
if (hasActiveTrace) await rpc.triggerCommand(sessionId, "__vitest_groupTraceStart", filepath, [{
|
|
1877
|
+
name: actionTraceGroupName,
|
|
1878
|
+
stack: clientError.stack
|
|
1879
|
+
}]);
|
|
1880
|
+
let status = "pass";
|
|
1881
|
+
const traceRangeId = hasActiveTraceView ? createBrowserTraceRangeId() : void 0;
|
|
1882
|
+
const element = typeof args[0] === "object" && "selector" in args[0] && "locator" in args[0] ? args[0] : void 0;
|
|
1883
|
+
if (hasActiveTraceView) await recordBrowserTraceEntry(currentTest, {
|
|
1884
|
+
name: actionTraceGroupName,
|
|
1885
|
+
kind: "action",
|
|
1886
|
+
range: {
|
|
1887
|
+
id: traceRangeId,
|
|
1888
|
+
phase: "start"
|
|
1889
|
+
},
|
|
1890
|
+
element,
|
|
1891
|
+
stack: clientError.stack
|
|
1892
|
+
});
|
|
1893
|
+
try {
|
|
1894
|
+
return await rpc.triggerCommand(sessionId, command, filepath, args);
|
|
1895
|
+
} catch (err) {
|
|
1896
|
+
var _clientError$stack;
|
|
1897
|
+
status = "fail";
|
|
1898
|
+
clientError.message = err.message;
|
|
1899
|
+
clientError.name = err.name;
|
|
1900
|
+
clientError.stack = (_clientError$stack = clientError.stack) === null || _clientError$stack === void 0 ? void 0 : _clientError$stack.replace(clientError.message, err.message);
|
|
1901
|
+
throw clientError;
|
|
1902
|
+
} finally {
|
|
1903
|
+
if (hasActiveTraceView) await recordBrowserTraceEntry(currentTest, {
|
|
1904
|
+
name: actionTraceGroupName,
|
|
1905
|
+
kind: "action",
|
|
1906
|
+
range: {
|
|
1907
|
+
id: traceRangeId,
|
|
1908
|
+
phase: "end"
|
|
1909
|
+
},
|
|
1910
|
+
status,
|
|
1911
|
+
element,
|
|
1912
|
+
stack: clientError.stack
|
|
1913
|
+
});
|
|
1914
|
+
if (hasActiveTrace) await rpc.triggerCommand(sessionId, "__vitest_groupTraceEnd", filepath, []);
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1919
|
+
var provider = (/* @__PURE__ */ getBrowserState()).provider;
|
|
1920
|
+
|
|
1921
|
+
//#endregion
|
|
1922
|
+
//#region src/client/tester/tester.ts
|
|
1923
|
+
var debugVar = getConfig().env.VITEST_BROWSER_DEBUG;
|
|
1924
|
+
var debug = debugVar && debugVar !== "false" ? (...args) => {
|
|
1925
|
+
var _client$rpc$debug, _client$rpc;
|
|
1926
|
+
return (_client$rpc$debug = (_client$rpc = client.rpc).debug) === null || _client$rpc$debug === void 0 ? void 0 : _client$rpc$debug.call(_client$rpc, ...args.map(String));
|
|
1927
|
+
} : void 0;
|
|
1928
|
+
var otelConfig = getConfig().experimental.openTelemetry;
|
|
1929
|
+
var traces = new Traces({
|
|
1930
|
+
enabled: !!((otelConfig === null || otelConfig === void 0 ? void 0 : otelConfig.enabled) && (otelConfig === null || otelConfig === void 0 ? void 0 : otelConfig.browserSdkPath)),
|
|
1931
|
+
sdkPath: `/@fs/${otelConfig === null || otelConfig === void 0 ? void 0 : otelConfig.browserSdkPath}`
|
|
1932
|
+
});
|
|
1933
|
+
var rootTesterSpan;
|
|
1934
|
+
(/* @__PURE__ */ getBrowserState()).traces = traces;
|
|
1935
|
+
channel.addEventListener("message", async (e) => {
|
|
1936
|
+
await client.waitForConnection();
|
|
1937
|
+
const data = e.data;
|
|
1938
|
+
debug === null || debug === void 0 || debug("event from orchestrator", JSON.stringify(e.data));
|
|
1939
|
+
if (!isEvent(data)) {
|
|
1940
|
+
unhandledError(/* @__PURE__ */ new Error(`Unknown message: ${JSON.stringify(e.data)}`), "Unknown Iframe Message");
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1943
|
+
if (!("iframeId" in data) || data.iframeId !== (/* @__PURE__ */ getBrowserState()).iframeId) return;
|
|
1944
|
+
switch (data.event) {
|
|
1945
|
+
case "execute": {
|
|
1946
|
+
const { method, files, context, concurrencyId, workerId } = data;
|
|
1947
|
+
const state = /* @__PURE__ */ getWorkerState();
|
|
1948
|
+
const parsedContext = parse(context);
|
|
1949
|
+
state.ctx.concurrencyId = concurrencyId;
|
|
1950
|
+
state.ctx.workerId = workerId;
|
|
1951
|
+
state.ctx.providedContext = parsedContext;
|
|
1952
|
+
state.providedContext = parsedContext;
|
|
1953
|
+
state.metaEnv.VITEST_POOL_ID = String(concurrencyId);
|
|
1954
|
+
state.metaEnv.VITEST_WORKER_ID = String(workerId);
|
|
1955
|
+
if (method === "collect") await executeTests("collect", files).catch((err) => unhandledError(err, "Collect Error"));
|
|
1956
|
+
else await executeTests("run", files).catch((err) => unhandledError(err, "Run Error"));
|
|
1957
|
+
break;
|
|
1958
|
+
}
|
|
1959
|
+
case "cleanup":
|
|
1960
|
+
await cleanup().catch((err) => unhandledError(err, "Cleanup Error"));
|
|
1961
|
+
rootTesterSpan === null || rootTesterSpan === void 0 || rootTesterSpan.span.end();
|
|
1962
|
+
await traces.finish();
|
|
1963
|
+
break;
|
|
1964
|
+
case "prepare": {
|
|
1965
|
+
await traces.waitInit();
|
|
1966
|
+
const tracesContext = traces.getContextFromCarrier(data.otelCarrier);
|
|
1967
|
+
traces.recordInitSpan(tracesContext);
|
|
1968
|
+
rootTesterSpan = traces.startContextSpan(`vitest.browser.tester.run`, tracesContext);
|
|
1969
|
+
traces.bind(rootTesterSpan.context);
|
|
1970
|
+
await prepare(data).catch((err) => unhandledError(err, "Prepare Error"));
|
|
1971
|
+
break;
|
|
1972
|
+
}
|
|
1973
|
+
case "viewport:done":
|
|
1974
|
+
case "viewport:fail":
|
|
1975
|
+
case "viewport": break;
|
|
1976
|
+
default: unhandledError(/* @__PURE__ */ new Error(`Unknown event: ${data.event}`), "Unknown Event");
|
|
1977
|
+
}
|
|
1978
|
+
channel.postMessage({
|
|
1979
|
+
event: `response:${data.event}`,
|
|
1980
|
+
iframeId: (/* @__PURE__ */ getBrowserState()).iframeId
|
|
1981
|
+
});
|
|
1982
|
+
});
|
|
1983
|
+
var url = new URL(location.href);
|
|
1984
|
+
var iframeId = url.searchParams.get("iframeId");
|
|
1985
|
+
var commands = new CommandsManager();
|
|
1986
|
+
(/* @__PURE__ */ getBrowserState()).commands = commands;
|
|
1987
|
+
(/* @__PURE__ */ getBrowserState()).activeTraceTaskIds = /* @__PURE__ */ new Set();
|
|
1988
|
+
(/* @__PURE__ */ getBrowserState()).browserTraceAttempts = /* @__PURE__ */ new Map();
|
|
1989
|
+
(/* @__PURE__ */ getBrowserState()).iframeId = iframeId;
|
|
1990
|
+
registerPageMarkHandler((name, options) => page.mark(name, options));
|
|
1991
|
+
channel.postMessage({
|
|
1992
|
+
event: "ready",
|
|
1993
|
+
iframeId
|
|
1994
|
+
});
|
|
1995
|
+
var contextSwitched = false;
|
|
1996
|
+
async function prepareTestEnvironment(options) {
|
|
1997
|
+
debug === null || debug === void 0 || debug("trying to resolve the runner");
|
|
1998
|
+
const config = getConfig();
|
|
1999
|
+
const rpc = createSafeRpc(client);
|
|
2000
|
+
const state = /* @__PURE__ */ getWorkerState();
|
|
2001
|
+
state.metaEnv = __vitest_browser_import_meta_env_init__;
|
|
2002
|
+
state.onCancel = onCancel;
|
|
2003
|
+
state.ctx.rpc = rpc;
|
|
2004
|
+
state.rpc = rpc;
|
|
2005
|
+
const mocker = new VitestBrowserClientMocker(createModuleMockerInterceptor(), rpc, SpyModule.createMockInstance, { root: (/* @__PURE__ */ getBrowserState()).viteConfig.root });
|
|
2006
|
+
globalThis.__vitest_mocker__ = mocker;
|
|
2007
|
+
if (!config.disableConsoleIntercept) setupConsoleLogSpy();
|
|
2008
|
+
setupDialogsSpy();
|
|
2009
|
+
const runner = await initiateRunner(state, mocker, config);
|
|
2010
|
+
(/* @__PURE__ */ getBrowserState()).runner = runner;
|
|
2011
|
+
if (server.provider === "webdriverio") {
|
|
2012
|
+
let switchPromise = null;
|
|
2013
|
+
commands.onCommand(async () => {
|
|
2014
|
+
if (switchPromise) await switchPromise;
|
|
2015
|
+
if (!contextSwitched) {
|
|
2016
|
+
switchPromise = rpc.wdioSwitchContext("iframe").finally(() => {
|
|
2017
|
+
switchPromise = null;
|
|
2018
|
+
contextSwitched = true;
|
|
2019
|
+
});
|
|
2020
|
+
await switchPromise;
|
|
2021
|
+
}
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
state.durations.prepare = performance.now() - options.startTime;
|
|
2025
|
+
return {
|
|
2026
|
+
runner,
|
|
2027
|
+
config,
|
|
2028
|
+
state
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
var preparedData;
|
|
2032
|
+
async function executeTests(method, specifications) {
|
|
2033
|
+
if (!preparedData) throw new Error(`Data was not properly initialized. This is a bug in Vitest. Please, open a new issue with reproduction.`);
|
|
2034
|
+
debug === null || debug === void 0 || debug("runner resolved successfully");
|
|
2035
|
+
const { runner, state } = preparedData;
|
|
2036
|
+
state.ctx.files = specifications;
|
|
2037
|
+
runner.setMethod(method);
|
|
2038
|
+
const version = url.searchParams.get("browserv") || "";
|
|
2039
|
+
specifications.forEach(({ filepath }) => {
|
|
2040
|
+
const currentVersion = browserHashMap.get(filepath);
|
|
2041
|
+
if (!currentVersion || currentVersion[1] !== version) browserHashMap.set(filepath, version);
|
|
2042
|
+
});
|
|
2043
|
+
for (const file of specifications) {
|
|
2044
|
+
state.filepath = file.filepath;
|
|
2045
|
+
debug === null || debug === void 0 || debug("running test file", file.filepath);
|
|
2046
|
+
await traces.$(`vitest.test.runner.${method}.module`, { attributes: { "code.file.path": file.filepath } }, async () => {
|
|
2047
|
+
if (method === "run") await startTests([file], runner);
|
|
2048
|
+
else await collectTests([file], runner);
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
async function prepare(options) {
|
|
2053
|
+
preparedData = await prepareTestEnvironment(options);
|
|
2054
|
+
debug === null || debug === void 0 || debug("runner resolved successfully");
|
|
2055
|
+
const { config, state } = preparedData;
|
|
2056
|
+
state.durations.prepare = performance.now() - state.durations.prepare;
|
|
2057
|
+
debug === null || debug === void 0 || debug("prepare time", state.durations.prepare, "ms");
|
|
2058
|
+
await Promise.all([
|
|
2059
|
+
setupCommonEnv(config),
|
|
2060
|
+
startCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.browser.isolate }),
|
|
2061
|
+
(async () => {
|
|
2062
|
+
const VitestIndex = await __vitePreload(() => import("vitest"), []);
|
|
2063
|
+
Object.defineProperty(window, "__vitest_index__", {
|
|
2064
|
+
value: VitestIndex,
|
|
2065
|
+
enumerable: false
|
|
2066
|
+
});
|
|
2067
|
+
})()
|
|
2068
|
+
]);
|
|
2069
|
+
if (!config.browser.trackUnhandledErrors) (/* @__PURE__ */ getBrowserState()).disposeExceptionTracker();
|
|
2070
|
+
}
|
|
2071
|
+
async function cleanup() {
|
|
2072
|
+
const state = /* @__PURE__ */ getWorkerState();
|
|
2073
|
+
const config = getConfig();
|
|
2074
|
+
const rpc = state.rpc;
|
|
2075
|
+
const cleanupSymbol = Symbol.for("vitest:component-cleanup");
|
|
2076
|
+
if (cleanupSymbol in page) try {
|
|
2077
|
+
await page[cleanupSymbol]();
|
|
2078
|
+
} catch (error) {
|
|
2079
|
+
await unhandledError(error, "Cleanup Error");
|
|
2080
|
+
}
|
|
2081
|
+
await userEvent.cleanup().catch((error) => unhandledError(error, "Cleanup Error"));
|
|
2082
|
+
await Promise.all((/* @__PURE__ */ getBrowserState()).cleanups.map((fn) => fn())).catch((error) => unhandledError(error, "Cleanup Error"));
|
|
2083
|
+
if (contextSwitched) await rpc.wdioSwitchContext("parent").catch((error) => unhandledError(error, "Cleanup Error"));
|
|
2084
|
+
await stopCoverageInsideWorker(config.coverage, moduleRunner, { isolate: config.browser.isolate }).catch((error) => {
|
|
2085
|
+
return unhandledError(error, "Coverage Error");
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
function unhandledError(e, type) {
|
|
2089
|
+
return client.rpc.onUnhandledError({
|
|
2090
|
+
name: e.name,
|
|
2091
|
+
message: e.message,
|
|
2092
|
+
stack: e.stack
|
|
2093
|
+
}, type).catch(() => {});
|
|
2094
|
+
}
|
|
2095
|
+
function isEvent(data) {
|
|
2096
|
+
return typeof data === "object" && !!data && "event" in data;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
//#endregion
|