@vitest/browser 2.0.0-beta.3 → 2.0.0-beta.6

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/index.js CHANGED
@@ -3,11 +3,11 @@ import { readFile as readFile$1 } from 'node:fs/promises';
3
3
  import sirv from 'sirv';
4
4
  import { coverageConfigDefaults } from 'vitest/config';
5
5
  import { slash } from '@vitest/utils';
6
- import MagicString from 'magic-string';
7
- import { esmWalker } from '@vitest/utils/ast';
8
6
  import fs, { promises } from 'node:fs';
9
7
  import { resolve as resolve$1, dirname } from 'node:path';
10
8
  import { isFileServingAllowed } from 'vitest/node';
9
+ import MagicString from 'magic-string';
10
+ import { esmWalker } from '@vitest/utils/ast';
11
11
 
12
12
  const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
13
13
  function normalizeWindowsPath(input = "") {
@@ -159,248 +159,6 @@ const basename = function(p, extension) {
159
159
  return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
160
160
  };
161
161
 
162
- /**
163
- * @param {import('estree').Node} param
164
- * @returns {string[]}
165
- */
166
- function extract_names(param) {
167
- return extract_identifiers(param).map((node) => node.name);
168
- }
169
-
170
- /**
171
- * @param {import('estree').Node} param
172
- * @param {import('estree').Identifier[]} nodes
173
- * @returns {import('estree').Identifier[]}
174
- */
175
- function extract_identifiers(param, nodes = []) {
176
- switch (param.type) {
177
- case 'Identifier':
178
- nodes.push(param);
179
- break;
180
-
181
- case 'MemberExpression':
182
- let object = param;
183
- while (object.type === 'MemberExpression') {
184
- object = /** @type {any} */ (object.object);
185
- }
186
- nodes.push(/** @type {any} */ (object));
187
- break;
188
-
189
- case 'ObjectPattern':
190
- for (const prop of param.properties) {
191
- if (prop.type === 'RestElement') {
192
- extract_identifiers(prop.argument, nodes);
193
- } else {
194
- extract_identifiers(prop.value, nodes);
195
- }
196
- }
197
-
198
- break;
199
-
200
- case 'ArrayPattern':
201
- for (const element of param.elements) {
202
- if (element) extract_identifiers(element, nodes);
203
- }
204
-
205
- break;
206
-
207
- case 'RestElement':
208
- extract_identifiers(param.argument, nodes);
209
- break;
210
-
211
- case 'AssignmentPattern':
212
- extract_identifiers(param.left, nodes);
213
- break;
214
- }
215
-
216
- return nodes;
217
- }
218
-
219
- const viInjectedKey = "__vi_inject__";
220
- const viExportAllHelper = "__vitest_browser_runner__.exportAll";
221
- const skipHijack = [
222
- "/@vite/client",
223
- "/@vite/env",
224
- /vite\/dist\/client/
225
- ];
226
- function injectVitestModule(code, id, parse) {
227
- if (skipHijack.some((skip) => id.match(skip)))
228
- return;
229
- const s = new MagicString(code);
230
- let ast;
231
- try {
232
- ast = parse(code);
233
- } catch (err) {
234
- console.error(`Cannot parse ${id}:
235
- ${err.message}`);
236
- return;
237
- }
238
- let uid = 0;
239
- const idToImportMap = /* @__PURE__ */ new Map();
240
- const declaredConst = /* @__PURE__ */ new Set();
241
- const hoistIndex = 0;
242
- const transformImportDeclaration = (node) => {
243
- const source = node.source.value;
244
- if (skipHijack.some((skip) => source.match(skip)))
245
- return null;
246
- const importId = `__vi_esm_${uid++}__`;
247
- const hasSpecifiers = node.specifiers.length > 0;
248
- const code2 = hasSpecifiers ? `import { ${viInjectedKey} as ${importId} } from '${source}'
249
- ` : `import '${source}'
250
- `;
251
- return {
252
- code: code2,
253
- id: importId
254
- };
255
- };
256
- function defineImport(node) {
257
- const declaration = transformImportDeclaration(node);
258
- if (!declaration)
259
- return null;
260
- s.appendLeft(hoistIndex, declaration.code);
261
- return declaration.id;
262
- }
263
- function defineImportAll(source) {
264
- const importId = `__vi_esm_${uid++}__`;
265
- s.appendLeft(hoistIndex, `const { ${viInjectedKey}: ${importId} } = await import(${JSON.stringify(source)});
266
- `);
267
- return importId;
268
- }
269
- function defineExport(position, name, local = name) {
270
- s.appendLeft(
271
- position,
272
- `
273
- Object.defineProperty(${viInjectedKey}, "${name}", { enumerable: true, configurable: true, get(){ return ${local} }});`
274
- );
275
- }
276
- for (const node of ast.body) {
277
- if (node.type === "ImportDeclaration") {
278
- const importId = defineImport(node);
279
- if (!importId)
280
- continue;
281
- s.remove(node.start, node.end);
282
- for (const spec of node.specifiers) {
283
- if (spec.type === "ImportSpecifier") {
284
- idToImportMap.set(
285
- spec.local.name,
286
- `${importId}.${spec.imported.name}`
287
- );
288
- } else if (spec.type === "ImportDefaultSpecifier") {
289
- idToImportMap.set(spec.local.name, `${importId}.default`);
290
- } else {
291
- idToImportMap.set(spec.local.name, importId);
292
- }
293
- }
294
- }
295
- }
296
- for (const node of ast.body) {
297
- if (node.type === "ExportNamedDeclaration") {
298
- if (node.declaration) {
299
- if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
300
- defineExport(node.end, node.declaration.id.name);
301
- } else {
302
- for (const declaration of node.declaration.declarations) {
303
- const names = extract_names(declaration.id);
304
- for (const name of names)
305
- defineExport(node.end, name);
306
- }
307
- }
308
- s.remove(node.start, node.declaration.start);
309
- } else {
310
- s.remove(node.start, node.end);
311
- if (node.source) {
312
- const importId = defineImportAll(node.source.value);
313
- for (const spec of node.specifiers) {
314
- defineExport(
315
- hoistIndex,
316
- spec.exported.name,
317
- `${importId}.${spec.local.name}`
318
- );
319
- }
320
- } else {
321
- for (const spec of node.specifiers) {
322
- const local = spec.local.name;
323
- const binding = idToImportMap.get(local);
324
- defineExport(node.end, spec.exported.name, binding || local);
325
- }
326
- }
327
- }
328
- }
329
- if (node.type === "ExportDefaultDeclaration") {
330
- const expressionTypes = ["FunctionExpression", "ClassExpression"];
331
- if ("id" in node.declaration && node.declaration.id && !expressionTypes.includes(node.declaration.type)) {
332
- const { name } = node.declaration.id;
333
- s.remove(
334
- node.start,
335
- node.start + 15
336
- /* 'export default '.length */
337
- );
338
- s.append(
339
- `
340
- Object.defineProperty(${viInjectedKey}, "default", { enumerable: true, configurable: true, value: ${name} });`
341
- );
342
- } else {
343
- s.update(
344
- node.start,
345
- node.start + 14,
346
- `${viInjectedKey}.default =`
347
- );
348
- s.append(`
349
- export default { ${viInjectedKey}: ${viInjectedKey}.default };
350
- `);
351
- }
352
- }
353
- if (node.type === "ExportAllDeclaration") {
354
- s.remove(node.start, node.end);
355
- const importId = defineImportAll(node.source.value);
356
- if (node.exported)
357
- defineExport(hoistIndex, node.exported.name, `${importId}`);
358
- else
359
- s.appendLeft(hoistIndex, `${viExportAllHelper}(${viInjectedKey}, ${importId});
360
- `);
361
- }
362
- }
363
- esmWalker(ast, {
364
- onIdentifier(id2, info, parentStack) {
365
- const binding = idToImportMap.get(id2.name);
366
- if (!binding)
367
- return;
368
- if (info.hasBindingShortcut) {
369
- s.appendLeft(id2.end, `: ${binding}`);
370
- } else if (info.classDeclaration) {
371
- if (!declaredConst.has(id2.name)) {
372
- declaredConst.add(id2.name);
373
- const topNode = parentStack[parentStack.length - 2];
374
- s.prependRight(topNode.start, `const ${id2.name} = ${binding};
375
- `);
376
- }
377
- } else if (
378
- // don't transform class name identifier
379
- !info.classExpression
380
- ) {
381
- s.update(id2.start, id2.end, binding);
382
- }
383
- },
384
- // TODO: make env updatable
385
- onImportMeta() {
386
- },
387
- onDynamicImport(node) {
388
- const replace = "__vitest_browser_runner__.wrapModule(import(";
389
- s.overwrite(node.start, node.source.start, replace);
390
- s.overwrite(node.end - 1, node.end, "))");
391
- }
392
- });
393
- s.prepend(`const ${viInjectedKey} = { [Symbol.toStringTag]: "Module" };
394
- `);
395
- s.append(`
396
- export { ${viInjectedKey} }`);
397
- return {
398
- ast,
399
- code: s.toString(),
400
- map: s.generateMap({ hires: "boundary", source: id })
401
- };
402
- }
403
-
404
162
  function assertFileAccess(path, project) {
405
163
  if (!isFileServingAllowed(path, project.server) && !isFileServingAllowed(path, project.ctx.server))
406
164
  throw new Error(`Access denied to "${path}". See Vite config documentation for "server.fs": https://vitejs.dev/config/server-options.html#server-fs-strict.`);
@@ -531,11 +289,13 @@ function generateContextFile(project) {
531
289
  }).join("\n");
532
290
  return `
533
291
  const rpc = () => __vitest_worker__.rpc
292
+ const channel = new BroadcastChannel('vitest')
534
293
 
535
294
  export const server = {
536
295
  platform: ${JSON.stringify(process.platform)},
537
296
  version: ${JSON.stringify(process.version)},
538
297
  provider: ${JSON.stringify(project.browserProvider.name)},
298
+ browser: ${JSON.stringify(project.config.browser.name)},
539
299
  commands: {
540
300
  ${commandsCode}
541
301
  }
@@ -544,15 +304,227 @@ export const commands = server.commands
544
304
  export const page = {
545
305
  get config() {
546
306
  return __vitest_browser_runner__.config
307
+ },
308
+ viewport(width, height) {
309
+ const id = __vitest_browser_runner__.iframeId
310
+ channel.postMessage({ type: 'viewport', width, height, id })
311
+ return new Promise((resolve, reject) => {
312
+ channel.addEventListener('message', function handler(e) {
313
+ if (e.data.type === 'viewport:done' && e.data.id === id) {
314
+ channel.removeEventListener('message', handler)
315
+ resolve()
316
+ }
317
+ if (e.data.type === 'viewport:fail' && e.data.id === id) {
318
+ channel.removeEventListener('message', handler)
319
+ reject(new Error(e.data.error))
320
+ }
321
+ })
322
+ })
547
323
  }
548
324
  }
549
325
  `;
550
326
  }
551
327
 
328
+ function automockModule(code, parse) {
329
+ const ast = parse(code);
330
+ const m = new MagicString(code);
331
+ const allSpecifiers = [];
332
+ let importIndex = 0;
333
+ for (const _node of ast.body) {
334
+ if (_node.type === "ExportAllDeclaration") {
335
+ throw new Error(
336
+ `automocking files with \`export *\` is not supported in browser mode because it cannot be statically analysed`
337
+ );
338
+ }
339
+ if (_node.type === "ExportNamedDeclaration") {
340
+ let traversePattern2 = function(expression) {
341
+ if (expression.type === "Identifier") {
342
+ allSpecifiers.push({ name: expression.name });
343
+ } else if (expression.type === "ArrayPattern") {
344
+ expression.elements.forEach((element) => {
345
+ if (!element)
346
+ return;
347
+ traversePattern2(element);
348
+ });
349
+ } else if (expression.type === "ObjectPattern") {
350
+ expression.properties.forEach((property) => {
351
+ if (property.type === "RestElement")
352
+ traversePattern2(property);
353
+ else if (property.type === "Property")
354
+ traversePattern2(property.value);
355
+ else
356
+ ;
357
+ });
358
+ } else if (expression.type === "RestElement") {
359
+ traversePattern2(expression.argument);
360
+ } else if (expression.type === "AssignmentPattern") {
361
+ throw new Error(`AssignmentPattern is not supported. Please open a new bug report.`);
362
+ } else if (expression.type === "MemberExpression") {
363
+ throw new Error(`MemberExpression is not supported. Please open a new bug report.`);
364
+ } else ;
365
+ };
366
+ const node = _node;
367
+ const declaration = node.declaration;
368
+ if (declaration) {
369
+ if (declaration.type === "FunctionDeclaration") {
370
+ allSpecifiers.push({ name: declaration.id.name });
371
+ } else if (declaration.type === "VariableDeclaration") {
372
+ declaration.declarations.forEach((declaration2) => {
373
+ traversePattern2(declaration2.id);
374
+ });
375
+ } else if (declaration.type === "ClassDeclaration") {
376
+ allSpecifiers.push({ name: declaration.id.name });
377
+ } else ;
378
+ m.remove(node.start, declaration.start);
379
+ }
380
+ const specifiers = node.specifiers || [];
381
+ const source = node.source;
382
+ if (!source && specifiers.length) {
383
+ specifiers.forEach((specifier) => {
384
+ const exported = specifier.exported;
385
+ allSpecifiers.push({
386
+ alias: exported.type === "Literal" ? exported.raw : exported.name,
387
+ name: specifier.local.name
388
+ });
389
+ });
390
+ m.remove(node.start, node.end);
391
+ } else if (source && specifiers.length) {
392
+ const importNames = [];
393
+ specifiers.forEach((specifier) => {
394
+ const importedName = `__vitest_imported_${importIndex++}__`;
395
+ const exported = specifier.exported;
396
+ importNames.push([specifier.local.name, importedName]);
397
+ allSpecifiers.push({
398
+ name: importedName,
399
+ alias: exported.type === "Literal" ? exported.raw : exported.name
400
+ });
401
+ });
402
+ const importString = `import { ${importNames.map(([name, alias]) => `${name} as ${alias}`).join(", ")} } from '${source.value}'`;
403
+ m.overwrite(node.start, node.end, importString);
404
+ }
405
+ }
406
+ if (_node.type === "ExportDefaultDeclaration") {
407
+ const node = _node;
408
+ const declaration = node.declaration;
409
+ allSpecifiers.push({ name: "__vitest_default", alias: "default" });
410
+ m.overwrite(node.start, declaration.start, `const __vitest_default = `);
411
+ }
412
+ }
413
+ const moduleObject = `
414
+ const __vitest_es_current_module__ = {
415
+ __esModule: true,
416
+ ${allSpecifiers.map(({ name }) => `["${name}"]: ${name},`).join("\n ")}
417
+ }
418
+ const __vitest_mocked_module__ = __vitest_mocker__.mockObject(__vitest_es_current_module__)
419
+ `;
420
+ const assigning = allSpecifiers.map(({ name }, index) => {
421
+ return `const __vitest_mocked_${index}__ = __vitest_mocked_module__["${name}"]`;
422
+ }).join("\n");
423
+ const redeclarations = allSpecifiers.map(({ name, alias }, index) => {
424
+ return ` __vitest_mocked_${index}__ as ${alias || name},`;
425
+ }).join("\n");
426
+ const specifiersExports = `
427
+ export {
428
+ ${redeclarations}
429
+ }
430
+ `;
431
+ m.append(moduleObject + assigning + specifiersExports);
432
+ return m;
433
+ }
434
+
435
+ var BrowserMocker = (project) => {
436
+ return [
437
+ {
438
+ name: "vitest:browser:mocker",
439
+ enforce: "pre",
440
+ async load(id) {
441
+ const data = project.browserMocker.mocks.get(id);
442
+ if (!data)
443
+ return;
444
+ const { mock, sessionId } = data;
445
+ if (mock === void 0) {
446
+ const rpc = project.browserRpc.testers.get(sessionId);
447
+ if (!rpc)
448
+ throw new Error(`WebSocket rpc was destroyed for session ${sessionId}`);
449
+ const exports = await rpc.startMocking(id);
450
+ const module = `const module = __vitest_mocker__.get('${id}');`;
451
+ const keys = exports.map((name) => {
452
+ if (name === "default")
453
+ return `export default module['default'];`;
454
+ return `export const ${name} = module['${name}'];`;
455
+ }).join("\n");
456
+ return `${module}
457
+ ${keys}`;
458
+ }
459
+ if (mock === null)
460
+ return;
461
+ return readFile$1(mock, "utf-8");
462
+ }
463
+ },
464
+ {
465
+ name: "vitest:browser:automocker",
466
+ enforce: "post",
467
+ transform(code, id) {
468
+ const data = project.browserMocker.mocks.get(id);
469
+ if (!data)
470
+ return;
471
+ if (data.mock === null) {
472
+ const m = automockModule(code, this.parse);
473
+ return {
474
+ code: m.toString(),
475
+ map: m.generateMap({ hires: "boundary", source: id })
476
+ };
477
+ }
478
+ }
479
+ }
480
+ ];
481
+ };
482
+
483
+ function injectDynamicImport(code, id, parse) {
484
+ const s = new MagicString(code);
485
+ let ast;
486
+ try {
487
+ ast = parse(code);
488
+ } catch (err) {
489
+ console.error(`Cannot parse ${id}:
490
+ ${err.message}`);
491
+ return;
492
+ }
493
+ esmWalker(ast, {
494
+ // TODO: make env updatable
495
+ onImportMeta() {
496
+ },
497
+ onDynamicImport(node) {
498
+ const replace = "__vitest_browser_runner__.wrapModule(() => import(";
499
+ s.overwrite(node.start, node.source.start, replace);
500
+ s.overwrite(node.end - 1, node.end, "))");
501
+ }
502
+ });
503
+ return {
504
+ ast,
505
+ code: s.toString(),
506
+ map: s.generateMap({ hires: "boundary", source: id })
507
+ };
508
+ }
509
+
510
+ const regexDynamicImport = /import\s*\(/;
511
+ var DynamicImport = () => {
512
+ return {
513
+ name: "vitest:browser:esm-injector",
514
+ enforce: "post",
515
+ transform(source, id) {
516
+ if (!regexDynamicImport.test(source))
517
+ return;
518
+ return injectDynamicImport(source, id, this.parse);
519
+ }
520
+ };
521
+ };
522
+
552
523
  var index = (project, base = "/") => {
553
524
  const pkgRoot = resolve(fileURLToPath(import.meta.url), "../..");
554
525
  const distRoot = resolve(pkgRoot, "dist");
555
526
  return [
527
+ ...BrowserMocker(project),
556
528
  {
557
529
  enforce: "pre",
558
530
  name: "vitest:browser",
@@ -565,8 +537,11 @@ var index = (project, base = "/") => {
565
537
  },
566
538
  async configureServer(server) {
567
539
  const testerHtml = readFile$1(resolve(distRoot, "client/tester.html"), "utf8");
568
- const runnerHtml = readFile$1(resolve(distRoot, "client/index.html"), "utf8");
540
+ const orchestratorHtml = project.config.browser.ui ? readFile$1(resolve(distRoot, "client/__vitest__/index.html"), "utf8") : readFile$1(resolve(distRoot, "client/orchestrator.html"), "utf8");
569
541
  const injectorJs = readFile$1(resolve(distRoot, "client/esm-client-injector.js"), "utf8");
542
+ const manifest = (async () => {
543
+ return JSON.parse(await readFile$1(`${distRoot}/client/.vite/manifest.json`, "utf8"));
544
+ })();
570
545
  const favicon = `${base}favicon.svg`;
571
546
  const testerPrefix = `${base}__vitest_test__/__test__/`;
572
547
  server.middlewares.use((_req, res, next) => {
@@ -593,12 +568,26 @@ var index = (project, base = "/") => {
593
568
  config.env.VITEST_BROWSER_DEBUG = process.env.VITEST_BROWSER_DEBUG || "";
594
569
  const injector = replacer(await injectorJs, {
595
570
  __VITEST_CONFIG__: JSON.stringify(config),
596
- __VITEST_FILES__: JSON.stringify(files)
571
+ __VITEST_FILES__: JSON.stringify(files),
572
+ __VITEST_TYPE__: url.pathname === base ? '"orchestrator"' : '"tester"'
597
573
  });
598
574
  if (url.pathname === base) {
599
575
  if (!indexScripts)
600
576
  indexScripts = await formatScripts(project.config.browser.indexScripts, server);
601
- const html2 = replacer(await runnerHtml, {
577
+ let baseHtml = await orchestratorHtml;
578
+ if (project.config.browser.ui) {
579
+ const manifestContent = await manifest;
580
+ const jsEntry = manifestContent["orchestrator.html"].file;
581
+ baseHtml = baseHtml.replaceAll("./assets/", `${base}__vitest__/assets/`).replace(
582
+ "<!-- !LOAD_METADATA! -->",
583
+ [
584
+ "<script>{__VITEST_INJECTOR__}<\/script>",
585
+ "{__VITEST_SCRIPTS__}",
586
+ `<script type="module" crossorigin src="${jsEntry}"><\/script>`
587
+ ].join("\n")
588
+ );
589
+ }
590
+ const html2 = replacer(baseHtml, {
602
591
  __VITEST_FAVICON__: favicon,
603
592
  __VITEST_TITLE__: "Vitest Browser Runner",
604
593
  __VITEST_SCRIPTS__: indexScripts,
@@ -610,6 +599,7 @@ var index = (project, base = "/") => {
610
599
  }
611
600
  const decodedTestFile = decodeURIComponent(url.pathname.slice(testerPrefix.length));
612
601
  const tests = decodedTestFile === "__vitest_all__" || !files.includes(decodedTestFile) ? "__vitest_browser_runner__.files" : JSON.stringify([decodedTestFile]);
602
+ const iframeId = decodedTestFile === "__vitest_all__" ? '"__vitest_all__"' : JSON.stringify(decodedTestFile);
613
603
  if (!testerScripts)
614
604
  testerScripts = await formatScripts(project.config.browser.testerScripts, server);
615
605
  const html = replacer(await testerHtml, {
@@ -621,6 +611,7 @@ var index = (project, base = "/") => {
621
611
  // TODO: have only a single global variable to not pollute the global scope
622
612
  `<script type="module">
623
613
  __vitest_browser_runner__.runningFiles = ${tests}
614
+ __vitest_browser_runner__.iframeId = ${iframeId}
624
615
  __vitest_browser_runner__.runTests(__vitest_browser_runner__.runningFiles)
625
616
  <\/script>`
626
617
  )
@@ -677,6 +668,9 @@ var index = (project, base = "/") => {
677
668
  "vitest/browser",
678
669
  "vitest/runners",
679
670
  "@vitest/utils",
671
+ "std-env",
672
+ "tinybench",
673
+ "tinyspy",
680
674
  // loupe is manually transformed
681
675
  "loupe"
682
676
  ],
@@ -714,16 +708,7 @@ export default globalThis.loupe`;
714
708
  }
715
709
  },
716
710
  BrowserContext(project),
717
- {
718
- name: "vitest:browser:esm-injector",
719
- enforce: "post",
720
- transform(source, id) {
721
- const hijackESM = project.config.browser.slowHijackESM ?? false;
722
- if (!hijackESM)
723
- return;
724
- return injectVitestModule(source, id, this.parse);
725
- }
726
- }
711
+ DynamicImport()
727
712
  ];
728
713
  };
729
714
  function resolveCoverageFolder(project) {
@@ -736,7 +721,7 @@ function resolveCoverageFolder(project) {
736
721
  if (!htmlReporter)
737
722
  return void 0;
738
723
  const root = resolve(
739
- options.root || options.root || process.cwd(),
724
+ options.root || process.cwd(),
740
725
  options.coverage.reportsDirectory || coverageConfigDefaults.reportsDirectory
741
726
  );
742
727
  const subdir = Array.isArray(htmlReporter) && htmlReporter.length > 1 && "subdir" in htmlReporter[1] ? htmlReporter[1].subdir : void 0;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/browser",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.3",
4
+ "version": "2.0.0-beta.6",
5
5
  "description": "Browser running for Vitest",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -47,7 +47,7 @@
47
47
  "peerDependencies": {
48
48
  "playwright": "*",
49
49
  "webdriverio": "*",
50
- "vitest": "2.0.0-beta.3"
50
+ "vitest": "2.0.0-beta.6"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "playwright": {
@@ -63,20 +63,22 @@
63
63
  "dependencies": {
64
64
  "magic-string": "^0.30.10",
65
65
  "sirv": "^2.0.4",
66
- "@vitest/utils": "2.0.0-beta.3"
66
+ "@vitest/utils": "2.0.0-beta.6"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@types/ws": "^8.5.10",
70
70
  "@wdio/protocols": "^8.32.0",
71
+ "birpc": "0.2.17",
72
+ "flatted": "^3.3.1",
71
73
  "periscopic": "^4.0.2",
72
74
  "playwright": "^1.44.0",
73
75
  "playwright-core": "^1.44.0",
74
76
  "safaridriver": "^0.1.2",
75
77
  "webdriverio": "^8.36.1",
76
- "@vitest/runner": "2.0.0-beta.3",
77
- "@vitest/ui": "2.0.0-beta.3",
78
- "@vitest/ws-client": "2.0.0-beta.3",
79
- "vitest": "2.0.0-beta.3"
78
+ "@vitest/ui": "2.0.0-beta.6",
79
+ "@vitest/runner": "2.0.0-beta.6",
80
+ "@vitest/ws-client": "2.0.0-beta.6",
81
+ "vitest": "2.0.0-beta.6"
80
82
  },
81
83
  "scripts": {
82
84
  "build": "rimraf dist && pnpm build:node && pnpm build:client",