@vitest/browser 2.1.4 → 2.2.0-beta.1

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.
@@ -0,0 +1,195 @@
1
+ (function polyfill() {
2
+ const relList = document.createElement("link").relList;
3
+ if (relList && relList.supports && relList.supports("modulepreload")) {
4
+ return;
5
+ }
6
+ for (const link of document.querySelectorAll('link[rel="modulepreload"]')) {
7
+ processPreload(link);
8
+ }
9
+ new MutationObserver((mutations) => {
10
+ for (const mutation of mutations) {
11
+ if (mutation.type !== "childList") {
12
+ continue;
13
+ }
14
+ for (const node of mutation.addedNodes) {
15
+ if (node.tagName === "LINK" && node.rel === "modulepreload")
16
+ processPreload(node);
17
+ }
18
+ }
19
+ }).observe(document, { childList: true, subtree: true });
20
+ function getFetchOpts(link) {
21
+ const fetchOpts = {};
22
+ if (link.integrity) fetchOpts.integrity = link.integrity;
23
+ if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
24
+ if (link.crossOrigin === "use-credentials")
25
+ fetchOpts.credentials = "include";
26
+ else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
27
+ else fetchOpts.credentials = "same-origin";
28
+ return fetchOpts;
29
+ }
30
+ function processPreload(link) {
31
+ if (link.ep)
32
+ return;
33
+ link.ep = true;
34
+ const fetchOpts = getFetchOpts(link);
35
+ fetch(link.href, fetchOpts);
36
+ }
37
+ })();
38
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
39
+ function normalizeWindowsPath(input = "") {
40
+ if (!input) {
41
+ return input;
42
+ }
43
+ return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
44
+ }
45
+ const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
46
+ const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
47
+ function cwd() {
48
+ if (typeof process !== "undefined" && typeof process.cwd === "function") {
49
+ return process.cwd().replace(/\\/g, "/");
50
+ }
51
+ return "/";
52
+ }
53
+ const resolve = function(...arguments_) {
54
+ arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
55
+ let resolvedPath = "";
56
+ let resolvedAbsolute = false;
57
+ for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
58
+ const path = index >= 0 ? arguments_[index] : cwd();
59
+ if (!path || path.length === 0) {
60
+ continue;
61
+ }
62
+ resolvedPath = `${path}/${resolvedPath}`;
63
+ resolvedAbsolute = isAbsolute(path);
64
+ }
65
+ resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
66
+ if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
67
+ return `/${resolvedPath}`;
68
+ }
69
+ return resolvedPath.length > 0 ? resolvedPath : ".";
70
+ };
71
+ function normalizeString(path, allowAboveRoot) {
72
+ let res = "";
73
+ let lastSegmentLength = 0;
74
+ let lastSlash = -1;
75
+ let dots = 0;
76
+ let char = null;
77
+ for (let index = 0; index <= path.length; ++index) {
78
+ if (index < path.length) {
79
+ char = path[index];
80
+ } else if (char === "/") {
81
+ break;
82
+ } else {
83
+ char = "/";
84
+ }
85
+ if (char === "/") {
86
+ if (lastSlash === index - 1 || dots === 1) ;
87
+ else if (dots === 2) {
88
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
89
+ if (res.length > 2) {
90
+ const lastSlashIndex = res.lastIndexOf("/");
91
+ if (lastSlashIndex === -1) {
92
+ res = "";
93
+ lastSegmentLength = 0;
94
+ } else {
95
+ res = res.slice(0, lastSlashIndex);
96
+ lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
97
+ }
98
+ lastSlash = index;
99
+ dots = 0;
100
+ continue;
101
+ } else if (res.length > 0) {
102
+ res = "";
103
+ lastSegmentLength = 0;
104
+ lastSlash = index;
105
+ dots = 0;
106
+ continue;
107
+ }
108
+ }
109
+ if (allowAboveRoot) {
110
+ res += res.length > 0 ? "/.." : "..";
111
+ lastSegmentLength = 2;
112
+ }
113
+ } else {
114
+ if (res.length > 0) {
115
+ res += `/${path.slice(lastSlash + 1, index)}`;
116
+ } else {
117
+ res = path.slice(lastSlash + 1, index);
118
+ }
119
+ lastSegmentLength = index - lastSlash - 1;
120
+ }
121
+ lastSlash = index;
122
+ dots = 0;
123
+ } else if (char === "." && dots !== -1) {
124
+ ++dots;
125
+ } else {
126
+ dots = -1;
127
+ }
128
+ }
129
+ return res;
130
+ }
131
+ const isAbsolute = function(p) {
132
+ return _IS_ABSOLUTE_RE.test(p);
133
+ };
134
+ const relative = function(from, to) {
135
+ const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
136
+ const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
137
+ if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) {
138
+ return _to.join("/");
139
+ }
140
+ const _fromCopy = [..._from];
141
+ for (const segment of _fromCopy) {
142
+ if (_to[0] !== segment) {
143
+ break;
144
+ }
145
+ _from.shift();
146
+ _to.shift();
147
+ }
148
+ return [..._from.map(() => ".."), ..._to].join("/");
149
+ };
150
+ async function importId(id) {
151
+ const name = `/@id/${id}`.replace(/\\/g, "/");
152
+ return (/* @__PURE__ */ getBrowserState()).wrapModule(() => import(
153
+ /* @vite-ignore */
154
+ name
155
+ ));
156
+ }
157
+ async function importFs(id) {
158
+ const name = `/@fs/${id}`.replace(/\\/g, "/");
159
+ return (/* @__PURE__ */ getBrowserState()).wrapModule(() => import(
160
+ /* @vite-ignore */
161
+ name
162
+ ));
163
+ }
164
+ const executor = {
165
+ isBrowser: true,
166
+ executeId: (id) => {
167
+ if (id[0] === "/" || id[1] === ":") {
168
+ return importFs(id);
169
+ }
170
+ return importId(id);
171
+ }
172
+ };
173
+ function getConfig() {
174
+ return (/* @__PURE__ */ getBrowserState()).config;
175
+ }
176
+ // @__NO_SIDE_EFFECTS__
177
+ function getBrowserState() {
178
+ return window.__vitest_browser_runner__;
179
+ }
180
+ // @__NO_SIDE_EFFECTS__
181
+ function getWorkerState() {
182
+ const state = window.__vitest_worker__;
183
+ if (!state) {
184
+ throw new Error("Worker state is not found. This is an issue with Vitest. Please, open an issue.");
185
+ }
186
+ return state;
187
+ }
188
+ export {
189
+ getConfig as a,
190
+ resolve as b,
191
+ getWorkerState as c,
192
+ executor as e,
193
+ getBrowserState as g,
194
+ relative as r
195
+ };
@@ -26,8 +26,8 @@
26
26
  {__VITEST_INJECTOR__}
27
27
  {__VITEST_ERROR_CATCHER__}
28
28
  {__VITEST_SCRIPTS__}
29
- <script type="module" crossorigin src="/__vitest_browser__/orchestrator-NReaboR_.js"></script>
30
- <link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-CUwLt_eT.js">
29
+ <script type="module" crossorigin src="/__vitest_browser__/orchestrator-DnP17K36.js"></script>
30
+ <link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-Owv5OOOf.js">
31
31
  </head>
32
32
  <body>
33
33
  <div id="vitest-tester"></div>
@@ -5,19 +5,8 @@
5
5
  <link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Vitest Browser Tester</title>
8
- <style>
9
- html {
10
- padding: 0;
11
- margin: 0;
12
- }
13
- body {
14
- padding: 0;
15
- margin: 0;
16
- min-height: 100vh;
17
- }
18
- </style>
19
- <script type="module" crossorigin src="/__vitest_browser__/tester-CAAquV6P.js"></script>
20
- <link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-CUwLt_eT.js">
8
+ <script type="module" crossorigin src="/__vitest_browser__/tester-BaiNqOPw.js"></script>
9
+ <link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-Owv5OOOf.js">
21
10
  </head>
22
11
  <body>
23
12
  </body>
package/dist/context.js CHANGED
@@ -1,3 +1,35 @@
1
+ function ensureAwaited(promise) {
2
+ const test = (/* @__PURE__ */ getWorkerState()).current;
3
+ if (!test || test.type !== "test") {
4
+ return promise();
5
+ }
6
+ let awaited = false;
7
+ const sourceError = new Error("STACK_TRACE_ERROR");
8
+ test.onFinished ??= [];
9
+ test.onFinished.push(() => {
10
+ if (!awaited) {
11
+ const error = new Error(
12
+ `The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.`
13
+ );
14
+ error.stack = sourceError.stack?.replace(sourceError.message, error.message);
15
+ throw error;
16
+ }
17
+ });
18
+ let promiseResult;
19
+ return {
20
+ then(onFulfilled, onRejected) {
21
+ awaited = true;
22
+ return (promiseResult ||= promise()).then(onFulfilled, onRejected);
23
+ },
24
+ catch(onRejected) {
25
+ return (promiseResult ||= promise()).catch(onRejected);
26
+ },
27
+ finally(onFinally) {
28
+ return (promiseResult ||= promise()).finally(onFinally);
29
+ },
30
+ [Symbol.toStringTag]: "Promise"
31
+ };
32
+ }
1
33
  // @__NO_SIDE_EFFECTS__
2
34
  function getBrowserState() {
3
35
  return window.__vitest_browser_runner__;
@@ -100,12 +132,14 @@ function createUserEvent(__tl_user_event_base__, options) {
100
132
  return createUserEvent(__tl_user_event_base__, options2);
101
133
  },
102
134
  async cleanup() {
103
- if (typeof __tl_user_event_base__ !== "undefined") {
104
- __tl_user_event__ = __tl_user_event_base__?.setup(options ?? {});
105
- return;
106
- }
107
- await triggerCommand("__vitest_cleanup", keyboard);
108
- keyboard.unreleased = [];
135
+ return ensureAwaited(async () => {
136
+ if (typeof __tl_user_event_base__ !== "undefined") {
137
+ __tl_user_event__ = __tl_user_event_base__?.setup(options ?? {});
138
+ return;
139
+ }
140
+ await triggerCommand("__vitest_cleanup", keyboard);
141
+ keyboard.unreleased = [];
142
+ });
109
143
  },
110
144
  click(element, options2 = {}) {
111
145
  return convertToLocator(element).click(processClickOptions(options2));
@@ -142,38 +176,44 @@ function createUserEvent(__tl_user_event_base__, options) {
142
176
  },
143
177
  // testing-library user-event
144
178
  async type(element, text, options2 = {}) {
145
- if (typeof __tl_user_event__ !== "undefined") {
146
- return __tl_user_event__.type(
147
- element instanceof Element ? element : element.element(),
179
+ return ensureAwaited(async () => {
180
+ if (typeof __tl_user_event__ !== "undefined") {
181
+ return __tl_user_event__.type(
182
+ element instanceof Element ? element : element.element(),
183
+ text,
184
+ options2
185
+ );
186
+ }
187
+ const selector = convertToSelector(element);
188
+ const { unreleased } = await triggerCommand(
189
+ "__vitest_type",
190
+ selector,
148
191
  text,
149
- options2
192
+ { ...options2, unreleased: keyboard.unreleased }
150
193
  );
151
- }
152
- const selector = convertToSelector(element);
153
- const { unreleased } = await triggerCommand(
154
- "__vitest_type",
155
- selector,
156
- text,
157
- { ...options2, unreleased: keyboard.unreleased }
158
- );
159
- keyboard.unreleased = unreleased;
194
+ keyboard.unreleased = unreleased;
195
+ });
160
196
  },
161
197
  tab(options2 = {}) {
162
- if (typeof __tl_user_event__ !== "undefined") {
163
- return __tl_user_event__.tab(options2);
164
- }
165
- return triggerCommand("__vitest_tab", options2);
198
+ return ensureAwaited(() => {
199
+ if (typeof __tl_user_event__ !== "undefined") {
200
+ return __tl_user_event__.tab(options2);
201
+ }
202
+ return triggerCommand("__vitest_tab", options2);
203
+ });
166
204
  },
167
205
  async keyboard(text) {
168
- if (typeof __tl_user_event__ !== "undefined") {
169
- return __tl_user_event__.keyboard(text);
170
- }
171
- const { unreleased } = await triggerCommand(
172
- "__vitest_keyboard",
173
- text,
174
- keyboard
175
- );
176
- keyboard.unreleased = unreleased;
206
+ return ensureAwaited(async () => {
207
+ if (typeof __tl_user_event__ !== "undefined") {
208
+ return __tl_user_event__.keyboard(text);
209
+ }
210
+ const { unreleased } = await triggerCommand(
211
+ "__vitest_keyboard",
212
+ text,
213
+ keyboard
214
+ );
215
+ keyboard.unreleased = unreleased;
216
+ });
177
217
  }
178
218
  };
179
219
  }
@@ -214,10 +254,10 @@ const page = {
214
254
  screenshotIds[repeatCount] ??= {};
215
255
  screenshotIds[repeatCount][taskName] = number + 1;
216
256
  const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
217
- return triggerCommand("__vitest_screenshot", name, {
257
+ return ensureAwaited(() => triggerCommand("__vitest_screenshot", name, {
218
258
  ...options,
219
259
  element: options.element ? convertToSelector(options.element) : void 0
220
- });
260
+ }));
221
261
  },
222
262
  getByRole() {
223
263
  throw new Error('Method "getByRole" is not implemented in the current provider.');
@@ -1,6 +1,38 @@
1
1
  import { server, page } from '@vitest/browser/context';
2
2
  import { I as Ivya, a as getByRoleSelector, c as getByAltTextSelector, g as getByLabelSelector, d as getByPlaceholderSelector, b as getByTestIdSelector, e as getByTextSelector, f as getByTitleSelector, h as getElementError } from './public-utils-D6S2-5kI.js';
3
3
 
4
+ function ensureAwaited(promise) {
5
+ const test = (/* @__PURE__ */ getWorkerState()).current;
6
+ if (!test || test.type !== "test") {
7
+ return promise();
8
+ }
9
+ let awaited = false;
10
+ const sourceError = new Error("STACK_TRACE_ERROR");
11
+ test.onFinished ??= [];
12
+ test.onFinished.push(() => {
13
+ if (!awaited) {
14
+ const error = new Error(
15
+ `The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.`
16
+ );
17
+ error.stack = sourceError.stack?.replace(sourceError.message, error.message);
18
+ throw error;
19
+ }
20
+ });
21
+ let promiseResult;
22
+ return {
23
+ then(onFulfilled, onRejected) {
24
+ awaited = true;
25
+ return (promiseResult ||= promise()).then(onFulfilled, onRejected);
26
+ },
27
+ catch(onRejected) {
28
+ return (promiseResult ||= promise()).catch(onRejected);
29
+ },
30
+ finally(onFinally) {
31
+ return (promiseResult ||= promise()).finally(onFinally);
32
+ },
33
+ [Symbol.toStringTag]: "Promise"
34
+ };
35
+ }
4
36
  // @__NO_SIDE_EFFECTS__
5
37
  function getBrowserState() {
6
38
  return window.__vitest_browser_runner__;
@@ -214,13 +246,13 @@ class Locator {
214
246
  }
215
247
  triggerCommand(command, ...args) {
216
248
  const filepath = this.worker.filepath || this.worker.current?.file?.filepath || void 0;
217
- return this.rpc.triggerCommand(
249
+ return ensureAwaited(() => this.rpc.triggerCommand(
218
250
  this.state.contextId,
219
251
  command,
220
252
  filepath,
221
253
  args
222
- );
254
+ ));
223
255
  }
224
256
  }
225
257
 
226
- export { Locator as L, convertElementToCssSelector as c, selectorEngine as s };
258
+ export { Locator as L, convertElementToCssSelector as c, ensureAwaited as e, selectorEngine as s };
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import { WebSocketServer } from 'ws';
16
16
  import { parseErrorStacktrace, parseStacktrace } from '@vitest/utils/source-map';
17
17
  import * as nodeos from 'node:os';
18
18
 
19
- var version = "2.1.4";
19
+ var version = "2.2.0-beta.1";
20
20
 
21
21
  const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
22
22
  function normalizeWindowsPath(input = "") {
@@ -826,6 +826,7 @@ const keyboardCleanup = async (context, state) => {
826
826
  throw new TypeError(`Provider "${context.provider.name}" does not support keyboard api`);
827
827
  }
828
828
  };
829
+ 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"]);
829
830
  async function keyboardImplementation(pressed, provider, contextId, text, selectAll2, skipRelease) {
830
831
  if (provider instanceof PlaywrightBrowserProvider) {
831
832
  const page = provider.getPage(contextId);
@@ -833,7 +834,9 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
833
834
  for (const { releasePrevious, releaseSelf, repeat, keyDef } of actions) {
834
835
  const key = keyDef.key;
835
836
  if (pressed.has(key)) {
836
- await page.keyboard.up(key);
837
+ if (VALID_KEYS.has(key)) {
838
+ await page.keyboard.up(key);
839
+ }
837
840
  pressed.delete(key);
838
841
  }
839
842
  if (!releasePrevious) {
@@ -842,10 +845,16 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
842
845
  continue;
843
846
  }
844
847
  for (let i = 1; i <= repeat; i++) {
845
- await page.keyboard.down(key);
848
+ if (VALID_KEYS.has(key)) {
849
+ await page.keyboard.down(key);
850
+ } else {
851
+ await page.keyboard.insertText(key);
852
+ }
846
853
  }
847
854
  if (releaseSelf) {
848
- await page.keyboard.up(key);
855
+ if (VALID_KEYS.has(key)) {
856
+ await page.keyboard.up(key);
857
+ }
849
858
  } else {
850
859
  pressed.add(key);
851
860
  }
@@ -853,7 +862,9 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
853
862
  }
854
863
  if (!skipRelease && pressed.size) {
855
864
  for (const key of pressed) {
856
- await page.keyboard.up(key);
865
+ if (VALID_KEYS.has(key)) {
866
+ await page.keyboard.up(key);
867
+ }
857
868
  }
858
869
  }
859
870
  } else if (provider instanceof WebdriverBrowserProvider) {
@@ -1429,7 +1440,8 @@ async function resolveTester(server, url, res, next) {
1429
1440
  });
1430
1441
  const testerHtml = typeof server.testerHtml === "string" ? server.testerHtml : await server.testerHtml;
1431
1442
  try {
1432
- const indexhtml = await server.vite.transformIndexHtml(url.pathname, testerHtml);
1443
+ const url2 = join("/@fs/", server.testerFilepath);
1444
+ const indexhtml = await server.vite.transformIndexHtml(url2, testerHtml);
1433
1445
  return replacer(indexhtml, {
1434
1446
  __VITEST_FAVICON__: server.faviconUrl,
1435
1447
  __VITEST_INJECTOR__: injector,
@@ -1621,7 +1633,7 @@ var BrowserPlugin = (browserServer, base = "/") => {
1621
1633
  "msw",
1622
1634
  "msw/browser"
1623
1635
  ];
1624
- if (project.config.diff) {
1636
+ if (typeof project.config.diff === "string") {
1625
1637
  entries.push(project.config.diff);
1626
1638
  }
1627
1639
  if (project.ctx.coverageProvider) {
@@ -1798,21 +1810,22 @@ var BrowserPlugin = (browserServer, base = "/") => {
1798
1810
  name: "vitest:browser:transform-tester-html",
1799
1811
  enforce: "pre",
1800
1812
  async transformIndexHtml(html, ctx) {
1801
- if (!ctx.path.startsWith(browserServer.prefixTesterUrl)) {
1813
+ if (ctx.filename !== browserServer.testerFilepath) {
1802
1814
  return;
1803
1815
  }
1804
1816
  if (!browserServer.testerScripts) {
1805
- const testerScripts2 = await browserServer.formatScripts(
1817
+ const testerScripts = await browserServer.formatScripts(
1806
1818
  project.config.browser.testerScripts
1807
1819
  );
1808
- browserServer.testerScripts = testerScripts2;
1820
+ browserServer.testerScripts = testerScripts;
1809
1821
  }
1810
1822
  const stateJs = typeof browserServer.stateJs === "string" ? browserServer.stateJs : await browserServer.stateJs;
1811
- const testerScripts = [];
1812
- if (resolve(distRoot, "client/tester/tester.html") !== browserServer.testerFilepath) {
1823
+ const testerTags = [];
1824
+ const isDefaultTemplate = resolve(distRoot, "client/tester/tester.html") === browserServer.testerFilepath;
1825
+ if (!isDefaultTemplate) {
1813
1826
  const manifestContent = browserServer.manifest instanceof Promise ? await browserServer.manifest : browserServer.manifest;
1814
1827
  const testerEntry = manifestContent["tester/tester.html"];
1815
- testerScripts.push({
1828
+ testerTags.push({
1816
1829
  tag: "script",
1817
1830
  attrs: {
1818
1831
  type: "module",
@@ -1824,7 +1837,7 @@ var BrowserPlugin = (browserServer, base = "/") => {
1824
1837
  for (const importName of testerEntry.imports || []) {
1825
1838
  const entryManifest = manifestContent[importName];
1826
1839
  if (entryManifest) {
1827
- testerScripts.push(
1840
+ testerTags.push(
1828
1841
  {
1829
1842
  tag: "link",
1830
1843
  attrs: {
@@ -1837,6 +1850,21 @@ var BrowserPlugin = (browserServer, base = "/") => {
1837
1850
  );
1838
1851
  }
1839
1852
  }
1853
+ } else {
1854
+ testerTags.push({
1855
+ tag: "style",
1856
+ children: `
1857
+ html {
1858
+ padding: 0;
1859
+ margin: 0;
1860
+ }
1861
+ body {
1862
+ padding: 0;
1863
+ margin: 0;
1864
+ min-height: 100vh;
1865
+ }`,
1866
+ injectTo: "head"
1867
+ });
1840
1868
  }
1841
1869
  return [
1842
1870
  {
@@ -1866,7 +1894,7 @@ var BrowserPlugin = (browserServer, base = "/") => {
1866
1894
  injectTo: "head"
1867
1895
  } : null,
1868
1896
  ...browserServer.testerScripts,
1869
- ...testerScripts,
1897
+ ...testerTags,
1870
1898
  {
1871
1899
  tag: "script",
1872
1900
  attrs: {
@@ -2138,7 +2166,9 @@ function setupBrowserRpc(server) {
2138
2166
  return ctx.report("onUserConsoleLog", log);
2139
2167
  },
2140
2168
  resolveSnapshotPath(testPath) {
2141
- return ctx.snapshot.resolvePath(testPath);
2169
+ return ctx.snapshot.resolvePath(testPath, {
2170
+ config: project.getSerializableConfig()
2171
+ });
2142
2172
  },
2143
2173
  resolveSnapshotRawPath(testPath, rawPath) {
2144
2174
  return ctx.snapshot.resolveRawPath(testPath, rawPath);
@@ -2589,8 +2619,13 @@ function createBrowserPool(ctx) {
2589
2619
  [...files2.map((f) => relative(project.config.root, f))].join(", ")
2590
2620
  );
2591
2621
  const promise = waitForTests(method, contextId, project, files2);
2592
- promises.push(promise);
2593
- orchestrator.createTesters(files2);
2622
+ const tester = orchestrator.createTesters(files2).catch((error) => {
2623
+ if (error instanceof Error && error.message.startsWith("[birpc] rpc is closed")) {
2624
+ return;
2625
+ }
2626
+ return Promise.reject(error);
2627
+ });
2628
+ promises.push(promise, tester);
2594
2629
  } else {
2595
2630
  const contextId = crypto.randomUUID();
2596
2631
  const waitPromise = waitForTests(method, contextId, project, files2);
@@ -2622,6 +2657,7 @@ function createBrowserPool(ctx) {
2622
2657
  if (isCancelled) {
2623
2658
  break;
2624
2659
  }
2660
+ await project.initBrowserProvider();
2625
2661
  await executeTests(method, project, files);
2626
2662
  }
2627
2663
  };
@@ -2641,6 +2677,11 @@ function createBrowserPool(ctx) {
2641
2677
  async close() {
2642
2678
  await Promise.all([...providers].map((provider) => provider.close()));
2643
2679
  providers.clear();
2680
+ ctx.resolvedProjects.forEach((project) => {
2681
+ project.browser?.state.orchestrators.forEach((orchestrator) => {
2682
+ orchestrator.$close();
2683
+ });
2684
+ });
2644
2685
  },
2645
2686
  runTests: (files) => runWorkspaceTests("run", files),
2646
2687
  collectTests: (files) => runWorkspaceTests("collect", files)
@@ -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-Cgg35wOd.js';
3
+ export { L as Locator, s as selectorEngine } from '../index-CKtADM3n.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-Cgg35wOd.js';
3
+ import { s as selectorEngine, L as Locator } from '../index-CKtADM3n.js';
4
4
  import 'vitest/utils';
5
5
 
6
6
  page.extend({