@vitest/browser 2.0.0-beta.11 → 2.0.0-beta.13

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.
@@ -1,7 +1,9 @@
1
- import { c as channel, g as getBrowserState, a as client, b as getConfig, r as relative, d as rpcDone } from "./rpc-D6HtJ5Rb.js";
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 { c as channel, g as getBrowserState, a as client, b as globalChannel, d as getConfig, r as relative } from "./client-dLyjuL0K.js";
2
5
  import { http } from "/__virtual_vitest__?id=msw%2Fcore%2Fhttp";
3
6
  import { setupWorker } from "/__virtual_vitest__?id=msw%2Fbrowser";
4
- import "/__virtual_vitest__?id=vitest%2Futils";
5
7
  function generateHash(str) {
6
8
  let hash = 0;
7
9
  if (str.length === 0) {
@@ -21,7 +23,7 @@ function createModuleMocker() {
21
23
  const mocks = /* @__PURE__ */ new Map();
22
24
  const worker = setupWorker(
23
25
  http.get(/.+/, async ({ request }) => {
24
- const path = removeTimestamp(request.url.slice(location.origin.length));
26
+ const path = cleanQuery(request.url.slice(location.origin.length));
25
27
  if (!mocks.has(path)) {
26
28
  return passthrough();
27
29
  }
@@ -107,8 +109,9 @@ function getFactoryExports(id) {
107
109
  });
108
110
  }
109
111
  const timestampRegexp = /(\?|&)t=\d{13}/;
110
- function removeTimestamp(url2) {
111
- return url2.replace(timestampRegexp, "");
112
+ const versionRegexp = /(\?|&)v=\w{8}/;
113
+ function cleanQuery(url2) {
114
+ return url2.replace(timestampRegexp, "").replace(versionRegexp, "");
112
115
  }
113
116
  function passthrough() {
114
117
  return new Response(null, {
@@ -135,46 +138,191 @@ function injectQuery(url2, queryToInject) {
135
138
  }
136
139
  const url = new URL(location.href);
137
140
  const ID_ALL = "__vitest_all__";
138
- const iframes = /* @__PURE__ */ new Map();
141
+ class IframeOrchestrator {
142
+ constructor() {
143
+ __publicField(this, "cancelled", false);
144
+ __publicField(this, "runningFiles", /* @__PURE__ */ new Set());
145
+ __publicField(this, "mocker", createModuleMocker());
146
+ __publicField(this, "iframes", /* @__PURE__ */ new Map());
147
+ }
148
+ async init() {
149
+ const testFiles = getBrowserState().files;
150
+ debug("test files", testFiles.join(", "));
151
+ this.runningFiles.clear();
152
+ testFiles.forEach((file) => this.runningFiles.add(file));
153
+ channel.addEventListener(
154
+ "message",
155
+ (e) => this.onIframeEvent(e)
156
+ );
157
+ globalChannel.addEventListener(
158
+ "message",
159
+ (e) => this.onGlobalChannelEvent(e)
160
+ );
161
+ }
162
+ async createTesters(testFiles) {
163
+ this.cancelled = false;
164
+ this.runningFiles.clear();
165
+ testFiles.forEach((file) => this.runningFiles.add(file));
166
+ const config = getConfig();
167
+ const container = await getContainer(config);
168
+ if (config.browser.ui) {
169
+ container.className = "scrolls";
170
+ container.textContent = "";
171
+ }
172
+ const { width, height } = config.browser.viewport;
173
+ this.iframes.forEach((iframe) => iframe.remove());
174
+ this.iframes.clear();
175
+ if (config.isolate === false) {
176
+ const iframe = this.createIframe(container, ID_ALL);
177
+ await setIframeViewport(iframe, width, height);
178
+ return;
179
+ }
180
+ for (const file of testFiles) {
181
+ if (this.cancelled) {
182
+ done();
183
+ return;
184
+ }
185
+ const iframe = this.createIframe(container, file);
186
+ await setIframeViewport(iframe, width, height);
187
+ await new Promise((resolve) => {
188
+ channel.addEventListener(
189
+ "message",
190
+ function handler(e) {
191
+ if (e.data.type === "done" || e.data.type === "error") {
192
+ channel.removeEventListener("message", handler);
193
+ resolve();
194
+ }
195
+ }
196
+ );
197
+ });
198
+ }
199
+ }
200
+ createIframe(container, file) {
201
+ if (this.iframes.has(file)) {
202
+ this.iframes.get(file).remove();
203
+ this.iframes.delete(file);
204
+ }
205
+ const iframe = document.createElement("iframe");
206
+ iframe.setAttribute("loading", "eager");
207
+ iframe.setAttribute(
208
+ "src",
209
+ `${url.pathname}__vitest_test__/__test__/${getBrowserState().contextId}/${encodeURIComponent(file)}`
210
+ );
211
+ iframe.setAttribute("data-vitest", "true");
212
+ iframe.style.display = "block";
213
+ iframe.style.border = "none";
214
+ iframe.style.zIndex = "1";
215
+ iframe.style.position = "relative";
216
+ iframe.setAttribute("allowfullscreen", "true");
217
+ iframe.setAttribute("allow", "clipboard-write;");
218
+ iframe.setAttribute("name", "vitest-iframe");
219
+ this.iframes.set(file, iframe);
220
+ container.appendChild(iframe);
221
+ return iframe;
222
+ }
223
+ async onGlobalChannelEvent(e) {
224
+ debug("global channel event", JSON.stringify(e.data));
225
+ switch (e.data.type) {
226
+ case "cancel": {
227
+ this.cancelled = true;
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ async onIframeEvent(e) {
233
+ var _a;
234
+ debug("iframe event", JSON.stringify(e.data));
235
+ switch (e.data.type) {
236
+ case "viewport": {
237
+ const { width, height, id } = e.data;
238
+ const iframe = this.iframes.get(id);
239
+ if (!iframe) {
240
+ const error = new Error(`Cannot find iframe with id ${id}`);
241
+ channel.postMessage({
242
+ type: "viewport:fail",
243
+ id,
244
+ error: error.message
245
+ });
246
+ await client.rpc.onUnhandledError(
247
+ {
248
+ name: "Teardown Error",
249
+ message: error.message
250
+ },
251
+ "Teardown Error"
252
+ );
253
+ return;
254
+ }
255
+ await setIframeViewport(iframe, width, height);
256
+ channel.postMessage({ type: "viewport:done", id });
257
+ break;
258
+ }
259
+ case "done": {
260
+ const filenames = e.data.filenames;
261
+ filenames.forEach((filename) => this.runningFiles.delete(filename));
262
+ if (!this.runningFiles.size) {
263
+ const ui = getUiAPI();
264
+ if (ui && filenames.length > 1) {
265
+ const id = generateFileId(filenames[filenames.length - 1]);
266
+ ui.setCurrentFileId(id);
267
+ }
268
+ await done();
269
+ } else {
270
+ const iframeId = e.data.id;
271
+ (_a = this.iframes.get(iframeId)) == null ? void 0 : _a.remove();
272
+ this.iframes.delete(iframeId);
273
+ }
274
+ break;
275
+ }
276
+ case "error": {
277
+ const iframeId = e.data.id;
278
+ this.iframes.delete(iframeId);
279
+ await client.rpc.onUnhandledError(e.data.error, e.data.errorType);
280
+ if (iframeId === ID_ALL) {
281
+ this.runningFiles.clear();
282
+ } else {
283
+ this.runningFiles.delete(iframeId);
284
+ }
285
+ if (!this.runningFiles.size) {
286
+ await done();
287
+ }
288
+ break;
289
+ }
290
+ case "mock:invalidate":
291
+ this.mocker.invalidate();
292
+ break;
293
+ case "unmock":
294
+ await this.mocker.unmock(e.data);
295
+ break;
296
+ case "mock":
297
+ await this.mocker.mock(e.data);
298
+ break;
299
+ case "mock-factory:error":
300
+ case "mock-factory:response":
301
+ break;
302
+ default: {
303
+ e.data;
304
+ await client.rpc.onUnhandledError(
305
+ {
306
+ name: "Unexpected Event",
307
+ message: `Unexpected event: ${e.data.type}`
308
+ },
309
+ "Unexpected Event"
310
+ );
311
+ await done();
312
+ }
313
+ }
314
+ }
315
+ }
316
+ const orchestrator = new IframeOrchestrator();
139
317
  let promiseTesters;
140
318
  getBrowserState().createTesters = async (files) => {
141
319
  await promiseTesters;
142
- promiseTesters = createTesters(files).finally(() => {
320
+ promiseTesters = orchestrator.createTesters(files).finally(() => {
143
321
  promiseTesters = void 0;
144
322
  });
145
323
  await promiseTesters;
146
324
  };
147
- function debug(...args) {
148
- const debug2 = getConfig().env.VITEST_BROWSER_DEBUG;
149
- if (debug2 && debug2 !== "false") {
150
- client.rpc.debug(...args.map(String));
151
- }
152
- }
153
- function createIframe(container, file) {
154
- if (iframes.has(file)) {
155
- iframes.get(file).remove();
156
- iframes.delete(file);
157
- }
158
- const iframe = document.createElement("iframe");
159
- iframe.setAttribute("loading", "eager");
160
- iframe.setAttribute(
161
- "src",
162
- `${url.pathname}__vitest_test__/__test__/${getBrowserState().contextId}/${encodeURIComponent(file)}`
163
- );
164
- iframe.setAttribute("data-vitest", "true");
165
- iframe.style.display = "block";
166
- iframe.style.border = "none";
167
- iframe.style.zIndex = "1";
168
- iframe.style.position = "relative";
169
- iframe.setAttribute("allowfullscreen", "true");
170
- iframe.setAttribute("allow", "clipboard-write;");
171
- iframe.setAttribute("name", "vitest-iframe");
172
- iframes.set(file, iframe);
173
- container.appendChild(iframe);
174
- return iframe;
175
- }
176
325
  async function done() {
177
- await rpcDone();
178
326
  await client.rpc.finishBrowserTests(getBrowserState().contextId);
179
327
  }
180
328
  async function getContainer(config) {
@@ -191,136 +339,13 @@ async function getContainer(config) {
191
339
  }
192
340
  return document.querySelector("#vitest-tester");
193
341
  }
194
- const runningFiles = /* @__PURE__ */ new Set();
195
342
  client.ws.addEventListener("open", async () => {
196
343
  const testFiles = getBrowserState().files;
197
- debug("test files", testFiles.join(", "));
198
- runningFiles.clear();
199
- testFiles.forEach((file) => runningFiles.add(file));
200
- const mocker = createModuleMocker();
201
- channel.addEventListener(
202
- "message",
203
- async (e) => {
204
- var _a;
205
- debug("channel event", JSON.stringify(e.data));
206
- switch (e.data.type) {
207
- case "viewport": {
208
- const { width, height, id } = e.data;
209
- const iframe = iframes.get(id);
210
- if (!iframe) {
211
- const error = new Error(`Cannot find iframe with id ${id}`);
212
- channel.postMessage({
213
- type: "viewport:fail",
214
- id,
215
- error: error.message
216
- });
217
- await client.rpc.onUnhandledError(
218
- {
219
- name: "Teardown Error",
220
- message: error.message
221
- },
222
- "Teardown Error"
223
- );
224
- return;
225
- }
226
- await setIframeViewport(iframe, width, height);
227
- channel.postMessage({ type: "viewport:done", id });
228
- break;
229
- }
230
- case "done": {
231
- const filenames = e.data.filenames;
232
- filenames.forEach((filename) => runningFiles.delete(filename));
233
- if (!runningFiles.size) {
234
- const ui = getUiAPI();
235
- if (ui && filenames.length > 1) {
236
- const id = generateFileId(filenames[filenames.length - 1]);
237
- ui.setCurrentFileId(id);
238
- }
239
- await done();
240
- } else {
241
- const iframeId = e.data.id;
242
- (_a = iframes.get(iframeId)) == null ? void 0 : _a.remove();
243
- iframes.delete(iframeId);
244
- }
245
- break;
246
- }
247
- case "error": {
248
- const iframeId = e.data.id;
249
- iframes.delete(iframeId);
250
- await client.rpc.onUnhandledError(e.data.error, e.data.errorType);
251
- if (iframeId === ID_ALL) {
252
- runningFiles.clear();
253
- } else {
254
- runningFiles.delete(iframeId);
255
- }
256
- if (!runningFiles.size) {
257
- await done();
258
- }
259
- break;
260
- }
261
- case "mock:invalidate":
262
- mocker.invalidate();
263
- break;
264
- case "unmock":
265
- await mocker.unmock(e.data);
266
- break;
267
- case "mock":
268
- await mocker.mock(e.data);
269
- break;
270
- case "mock-factory:error":
271
- case "mock-factory:response":
272
- break;
273
- default: {
274
- e.data;
275
- await client.rpc.onUnhandledError(
276
- {
277
- name: "Unexpected Event",
278
- message: `Unexpected event: ${e.data.type}`
279
- },
280
- "Unexpected Event"
281
- );
282
- await done();
283
- }
284
- }
285
- }
286
- );
344
+ await orchestrator.init();
287
345
  if (testFiles.length) {
288
- await createTesters(testFiles);
346
+ await orchestrator.createTesters(testFiles);
289
347
  }
290
348
  });
291
- async function createTesters(testFiles) {
292
- runningFiles.clear();
293
- testFiles.forEach((file) => runningFiles.add(file));
294
- const config = getConfig();
295
- const container = await getContainer(config);
296
- if (config.browser.ui) {
297
- container.className = "scrolls";
298
- container.textContent = "";
299
- }
300
- const { width, height } = config.browser.viewport;
301
- iframes.forEach((iframe) => iframe.remove());
302
- iframes.clear();
303
- if (config.isolate === false) {
304
- const iframe = createIframe(container, ID_ALL);
305
- await setIframeViewport(iframe, width, height);
306
- } else {
307
- for (const file of testFiles) {
308
- const iframe = createIframe(container, file);
309
- await setIframeViewport(iframe, width, height);
310
- await new Promise((resolve) => {
311
- channel.addEventListener(
312
- "message",
313
- function handler(e) {
314
- if (e.data.type === "done" || e.data.type === "error") {
315
- channel.removeEventListener("message", handler);
316
- resolve();
317
- }
318
- }
319
- );
320
- });
321
- }
322
- }
323
- }
324
349
  function generateFileId(file) {
325
350
  const config = getConfig();
326
351
  const project = config.name || "";
@@ -336,3 +361,9 @@ async function setIframeViewport(iframe, width, height) {
336
361
  iframe.style.height = `${height}px`;
337
362
  }
338
363
  }
364
+ function debug(...args) {
365
+ const debug2 = getConfig().env.VITEST_BROWSER_DEBUG;
366
+ if (debug2 && debug2 !== "false") {
367
+ client.rpc.debug(...args.map(String));
368
+ }
369
+ }