@vitest/browser 1.6.0 → 2.0.0-beta.10
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/context.d.ts +127 -0
- package/dist/client/.vite/manifest.json +24 -0
- package/dist/client/__vitest__/assets/index-BMAciMM5.js +51 -0
- package/dist/client/__vitest__/assets/index-BcFb8Rbc.css +1 -0
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/orchestrator-BCpOi5ot.js +301 -0
- package/dist/client/__vitest_browser__/{rpc-slP7oy1q.js → rpc-CImfI7bO.js} +288 -392
- package/dist/client/__vitest_browser__/{tester-RmfypyZ0.js → tester-e70VCOgC.js} +351 -44
- package/dist/client/esm-client-injector.js +14 -28
- package/dist/client/{index.html → orchestrator.html} +8 -7
- package/dist/client/tester.html +4 -3
- package/dist/context.js +87 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +406 -268
- package/dist/providers.js +12 -112
- package/dist/webdriver-CXn0ag9T.js +170 -0
- package/package.json +23 -13
- package/providers/playwright.d.ts +14 -2
- package/providers/webdriverio.d.ts +4 -0
- package/providers.d.ts +5 -5
- package/dist/client/__vitest__/assets/index-TpLatVz2.js +0 -35
- package/dist/client/__vitest__/assets/index-fUmMsp0O.css +0 -1
- package/dist/client/__vitest_browser__/main-v2hiOVax.js +0 -102
|
@@ -10,7 +10,10 @@ var __publicField = (obj, key, value) => {
|
|
|
10
10
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
11
11
|
return value;
|
|
12
12
|
};
|
|
13
|
-
import { i as importId,
|
|
13
|
+
import { i as importId, b as getConfig, e as rpc$1, _ as __vitePreload, a as channel, f as extname, g as getBrowserState, w as waitForChannel, j as join, c as client, l as loadSafeRpc, o as onCancel } from "./rpc-CImfI7bO.js";
|
|
14
|
+
function getType(value) {
|
|
15
|
+
return Object.prototype.toString.apply(value).slice(8, -1);
|
|
16
|
+
}
|
|
14
17
|
function showPopupWarning(name, value, defaultValue) {
|
|
15
18
|
return (...params) => {
|
|
16
19
|
const formatedParams = params.map((p) => JSON.stringify(p)).join(", ");
|
|
@@ -42,14 +45,17 @@ async function setupConsoleLogSpy() {
|
|
|
42
45
|
return format(input);
|
|
43
46
|
};
|
|
44
47
|
const processLog = (args) => args.map(formatInput).join(" ");
|
|
45
|
-
const sendLog = (type, content) => {
|
|
46
|
-
var _a, _b;
|
|
48
|
+
const sendLog = (type, content, disableStack) => {
|
|
49
|
+
var _a, _b, _c;
|
|
47
50
|
if (content.startsWith("[vite]"))
|
|
48
51
|
return;
|
|
49
52
|
const unknownTestId = "__vitest__unknown_test__";
|
|
50
53
|
const taskId = ((_b = (_a = globalThis.__vitest_worker__) == null ? void 0 : _a.current) == null ? void 0 : _b.id) ?? unknownTestId;
|
|
54
|
+
const origin = getConfig().printConsoleTrace && !disableStack ? (_c = new Error("STACK_TRACE").stack) == null ? void 0 : _c.split("\n").slice(1).join("\n") : void 0;
|
|
51
55
|
rpc$1().sendLog({
|
|
56
|
+
origin,
|
|
52
57
|
content,
|
|
58
|
+
browser: true,
|
|
53
59
|
time: Date$1.now(),
|
|
54
60
|
taskId,
|
|
55
61
|
type,
|
|
@@ -78,18 +84,19 @@ async function setupConsoleLogSpy() {
|
|
|
78
84
|
return dirxml(...args);
|
|
79
85
|
};
|
|
80
86
|
console$1.trace = (...args) => {
|
|
87
|
+
var _a;
|
|
81
88
|
const content = processLog(args);
|
|
82
|
-
const error2 = new Error("Trace");
|
|
83
|
-
const stack = (error2.stack || "").split("\n").slice(2).join("\n");
|
|
84
|
-
sendLog("
|
|
85
|
-
${stack}
|
|
89
|
+
const error2 = new Error("$$Trace");
|
|
90
|
+
const stack = (error2.stack || "").split("\n").slice(((_a = error2.stack) == null ? void 0 : _a.includes("$$Trace")) ? 2 : 1).join("\n");
|
|
91
|
+
sendLog("stderr", `${content}
|
|
92
|
+
${stack}`, true);
|
|
86
93
|
return trace(...args);
|
|
87
94
|
};
|
|
88
95
|
const timeLabels = {};
|
|
89
96
|
console$1.time = (label = "default") => {
|
|
90
|
-
const
|
|
97
|
+
const now2 = performance.now();
|
|
91
98
|
time(label);
|
|
92
|
-
timeLabels[label] =
|
|
99
|
+
timeLabels[label] = now2;
|
|
93
100
|
};
|
|
94
101
|
console$1.timeLog = (label = "default") => {
|
|
95
102
|
timeLog(label);
|
|
@@ -148,7 +155,7 @@ function rpc() {
|
|
|
148
155
|
return globalThis.__vitest_worker__.rpc;
|
|
149
156
|
}
|
|
150
157
|
const browserHashMap = /* @__PURE__ */ new Map();
|
|
151
|
-
function createBrowserRunner(runnerClass, coverageModule) {
|
|
158
|
+
function createBrowserRunner(runnerClass, mocker, state, coverageModule) {
|
|
152
159
|
return class BrowserTestRunner extends runnerClass {
|
|
153
160
|
constructor(options) {
|
|
154
161
|
super(options.config);
|
|
@@ -168,8 +175,11 @@ function createBrowserRunner(runnerClass, coverageModule) {
|
|
|
168
175
|
});
|
|
169
176
|
__publicField(this, "onAfterRunFiles", async (files) => {
|
|
170
177
|
var _a, _b;
|
|
171
|
-
|
|
172
|
-
|
|
178
|
+
const [coverage] = await Promise.all([
|
|
179
|
+
(_a = coverageModule == null ? void 0 : coverageModule.takeCoverage) == null ? void 0 : _a.call(coverageModule),
|
|
180
|
+
mocker.invalidate(),
|
|
181
|
+
(_b = super.onAfterRunFiles) == null ? void 0 : _b.call(this, files)
|
|
182
|
+
]);
|
|
173
183
|
if (coverage) {
|
|
174
184
|
await rpc$1().onAfterSuiteRun({
|
|
175
185
|
coverage,
|
|
@@ -179,6 +189,12 @@ function createBrowserRunner(runnerClass, coverageModule) {
|
|
|
179
189
|
}
|
|
180
190
|
});
|
|
181
191
|
__publicField(this, "onCollected", async (files) => {
|
|
192
|
+
files.forEach((file) => {
|
|
193
|
+
file.prepareDuration = state.durations.prepare;
|
|
194
|
+
file.environmentLoad = state.durations.environment;
|
|
195
|
+
state.durations.prepare = 0;
|
|
196
|
+
state.durations.environment = 0;
|
|
197
|
+
});
|
|
182
198
|
if (this.config.includeTaskLocation) {
|
|
183
199
|
try {
|
|
184
200
|
await updateFilesLocations(files);
|
|
@@ -196,8 +212,7 @@ function createBrowserRunner(runnerClass, coverageModule) {
|
|
|
196
212
|
hash = Date.now().toString();
|
|
197
213
|
this.hashMap.set(filepath, [false, hash]);
|
|
198
214
|
}
|
|
199
|
-
const
|
|
200
|
-
const prefix = `${base}${/^\w:/.test(filepath) ? "@fs/" : ""}`;
|
|
215
|
+
const prefix = `/${/^\w:/.test(filepath) ? "@fs/" : ""}`;
|
|
201
216
|
const query = `${test ? "browserv" : "v"}=${hash}`;
|
|
202
217
|
const importpath = `${prefix}${filepath}?${query}`.replace(/\/+/g, "/");
|
|
203
218
|
await __vitePreload(() => import(importpath), true ? __vite__mapDeps([]) : void 0);
|
|
@@ -207,10 +222,9 @@ function createBrowserRunner(runnerClass, coverageModule) {
|
|
|
207
222
|
};
|
|
208
223
|
}
|
|
209
224
|
let cachedRunner = null;
|
|
210
|
-
async function initiateRunner() {
|
|
225
|
+
async function initiateRunner(state, mocker, config) {
|
|
211
226
|
if (cachedRunner)
|
|
212
227
|
return cachedRunner;
|
|
213
|
-
const config = getConfig();
|
|
214
228
|
const [
|
|
215
229
|
{ VitestTestRunner, NodeBenchmarkRunner },
|
|
216
230
|
{ takeCoverageInsideWorker, loadDiffConfig, loadSnapshotSerializers }
|
|
@@ -219,7 +233,7 @@ async function initiateRunner() {
|
|
|
219
233
|
importId("vitest/browser")
|
|
220
234
|
]);
|
|
221
235
|
const runnerClass = config.mode === "test" ? VitestTestRunner : NodeBenchmarkRunner;
|
|
222
|
-
const BrowserRunner = createBrowserRunner(runnerClass, {
|
|
236
|
+
const BrowserRunner = createBrowserRunner(runnerClass, mocker, state, {
|
|
223
237
|
takeCoverage: () => takeCoverageInsideWorker(config.coverage, { executeId: importId })
|
|
224
238
|
});
|
|
225
239
|
if (!config.snapshotOptions.snapshotEnvironment)
|
|
@@ -258,25 +272,293 @@ async function updateFilesLocations(files) {
|
|
|
258
272
|
});
|
|
259
273
|
await Promise.all(promises);
|
|
260
274
|
}
|
|
261
|
-
|
|
262
|
-
throw new Error(`[vitest] ${name} is not implemented in browser environment yet.`);
|
|
263
|
-
}
|
|
275
|
+
const now = Date.now;
|
|
264
276
|
class VitestBrowserClientMocker {
|
|
265
|
-
|
|
266
|
-
|
|
277
|
+
constructor() {
|
|
278
|
+
__publicField(this, "queue", /* @__PURE__ */ new Set());
|
|
279
|
+
__publicField(this, "mocks", {});
|
|
280
|
+
__publicField(this, "mockObjects", {});
|
|
281
|
+
__publicField(this, "factories", {});
|
|
282
|
+
__publicField(this, "ids", /* @__PURE__ */ new Set());
|
|
283
|
+
__publicField(this, "spyModule");
|
|
284
|
+
}
|
|
285
|
+
setupWorker() {
|
|
286
|
+
channel.addEventListener("message", async (e) => {
|
|
287
|
+
if (e.data.type === "mock-factory:request") {
|
|
288
|
+
try {
|
|
289
|
+
const module = await this.resolve(e.data.id);
|
|
290
|
+
const exports = Object.keys(module);
|
|
291
|
+
channel.postMessage({
|
|
292
|
+
type: "mock-factory:response",
|
|
293
|
+
exports
|
|
294
|
+
});
|
|
295
|
+
} catch (err) {
|
|
296
|
+
const { processError } = await importId("vitest/browser");
|
|
297
|
+
channel.postMessage({
|
|
298
|
+
type: "mock-factory:error",
|
|
299
|
+
error: processError(err)
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
setSpyModule(mod) {
|
|
306
|
+
this.spyModule = mod;
|
|
307
|
+
}
|
|
308
|
+
async importActual(id, importer) {
|
|
309
|
+
const resolved = await rpc$1().resolveId(id, importer);
|
|
310
|
+
if (resolved == null)
|
|
311
|
+
throw new Error(`[vitest] Cannot resolve ${id} imported from ${importer}`);
|
|
312
|
+
const ext = extname(resolved.id);
|
|
313
|
+
const url2 = new URL(`/@id/${resolved.id}`, location.href);
|
|
314
|
+
const query = `_vitest_original&ext.${ext}`;
|
|
315
|
+
const actualUrl = `${url2.pathname}${url2.search ? `${url2.search}&${query}` : `?${query}`}${url2.hash}`;
|
|
316
|
+
return getBrowserState().wrapModule(() => __vitePreload(() => import(actualUrl), true ? __vite__mapDeps([]) : void 0));
|
|
317
|
+
}
|
|
318
|
+
async importMock(rawId, importer) {
|
|
319
|
+
await this.prepare();
|
|
320
|
+
const { resolvedId, type, mockPath } = await rpc$1().resolveMock(rawId, importer, false);
|
|
321
|
+
const factoryReturn = this.get(resolvedId);
|
|
322
|
+
if (factoryReturn)
|
|
323
|
+
return factoryReturn;
|
|
324
|
+
if (this.factories[resolvedId])
|
|
325
|
+
return await this.resolve(resolvedId);
|
|
326
|
+
if (type === "redirect") {
|
|
327
|
+
const url22 = new URL(`/@id/${mockPath}`, location.href);
|
|
328
|
+
return __vitePreload(() => import(url22.toString()), true ? __vite__mapDeps([]) : void 0);
|
|
329
|
+
}
|
|
330
|
+
const url2 = new URL(`/@id/${resolvedId}`, location.href);
|
|
331
|
+
const query = url2.search ? `${url2.search}&t=${now()}` : `?t=${now()}`;
|
|
332
|
+
const moduleObject = await __vitePreload(() => import(`${url2.pathname}${query}${url2.hash}`), true ? __vite__mapDeps([]) : void 0);
|
|
333
|
+
return this.mockObject(moduleObject);
|
|
334
|
+
}
|
|
335
|
+
getMockContext() {
|
|
336
|
+
return { callstack: null };
|
|
337
|
+
}
|
|
338
|
+
get(id) {
|
|
339
|
+
return this.mockObjects[id];
|
|
340
|
+
}
|
|
341
|
+
async invalidate() {
|
|
342
|
+
const ids = Array.from(this.ids);
|
|
343
|
+
if (!ids.length)
|
|
344
|
+
return;
|
|
345
|
+
await rpc$1().invalidate(ids);
|
|
346
|
+
channel.postMessage({ type: "mock:invalidate" });
|
|
347
|
+
this.ids.clear();
|
|
348
|
+
this.mocks = {};
|
|
349
|
+
this.mockObjects = {};
|
|
350
|
+
this.factories = {};
|
|
351
|
+
}
|
|
352
|
+
async resolve(id) {
|
|
353
|
+
const factory = this.factories[id];
|
|
354
|
+
if (!factory)
|
|
355
|
+
throw new Error(`Cannot resolve ${id} mock: no factory provided`);
|
|
356
|
+
try {
|
|
357
|
+
this.mockObjects[id] = await factory();
|
|
358
|
+
return this.mockObjects[id];
|
|
359
|
+
} catch (err) {
|
|
360
|
+
const vitestError = new Error(
|
|
361
|
+
'[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'
|
|
362
|
+
);
|
|
363
|
+
vitestError.cause = err;
|
|
364
|
+
throw vitestError;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
queueMock(id, importer, factory) {
|
|
368
|
+
const promise = rpc$1().resolveMock(id, importer, !!factory).then(async ({ mockPath, resolvedId }) => {
|
|
369
|
+
this.ids.add(resolvedId);
|
|
370
|
+
const urlPaths = resolveMockPaths(resolvedId);
|
|
371
|
+
const resolvedMock = typeof mockPath === "string" ? new URL(resolvedMockedPath(mockPath), location.href).toString() : mockPath;
|
|
372
|
+
urlPaths.forEach((url2) => {
|
|
373
|
+
this.mocks[url2] = resolvedMock;
|
|
374
|
+
this.factories[url2] = factory;
|
|
375
|
+
});
|
|
376
|
+
channel.postMessage({
|
|
377
|
+
type: "mock",
|
|
378
|
+
paths: urlPaths,
|
|
379
|
+
mock: resolvedMock
|
|
380
|
+
});
|
|
381
|
+
await waitForChannel("mock:done");
|
|
382
|
+
}).finally(() => {
|
|
383
|
+
this.queue.delete(promise);
|
|
384
|
+
});
|
|
385
|
+
this.queue.add(promise);
|
|
386
|
+
}
|
|
387
|
+
queueUnmock(id, importer) {
|
|
388
|
+
const promise = rpc$1().resolveId(id, importer).then(async (resolved) => {
|
|
389
|
+
if (!resolved)
|
|
390
|
+
return;
|
|
391
|
+
this.ids.delete(resolved.id);
|
|
392
|
+
const urlPaths = resolveMockPaths(resolved.id);
|
|
393
|
+
urlPaths.forEach((url2) => {
|
|
394
|
+
delete this.mocks[url2];
|
|
395
|
+
delete this.factories[url2];
|
|
396
|
+
delete this.mockObjects[url2];
|
|
397
|
+
});
|
|
398
|
+
channel.postMessage({
|
|
399
|
+
type: "unmock",
|
|
400
|
+
paths: urlPaths
|
|
401
|
+
});
|
|
402
|
+
await waitForChannel("unmock:done");
|
|
403
|
+
}).finally(() => {
|
|
404
|
+
this.queue.delete(promise);
|
|
405
|
+
});
|
|
406
|
+
this.queue.add(promise);
|
|
267
407
|
}
|
|
268
|
-
|
|
269
|
-
|
|
408
|
+
async prepare() {
|
|
409
|
+
if (!this.queue.size)
|
|
410
|
+
return;
|
|
411
|
+
await Promise.all([
|
|
412
|
+
...this.queue.values()
|
|
413
|
+
]);
|
|
414
|
+
}
|
|
415
|
+
// TODO: move this logic into a util(?)
|
|
416
|
+
mockObject(object, mockExports = {}) {
|
|
417
|
+
const finalizers = new Array();
|
|
418
|
+
const refs = new RefTracker();
|
|
419
|
+
const define = (container, key, value) => {
|
|
420
|
+
try {
|
|
421
|
+
container[key] = value;
|
|
422
|
+
return true;
|
|
423
|
+
} catch {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
const mockPropertiesOf = (container, newContainer) => {
|
|
428
|
+
const containerType = /* @__PURE__ */ getType(container);
|
|
429
|
+
const isModule = containerType === "Module" || !!container.__esModule;
|
|
430
|
+
for (const { key: property, descriptor } of getAllMockableProperties(container, isModule)) {
|
|
431
|
+
if (!isModule && descriptor.get) {
|
|
432
|
+
try {
|
|
433
|
+
Object.defineProperty(newContainer, property, descriptor);
|
|
434
|
+
} catch (error) {
|
|
435
|
+
}
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (isSpecialProp(property, containerType))
|
|
439
|
+
continue;
|
|
440
|
+
const value = container[property];
|
|
441
|
+
const refId = refs.getId(value);
|
|
442
|
+
if (refId !== void 0) {
|
|
443
|
+
finalizers.push(() => define(newContainer, property, refs.getMockedValue(refId)));
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
const type = /* @__PURE__ */ getType(value);
|
|
447
|
+
if (Array.isArray(value)) {
|
|
448
|
+
define(newContainer, property, []);
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
const isFunction = type.includes("Function") && typeof value === "function";
|
|
452
|
+
if ((!isFunction || value.__isMockFunction) && type !== "Object" && type !== "Module") {
|
|
453
|
+
define(newContainer, property, value);
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (!define(newContainer, property, isFunction ? value : {}))
|
|
457
|
+
continue;
|
|
458
|
+
if (isFunction) {
|
|
459
|
+
let mockFunction = function() {
|
|
460
|
+
if (this instanceof newContainer[property]) {
|
|
461
|
+
for (const { key, descriptor: descriptor2 } of getAllMockableProperties(this, false)) {
|
|
462
|
+
if (descriptor2.get)
|
|
463
|
+
continue;
|
|
464
|
+
const value2 = this[key];
|
|
465
|
+
const type2 = /* @__PURE__ */ getType(value2);
|
|
466
|
+
const isFunction2 = type2.includes("Function") && typeof value2 === "function";
|
|
467
|
+
if (isFunction2) {
|
|
468
|
+
const original = this[key];
|
|
469
|
+
const mock2 = spyModule.spyOn(this, key).mockImplementation(original);
|
|
470
|
+
mock2.mockRestore = () => {
|
|
471
|
+
mock2.mockReset();
|
|
472
|
+
mock2.mockImplementation(original);
|
|
473
|
+
return mock2;
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
const spyModule = this.spyModule;
|
|
480
|
+
if (!spyModule)
|
|
481
|
+
throw new Error("[vitest] `spyModule` is not defined. This is Vitest error. Please open a new issue with reproduction.");
|
|
482
|
+
const mock = spyModule.spyOn(newContainer, property).mockImplementation(mockFunction);
|
|
483
|
+
mock.mockRestore = () => {
|
|
484
|
+
mock.mockReset();
|
|
485
|
+
mock.mockImplementation(mockFunction);
|
|
486
|
+
return mock;
|
|
487
|
+
};
|
|
488
|
+
Object.defineProperty(newContainer[property], "length", { value: 0 });
|
|
489
|
+
}
|
|
490
|
+
refs.track(value, newContainer[property]);
|
|
491
|
+
mockPropertiesOf(value, newContainer[property]);
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
const mockedObject = mockExports;
|
|
495
|
+
mockPropertiesOf(object, mockedObject);
|
|
496
|
+
for (const finalizer of finalizers)
|
|
497
|
+
finalizer();
|
|
498
|
+
return mockedObject;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function isSpecialProp(prop, parentType) {
|
|
502
|
+
return parentType.includes("Function") && typeof prop === "string" && ["arguments", "callee", "caller", "length", "name"].includes(prop);
|
|
503
|
+
}
|
|
504
|
+
class RefTracker {
|
|
505
|
+
constructor() {
|
|
506
|
+
__publicField(this, "idMap", /* @__PURE__ */ new Map());
|
|
507
|
+
__publicField(this, "mockedValueMap", /* @__PURE__ */ new Map());
|
|
270
508
|
}
|
|
271
|
-
|
|
272
|
-
|
|
509
|
+
getId(value) {
|
|
510
|
+
return this.idMap.get(value);
|
|
273
511
|
}
|
|
274
|
-
|
|
275
|
-
|
|
512
|
+
getMockedValue(id) {
|
|
513
|
+
return this.mockedValueMap.get(id);
|
|
276
514
|
}
|
|
277
|
-
|
|
515
|
+
track(originalValue, mockedValue) {
|
|
516
|
+
const newId = this.idMap.size;
|
|
517
|
+
this.idMap.set(originalValue, newId);
|
|
518
|
+
this.mockedValueMap.set(newId, mockedValue);
|
|
519
|
+
return newId;
|
|
278
520
|
}
|
|
279
521
|
}
|
|
522
|
+
function getAllMockableProperties(obj, isModule) {
|
|
523
|
+
const allProps = /* @__PURE__ */ new Map();
|
|
524
|
+
let curr = obj;
|
|
525
|
+
do {
|
|
526
|
+
if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype)
|
|
527
|
+
break;
|
|
528
|
+
collectOwnProperties(curr, (key) => {
|
|
529
|
+
const descriptor = Object.getOwnPropertyDescriptor(curr, key);
|
|
530
|
+
if (descriptor)
|
|
531
|
+
allProps.set(key, { key, descriptor });
|
|
532
|
+
});
|
|
533
|
+
} while (curr = Object.getPrototypeOf(curr));
|
|
534
|
+
if (isModule && !allProps.has("default") && "default" in obj) {
|
|
535
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, "default");
|
|
536
|
+
if (descriptor)
|
|
537
|
+
allProps.set("default", { key: "default", descriptor });
|
|
538
|
+
}
|
|
539
|
+
return Array.from(allProps.values());
|
|
540
|
+
}
|
|
541
|
+
function collectOwnProperties(obj, collector) {
|
|
542
|
+
const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
|
|
543
|
+
Object.getOwnPropertyNames(obj).forEach(collect);
|
|
544
|
+
Object.getOwnPropertySymbols(obj).forEach(collect);
|
|
545
|
+
}
|
|
546
|
+
function resolvedMockedPath(path) {
|
|
547
|
+
const config = getBrowserState().viteConfig;
|
|
548
|
+
if (path.startsWith(config.root))
|
|
549
|
+
return path.slice(config.root.length);
|
|
550
|
+
return path;
|
|
551
|
+
}
|
|
552
|
+
function resolveMockPaths(path) {
|
|
553
|
+
const config = getBrowserState().viteConfig;
|
|
554
|
+
const fsRoot = join("/@fs/", config.root);
|
|
555
|
+
const paths = [path, join("/@fs/", path)];
|
|
556
|
+
if (path.startsWith(config.root))
|
|
557
|
+
paths.push(path.slice(config.root.length));
|
|
558
|
+
if (path.startsWith(fsRoot))
|
|
559
|
+
paths.push(path.slice(fsRoot.length));
|
|
560
|
+
return paths;
|
|
561
|
+
}
|
|
280
562
|
function on(event, listener) {
|
|
281
563
|
window.addEventListener(event, listener);
|
|
282
564
|
return () => window.removeEventListener(event, listener);
|
|
@@ -291,7 +573,13 @@ function serializeError(unhandledError) {
|
|
|
291
573
|
}
|
|
292
574
|
async function defaultErrorReport(type, unhandledError) {
|
|
293
575
|
const error = serializeError(unhandledError);
|
|
294
|
-
channel.postMessage({
|
|
576
|
+
channel.postMessage({
|
|
577
|
+
type: "error",
|
|
578
|
+
files: getBrowserState().runningFiles,
|
|
579
|
+
error,
|
|
580
|
+
errorType: type,
|
|
581
|
+
id: getBrowserState().iframeId
|
|
582
|
+
});
|
|
295
583
|
}
|
|
296
584
|
function catchWindowErrors(cb) {
|
|
297
585
|
let userErrorListenerCount = 0;
|
|
@@ -347,9 +635,16 @@ async function tryCall(fn) {
|
|
|
347
635
|
try {
|
|
348
636
|
return await fn();
|
|
349
637
|
} catch (err) {
|
|
350
|
-
const
|
|
351
|
-
const canTry = !reloadStart ||
|
|
352
|
-
|
|
638
|
+
const now2 = Date.now();
|
|
639
|
+
const canTry = !reloadStart || now2 - Number(reloadStart) < 3e4;
|
|
640
|
+
const errorStack = (() => {
|
|
641
|
+
var _a;
|
|
642
|
+
if (!err)
|
|
643
|
+
return null;
|
|
644
|
+
return ((_a = err.stack) == null ? void 0 : _a.includes(err.message)) ? err.stack : `${err.message}
|
|
645
|
+
${err.stack}`;
|
|
646
|
+
})();
|
|
647
|
+
debug("failed to resolve runner", "trying again:", canTry, "time is", now2, "reloadStart is", reloadStart, ":\n", errorStack);
|
|
353
648
|
if (!canTry) {
|
|
354
649
|
const error = serializeError(new Error("Vitest failed to load its runner after 30 seconds."));
|
|
355
650
|
error.cause = serializeError(err);
|
|
@@ -358,7 +653,7 @@ async function tryCall(fn) {
|
|
|
358
653
|
}
|
|
359
654
|
if (!reloadStart) {
|
|
360
655
|
const newUrl = new URL(location.href);
|
|
361
|
-
newUrl.searchParams.set("__reloadStart",
|
|
656
|
+
newUrl.searchParams.set("__reloadStart", now2.toString());
|
|
362
657
|
debug("set the new url because reload start is not set to", newUrl);
|
|
363
658
|
location.href = newUrl.toString();
|
|
364
659
|
} else {
|
|
@@ -367,14 +662,13 @@ async function tryCall(fn) {
|
|
|
367
662
|
}
|
|
368
663
|
}
|
|
369
664
|
}
|
|
665
|
+
const startTime = performance.now();
|
|
370
666
|
async function prepareTestEnvironment(files) {
|
|
371
667
|
debug("trying to resolve runner", `${reloadStart}`);
|
|
372
668
|
const config = getConfig();
|
|
373
|
-
const viteClientPath =
|
|
669
|
+
const viteClientPath = `/@vite/client`;
|
|
374
670
|
await __vitePreload(() => import(viteClientPath), true ? __vite__mapDeps([]) : void 0);
|
|
375
671
|
const rpc2 = await loadSafeRpc(client);
|
|
376
|
-
stopErrorHandler();
|
|
377
|
-
registerUnexpectedErrors(rpc2);
|
|
378
672
|
const providedContext = await client.rpc.getProvidedContext();
|
|
379
673
|
const state = {
|
|
380
674
|
ctx: {
|
|
@@ -382,7 +676,7 @@ async function prepareTestEnvironment(files) {
|
|
|
382
676
|
worker: "./browser.js",
|
|
383
677
|
workerId: 1,
|
|
384
678
|
config,
|
|
385
|
-
projectName: config.name,
|
|
679
|
+
projectName: config.name || "",
|
|
386
680
|
files,
|
|
387
681
|
environment: {
|
|
388
682
|
name: "browser",
|
|
@@ -405,27 +699,34 @@ async function prepareTestEnvironment(files) {
|
|
|
405
699
|
rpc: rpc2,
|
|
406
700
|
durations: {
|
|
407
701
|
environment: 0,
|
|
408
|
-
prepare:
|
|
702
|
+
prepare: startTime
|
|
409
703
|
},
|
|
410
704
|
providedContext
|
|
411
705
|
};
|
|
412
706
|
globalThis.__vitest_browser__ = true;
|
|
413
707
|
globalThis.__vitest_worker__ = state;
|
|
414
|
-
|
|
708
|
+
const mocker = new VitestBrowserClientMocker();
|
|
709
|
+
globalThis.__vitest_mocker__ = mocker;
|
|
415
710
|
await setupConsoleLogSpy();
|
|
416
711
|
setupDialogsSpy();
|
|
417
|
-
const
|
|
418
|
-
const version = url.searchParams.get("browserv") || "0";
|
|
712
|
+
const version = url.searchParams.get("browserv") || "";
|
|
419
713
|
files.forEach((filename) => {
|
|
420
714
|
const currentVersion = browserHashMap.get(filename);
|
|
421
715
|
if (!currentVersion || currentVersion[1] !== version)
|
|
422
716
|
browserHashMap.set(filename, [true, version]);
|
|
423
717
|
});
|
|
424
|
-
const runner = await
|
|
718
|
+
const [runner, { startTests, setupCommonEnv, SpyModule }] = await Promise.all([
|
|
719
|
+
initiateRunner(state, mocker, config),
|
|
720
|
+
importId("vitest/browser")
|
|
721
|
+
]);
|
|
722
|
+
mocker.setSpyModule(SpyModule);
|
|
723
|
+
mocker.setupWorker();
|
|
425
724
|
onCancel.then((reason) => {
|
|
426
725
|
var _a;
|
|
427
726
|
(_a = runner.onCancel) == null ? void 0 : _a.call(runner, reason);
|
|
428
727
|
});
|
|
728
|
+
stopErrorHandler();
|
|
729
|
+
registerUnexpectedErrors(rpc2);
|
|
429
730
|
return {
|
|
430
731
|
runner,
|
|
431
732
|
config,
|
|
@@ -435,7 +736,11 @@ async function prepareTestEnvironment(files) {
|
|
|
435
736
|
};
|
|
436
737
|
}
|
|
437
738
|
function done(files) {
|
|
438
|
-
channel.postMessage({
|
|
739
|
+
channel.postMessage({
|
|
740
|
+
type: "done",
|
|
741
|
+
filenames: files,
|
|
742
|
+
id: getBrowserState().iframeId
|
|
743
|
+
});
|
|
439
744
|
}
|
|
440
745
|
async function runTests(files) {
|
|
441
746
|
await client.waitForConnection();
|
|
@@ -460,6 +765,8 @@ async function runTests(files) {
|
|
|
460
765
|
}
|
|
461
766
|
debug("runner resolved successfully");
|
|
462
767
|
const { config, runner, state, setupCommonEnv, startTests } = preparedData;
|
|
768
|
+
state.durations.prepare = performance.now() - state.durations.prepare;
|
|
769
|
+
debug("prepare time", state.durations.prepare, "ms");
|
|
463
770
|
try {
|
|
464
771
|
await setupCommonEnv(config);
|
|
465
772
|
for (const file of files)
|
|
@@ -1,42 +1,28 @@
|
|
|
1
1
|
const moduleCache = new Map()
|
|
2
2
|
|
|
3
3
|
function wrapModule(module) {
|
|
4
|
-
if (module
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
.finally(() =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (exports === sourceModule)
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
if (Object(sourceModule) !== sourceModule || Array.isArray(sourceModule))
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
for (const key in sourceModule) {
|
|
21
|
-
if (key !== 'default') {
|
|
22
|
-
try {
|
|
23
|
-
Object.defineProperty(exports, key, {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
get: () => sourceModule[key],
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
catch (_err) { }
|
|
30
|
-
}
|
|
4
|
+
if (typeof module === 'function') {
|
|
5
|
+
const promise = new Promise((resolve, reject) => {
|
|
6
|
+
if (typeof __vitest_mocker__ === 'undefined')
|
|
7
|
+
return module().then(resolve, reject)
|
|
8
|
+
__vitest_mocker__.prepare().finally(() => {
|
|
9
|
+
module().then(resolve, reject)
|
|
10
|
+
})
|
|
11
|
+
})
|
|
12
|
+
moduleCache.set(promise, { promise, evaluated: false })
|
|
13
|
+
return promise.finally(() => moduleCache.delete(promise))
|
|
31
14
|
}
|
|
15
|
+
return module
|
|
32
16
|
}
|
|
33
17
|
|
|
34
18
|
window.__vitest_browser_runner__ = {
|
|
35
|
-
exportAll,
|
|
36
19
|
wrapModule,
|
|
37
20
|
moduleCache,
|
|
38
21
|
config: { __VITEST_CONFIG__ },
|
|
22
|
+
viteConfig: { __VITEST_VITE_CONFIG__ },
|
|
39
23
|
files: { __VITEST_FILES__ },
|
|
24
|
+
type: { __VITEST_TYPE__ },
|
|
25
|
+
contextId: { __VITEST_CONTEXT_ID__ },
|
|
40
26
|
}
|
|
41
27
|
|
|
42
28
|
const config = __vitest_browser_runner__.config
|
|
@@ -15,19 +15,20 @@
|
|
|
15
15
|
padding: 0;
|
|
16
16
|
margin: 0;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
html,
|
|
19
|
+
body,
|
|
20
|
+
iframe[data-vitest],
|
|
21
|
+
#vitest-tester {
|
|
22
|
+
width: 100%;
|
|
23
|
+
height: 100%;
|
|
22
24
|
}
|
|
23
25
|
</style>
|
|
24
26
|
<script>{__VITEST_INJECTOR__}</script>
|
|
25
27
|
{__VITEST_SCRIPTS__}
|
|
26
|
-
<script type="module" crossorigin src="/__vitest_browser__/
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/__vitest_browser__/rpc-
|
|
28
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-BCpOi5ot.js"></script>
|
|
29
|
+
<link rel="modulepreload" crossorigin href="/__vitest_browser__/rpc-CImfI7bO.js">
|
|
28
30
|
</head>
|
|
29
31
|
<body>
|
|
30
|
-
<iframe id="vitest-ui" src=""></iframe>
|
|
31
32
|
<div id="vitest-tester"></div>
|
|
32
33
|
</body>
|
|
33
34
|
</html>
|
package/dist/client/tester.html
CHANGED
|
@@ -13,14 +13,15 @@
|
|
|
13
13
|
body {
|
|
14
14
|
padding: 0;
|
|
15
15
|
margin: 0;
|
|
16
|
+
min-height: 100vh;
|
|
16
17
|
}
|
|
17
18
|
</style>
|
|
18
19
|
<script>{__VITEST_INJECTOR__}</script>
|
|
19
20
|
{__VITEST_SCRIPTS__}
|
|
20
|
-
<script type="module" crossorigin src="/__vitest_browser__/tester-
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/__vitest_browser__/rpc-
|
|
21
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-e70VCOgC.js"></script>
|
|
22
|
+
<link rel="modulepreload" crossorigin href="/__vitest_browser__/rpc-CImfI7bO.js">
|
|
22
23
|
</head>
|
|
23
|
-
<body>
|
|
24
|
+
<body style="width: 100%; height: 100%; transform: scale(1); transform-origin: left top;">
|
|
24
25
|
{__VITEST_APPEND__}
|
|
25
26
|
</body>
|
|
26
27
|
</html>
|