@vitest/browser 3.0.0-beta.3 → 3.0.0

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/client.js CHANGED
@@ -201,9 +201,9 @@ const parse = (text, reviver) => {
201
201
  * @returns {string}
202
202
  */
203
203
  const stringify = (value, replacer, space) => {
204
- const $ = replacer && typeof replacer === object ?
204
+ const $ = typeof replacer === object ?
205
205
  (k, v) => (k === '' || -1 < replacer.indexOf(k) ? v : void 0) :
206
- (replacer || noop);
206
+ (replacer);
207
207
  const known = new Map;
208
208
  const input = [];
209
209
  const output = [];
@@ -257,7 +257,8 @@ const PAGE_TYPE = getBrowserState().type;
257
257
  const PORT = location.port;
258
258
  const HOST = [location.hostname, PORT].filter(Boolean).join(":");
259
259
  const RPC_ID = PAGE_TYPE === "orchestrator" ? getBrowserState().sessionId : getBrowserState().testerId;
260
- const ENTRY_URL = `${location.protocol === "https:" ? "wss:" : "ws:"}//${HOST}/__vitest_browser_api__?type=${PAGE_TYPE}&rpcId=${RPC_ID}&sessionId=${getBrowserState().sessionId}&projectName=${getBrowserState().config.name || ""}`;
260
+ const METHOD = getBrowserState().method;
261
+ const ENTRY_URL = `${location.protocol === "https:" ? "wss:" : "ws:"}//${HOST}/__vitest_browser_api__?type=${PAGE_TYPE}&rpcId=${RPC_ID}&sessionId=${getBrowserState().sessionId}&projectName=${getBrowserState().config.name || ""}&method=${METHOD}`;
261
262
  let setCancel = (_) => {
262
263
  };
263
264
  const onCancel = new Promise((resolve) => {
package/dist/context.js CHANGED
@@ -129,7 +129,8 @@ function createUserEvent(__tl_user_event_base__, options) {
129
129
  const keyboard = {
130
130
  unreleased: []
131
131
  };
132
- return {
132
+ const modifier = provider === `playwright` ? "ControlOrMeta" : provider === "webdriverio" ? "Ctrl" : "Control";
133
+ const userEvent = {
133
134
  setup() {
134
135
  return createUserEvent();
135
136
  },
@@ -199,11 +200,22 @@ function createUserEvent(__tl_user_event_base__, options) {
199
200
  );
200
201
  keyboard.unreleased = unreleased;
201
202
  });
203
+ },
204
+ async copy() {
205
+ await userEvent.keyboard(`{${modifier}>}{c}{/${modifier}}`);
206
+ },
207
+ async cut() {
208
+ await userEvent.keyboard(`{${modifier}>}{x}{/${modifier}}`);
209
+ },
210
+ async paste() {
211
+ await userEvent.keyboard(`{${modifier}>}{v}{/${modifier}}`);
202
212
  }
203
213
  };
214
+ return userEvent;
204
215
  }
205
216
  function createPreviewUserEvent(userEventBase, options) {
206
217
  let userEvent = userEventBase.setup(options);
218
+ let clipboardData;
207
219
  function toElement(element) {
208
220
  return element instanceof Element ? element : element.element();
209
221
  }
@@ -271,6 +283,15 @@ function createPreviewUserEvent(userEventBase, options) {
271
283
  },
272
284
  async keyboard(text) {
273
285
  await userEvent.keyboard(text);
286
+ },
287
+ async copy() {
288
+ clipboardData = await userEvent.copy();
289
+ },
290
+ async cut() {
291
+ clipboardData = await userEvent.cut();
292
+ },
293
+ async paste() {
294
+ await userEvent.paste(clipboardData);
274
295
  }
275
296
  };
276
297
  for (const [name, fn] of Object.entries(vitestUserEvent)) {
@@ -235,6 +235,15 @@ class Locator {
235
235
  all() {
236
236
  return this.elements().map((element) => this.elementLocator(element));
237
237
  }
238
+ nth(index) {
239
+ return this.locator(`nth=${index}`);
240
+ }
241
+ first() {
242
+ return this.nth(0);
243
+ }
244
+ last() {
245
+ return this.nth(-1);
246
+ }
238
247
  toString() {
239
248
  return this.selector;
240
249
  }
package/dist/index.d.ts CHANGED
@@ -3,9 +3,10 @@ import { CDPSession, BrowserServerState as BrowserServerState$1, ProjectBrowser
3
3
  import * as vite from 'vite';
4
4
  import { HtmlTagDescriptor } from 'vite';
5
5
  import * as vitest from 'vitest';
6
- import { RunnerTestFile, TaskResultPack, AfterSuiteRunMeta, CancelReason, UserConsoleLog, SnapshotResult, SerializedConfig, ErrorWithDiff, ParsedStack } from 'vitest';
6
+ import { RunnerTestFile, AfterSuiteRunMeta, CancelReason, UserConsoleLog, SnapshotResult, SerializedConfig, ErrorWithDiff, ParsedStack } from 'vitest';
7
7
  import { StackTraceParserOptions } from '@vitest/utils/source-map';
8
8
  import { ServerIdResolution, ServerMockResolution } from '@vitest/mocker/node';
9
+ import { TaskResultPack, TaskEventPack } from '@vitest/runner';
9
10
 
10
11
  type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
11
12
  type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
@@ -28,8 +29,8 @@ interface WebSocketBrowserHandlers {
28
29
  resolveSnapshotRawPath: (testPath: string, rawPath: string) => string;
29
30
  onUnhandledError: (error: unknown, type: string) => Promise<void>;
30
31
  onQueued: (file: RunnerTestFile) => void;
31
- onCollected: (files?: RunnerTestFile[]) => Promise<void>;
32
- onTaskUpdate: (packs: TaskResultPack[]) => void;
32
+ onCollected: (files: RunnerTestFile[]) => Promise<void>;
33
+ onTaskUpdate: (packs: TaskResultPack[], events: TaskEventPack[]) => void;
33
34
  onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void;
34
35
  onCancel: (reason: CancelReason) => void;
35
36
  getCountOfFailedTests: () => number;
package/dist/index.js CHANGED
@@ -11,12 +11,12 @@ import { fileURLToPath } from 'node:url';
11
11
  import crypto from 'node:crypto';
12
12
  import { mkdir, readFile as readFile$1 } from 'node:fs/promises';
13
13
  import { parseErrorStacktrace, parseStacktrace } from '@vitest/utils/source-map';
14
- import { P as PlaywrightBrowserProvider, W as WebdriverBrowserProvider } from './webdriver-dkCg9pjp.js';
14
+ import { P as PlaywrightBrowserProvider, W as WebdriverBrowserProvider } from './webdriver-kh_HHy0p.js';
15
15
  import { resolve as resolve$1, dirname as dirname$1, basename as basename$1, normalize as normalize$1 } from 'node:path';
16
16
  import { WebSocketServer } from 'ws';
17
17
  import * as nodeos from 'node:os';
18
18
 
19
- var version = "3.0.0-beta.3";
19
+ var version = "3.0.0";
20
20
 
21
21
  const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
22
22
  function normalizeWindowsPath(input = "") {
@@ -30,6 +30,8 @@ const _UNC_REGEX = /^[/\\]{2}/;
30
30
  const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
31
31
  const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
32
32
  const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
33
+ const _EXTNAME_RE = /.(\.[^./]+)$/;
34
+ globalThis.process?.platform === "win32" ? ";" : ":";
33
35
  const normalize = function(path) {
34
36
  if (path.length === 0) {
35
37
  return ".";
@@ -59,24 +61,26 @@ const normalize = function(path) {
59
61
  }
60
62
  return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
61
63
  };
62
- const join = function(...arguments_) {
63
- if (arguments_.length === 0) {
64
- return ".";
65
- }
66
- let joined;
67
- for (const argument of arguments_) {
68
- if (argument && argument.length > 0) {
69
- if (joined === void 0) {
70
- joined = argument;
64
+ const join = function(...segments) {
65
+ let path = "";
66
+ for (const seg of segments) {
67
+ if (!seg) {
68
+ continue;
69
+ }
70
+ if (path.length > 0) {
71
+ const pathTrailing = path[path.length - 1] === "/";
72
+ const segLeading = seg[0] === "/";
73
+ const both = pathTrailing && segLeading;
74
+ if (both) {
75
+ path += seg.slice(1);
71
76
  } else {
72
- joined += `/${argument}`;
77
+ path += pathTrailing || segLeading ? seg : `/${seg}`;
73
78
  }
79
+ } else {
80
+ path += seg;
74
81
  }
75
82
  }
76
- if (joined === void 0) {
77
- return ".";
78
- }
79
- return normalize(joined.replace(/\/\/+/g, "/"));
83
+ return normalize(path);
80
84
  };
81
85
  function cwd() {
82
86
  if (typeof process !== "undefined" && typeof process.cwd === "function") {
@@ -164,7 +168,6 @@ function normalizeString(path, allowAboveRoot) {
164
168
  const isAbsolute = function(p) {
165
169
  return _IS_ABSOLUTE_RE.test(p);
166
170
  };
167
- const _EXTNAME_RE = /.(\.[^./]+)$/;
168
171
  const extname = function(p) {
169
172
  const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
170
173
  return match && match[1] || "";
@@ -193,7 +196,15 @@ const dirname = function(p) {
193
196
  return segments.join("/") || (isAbsolute(p) ? "/" : ".");
194
197
  };
195
198
  const basename = function(p, extension) {
196
- const lastSegment = normalizeWindowsPath(p).split("/").pop();
199
+ const segments = normalizeWindowsPath(p).split("/");
200
+ let lastSegment = "";
201
+ for (let i = segments.length - 1; i >= 0; i--) {
202
+ const val = segments[i];
203
+ if (val) {
204
+ lastSegment = val;
205
+ break;
206
+ }
207
+ }
197
208
  return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
198
209
  };
199
210
 
@@ -251,6 +262,7 @@ async function resolveOrchestrator(globalServer, url, res) {
251
262
  __VITEST_VITE_CONFIG__: JSON.stringify({
252
263
  root: browserProject.vite.config.root
253
264
  }),
265
+ __VITEST_METHOD__: JSON.stringify(session?.method || "run"),
254
266
  __VITEST_FILES__: JSON.stringify(files),
255
267
  __VITEST_TYPE__: '"orchestrator"',
256
268
  __VITEST_SESSION_ID__: JSON.stringify(sessionId),
@@ -468,6 +480,7 @@ async function resolveTester(globalServer, url, res, next) {
468
480
  root: browserProject.vite.config.root
469
481
  }),
470
482
  __VITEST_TYPE__: '"tester"',
483
+ __VITEST_METHOD__: JSON.stringify(method),
471
484
  __VITEST_SESSION_ID__: JSON.stringify(sessionId),
472
485
  __VITEST_TESTER_ID__: JSON.stringify(crypto.randomUUID()),
473
486
  __VITEST_PROVIDED_CONTEXT__: JSON.stringify(stringify(project.getProvidedContext()))
@@ -688,7 +701,7 @@ var BrowserPlugin = (parentServer, base = "/") => {
688
701
  name: "vitest:browser:tests",
689
702
  enforce: "pre",
690
703
  async config() {
691
- const project = parentServer.vitest.getProjectByName(parentServer.config.name);
704
+ const project = parentServer.project;
692
705
  const { testFiles: allTestFiles } = await project.globTestFiles();
693
706
  const browserTestFiles = allTestFiles.filter(
694
707
  (file) => getFilePoolName(project, file) === "browser"
@@ -766,6 +779,14 @@ var BrowserPlugin = (parentServer, base = "/") => {
766
779
  if (svelte) {
767
780
  exclude.push("vitest-browser-svelte");
768
781
  }
782
+ const vue = isPackageExists("vitest-browser-vue", fileRoot);
783
+ if (vue) {
784
+ include.push(
785
+ "vitest-browser-vue",
786
+ "vitest-browser-vue > @vue/test-utils",
787
+ "vitest-browser-vue > @vue/test-utils > @vue/compiler-core"
788
+ );
789
+ }
769
790
  const vueTestUtils = isPackageExists("@vue/test-utils", fileRoot);
770
791
  if (vueTestUtils) {
771
792
  include.push("@vue/test-utils");
@@ -877,7 +898,7 @@ var BrowserPlugin = (parentServer, base = "/") => {
877
898
  name: "vitest:browser:in-source-tests",
878
899
  transform(code, id) {
879
900
  const project = parentServer.vitest.getProjectByName(parentServer.config.name);
880
- if (!project.isCachedTestFile(id) || !code.includes("import.meta.vitest")) {
901
+ if (!project._isCachedTestFile(id) || !code.includes("import.meta.vitest")) {
881
902
  return;
882
903
  }
883
904
  const s = new MagicString(code, { filename: cleanUrl(id) });
@@ -1018,9 +1039,8 @@ body {
1018
1039
  {
1019
1040
  name: "test-utils-rewrite",
1020
1041
  setup(build) {
1021
- build.onResolve({ filter: /^@vue\/test-utils$/ }, (args) => {
1022
- const _require2 = getRequire();
1023
- const resolved = _require2.resolve(args.path, {
1042
+ build.onResolve({ filter: /^@vue\/(test-utils|compiler-core)$/ }, (args) => {
1043
+ const resolved = getRequire().resolve(args.path, {
1024
1044
  paths: [args.importer]
1025
1045
  });
1026
1046
  return { path: resolved };
@@ -2084,7 +2104,7 @@ const keyboardCleanup = async (context, state) => {
2084
2104
  throw new TypeError(`Provider "${context.provider.name}" does not support keyboard api`);
2085
2105
  }
2086
2106
  };
2087
- const VALID_KEYS = /* @__PURE__ */ new Set(["Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backquote", "`", "~", "Digit1", "1", "!", "Digit2", "2", "@", "Digit3", "3", "#", "Digit4", "4", "$", "Digit5", "5", "%", "Digit6", "6", "^", "Digit7", "7", "&", "Digit8", "8", "*", "Digit9", "9", "(", "Digit0", "0", ")", "Minus", "-", "_", "Equal", "=", "+", "Backslash", "\\", "|", "Backspace", "Tab", "KeyQ", "q", "Q", "KeyW", "w", "W", "KeyE", "e", "E", "KeyR", "r", "R", "KeyT", "t", "T", "KeyY", "y", "Y", "KeyU", "u", "U", "KeyI", "i", "I", "KeyO", "o", "O", "KeyP", "p", "P", "BracketLeft", "[", "{", "BracketRight", "]", "}", "CapsLock", "KeyA", "a", "A", "KeyS", "s", "S", "KeyD", "d", "D", "KeyF", "f", "F", "KeyG", "g", "G", "KeyH", "h", "H", "KeyJ", "j", "J", "KeyK", "k", "K", "KeyL", "l", "L", "Semicolon", ";", ":", "Quote", "'", '"', "Enter", "\n", "\r", "ShiftLeft", "Shift", "KeyZ", "z", "Z", "KeyX", "x", "X", "KeyC", "c", "C", "KeyV", "v", "V", "KeyB", "b", "B", "KeyN", "n", "N", "KeyM", "m", "M", "Comma", ",", "<", "Period", ".", ">", "Slash", "/", "?", "ShiftRight", "ControlLeft", "Control", "MetaLeft", "Meta", "AltLeft", "Alt", "Space", " ", "AltRight", "AltGraph", "MetaRight", "ContextMenu", "ControlRight", "PrintScreen", "ScrollLock", "Pause", "PageUp", "PageDown", "Insert", "Delete", "Home", "End", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown", "NumLock", "NumpadDivide", "NumpadMultiply", "NumpadSubtract", "Numpad7", "Numpad8", "Numpad9", "Numpad4", "Numpad5", "Numpad6", "NumpadAdd", "Numpad1", "Numpad2", "Numpad3", "Numpad0", "NumpadDecimal", "NumpadEnter"]);
2107
+ const VALID_KEYS = /* @__PURE__ */ new Set(["Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backquote", "`", "~", "Digit1", "1", "!", "Digit2", "2", "@", "Digit3", "3", "#", "Digit4", "4", "$", "Digit5", "5", "%", "Digit6", "6", "^", "Digit7", "7", "&", "Digit8", "8", "*", "Digit9", "9", "(", "Digit0", "0", ")", "Minus", "-", "_", "Equal", "=", "+", "Backslash", "\\", "|", "Backspace", "Tab", "KeyQ", "q", "Q", "KeyW", "w", "W", "KeyE", "e", "E", "KeyR", "r", "R", "KeyT", "t", "T", "KeyY", "y", "Y", "KeyU", "u", "U", "KeyI", "i", "I", "KeyO", "o", "O", "KeyP", "p", "P", "BracketLeft", "[", "{", "BracketRight", "]", "}", "CapsLock", "KeyA", "a", "A", "KeyS", "s", "S", "KeyD", "d", "D", "KeyF", "f", "F", "KeyG", "g", "G", "KeyH", "h", "H", "KeyJ", "j", "J", "KeyK", "k", "K", "KeyL", "l", "L", "Semicolon", ";", ":", "Quote", "'", '"', "Enter", "\n", "\r", "ShiftLeft", "Shift", "KeyZ", "z", "Z", "KeyX", "x", "X", "KeyC", "c", "C", "KeyV", "v", "V", "KeyB", "b", "B", "KeyN", "n", "N", "KeyM", "m", "M", "Comma", ",", "<", "Period", ".", ">", "Slash", "/", "?", "ShiftRight", "ControlLeft", "Control", "MetaLeft", "Meta", "AltLeft", "Alt", "Space", " ", "AltRight", "AltGraph", "MetaRight", "ContextMenu", "ControlRight", "PrintScreen", "ScrollLock", "Pause", "PageUp", "PageDown", "Insert", "Delete", "Home", "End", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown", "NumLock", "NumpadDivide", "NumpadMultiply", "NumpadSubtract", "Numpad7", "Numpad8", "Numpad9", "Numpad4", "Numpad5", "Numpad6", "NumpadAdd", "Numpad1", "Numpad2", "Numpad3", "Numpad0", "NumpadDecimal", "NumpadEnter", "ControlOrMeta"]);
2088
2108
  async function keyboardImplementation(pressed, provider, sessionId, text, selectAll2, skipRelease) {
2089
2109
  if (provider instanceof PlaywrightBrowserProvider) {
2090
2110
  const page = provider.getPage(sessionId);
@@ -2132,8 +2152,7 @@ async function keyboardImplementation(pressed, provider, sessionId, text, select
2132
2152
  let keyboard2 = browser.action("key");
2133
2153
  for (const { releasePrevious, releaseSelf, repeat, keyDef } of actions) {
2134
2154
  let key = keyDef.key;
2135
- const code = "location" in keyDef ? keyDef.key : keyDef.code;
2136
- const special = Key[code];
2155
+ const special = Key[key];
2137
2156
  if (special) {
2138
2157
  key = special;
2139
2158
  }
@@ -2802,6 +2821,12 @@ function setupBrowserRpc(globalServer) {
2802
2821
  new Error(`[vitest] Invalid URL ${request.url}. "projectName", "sessionId" and "rpcId" queries are required.`)
2803
2822
  );
2804
2823
  }
2824
+ const method = searchParams.get("method");
2825
+ if (method !== "run" && method !== "collect") {
2826
+ return error(
2827
+ new Error(`[vitest] Method query in ${request.url} is invalid. Method should be either "run" or "collect".`)
2828
+ );
2829
+ }
2805
2830
  if (type === "orchestrator") {
2806
2831
  const session = vitest._browserSessions.getSession(sessionId);
2807
2832
  session?.connected();
@@ -2814,7 +2839,7 @@ function setupBrowserRpc(globalServer) {
2814
2839
  }
2815
2840
  wss.handleUpgrade(request, socket, head, (ws) => {
2816
2841
  wss.emit("connection", ws, request);
2817
- const rpc = setupClient(project, rpcId, ws);
2842
+ const rpc = setupClient(project, rpcId, ws, method);
2818
2843
  const state = project.browser.state;
2819
2844
  const clients = type === "tester" ? state.testers : state.orchestrators;
2820
2845
  clients.set(rpcId, rpc);
@@ -2837,7 +2862,7 @@ function setupBrowserRpc(globalServer) {
2837
2862
  );
2838
2863
  }
2839
2864
  }
2840
- function setupClient(project, rpcId, ws) {
2865
+ function setupClient(project, rpcId, ws, method) {
2841
2866
  const mockResolver = new ServerMockResolver(globalServer.vite, {
2842
2867
  moduleDirectories: project.config.server?.deps?.moduleDirectories
2843
2868
  });
@@ -2851,23 +2876,35 @@ function setupBrowserRpc(globalServer) {
2851
2876
  vitest.state.catchError(error2, type);
2852
2877
  },
2853
2878
  async onQueued(file) {
2854
- vitest.state.collectFiles(project, [file]);
2855
- const testModule = vitest.state.getReportedEntity(file);
2856
- await vitest.report("onTestModuleQueued", testModule);
2879
+ if (method === "collect") {
2880
+ vitest.state.collectFiles(project, [file]);
2881
+ } else {
2882
+ await vitest._testRun.enqueued(project, file);
2883
+ }
2857
2884
  },
2858
2885
  async onCollected(files) {
2859
- vitest.state.collectFiles(project, files);
2860
- await vitest.report("onCollected", files);
2886
+ if (method === "collect") {
2887
+ vitest.state.collectFiles(project, files);
2888
+ } else {
2889
+ await vitest._testRun.collected(project, files);
2890
+ }
2861
2891
  },
2862
- async onTaskUpdate(packs) {
2863
- vitest.state.updateTasks(packs);
2864
- await vitest.report("onTaskUpdate", packs);
2892
+ async onTaskUpdate(packs, events) {
2893
+ if (method === "collect") {
2894
+ vitest.state.updateTasks(packs);
2895
+ } else {
2896
+ await vitest._testRun.updated(packs, events);
2897
+ }
2865
2898
  },
2866
2899
  onAfterSuiteRun(meta) {
2867
2900
  vitest.coverageProvider?.onAfterSuiteRun(meta);
2868
2901
  },
2869
- sendLog(log) {
2870
- return vitest.report("onUserConsoleLog", log);
2902
+ async sendLog(log) {
2903
+ if (method === "collect") {
2904
+ vitest.state.updateUserLog(log);
2905
+ } else {
2906
+ await vitest._testRun.log(log);
2907
+ }
2871
2908
  },
2872
2909
  resolveSnapshotPath(testPath) {
2873
2910
  return vitest.snapshot.resolvePath(testPath, {
@@ -253,6 +253,9 @@ declare abstract class Locator {
253
253
  element(): Element;
254
254
  elements(): Element[];
255
255
  all(): Locator[];
256
+ nth(index: number): Locator;
257
+ first(): Locator;
258
+ last(): Locator;
256
259
  toString(): string;
257
260
  toJSON(): string;
258
261
  private get state();
@@ -1,4 +1,4 @@
1
1
  import '@vitest/browser/context';
2
2
  import '../public-utils-D6S2-5kI.js';
3
- export { L as Locator, s as selectorEngine } from '../index-VFFcOojA.js';
3
+ export { L as Locator, s as selectorEngine } from '../index-Dos_sf7B.js';
4
4
  import 'vitest/utils';
@@ -1,6 +1,6 @@
1
1
  import { page, server } from '@vitest/browser/context';
2
2
  import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector } from '../public-utils-D6S2-5kI.js';
3
- import { s as selectorEngine, L as Locator } from '../index-VFFcOojA.js';
3
+ import { s as selectorEngine, L as Locator } from '../index-Dos_sf7B.js';
4
4
  import 'vitest/utils';
5
5
 
6
6
  page.extend({
@@ -1,6 +1,6 @@
1
1
  import { page, server, userEvent } from '@vitest/browser/context';
2
2
  import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector, h as getElementError } from '../public-utils-D6S2-5kI.js';
3
- import { s as selectorEngine, L as Locator, c as convertElementToCssSelector } from '../index-VFFcOojA.js';
3
+ import { s as selectorEngine, L as Locator, c as convertElementToCssSelector } from '../index-Dos_sf7B.js';
4
4
  import 'vitest/utils';
5
5
 
6
6
  page.extend({
@@ -1,6 +1,6 @@
1
1
  import { page, server } from '@vitest/browser/context';
2
2
  import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector, h as getElementError } from '../public-utils-D6S2-5kI.js';
3
- import { s as selectorEngine, L as Locator, c as convertElementToCssSelector } from '../index-VFFcOojA.js';
3
+ import { s as selectorEngine, L as Locator, c as convertElementToCssSelector } from '../index-Dos_sf7B.js';
4
4
  import 'vitest/utils';
5
5
 
6
6
  page.extend({
package/dist/providers.js CHANGED
@@ -1,4 +1,4 @@
1
- import { W as WebdriverBrowserProvider, P as PlaywrightBrowserProvider } from './webdriver-dkCg9pjp.js';
1
+ import { W as WebdriverBrowserProvider, P as PlaywrightBrowserProvider } from './webdriver-kh_HHy0p.js';
2
2
 
3
3
  class PreviewBrowserProvider {
4
4
  name = "preview";
@@ -129,6 +129,10 @@ class PlaywrightBrowserProvider {
129
129
  );
130
130
  });
131
131
  }
132
+ page.on("crash", () => {
133
+ const session = this.project.vitest._browserSessions.getSession(sessionId);
134
+ session?.reject(new Error("Page crashed when executing tests"));
135
+ });
132
136
  return page;
133
137
  }
134
138
  async openPage(sessionId, url, beforeNavigate) {
package/jest-dom.d.ts CHANGED
@@ -192,10 +192,10 @@ declare namespace matchers {
192
192
  *
193
193
  * const ancestor = getByTestId('ancestor')
194
194
  * const descendant = getByTestId('descendant')
195
- * const nonExistantElement = getByTestId('does-not-exist')
195
+ * const nonExistentElement = getByTestId('does-not-exist')
196
196
  * expect(ancestor).toContainElement(descendant)
197
197
  * expect(descendant).not.toContainElement(ancestor)
198
- * expect(ancestor).not.toContainElement(nonExistantElement)
198
+ * expect(ancestor).not.toContainElement(nonExistentElement)
199
199
  * @see
200
200
  * [testing-library/jest-dom#tocontainelement](https://github.com/testing-library/jest-dom#tocontainelement)
201
201
  */
@@ -282,7 +282,7 @@ declare namespace matchers {
282
282
  * <option value="avocado">Avocado</option>
283
283
  * </select>
284
284
  *
285
- * <label for="mutiple-select-example">Fruits</label>
285
+ * <label for="multiple-select-example">Fruits</label>
286
286
  * <select id="multiple-select-example" multiple>
287
287
  * <option value="">Select a fruit...</option>
288
288
  * <option value="banana" selected>Banana</option>
@@ -382,7 +382,7 @@ declare namespace matchers {
382
382
  * expect(element).toHaveTextContent('Content')
383
383
  * // to match the whole content
384
384
  * expect(element).toHaveTextContent(/^Text Content$/)
385
- * // to use case-insentive match
385
+ * // to use case-insensitive match
386
386
  * expect(element).toHaveTextContent(/content$/i)
387
387
  * expect(element).not.toHaveTextContent('content')
388
388
  * @see
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/browser",
3
3
  "type": "module",
4
- "version": "3.0.0-beta.3",
4
+ "version": "3.0.0",
5
5
  "description": "Browser running for Vitest",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -65,7 +65,7 @@
65
65
  "peerDependencies": {
66
66
  "playwright": "*",
67
67
  "webdriverio": "*",
68
- "vitest": "3.0.0-beta.3"
68
+ "vitest": "3.0.0"
69
69
  },
70
70
  "peerDependenciesMeta": {
71
71
  "playwright": {
@@ -84,10 +84,10 @@
84
84
  "magic-string": "^0.30.17",
85
85
  "msw": "^2.7.0",
86
86
  "sirv": "^3.0.0",
87
- "tinyrainbow": "^1.2.0",
87
+ "tinyrainbow": "^2.0.0",
88
88
  "ws": "^8.18.0",
89
- "@vitest/mocker": "3.0.0-beta.3",
90
- "@vitest/utils": "3.0.0-beta.3"
89
+ "@vitest/mocker": "3.0.0",
90
+ "@vitest/utils": "3.0.0"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@testing-library/jest-dom": "^6.6.3",
@@ -97,16 +97,16 @@
97
97
  "flatted": "^3.3.2",
98
98
  "ivya": "^1.1.1",
99
99
  "mime": "^4.0.6",
100
- "pathe": "^1.1.2",
100
+ "pathe": "^2.0.0",
101
101
  "periscopic": "^4.0.2",
102
102
  "playwright": "^1.49.1",
103
103
  "playwright-core": "^1.49.1",
104
104
  "safaridriver": "^1.0.0",
105
105
  "webdriverio": "^8.41.0",
106
- "@vitest/runner": "3.0.0-beta.3",
107
- "@vitest/ui": "3.0.0-beta.3",
108
- "@vitest/ws-client": "3.0.0-beta.3",
109
- "vitest": "3.0.0-beta.3"
106
+ "@vitest/runner": "3.0.0",
107
+ "@vitest/ws-client": "3.0.0",
108
+ "@vitest/ui": "3.0.0",
109
+ "vitest": "3.0.0"
110
110
  },
111
111
  "scripts": {
112
112
  "build": "rimraf dist && pnpm build:node && pnpm build:client",
@@ -9,9 +9,10 @@ import type {
9
9
  } from 'playwright'
10
10
  import { Protocol } from 'playwright-core/types/protocol'
11
11
  import '../matchers.js'
12
+ import type {} from "vitest/node"
12
13
 
13
14
  declare module 'vitest/node' {
14
- interface BrowserProviderOptions {
15
+ export interface BrowserProviderOptions {
15
16
  launch?: LaunchOptions
16
17
  context?: Omit<
17
18
  BrowserContextOptions,
@@ -1,8 +1,9 @@
1
1
  import type { RemoteOptions, ClickOptions, DragAndDropOptions } from 'webdriverio'
2
2
  import '../matchers.js'
3
+ import type {} from "vitest/node"
3
4
 
4
5
  declare module 'vitest/node' {
5
- interface BrowserProviderOptions extends Partial<RemoteOptions> {}
6
+ export interface BrowserProviderOptions extends Partial<RemoteOptions> {}
6
7
 
7
8
  export interface UserEventClickOptions extends ClickOptions {}
8
9