@vitest/browser 2.1.2 → 2.1.4
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 +7 -1
- package/dist/client/.vite/manifest.json +7 -7
- package/dist/client/__vitest__/assets/index-CGSAdLIf.css +1 -0
- package/dist/client/__vitest__/assets/index-DWjHzG4O.js +52 -0
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/orchestrator-NReaboR_.js +350 -0
- package/dist/client/__vitest_browser__/{tester-iPUw4msx.js → tester-CAAquV6P.js} +4495 -4099
- package/dist/client/__vitest_browser__/utils-CUwLt_eT.js +81 -0
- package/dist/client/error-catcher.js +3 -1
- package/dist/client/esm-client-injector.js +50 -48
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/tester.html +3 -8
- package/dist/client.js +28 -5
- package/dist/context.js +32 -23
- package/dist/index.d.ts +10 -6
- package/dist/index.js +1917 -1763
- package/dist/locators/preview.js +1 -1
- package/dist/state.js +1 -1
- package/dist/utils.js +1 -1
- package/matchers.d.ts +1 -1
- package/package.json +17 -17
- package/dist/client/__vitest__/assets/index-CADIw8eX.js +0 -52
- package/dist/client/__vitest__/assets/index-D5rK8X7L.css +0 -1
- package/dist/client/__vitest_browser__/orchestrator-N9hisloQ.js +0 -1096
- package/dist/client/__vitest_browser__/preload-helper-D-WYp1PK.js +0 -317
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
})();
|
|
24
24
|
</script>
|
|
25
25
|
<!-- !LOAD_METADATA! -->
|
|
26
|
-
<script type="module" crossorigin src="./assets/index-
|
|
27
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
26
|
+
<script type="module" crossorigin src="./assets/index-DWjHzG4O.js"></script>
|
|
27
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CGSAdLIf.css">
|
|
28
28
|
</head>
|
|
29
29
|
<body>
|
|
30
30
|
<div id="app"></div>
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { g as getBrowserState, a as getConfig } from "./utils-CUwLt_eT.js";
|
|
5
|
+
import { client, channel, globalChannel } from "@vitest/browser/client";
|
|
6
|
+
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
7
|
+
function normalizeWindowsPath(input = "") {
|
|
8
|
+
if (!input) {
|
|
9
|
+
return input;
|
|
10
|
+
}
|
|
11
|
+
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
12
|
+
}
|
|
13
|
+
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
14
|
+
const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
|
|
15
|
+
function cwd() {
|
|
16
|
+
if (typeof process !== "undefined" && typeof process.cwd === "function") {
|
|
17
|
+
return process.cwd().replace(/\\/g, "/");
|
|
18
|
+
}
|
|
19
|
+
return "/";
|
|
20
|
+
}
|
|
21
|
+
const resolve = function(...arguments_) {
|
|
22
|
+
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
|
23
|
+
let resolvedPath = "";
|
|
24
|
+
let resolvedAbsolute = false;
|
|
25
|
+
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
|
26
|
+
const path = index >= 0 ? arguments_[index] : cwd();
|
|
27
|
+
if (!path || path.length === 0) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
resolvedPath = `${path}/${resolvedPath}`;
|
|
31
|
+
resolvedAbsolute = isAbsolute(path);
|
|
32
|
+
}
|
|
33
|
+
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
|
34
|
+
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
|
35
|
+
return `/${resolvedPath}`;
|
|
36
|
+
}
|
|
37
|
+
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
38
|
+
};
|
|
39
|
+
function normalizeString(path, allowAboveRoot) {
|
|
40
|
+
let res = "";
|
|
41
|
+
let lastSegmentLength = 0;
|
|
42
|
+
let lastSlash = -1;
|
|
43
|
+
let dots = 0;
|
|
44
|
+
let char = null;
|
|
45
|
+
for (let index = 0; index <= path.length; ++index) {
|
|
46
|
+
if (index < path.length) {
|
|
47
|
+
char = path[index];
|
|
48
|
+
} else if (char === "/") {
|
|
49
|
+
break;
|
|
50
|
+
} else {
|
|
51
|
+
char = "/";
|
|
52
|
+
}
|
|
53
|
+
if (char === "/") {
|
|
54
|
+
if (lastSlash === index - 1 || dots === 1) ;
|
|
55
|
+
else if (dots === 2) {
|
|
56
|
+
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
|
57
|
+
if (res.length > 2) {
|
|
58
|
+
const lastSlashIndex = res.lastIndexOf("/");
|
|
59
|
+
if (lastSlashIndex === -1) {
|
|
60
|
+
res = "";
|
|
61
|
+
lastSegmentLength = 0;
|
|
62
|
+
} else {
|
|
63
|
+
res = res.slice(0, lastSlashIndex);
|
|
64
|
+
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
65
|
+
}
|
|
66
|
+
lastSlash = index;
|
|
67
|
+
dots = 0;
|
|
68
|
+
continue;
|
|
69
|
+
} else if (res.length > 0) {
|
|
70
|
+
res = "";
|
|
71
|
+
lastSegmentLength = 0;
|
|
72
|
+
lastSlash = index;
|
|
73
|
+
dots = 0;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (allowAboveRoot) {
|
|
78
|
+
res += res.length > 0 ? "/.." : "..";
|
|
79
|
+
lastSegmentLength = 2;
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
if (res.length > 0) {
|
|
83
|
+
res += `/${path.slice(lastSlash + 1, index)}`;
|
|
84
|
+
} else {
|
|
85
|
+
res = path.slice(lastSlash + 1, index);
|
|
86
|
+
}
|
|
87
|
+
lastSegmentLength = index - lastSlash - 1;
|
|
88
|
+
}
|
|
89
|
+
lastSlash = index;
|
|
90
|
+
dots = 0;
|
|
91
|
+
} else if (char === "." && dots !== -1) {
|
|
92
|
+
++dots;
|
|
93
|
+
} else {
|
|
94
|
+
dots = -1;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return res;
|
|
98
|
+
}
|
|
99
|
+
const isAbsolute = function(p) {
|
|
100
|
+
return _IS_ABSOLUTE_RE.test(p);
|
|
101
|
+
};
|
|
102
|
+
const relative = function(from, to) {
|
|
103
|
+
const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
104
|
+
const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
105
|
+
if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) {
|
|
106
|
+
return _to.join("/");
|
|
107
|
+
}
|
|
108
|
+
const _fromCopy = [..._from];
|
|
109
|
+
for (const segment of _fromCopy) {
|
|
110
|
+
if (_to[0] !== segment) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
_from.shift();
|
|
114
|
+
_to.shift();
|
|
115
|
+
}
|
|
116
|
+
return [..._from.map(() => ".."), ..._to].join("/");
|
|
117
|
+
};
|
|
118
|
+
function generateHash(str) {
|
|
119
|
+
let hash = 0;
|
|
120
|
+
if (str.length === 0) {
|
|
121
|
+
return `${hash}`;
|
|
122
|
+
}
|
|
123
|
+
for (let i = 0; i < str.length; i++) {
|
|
124
|
+
const char = str.charCodeAt(i);
|
|
125
|
+
hash = (hash << 5) - hash + char;
|
|
126
|
+
hash = hash & hash;
|
|
127
|
+
}
|
|
128
|
+
return `${hash}`;
|
|
129
|
+
}
|
|
130
|
+
function getUiAPI() {
|
|
131
|
+
return window.__vitest_ui_api__;
|
|
132
|
+
}
|
|
133
|
+
const url = new URL(location.href);
|
|
134
|
+
const ID_ALL = "__vitest_all__";
|
|
135
|
+
class IframeOrchestrator {
|
|
136
|
+
constructor() {
|
|
137
|
+
__publicField(this, "cancelled", false);
|
|
138
|
+
__publicField(this, "runningFiles", /* @__PURE__ */ new Set());
|
|
139
|
+
__publicField(this, "iframes", /* @__PURE__ */ new Map());
|
|
140
|
+
}
|
|
141
|
+
async init() {
|
|
142
|
+
const testFiles = getBrowserState().files;
|
|
143
|
+
debug("test files", testFiles.join(", "));
|
|
144
|
+
this.runningFiles.clear();
|
|
145
|
+
testFiles.forEach((file) => this.runningFiles.add(file));
|
|
146
|
+
channel.addEventListener(
|
|
147
|
+
"message",
|
|
148
|
+
(e) => this.onIframeEvent(e)
|
|
149
|
+
);
|
|
150
|
+
globalChannel.addEventListener(
|
|
151
|
+
"message",
|
|
152
|
+
(e) => this.onGlobalChannelEvent(e)
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
async createTesters(testFiles) {
|
|
156
|
+
this.cancelled = false;
|
|
157
|
+
this.runningFiles.clear();
|
|
158
|
+
testFiles.forEach((file) => this.runningFiles.add(file));
|
|
159
|
+
const config = getConfig();
|
|
160
|
+
const container = await getContainer(config);
|
|
161
|
+
if (config.browser.ui) {
|
|
162
|
+
container.className = "absolute origin-top mt-[8px]";
|
|
163
|
+
container.parentElement.setAttribute("data-ready", "true");
|
|
164
|
+
container.textContent = "";
|
|
165
|
+
}
|
|
166
|
+
const { width, height } = config.browser.viewport;
|
|
167
|
+
this.iframes.forEach((iframe) => iframe.remove());
|
|
168
|
+
this.iframes.clear();
|
|
169
|
+
if (config.isolate === false) {
|
|
170
|
+
const iframe = this.createIframe(container, ID_ALL);
|
|
171
|
+
await setIframeViewport(iframe, width, height);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
for (const file of testFiles) {
|
|
175
|
+
if (this.cancelled) {
|
|
176
|
+
done();
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const iframe = this.createIframe(container, file);
|
|
180
|
+
await setIframeViewport(iframe, width, height);
|
|
181
|
+
await new Promise((resolve2) => {
|
|
182
|
+
channel.addEventListener(
|
|
183
|
+
"message",
|
|
184
|
+
function handler(e) {
|
|
185
|
+
if (e.data.type === "done" || e.data.type === "error") {
|
|
186
|
+
channel.removeEventListener("message", handler);
|
|
187
|
+
resolve2();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
createIframe(container, file) {
|
|
195
|
+
if (this.iframes.has(file)) {
|
|
196
|
+
this.iframes.get(file).remove();
|
|
197
|
+
this.iframes.delete(file);
|
|
198
|
+
}
|
|
199
|
+
const iframe = document.createElement("iframe");
|
|
200
|
+
iframe.setAttribute("loading", "eager");
|
|
201
|
+
iframe.setAttribute(
|
|
202
|
+
"src",
|
|
203
|
+
`${url.pathname}__vitest_test__/__test__/${getBrowserState().contextId}/${encodeURIComponent(file)}`
|
|
204
|
+
);
|
|
205
|
+
iframe.setAttribute("data-vitest", "true");
|
|
206
|
+
iframe.style.border = "none";
|
|
207
|
+
iframe.style.width = "100%";
|
|
208
|
+
iframe.style.height = "100%";
|
|
209
|
+
iframe.setAttribute("allowfullscreen", "true");
|
|
210
|
+
iframe.setAttribute("allow", "clipboard-write;");
|
|
211
|
+
iframe.setAttribute("name", "vitest-iframe");
|
|
212
|
+
this.iframes.set(file, iframe);
|
|
213
|
+
container.appendChild(iframe);
|
|
214
|
+
return iframe;
|
|
215
|
+
}
|
|
216
|
+
async onGlobalChannelEvent(e) {
|
|
217
|
+
debug("global channel event", JSON.stringify(e.data));
|
|
218
|
+
switch (e.data.type) {
|
|
219
|
+
case "cancel": {
|
|
220
|
+
this.cancelled = true;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async onIframeEvent(e) {
|
|
226
|
+
var _a;
|
|
227
|
+
debug("iframe event", JSON.stringify(e.data));
|
|
228
|
+
switch (e.data.type) {
|
|
229
|
+
case "viewport": {
|
|
230
|
+
const { width, height, id } = e.data;
|
|
231
|
+
const iframe = this.iframes.get(id);
|
|
232
|
+
if (!iframe) {
|
|
233
|
+
const error = new Error(`Cannot find iframe with id ${id}`);
|
|
234
|
+
channel.postMessage({
|
|
235
|
+
type: "viewport:fail",
|
|
236
|
+
id,
|
|
237
|
+
error: error.message
|
|
238
|
+
});
|
|
239
|
+
await client.rpc.onUnhandledError(
|
|
240
|
+
{
|
|
241
|
+
name: "Teardown Error",
|
|
242
|
+
message: error.message
|
|
243
|
+
},
|
|
244
|
+
"Teardown Error"
|
|
245
|
+
);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
await setIframeViewport(iframe, width, height);
|
|
249
|
+
channel.postMessage({ type: "viewport:done", id });
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
case "done": {
|
|
253
|
+
const filenames = e.data.filenames;
|
|
254
|
+
filenames.forEach((filename) => this.runningFiles.delete(filename));
|
|
255
|
+
if (!this.runningFiles.size) {
|
|
256
|
+
const ui = getUiAPI();
|
|
257
|
+
if (ui && filenames.length > 1) {
|
|
258
|
+
const id = generateFileId(filenames[filenames.length - 1]);
|
|
259
|
+
ui.setCurrentFileId(id);
|
|
260
|
+
}
|
|
261
|
+
await done();
|
|
262
|
+
} else {
|
|
263
|
+
const iframeId = e.data.id;
|
|
264
|
+
(_a = this.iframes.get(iframeId)) == null ? void 0 : _a.remove();
|
|
265
|
+
this.iframes.delete(iframeId);
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case "error": {
|
|
270
|
+
const iframeId = e.data.id;
|
|
271
|
+
this.iframes.delete(iframeId);
|
|
272
|
+
await client.rpc.onUnhandledError(e.data.error, e.data.errorType);
|
|
273
|
+
if (iframeId === ID_ALL) {
|
|
274
|
+
this.runningFiles.clear();
|
|
275
|
+
} else {
|
|
276
|
+
this.runningFiles.delete(iframeId);
|
|
277
|
+
}
|
|
278
|
+
if (!this.runningFiles.size) {
|
|
279
|
+
await done();
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
default: {
|
|
284
|
+
e.data;
|
|
285
|
+
await client.rpc.onUnhandledError(
|
|
286
|
+
{
|
|
287
|
+
name: "Unexpected Event",
|
|
288
|
+
message: `Unexpected event: ${e.data.type}`
|
|
289
|
+
},
|
|
290
|
+
"Unexpected Event"
|
|
291
|
+
);
|
|
292
|
+
await done();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const orchestrator = new IframeOrchestrator();
|
|
298
|
+
let promiseTesters;
|
|
299
|
+
getBrowserState().createTesters = async (files) => {
|
|
300
|
+
await promiseTesters;
|
|
301
|
+
promiseTesters = orchestrator.createTesters(files).finally(() => {
|
|
302
|
+
promiseTesters = void 0;
|
|
303
|
+
});
|
|
304
|
+
await promiseTesters;
|
|
305
|
+
};
|
|
306
|
+
async function done() {
|
|
307
|
+
await client.rpc.finishBrowserTests(getBrowserState().contextId);
|
|
308
|
+
}
|
|
309
|
+
async function getContainer(config) {
|
|
310
|
+
if (config.browser.ui) {
|
|
311
|
+
const element = document.querySelector("#tester-ui");
|
|
312
|
+
if (!element) {
|
|
313
|
+
return new Promise((resolve2) => {
|
|
314
|
+
setTimeout(() => {
|
|
315
|
+
resolve2(getContainer(config));
|
|
316
|
+
}, 30);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
return element;
|
|
320
|
+
}
|
|
321
|
+
return document.querySelector("#vitest-tester");
|
|
322
|
+
}
|
|
323
|
+
client.waitForConnection().then(async () => {
|
|
324
|
+
const testFiles = getBrowserState().files;
|
|
325
|
+
await orchestrator.init();
|
|
326
|
+
if (testFiles.length) {
|
|
327
|
+
await orchestrator.createTesters(testFiles);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
function generateFileId(file) {
|
|
331
|
+
const config = getConfig();
|
|
332
|
+
const project = config.name || "";
|
|
333
|
+
const path = relative(config.root, file);
|
|
334
|
+
return generateHash(`${path}${project}`);
|
|
335
|
+
}
|
|
336
|
+
async function setIframeViewport(iframe, width, height) {
|
|
337
|
+
const ui = getUiAPI();
|
|
338
|
+
if (ui) {
|
|
339
|
+
await ui.setIframeViewport(width, height);
|
|
340
|
+
} else {
|
|
341
|
+
iframe.style.width = `${width}px`;
|
|
342
|
+
iframe.style.height = `${height}px`;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function debug(...args) {
|
|
346
|
+
const debug2 = getConfig().env.VITEST_BROWSER_DEBUG;
|
|
347
|
+
if (debug2 && debug2 !== "false") {
|
|
348
|
+
client.rpc.debug(...args.map(String));
|
|
349
|
+
}
|
|
350
|
+
}
|