@vitest/browser 5.0.0-beta.1 → 5.0.0-beta.3

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.
Files changed (35) hide show
  1. package/context.d.ts +40 -1
  2. package/dist/client/.vite/manifest.json +8 -8
  3. package/dist/client/__vitest__/assets/index-BlLo6Q_D.css +1 -0
  4. package/dist/client/__vitest__/assets/index-O8gheoYf.js +89 -0
  5. package/dist/client/__vitest__/index.html +2 -2
  6. package/dist/client/__vitest_browser__/defineProperty-C3k2g8Sk.js +267 -0
  7. package/dist/client/__vitest_browser__/orchestrator-B44yH1M4.js +343 -0
  8. package/dist/client/__vitest_browser__/rrweb-snapshot-iZCFA2to.js +4388 -0
  9. package/dist/client/__vitest_browser__/tester-Byk-s_d6.js +5088 -0
  10. package/dist/client/orchestrator.html +2 -2
  11. package/dist/client/tester/locators.d.ts +69 -0
  12. package/dist/client/tester/tester.html +2 -2
  13. package/dist/client/tester/trace.d.ts +11 -7
  14. package/dist/client.js +10 -1
  15. package/dist/context.js +73 -44
  16. package/dist/expect-element.js +30 -30
  17. package/dist/index.d.ts +6 -22
  18. package/dist/index.js +99 -4573
  19. package/dist/locators-DUkyvRhY.js +5 -0
  20. package/dist/locators.d.ts +9 -1
  21. package/dist/locators.js +1 -1
  22. package/dist/shared/screenshotMatcher/types.d.ts +4 -3
  23. package/dist/state.js +64 -14
  24. package/dist/types.d.ts +2 -0
  25. package/jest-dom.d.ts +1 -0
  26. package/matchers.d.ts +2 -1
  27. package/package.json +10 -7
  28. package/dist/client/__vitest__/assets/index-BmuVn2L3.js +0 -136
  29. package/dist/client/__vitest__/assets/index-CxYquQyv.css +0 -1
  30. package/dist/client/__vitest__/bg.png +0 -0
  31. package/dist/client/__vitest_browser__/orchestrator-pTEf6o0n.js +0 -383
  32. package/dist/client/__vitest_browser__/rrweb-snapshot-xhvrgOHx.js +0 -5476
  33. package/dist/client/__vitest_browser__/tester-CIKiUsoz.js +0 -2431
  34. package/dist/client/__vitest_browser__/utils-BYUpz6v6.js +0 -3379
  35. package/dist/index-BlWsE3ij.js +0 -5
@@ -23,8 +23,8 @@
23
23
  })();
24
24
  </script>
25
25
  <!-- !LOAD_METADATA! -->
26
- <script type="module" src="./assets/index-BmuVn2L3.js"></script>
27
- <link rel="stylesheet" href="./assets/index-CxYquQyv.css">
26
+ <script type="module" src="./assets/index-O8gheoYf.js"></script>
27
+ <link rel="stylesheet" href="./assets/index-BlLo6Q_D.css">
28
28
  </head>
29
29
  <body>
30
30
  <div id="app"></div>
@@ -0,0 +1,267 @@
1
+ //#region \0vite/modulepreload-polyfill.js
2
+ (function polyfill() {
3
+ const relList = document.createElement("link").relList;
4
+ if (relList && relList.supports && relList.supports("modulepreload")) return;
5
+ for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link);
6
+ new MutationObserver((mutations) => {
7
+ for (const mutation of mutations) {
8
+ if (mutation.type !== "childList") continue;
9
+ for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
10
+ }
11
+ }).observe(document, {
12
+ childList: true,
13
+ subtree: true
14
+ });
15
+ function getFetchOpts(link) {
16
+ const fetchOpts = {};
17
+ if (link.integrity) fetchOpts.integrity = link.integrity;
18
+ if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
19
+ if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
20
+ else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
21
+ else fetchOpts.credentials = "same-origin";
22
+ return fetchOpts;
23
+ }
24
+ function processPreload(link) {
25
+ if (link.ep) return;
26
+ link.ep = true;
27
+ const fetchOpts = getFetchOpts(link);
28
+ fetch(link.href, fetchOpts);
29
+ }
30
+ })();
31
+
32
+ //#endregion
33
+ //#region ../../node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs
34
+ var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
35
+ function normalizeWindowsPath(input = "") {
36
+ if (!input) return input;
37
+ return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
38
+ }
39
+ var _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
40
+ var _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
41
+ function cwd() {
42
+ if (typeof process !== "undefined" && typeof process.cwd === "function") return process.cwd().replace(/\\/g, "/");
43
+ return "/";
44
+ }
45
+ var resolve = function(...arguments_) {
46
+ arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
47
+ let resolvedPath = "";
48
+ let resolvedAbsolute = false;
49
+ for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
50
+ const path = index >= 0 ? arguments_[index] : cwd();
51
+ if (!path || path.length === 0) continue;
52
+ resolvedPath = `${path}/${resolvedPath}`;
53
+ resolvedAbsolute = isAbsolute(path);
54
+ }
55
+ resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
56
+ if (resolvedAbsolute && !isAbsolute(resolvedPath)) return `/${resolvedPath}`;
57
+ return resolvedPath.length > 0 ? resolvedPath : ".";
58
+ };
59
+ function normalizeString(path, allowAboveRoot) {
60
+ let res = "";
61
+ let lastSegmentLength = 0;
62
+ let lastSlash = -1;
63
+ let dots = 0;
64
+ let char = null;
65
+ for (let index = 0; index <= path.length; ++index) {
66
+ if (index < path.length) char = path[index];
67
+ else if (char === "/") break;
68
+ else char = "/";
69
+ if (char === "/") {
70
+ if (lastSlash === index - 1 || dots === 1);
71
+ else if (dots === 2) {
72
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
73
+ if (res.length > 2) {
74
+ const lastSlashIndex = res.lastIndexOf("/");
75
+ if (lastSlashIndex === -1) {
76
+ res = "";
77
+ lastSegmentLength = 0;
78
+ } else {
79
+ res = res.slice(0, lastSlashIndex);
80
+ lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
81
+ }
82
+ lastSlash = index;
83
+ dots = 0;
84
+ continue;
85
+ } else if (res.length > 0) {
86
+ res = "";
87
+ lastSegmentLength = 0;
88
+ lastSlash = index;
89
+ dots = 0;
90
+ continue;
91
+ }
92
+ }
93
+ if (allowAboveRoot) {
94
+ res += res.length > 0 ? "/.." : "..";
95
+ lastSegmentLength = 2;
96
+ }
97
+ } else {
98
+ if (res.length > 0) res += `/${path.slice(lastSlash + 1, index)}`;
99
+ else res = path.slice(lastSlash + 1, index);
100
+ lastSegmentLength = index - lastSlash - 1;
101
+ }
102
+ lastSlash = index;
103
+ dots = 0;
104
+ } else if (char === "." && dots !== -1) ++dots;
105
+ else dots = -1;
106
+ }
107
+ return res;
108
+ }
109
+ var isAbsolute = function(p) {
110
+ return _IS_ABSOLUTE_RE.test(p);
111
+ };
112
+ var relative = function(from, to) {
113
+ const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
114
+ const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
115
+ if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) return _to.join("/");
116
+ const _fromCopy = [..._from];
117
+ for (const segment of _fromCopy) {
118
+ if (_to[0] !== segment) break;
119
+ _from.shift();
120
+ _to.shift();
121
+ }
122
+ return [..._from.map(() => ".."), ..._to].join("/");
123
+ };
124
+
125
+ //#endregion
126
+ //#region \0vite/preload-helper.js
127
+ var scriptRel = "modulepreload";
128
+ var assetsURL = function(dep) {
129
+ return "/" + dep;
130
+ };
131
+ var seen = {};
132
+ var __vitePreload = function preload(baseModule, deps, importerUrl) {
133
+ let promise = Promise.resolve();
134
+ if (true && deps && deps.length > 0) {
135
+ const links = document.getElementsByTagName("link");
136
+ const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
137
+ const cspNonce = (cspNonceMeta === null || cspNonceMeta === void 0 ? void 0 : cspNonceMeta.nonce) || (cspNonceMeta === null || cspNonceMeta === void 0 ? void 0 : cspNonceMeta.getAttribute("nonce"));
138
+ function allSettled(promises) {
139
+ return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
140
+ status: "fulfilled",
141
+ value
142
+ }), (reason) => ({
143
+ status: "rejected",
144
+ reason
145
+ }))));
146
+ }
147
+ promise = allSettled(deps.map((dep) => {
148
+ dep = assetsURL(dep, importerUrl);
149
+ if (dep in seen) return;
150
+ seen[dep] = true;
151
+ const isCss = dep.endsWith(".css");
152
+ const cssSelector = isCss ? "[rel=\"stylesheet\"]" : "";
153
+ if (!!importerUrl) for (let i = links.length - 1; i >= 0; i--) {
154
+ const link = links[i];
155
+ if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
156
+ }
157
+ else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return;
158
+ const link = document.createElement("link");
159
+ link.rel = isCss ? "stylesheet" : scriptRel;
160
+ if (!isCss) link.as = "script";
161
+ link.crossOrigin = "";
162
+ link.href = dep;
163
+ if (cspNonce) link.setAttribute("nonce", cspNonce);
164
+ document.head.appendChild(link);
165
+ if (isCss) return new Promise((res, rej) => {
166
+ link.addEventListener("load", res);
167
+ link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
168
+ });
169
+ }));
170
+ }
171
+ function handlePreloadError(err) {
172
+ const e = new Event("vite:preloadError", { cancelable: true });
173
+ e.payload = err;
174
+ window.dispatchEvent(e);
175
+ if (!e.defaultPrevented) throw err;
176
+ }
177
+ return promise.then((res) => {
178
+ for (const item of res || []) {
179
+ if (item.status !== "rejected") continue;
180
+ handlePreloadError(item.reason);
181
+ }
182
+ return baseModule().catch(handlePreloadError);
183
+ });
184
+ };
185
+
186
+ //#endregion
187
+ //#region src/client/utils.ts
188
+ async function importId(id) {
189
+ const name = `/@id/${id}`.replace(/\\/g, "/");
190
+ return (/* @__PURE__ */ getBrowserState()).wrapModule(() => __vitePreload(() => import(
191
+ /* @vite-ignore */
192
+ name
193
+ ), []));
194
+ }
195
+ async function importFs(id) {
196
+ const name = `/@fs/${id}`.replace(/\\/g, "/");
197
+ return (/* @__PURE__ */ getBrowserState()).wrapModule(() => __vitePreload(() => import(
198
+ /* @vite-ignore */
199
+ name
200
+ ), []));
201
+ }
202
+ var moduleRunner = {
203
+ isBrowser: true,
204
+ import: (id) => {
205
+ if (id[0] === "/" || id[1] === ":") return importFs(id);
206
+ return importId(id);
207
+ }
208
+ };
209
+ var now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
210
+ function getConfig() {
211
+ return (/* @__PURE__ */ getBrowserState()).config;
212
+ }
213
+ /* @__NO_SIDE_EFFECTS__ */
214
+ function getBrowserState() {
215
+ return window.__vitest_browser_runner__;
216
+ }
217
+ /* @__NO_SIDE_EFFECTS__ */
218
+ function getWorkerState() {
219
+ const state = window.__vitest_worker__;
220
+ if (!state) throw new Error("Worker state is not found. This is an issue with Vitest. Please, open an issue.");
221
+ return state;
222
+ }
223
+
224
+ //#endregion
225
+ //#region \0@oxc-project+runtime@0.128.0/helpers/typeof.js
226
+ function _typeof(o) {
227
+ "@babel/helpers - typeof";
228
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
229
+ return typeof o;
230
+ } : function(o) {
231
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
232
+ }, _typeof(o);
233
+ }
234
+
235
+ //#endregion
236
+ //#region \0@oxc-project+runtime@0.128.0/helpers/toPrimitive.js
237
+ function toPrimitive(t, r) {
238
+ if ("object" != _typeof(t) || !t) return t;
239
+ var e = t[Symbol.toPrimitive];
240
+ if (void 0 !== e) {
241
+ var i = e.call(t, r || "default");
242
+ if ("object" != _typeof(i)) return i;
243
+ throw new TypeError("@@toPrimitive must return a primitive value.");
244
+ }
245
+ return ("string" === r ? String : Number)(t);
246
+ }
247
+
248
+ //#endregion
249
+ //#region \0@oxc-project+runtime@0.128.0/helpers/toPropertyKey.js
250
+ function toPropertyKey(t) {
251
+ var i = toPrimitive(t, "string");
252
+ return "symbol" == _typeof(i) ? i : i + "";
253
+ }
254
+
255
+ //#endregion
256
+ //#region \0@oxc-project+runtime@0.128.0/helpers/defineProperty.js
257
+ function _defineProperty(e, r, t) {
258
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
259
+ value: t,
260
+ enumerable: !0,
261
+ configurable: !0,
262
+ writable: !0
263
+ }) : e[r] = t, e;
264
+ }
265
+
266
+ //#endregion
267
+ export { moduleRunner as a, relative as c, getWorkerState as i, resolve as l, getBrowserState as n, now as o, getConfig as r, __vitePreload as s, _defineProperty as t };
@@ -0,0 +1,343 @@
1
+ import { c as relative, n as getBrowserState, r as getConfig, t as _defineProperty } from "./defineProperty-C3k2g8Sk.js";
2
+ import { channel, client, globalChannel } from "@vitest/browser/client";
3
+ import { Traces } from "vitest/internal/traces";
4
+
5
+ //#region src/client/ui.ts
6
+ /* @__NO_SIDE_EFFECTS__ */
7
+ function getUiAPI() {
8
+ return window.__vitest_ui_api__;
9
+ }
10
+
11
+ //#endregion
12
+ //#region src/client/orchestrator.ts
13
+ var ID_ALL = "__vitest_all__";
14
+ var IframeOrchestrator = class {
15
+ constructor() {
16
+ _defineProperty(this, "cancelled", false);
17
+ _defineProperty(this, "recreateNonIsolatedIframe", false);
18
+ _defineProperty(this, "iframes", /* @__PURE__ */ new Map());
19
+ _defineProperty(this, "eventTarget", new EventTarget());
20
+ _defineProperty(this, "traces", void 0);
21
+ _defineProperty(this, "loggedIframe", /* @__PURE__ */ new WeakSet());
22
+ _defineProperty(this, "iframeEvents", /* @__PURE__ */ new WeakMap());
23
+ debug("init orchestrator", (/* @__PURE__ */ getBrowserState()).sessionId);
24
+ const otelConfig = (/* @__PURE__ */ getBrowserState()).config.experimental.openTelemetry;
25
+ this.traces = new Traces({
26
+ enabled: !!((otelConfig === null || otelConfig === void 0 ? void 0 : otelConfig.enabled) && otelConfig.browserSdkPath),
27
+ sdkPath: `/@fs/${otelConfig === null || otelConfig === void 0 ? void 0 : otelConfig.browserSdkPath}`
28
+ });
29
+ channel.addEventListener("message", (e) => this.onIframeEvent(e));
30
+ globalChannel.addEventListener("message", (e) => this.onGlobalChannelEvent(e));
31
+ }
32
+ async createTesters(options) {
33
+ await this.traces.waitInit();
34
+ this.traces.recordInitSpan(this.traces.getContextFromCarrier((/* @__PURE__ */ getBrowserState()).otelCarrier));
35
+ const orchestratorSpan = this.traces.startContextSpan("vitest.browser.orchestrator.run", this.traces.getContextFromCarrier(options.otelCarrier));
36
+ orchestratorSpan.span.setAttributes({ "vitest.browser.files": options.files.map((f) => f.filepath) });
37
+ const endSpan = async () => {
38
+ orchestratorSpan.span.end();
39
+ await this.traces.flush();
40
+ };
41
+ const startTime = performance.now();
42
+ this.cancelled = false;
43
+ const config = getConfig();
44
+ debug("create testers", ...options.files.join(", "));
45
+ const container = await getContainer(config);
46
+ if (config.browser.ui) {
47
+ container.setAttribute("data-ready", "true");
48
+ if (container.textContent) container.textContent = "";
49
+ }
50
+ if (config.browser.isolate === false) {
51
+ await this.runNonIsolatedTests(container, options, startTime, orchestratorSpan.context);
52
+ await endSpan();
53
+ return;
54
+ }
55
+ this.iframes.forEach((iframe) => iframe.remove());
56
+ this.iframes.clear();
57
+ for (let i = 0; i < options.files.length; i++) {
58
+ if (this.cancelled) {
59
+ await endSpan();
60
+ return;
61
+ }
62
+ const file = options.files[i];
63
+ debug("create iframe", file.filepath);
64
+ await this.runIsolatedTestInIframe(container, file, options, startTime, orchestratorSpan.context);
65
+ }
66
+ await endSpan();
67
+ }
68
+ async cleanupTesters() {
69
+ if (getConfig().browser.isolate) {
70
+ const files = Array.from(this.iframes.keys());
71
+ const ui = /* @__PURE__ */ getUiAPI();
72
+ if (ui && files[0]) {
73
+ const id = generateFileId(files[0]);
74
+ ui.setCurrentFileId(id);
75
+ }
76
+ return;
77
+ }
78
+ if (!this.iframes.get(ID_ALL)) return;
79
+ await this.sendEventToIframe({
80
+ event: "cleanup",
81
+ iframeId: ID_ALL
82
+ });
83
+ this.recreateNonIsolatedIframe = true;
84
+ }
85
+ async runNonIsolatedTests(container, options, startTime, otelContext) {
86
+ if (this.recreateNonIsolatedIframe) {
87
+ this.recreateNonIsolatedIframe = false;
88
+ this.iframes.get(ID_ALL).remove();
89
+ this.iframes.delete(ID_ALL);
90
+ debug("recreate non-isolated iframe");
91
+ }
92
+ if (!this.iframes.has(ID_ALL)) {
93
+ debug("preparing non-isolated iframe");
94
+ await this.prepareIframe(container, ID_ALL, startTime, otelContext);
95
+ }
96
+ const { width, height } = getConfig().browser.viewport;
97
+ await setIframeViewport(width, height);
98
+ debug("run non-isolated tests", options.files.join(", "));
99
+ await this.sendEventToIframe({
100
+ event: "execute",
101
+ iframeId: ID_ALL,
102
+ files: options.files,
103
+ method: options.method,
104
+ context: options.providedContext
105
+ });
106
+ debug("finished running tests", options.files.join(", "));
107
+ }
108
+ async runIsolatedTestInIframe(container, spec, options, startTime, otelContext) {
109
+ const { width, height } = getConfig().browser.viewport;
110
+ const file = spec.filepath;
111
+ if (this.iframes.has(file)) {
112
+ this.iframes.get(file).remove();
113
+ this.iframes.delete(file);
114
+ }
115
+ await this.prepareIframe(container, file, startTime, otelContext);
116
+ await setIframeViewport(width, height);
117
+ await this.sendEventToIframe({
118
+ event: "execute",
119
+ files: [spec],
120
+ method: options.method,
121
+ iframeId: file,
122
+ context: options.providedContext
123
+ });
124
+ await this.sendEventToIframe({
125
+ event: "cleanup",
126
+ iframeId: file
127
+ });
128
+ }
129
+ dispatchIframeError(error) {
130
+ const event = new CustomEvent("iframeerror", { detail: error });
131
+ this.eventTarget.dispatchEvent(event);
132
+ return error;
133
+ }
134
+ async prepareIframe(container, iframeId, startTime, otelContext) {
135
+ const iframe = this.createTestIframe(iframeId);
136
+ container.appendChild(iframe);
137
+ await new Promise((resolve, reject) => {
138
+ iframe.onload = () => {
139
+ const href = this.getIframeHref(iframe);
140
+ debug("iframe loaded with href", href);
141
+ if (href !== iframe.src) reject(this.dispatchIframeError(/* @__PURE__ */ new Error(`Cannot connect to the iframe. Did you change the location or submitted a form? If so, don't forget to call \`event.preventDefault()\` to avoid reloading the page.
142
+
143
+ Received URL: ${href || "unknown due to CORS"}\nExpected: ${iframe.src}`)));
144
+ else if (this.iframes.has(iframeId)) {
145
+ const events = this.iframeEvents.get(iframe);
146
+ if (events === null || events === void 0 ? void 0 : events.size) this.dispatchIframeError(new Error(this.createWarningMessage(iframeId, "during a test")));
147
+ else this.warnReload(iframe, iframeId);
148
+ } else {
149
+ this.iframes.set(iframeId, iframe);
150
+ this.sendEventToIframe({
151
+ event: "prepare",
152
+ iframeId,
153
+ startTime,
154
+ otelCarrier: this.traces.getContextCarrier(otelContext)
155
+ }).then(resolve, (error) => reject(this.dispatchIframeError(error)));
156
+ }
157
+ };
158
+ iframe.onerror = (e) => {
159
+ if (typeof e === "string") reject(this.dispatchIframeError(new Error(e)));
160
+ else if (e instanceof ErrorEvent) reject(this.dispatchIframeError(e.error));
161
+ else reject(this.dispatchIframeError(/* @__PURE__ */ new Error(`Cannot load the iframe ${iframeId}.`)));
162
+ };
163
+ });
164
+ return iframe;
165
+ }
166
+ createWarningMessage(iframeId, location) {
167
+ return `The iframe${iframeId === ID_ALL ? "" : ` for "${iframeId}"`} was reloaded ${location}. This can lead to unexpected behavior during tests, duplicated test results or tests hanging.\n\nMake sure that your test code does not change window's location, submit forms without preventing default behavior, or imports unoptimized dependencies.\nIf you are using a framework that manipulates browser history (like React Router), consider using memory-based routing for tests. If you think this is a false positive, open an issue with a reproduction: https://github.com/vitest-dev/vitest/issues/new`;
168
+ }
169
+ warnReload(iframe, iframeId) {
170
+ if (this.loggedIframe.has(iframe)) return;
171
+ this.loggedIframe.add(iframe);
172
+ const message = `\x1B[41m WARNING \x1B[49m ${this.createWarningMessage(iframeId, "multiple times")}`;
173
+ client.rpc.sendLog("run", {
174
+ type: "stderr",
175
+ time: Date.now(),
176
+ content: message,
177
+ size: message.length,
178
+ taskId: iframeId === ID_ALL ? void 0 : generateFileId(iframeId)
179
+ }).catch(() => {});
180
+ }
181
+ getIframeHref(iframe) {
182
+ try {
183
+ var _iframe$contentWindow;
184
+ return (_iframe$contentWindow = iframe.contentWindow) === null || _iframe$contentWindow === void 0 ? void 0 : _iframe$contentWindow.location.href;
185
+ } catch {
186
+ return;
187
+ }
188
+ }
189
+ createTestIframe(iframeId) {
190
+ const iframe = document.createElement("iframe");
191
+ const src = `/?sessionId=${(/* @__PURE__ */ getBrowserState()).sessionId}&iframeId=${iframeId}`;
192
+ const config = getConfig();
193
+ iframe.setAttribute("loading", "eager");
194
+ iframe.setAttribute("src", src);
195
+ iframe.setAttribute("data-vitest", "true");
196
+ iframe.setAttribute("allowfullscreen", "true");
197
+ iframe.setAttribute("allow", "clipboard-write;");
198
+ iframe.setAttribute("name", "vitest-iframe");
199
+ iframe.style.setProperty("border", "none");
200
+ iframe.style.setProperty("background-color", "#fff");
201
+ iframe.style.setProperty("width", "var(--viewport-width)");
202
+ iframe.style.setProperty("height", "var(--viewport-height)");
203
+ if (config.browser.ui) {
204
+ if (config.browser.name !== "firefox") iframe.style.setProperty("transform", "scale(min(1, calc(100cqw / var(--viewport-width)), calc(100cqh / var(--viewport-height))))");
205
+ else {
206
+ iframe.style.setProperty("--container-width", "100cqw");
207
+ iframe.style.setProperty("--container-height", "100cqh");
208
+ iframe.style.setProperty("transform", "scale(min(1, tan(atan2(var(--container-width), var(--viewport-width))), tan(atan2(var(--container-height), var(--viewport-height)))))");
209
+ }
210
+ iframe.style.setProperty("transform-origin", "top left");
211
+ }
212
+ return iframe;
213
+ }
214
+ async onGlobalChannelEvent(e) {
215
+ debug("global channel event", JSON.stringify(e.data));
216
+ switch (e.data.type) {
217
+ case "cancel":
218
+ this.cancelled = true;
219
+ break;
220
+ }
221
+ }
222
+ async onIframeEvent(e) {
223
+ debug("iframe event", JSON.stringify(e.data));
224
+ switch (e.data.event) {
225
+ case "viewport": {
226
+ const { width, height, iframeId: id } = e.data;
227
+ if (!this.iframes.get(id)) {
228
+ const error = `Cannot find iframe with id ${id}`;
229
+ channel.postMessage({
230
+ event: "viewport:fail",
231
+ iframeId: id,
232
+ error
233
+ });
234
+ await client.rpc.onUnhandledError({
235
+ name: "Teardown Error",
236
+ message: error
237
+ }, "Teardown Error");
238
+ break;
239
+ }
240
+ await setIframeViewport(width, height);
241
+ channel.postMessage({
242
+ event: "viewport:done",
243
+ iframeId: id
244
+ });
245
+ break;
246
+ }
247
+ default:
248
+ if (typeof e.data.event === "string" && e.data.event.startsWith("response:")) break;
249
+ await client.rpc.onUnhandledError({
250
+ name: "Unexpected Event",
251
+ message: `Unexpected event: ${e.data.event}`
252
+ }, "Unexpected Event");
253
+ }
254
+ }
255
+ async sendEventToIframe(event) {
256
+ const iframe = this.iframes.get(event.iframeId);
257
+ if (!iframe) throw new Error(`Cannot find iframe with id ${event.iframeId}`);
258
+ let events = this.iframeEvents.get(iframe);
259
+ if (!events) {
260
+ events = /* @__PURE__ */ new Set();
261
+ this.iframeEvents.set(iframe, events);
262
+ }
263
+ events.add(event.event);
264
+ channel.postMessage(event);
265
+ return new Promise((resolve, reject) => {
266
+ const cleanupEvents = () => {
267
+ channel.removeEventListener("message", onReceived);
268
+ this.eventTarget.removeEventListener("iframeerror", onError);
269
+ };
270
+ function onReceived(e) {
271
+ if (e.data.iframeId === event.iframeId && e.data.event === `response:${event.event}`) {
272
+ resolve();
273
+ cleanupEvents();
274
+ events.delete(event.event);
275
+ }
276
+ }
277
+ function onError(e) {
278
+ reject(e.detail);
279
+ cleanupEvents();
280
+ events.delete(event.event);
281
+ }
282
+ this.eventTarget.addEventListener("iframeerror", onError);
283
+ channel.addEventListener("message", onReceived);
284
+ });
285
+ }
286
+ };
287
+ var orchestrator = new IframeOrchestrator();
288
+ (/* @__PURE__ */ getBrowserState()).orchestrator = orchestrator;
289
+ async function getContainer(config) {
290
+ if (config.browser.ui) {
291
+ const element = document.querySelector("#tester-ui");
292
+ if (!element) return new Promise((resolve) => {
293
+ queueMicrotask(() => {
294
+ resolve(getContainer(config));
295
+ });
296
+ });
297
+ return element;
298
+ }
299
+ return document.querySelector("#vitest-tester");
300
+ }
301
+ function generateFileId(file) {
302
+ const config = getConfig();
303
+ return generateFileHash(relative(config.root, file), config.name, {
304
+ typecheck: config.pool === "typescript",
305
+ __vitest_label__: config.mergeReportsLabel
306
+ });
307
+ }
308
+ function generateFileHash(file, projectName, meta) {
309
+ return generateHash([
310
+ file,
311
+ projectName || "",
312
+ (meta === null || meta === void 0 ? void 0 : meta.typecheck) ? "__typecheck__" : "",
313
+ (meta === null || meta === void 0 ? void 0 : meta.__vitest_label__) || ""
314
+ ].join("\0"));
315
+ }
316
+ function generateHash(str) {
317
+ let hash = 0;
318
+ if (str.length === 0) return `${hash}`;
319
+ for (let i = 0; i < str.length; i++) {
320
+ const char = str.charCodeAt(i);
321
+ hash = (hash << 5) - hash + char;
322
+ hash = hash & hash;
323
+ }
324
+ return `${hash}`;
325
+ }
326
+ async function setIframeViewport(width, height) {
327
+ const ui = /* @__PURE__ */ getUiAPI();
328
+ if (ui) await ui.setIframeViewport(width, height);
329
+ else {
330
+ document.body.style.setProperty("--viewport-width", `${width}px`);
331
+ document.body.style.setProperty("--viewport-height", `${height}px`);
332
+ await client.rpc.triggerCommand((/* @__PURE__ */ getBrowserState()).sessionId, "__vitest_viewport", void 0, [{
333
+ width,
334
+ height
335
+ }]);
336
+ }
337
+ }
338
+ function debug(...args) {
339
+ const debug = getConfig().env.VITEST_BROWSER_DEBUG;
340
+ if (debug && debug !== "false") client.rpc.debug(...args.map(String));
341
+ }
342
+
343
+ //#endregion