@nuxt/test-utils 3.23.0 → 4.0.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.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Nuxt Test Utils
2
2
 
3
+ [![nuxt.care health](https://img.shields.io/endpoint?url=https://nuxt.care/api/badge/test-utils)](https://nuxt.care/?search=test-utils)
4
+
5
+
3
6
  🧪 [Nuxt](https://nuxt.com/) Test Utils
4
7
 
5
8
  ## Overview
package/dist/config.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { NuxtConfig, Nuxt } from '@nuxt/schema';
1
+ import { NuxtConfig, Nuxt, ViteConfig } from '@nuxt/schema';
2
2
  import { InlineConfig } from 'vitest/node';
3
3
  import { TestProjectInlineConfiguration } from 'vitest/config';
4
4
  import { DotenvOptions } from 'c12';
@@ -6,7 +6,7 @@ import { UserConfig, UserConfigFnPromise } from 'vite';
6
6
 
7
7
  interface GetVitestConfigOptions {
8
8
  nuxt: Nuxt;
9
- viteConfig: UserConfig;
9
+ viteConfig: ViteConfig;
10
10
  }
11
11
  interface LoadNuxtOptions {
12
12
  dotenv?: Partial<DotenvOptions>;
@@ -57,11 +57,6 @@ declare module 'vitest/node' {
57
57
  nuxt?: NuxtEnvironmentOptions;
58
58
  }
59
59
  }
60
- declare module 'vitest' {
61
- interface EnvironmentOptions {
62
- nuxt?: NuxtEnvironmentOptions;
63
- }
64
- }
65
60
 
66
61
  export { defineVitestConfig, defineVitestProject, getVitestConfigFromNuxt };
67
62
  export type { NuxtEnvironmentOptions };
package/dist/config.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  import process from 'node:process';
2
- import { defineConfig } from 'vite';
3
2
  import { setupDotenv } from 'c12';
4
- import { defu } from 'defu';
3
+ import { defu, createDefu } from 'defu';
5
4
  import { createResolver, findPath } from '@nuxt/kit';
6
5
  import { resolveModulePath } from 'exsolve';
7
6
  import { getPackageInfoSync } from 'local-pkg';
@@ -107,7 +106,9 @@ async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
107
106
  break;
108
107
  }
109
108
  }
110
- const h3Info = getPackageInfoSync("h3", {
109
+ const projectH3Path = resolveModulePath("h3/package.json", { from: rootDir, try: true });
110
+ const projectH3Info = projectH3Path ? getPackageInfoSync("h3", { paths: [projectH3Path] }) : void 0;
111
+ const h3Info = projectH3Info || getPackageInfoSync("h3", {
111
112
  paths: nitroPath ? [nitroPath] : options.nuxt.options.modulesDir
112
113
  });
113
114
  const resolver = createResolver(import.meta.url);
@@ -160,7 +161,7 @@ async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
160
161
  },
161
162
  deps: {
162
163
  optimizer: {
163
- web: {
164
+ client: {
164
165
  enabled: false
165
166
  }
166
167
  }
@@ -216,6 +217,7 @@ async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
216
217
  );
217
218
  delete resolvedConfig.define["process.browser"];
218
219
  delete resolvedConfig.customLogger;
220
+ delete resolvedConfig.ssr;
219
221
  if (!Array.isArray(resolvedConfig.test.setupFiles)) {
220
222
  resolvedConfig.test.setupFiles = [resolvedConfig.test.setupFiles].filter(Boolean);
221
223
  }
@@ -228,8 +230,9 @@ async function defineVitestProject(config) {
228
230
  resolvedConfig.test.environment = "nuxt";
229
231
  return resolvedConfig;
230
232
  }
233
+ const defineViteConfig = (config) => config;
231
234
  function defineVitestConfig(config = {}) {
232
- return defineConfig(async () => {
235
+ return defineViteConfig(async () => {
233
236
  const resolvedConfig = await resolveConfig(config);
234
237
  if (resolvedConfig.test.browser?.enabled) {
235
238
  return resolvedConfig;
@@ -241,25 +244,29 @@ function defineVitestConfig(config = {}) {
241
244
  }
242
245
  const defaultEnvironment = resolvedConfig.test.environment || "node";
243
246
  if (defaultEnvironment !== "nuxt") {
244
- const key = "projects" in resolvedConfig.test ? "projects" : "workspace" in resolvedConfig.test ? "workspace" : await import('vitest/package.json', { with: { type: 'json' } }).then((r) => {
245
- const [major, minor] = (r.default || r).version.split(".");
246
- return Number.parseInt(major, 10) > 3 || Number.parseInt(major, 10) === 3 && Number.parseInt(minor, 10) >= 2;
247
- }) ? "projects" : "workspace";
248
- resolvedConfig.test[key] = [];
249
- resolvedConfig.test[key].push({
250
- extends: true,
247
+ const merge = createDefu((obj, key, value) => {
248
+ if (Array.isArray(value) && Array.isArray(obj[key])) {
249
+ obj[key] = [.../* @__PURE__ */ new Set([...value, ...obj[key]])];
250
+ return true;
251
+ }
252
+ });
253
+ const nuxtProject = merge({
254
+ ...resolvedConfig,
251
255
  test: {
256
+ ...resolvedConfig.test,
252
257
  name: "nuxt",
253
258
  environment: "nuxt",
254
- include: [
255
- "**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
256
- "{test,tests}/nuxt/**.*"
257
- ]
259
+ include: []
258
260
  }
259
- });
260
- resolvedConfig.test[key].push({
261
- extends: true,
261
+ }, resolvedConfig);
262
+ nuxtProject.test.include = [
263
+ "**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
264
+ "{test,tests}/nuxt/**.*"
265
+ ];
266
+ const defaultProject = merge({
267
+ ...resolvedConfig,
262
268
  test: {
269
+ ...resolvedConfig.test,
263
270
  name: defaultEnvironment,
264
271
  environment: defaultEnvironment,
265
272
  exclude: [
@@ -272,7 +279,12 @@ function defineVitestConfig(config = {}) {
272
279
  "./{test,tests}/nuxt/**.*"
273
280
  ]
274
281
  }
275
- });
282
+ }, resolvedConfig);
283
+ delete resolvedConfig.test.name;
284
+ delete resolvedConfig.test.environment;
285
+ delete resolvedConfig.test.include;
286
+ delete resolvedConfig.test.exclude;
287
+ resolvedConfig.test.projects = [nuxtProject, defaultProject];
276
288
  }
277
289
  return resolvedConfig;
278
290
  });
package/dist/e2e.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TestOptions, b as TestContext, a as TestHooks } from './shared/test-utils.C9GKP_T5.mjs';
2
- export { $ as $fetch, G as GotoOptions, N as NuxtPage, S as StartServerOptions, h as TestRunner, c as createBrowser, d as createPage, f as fetch, g as getBrowser, s as startServer, e as stopServer, u as url, w as waitForHydration } from './shared/test-utils.C9GKP_T5.mjs';
1
+ import { T as TestOptions, b as TestContext, a as TestHooks } from './shared/test-utils.BLyxqr96.mjs';
2
+ export { $ as $fetch, G as GotoOptions, N as NuxtPage, S as StartServerOptions, c as TestRunner, d as createBrowser, e as createPage, f as fetch, g as getBrowser, s as startServer, h as stopServer, u as url, w as waitForHydration } from './shared/test-utils.BLyxqr96.mjs';
3
3
  import { LogType } from 'consola';
4
4
  import 'playwright-core';
5
5
  import '@nuxt/schema';
package/dist/e2e.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { b as buildFixture, c as createBrowser, a as createPage, d as createTest, g as getBrowser, l as loadFixture, e as setup, s as setupMaps, w as waitForHydration } from './shared/test-utils.5cnw0YZR.mjs';
1
+ export { b as buildFixture, c as createBrowser, a as createPage, d as createTest, g as getBrowser, l as loadFixture, s as setup, e as setupMaps, w as waitForHydration } from './shared/test-utils.E_cAGA8l.mjs';
2
2
  import { u as useTestContext } from './shared/test-utils.BsmyE2FA.mjs';
3
3
  export { $ as $fetch, c as createTestContext, e as exposeContextToEnv, f as fetch, i as isDev, r as recoverContextFromEnv, s as setTestContext, a as startServer, b as stopServer, d as url } from './shared/test-utils.BsmyE2FA.mjs';
4
4
  import { consola } from 'consola';
package/dist/module.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { UserConfig } from 'vitest/node';
2
+ import { TestUserConfig } from 'vitest/config';
3
3
 
4
4
  interface NuxtVitestOptions {
5
5
  startOnBoot?: boolean;
6
6
  logToConsole?: boolean;
7
- vitestConfig?: UserConfig;
7
+ vitestConfig?: TestUserConfig;
8
8
  }
9
9
  declare const _default: _nuxt_schema.NuxtModule<NuxtVitestOptions, NuxtVitestOptions, false>;
10
10
 
package/dist/module.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import { resolveIgnorePatterns, logger, useNuxt, addDevServerHandler, defineNuxtModule, createResolver, resolvePath } from '@nuxt/kit';
1
+ import { resolveIgnorePatterns, logger, addDevServerHandler, useNuxt, defineNuxtModule, createResolver, resolvePath } from '@nuxt/kit';
2
+ import { refreshCustomTabs, addCustomTab, onDevToolsInitialized } from '@nuxt/devtools-kit';
2
3
  import { extname, join, dirname, relative, resolve } from 'pathe';
3
4
  import { isCI, hasTTY, provider } from 'std-env';
4
5
  import { walk } from 'estree-walker';
@@ -13,7 +14,7 @@ import { detectPackageManager, addDependency } from 'nypm';
13
14
  import { h } from 'vue';
14
15
  import { debounce } from 'perfect-debounce';
15
16
  import { fork } from 'node:child_process';
16
- import { c as createVitestTestSummary, l as listenCliMessages, s as sendMessageToCli } from './shared/test-utils.DDUpsMYL.mjs';
17
+ import { l as listenCliMessages, s as sendMessageToCli, c as createVitestTestSummary } from './shared/test-utils.DDUpsMYL.mjs';
17
18
  import { distDir } from '#dirs';
18
19
  import 'destr';
19
20
  import 'scule';
@@ -24,195 +25,193 @@ const PLUGIN_NAME$1 = "nuxt:vitest:mock-transform";
24
25
  const HELPER_MOCK_IMPORT = "mockNuxtImport";
25
26
  const HELPER_MOCK_COMPONENT = "mockComponent";
26
27
  const HELPER_MOCK_HOIST = "__NUXT_VITEST_MOCKS";
28
+ const HELPER_MOCK_HOIST_ORIGINAL = "__NUXT_VITEST_MOCKS_ORIGINAL";
27
29
  const HELPERS_NAME = [HELPER_MOCK_IMPORT, HELPER_MOCK_COMPONENT];
28
30
  const createMockPlugin = (ctx) => createUnplugin(() => {
29
- function transform(code, id) {
30
- if (!HELPERS_NAME.some((n) => code.includes(n))) return;
31
- if (id.includes("/node_modules/")) return;
32
- let ast;
33
- try {
34
- ast = this.parse(code, {
35
- // @ts-expect-error compatibility with rollup v3
36
- sourceType: "module",
37
- ecmaVersion: "latest",
38
- ranges: true
39
- });
40
- } catch {
41
- return;
42
- }
43
- let insertionPoint = 0;
44
- let hasViImport = false;
45
- const s = new MagicString(code);
46
- const mocksImport = [];
47
- const mocksComponent = [];
48
- const importPathsList = /* @__PURE__ */ new Set();
49
- walk(ast, {
50
- enter: (node, parent) => {
51
- if (isImportDeclaration(node)) {
52
- if (node.source.value === "vitest" && !hasViImport) {
53
- const viImport = node.specifiers.find(
54
- (i) => isImportSpecifier(i) && i.imported.type === "Identifier" && i.imported.name === "vi"
55
- );
56
- if (viImport) {
57
- insertionPoint = endOf(node);
58
- hasViImport = true;
59
- }
60
- return;
61
- }
62
- }
63
- if (!isCallExpression(node)) return;
64
- if (isIdentifier(node.callee) && node.callee.name === HELPER_MOCK_IMPORT) {
65
- if (node.arguments.length !== 2) {
66
- return this.error(
67
- new Error(
68
- `${HELPER_MOCK_IMPORT}() should have exactly 2 arguments`
69
- ),
70
- startOf(node)
71
- );
72
- }
73
- const importTarget = node.arguments[0];
74
- const name = isLiteral(importTarget) ? importTarget.value : isIdentifier(importTarget) ? importTarget.name : void 0;
75
- if (typeof name !== "string") {
76
- return this.error(
77
- new Error(
78
- `The first argument of ${HELPER_MOCK_IMPORT}() must be a string literal or mocked target`
79
- ),
80
- startOf(importTarget)
81
- );
82
- }
83
- const importItem = ctx.imports.find((_) => name === (_.as || _.name));
84
- if (!importItem) {
85
- return this.error(`Cannot find import "${name}" to mock`);
86
- }
87
- s.overwrite(
88
- isExpressionStatement(parent) ? startOf(parent) : startOf(node.arguments[0]),
89
- isExpressionStatement(parent) ? endOf(parent) : endOf(node.arguments[1]),
90
- ""
91
- );
92
- mocksImport.push({
93
- name,
94
- import: importItem,
95
- factory: code.slice(
96
- startOf(node.arguments[1]),
97
- endOf(node.arguments[1])
98
- )
99
- });
100
- }
101
- if (isIdentifier(node.callee) && node.callee.name === HELPER_MOCK_COMPONENT) {
102
- if (node.arguments.length !== 2) {
103
- return this.error(
104
- new Error(
105
- `${HELPER_MOCK_COMPONENT}() should have exactly 2 arguments`
106
- ),
107
- startOf(node)
108
- );
109
- }
110
- const componentName = node.arguments[0];
111
- if (!isLiteral(componentName) || typeof componentName.value !== "string") {
112
- return this.error(
113
- new Error(
114
- `The first argument of ${HELPER_MOCK_COMPONENT}() must be a string literal`
115
- ),
116
- startOf(componentName)
117
- );
118
- }
119
- const pathOrName = componentName.value;
120
- const component = ctx.components.find(
121
- (_) => _.pascalName === pathOrName || _.kebabName === pathOrName
122
- );
123
- const path = component?.filePath || pathOrName;
124
- s.overwrite(
125
- isExpressionStatement(parent) ? startOf(parent) : startOf(node.arguments[1]),
126
- isExpressionStatement(parent) ? endOf(parent) : endOf(node.arguments[1]),
127
- ""
128
- );
129
- mocksComponent.push({
130
- path,
131
- factory: code.slice(
132
- startOf(node.arguments[1]),
133
- endOf(node.arguments[1])
134
- )
31
+ return {
32
+ name: PLUGIN_NAME$1,
33
+ enforce: "post",
34
+ vite: {
35
+ transform(code, id) {
36
+ if (!HELPERS_NAME.some((n) => code.includes(n))) return;
37
+ if (id.includes("/node_modules/")) return;
38
+ let ast;
39
+ try {
40
+ ast = this.parse(code, {
41
+ // @ts-expect-error compatibility with rollup v3
42
+ sourceType: "module",
43
+ ecmaVersion: "latest",
44
+ ranges: true
135
45
  });
46
+ } catch {
47
+ return;
136
48
  }
137
- }
138
- });
139
- if (mocksImport.length === 0 && mocksComponent.length === 0) return;
140
- const mockLines = [];
141
- if (mocksImport.length) {
142
- const mockImportMap = /* @__PURE__ */ new Map();
143
- for (const mock of mocksImport) {
144
- if (!mockImportMap.has(mock.import.from)) {
145
- mockImportMap.set(mock.import.from, []);
146
- }
147
- mockImportMap.get(mock.import.from).push(mock);
148
- }
149
- mockLines.push(
150
- ...Array.from(mockImportMap.entries()).flatMap(
151
- ([from, mocks]) => {
152
- importPathsList.add(from);
153
- const lines = [
154
- `vi.mock(${JSON.stringify(from)}, async (importOriginal) => {`,
155
- ` const mocks = globalThis.${HELPER_MOCK_HOIST}`,
156
- ` if (!mocks[${JSON.stringify(from)}]) {`,
157
- ` mocks[${JSON.stringify(from)}] = { ...await importOriginal(${JSON.stringify(from)}) }`,
158
- ` }`
159
- ];
160
- for (const mock of mocks) {
161
- if (mock.import.name === "default") {
162
- lines.push(
163
- ` mocks[${JSON.stringify(from)}]["default"] = await (${mock.factory})();`
49
+ let insertionPoint = 0;
50
+ let hasViImport = false;
51
+ const s = new MagicString(code);
52
+ const mocksImport = [];
53
+ const mocksComponent = [];
54
+ const importPathsList = /* @__PURE__ */ new Set();
55
+ walk(ast, {
56
+ enter: (node, parent) => {
57
+ if (isImportDeclaration(node)) {
58
+ if (node.source.value === "vitest" && !hasViImport) {
59
+ const viImport = node.specifiers.find(
60
+ (i) => isImportSpecifier(i) && i.imported.type === "Identifier" && i.imported.name === "vi"
61
+ );
62
+ if (viImport) {
63
+ insertionPoint = endOf(node);
64
+ hasViImport = true;
65
+ }
66
+ return;
67
+ }
68
+ }
69
+ if (!isCallExpression(node)) return;
70
+ if (isIdentifier(node.callee) && node.callee.name === HELPER_MOCK_IMPORT) {
71
+ if (node.arguments.length !== 2) {
72
+ return this.error(
73
+ new Error(
74
+ `${HELPER_MOCK_IMPORT}() should have exactly 2 arguments`
75
+ ),
76
+ startOf(node)
77
+ );
78
+ }
79
+ const importTarget = node.arguments[0];
80
+ const name = isLiteral(importTarget) ? importTarget.value : isIdentifier(importTarget) ? importTarget.name : void 0;
81
+ if (typeof name !== "string") {
82
+ return this.error(
83
+ new Error(
84
+ `The first argument of ${HELPER_MOCK_IMPORT}() must be a string literal or mocked target`
85
+ ),
86
+ startOf(importTarget)
87
+ );
88
+ }
89
+ const importItem = ctx.imports.find((_) => name === (_.as || _.name));
90
+ if (!importItem) {
91
+ return this.error(`Cannot find import "${name}" to mock`);
92
+ }
93
+ s.overwrite(
94
+ isExpressionStatement(parent) ? startOf(parent) : startOf(node.arguments[0]),
95
+ isExpressionStatement(parent) ? endOf(parent) : endOf(node.arguments[1]),
96
+ ""
97
+ );
98
+ mocksImport.push({
99
+ name,
100
+ import: importItem,
101
+ factory: code.slice(
102
+ startOf(node.arguments[1]),
103
+ endOf(node.arguments[1])
104
+ )
105
+ });
106
+ }
107
+ if (isIdentifier(node.callee) && node.callee.name === HELPER_MOCK_COMPONENT) {
108
+ if (node.arguments.length !== 2) {
109
+ return this.error(
110
+ new Error(
111
+ `${HELPER_MOCK_COMPONENT}() should have exactly 2 arguments`
112
+ ),
113
+ startOf(node)
164
114
  );
165
- } else {
166
- lines.push(
167
- ` mocks[${JSON.stringify(from)}][${JSON.stringify(mock.name)}] = await (${mock.factory})();`
115
+ }
116
+ const componentName = node.arguments[0];
117
+ if (!isLiteral(componentName) || typeof componentName.value !== "string") {
118
+ return this.error(
119
+ new Error(
120
+ `The first argument of ${HELPER_MOCK_COMPONENT}() must be a string literal`
121
+ ),
122
+ startOf(componentName)
168
123
  );
169
124
  }
125
+ const pathOrName = componentName.value;
126
+ const component = ctx.components.find(
127
+ (_) => _.pascalName === pathOrName || _.kebabName === pathOrName
128
+ );
129
+ const path = component?.filePath || pathOrName;
130
+ s.overwrite(
131
+ isExpressionStatement(parent) ? startOf(parent) : startOf(node.arguments[1]),
132
+ isExpressionStatement(parent) ? endOf(parent) : endOf(node.arguments[1]),
133
+ ""
134
+ );
135
+ mocksComponent.push({
136
+ path,
137
+ factory: code.slice(
138
+ startOf(node.arguments[1]),
139
+ endOf(node.arguments[1])
140
+ )
141
+ });
170
142
  }
171
- lines.push(` return mocks[${JSON.stringify(from)}] `);
172
- lines.push(`});`);
173
- return lines;
174
143
  }
175
- )
176
- );
177
- }
178
- if (mocksComponent.length) {
179
- mockLines.push(
180
- ...mocksComponent.flatMap((mock) => {
181
- return [
182
- `vi.mock(${JSON.stringify(mock.path)}, async () => {`,
183
- ` const factory = (${mock.factory});`,
184
- ` const result = typeof factory === 'function' ? await factory() : await factory`,
185
- ` return 'default' in result ? result : { default: result }`,
186
- "});"
187
- ];
188
- })
189
- );
190
- }
191
- if (!mockLines.length) return;
192
- s.appendLeft(insertionPoint, `
144
+ });
145
+ if (mocksImport.length === 0 && mocksComponent.length === 0) return;
146
+ const mockLines = [];
147
+ if (mocksImport.length) {
148
+ const mockImportMap = /* @__PURE__ */ new Map();
149
+ for (const mock of mocksImport) {
150
+ if (!mockImportMap.has(mock.import.from)) {
151
+ mockImportMap.set(mock.import.from, []);
152
+ }
153
+ mockImportMap.get(mock.import.from).push(mock);
154
+ }
155
+ mockLines.push(
156
+ ...Array.from(mockImportMap.entries()).flatMap(
157
+ ([from, mocks]) => {
158
+ importPathsList.add(from);
159
+ const quotedFrom = JSON.stringify(from);
160
+ const mockModuleEntry = `globalThis.${HELPER_MOCK_HOIST}[${quotedFrom}]`;
161
+ const lines = [
162
+ `vi.mock(${quotedFrom}, async (importOriginal) => {`,
163
+ ` if (!${mockModuleEntry}) {`,
164
+ ` const original = await importOriginal(${quotedFrom})`,
165
+ ` ${mockModuleEntry} = { ...original }`,
166
+ ` ${mockModuleEntry}.${HELPER_MOCK_HOIST_ORIGINAL} = { ...original }`,
167
+ ` }`
168
+ ];
169
+ for (const mock of mocks) {
170
+ const quotedName = JSON.stringify(mock.import.name === "default" ? "default" : mock.name);
171
+ lines.push(
172
+ ` ${mockModuleEntry}[${quotedName}] = await (${mock.factory})(${mockModuleEntry}.${HELPER_MOCK_HOIST_ORIGINAL}[${quotedName}]);`
173
+ );
174
+ }
175
+ lines.push(` return ${mockModuleEntry} `);
176
+ lines.push(`});`);
177
+ return lines;
178
+ }
179
+ )
180
+ );
181
+ }
182
+ if (mocksComponent.length) {
183
+ mockLines.push(
184
+ ...mocksComponent.flatMap((mock) => {
185
+ return [
186
+ `vi.mock(${JSON.stringify(mock.path)}, async () => {`,
187
+ ` const factory = (${mock.factory});`,
188
+ ` const result = typeof factory === 'function' ? await factory() : await factory`,
189
+ ` return 'default' in result ? result : { default: result }`,
190
+ "});"
191
+ ];
192
+ })
193
+ );
194
+ }
195
+ if (!mockLines.length) return;
196
+ s.appendLeft(insertionPoint, `
193
197
  vi.hoisted(() => {
194
198
  if(!globalThis.${HELPER_MOCK_HOIST}){
195
199
  vi.stubGlobal(${JSON.stringify(HELPER_MOCK_HOIST)}, {})
196
200
  }
197
201
  });
198
202
  `);
199
- if (!hasViImport) s.prepend(`import {vi} from "vitest";
203
+ if (!hasViImport) s.prepend(`import {vi} from "vitest";
200
204
  `);
201
- s.appendLeft(insertionPoint, "\n" + mockLines.join("\n") + "\n");
202
- importPathsList.forEach((p) => {
203
- s.append(`
205
+ s.appendLeft(insertionPoint, "\n" + mockLines.join("\n") + "\n");
206
+ importPathsList.forEach((p) => {
207
+ s.append(`
204
208
  import ${JSON.stringify(p)};`);
205
- });
206
- return {
207
- code: s.toString(),
208
- map: s.generateMap()
209
- };
210
- }
211
- return {
212
- name: PLUGIN_NAME$1,
213
- enforce: "post",
214
- vite: {
215
- transform,
209
+ });
210
+ return {
211
+ code: s.toString(),
212
+ map: s.generateMap()
213
+ };
214
+ },
216
215
  // Place Vitest's mock plugin after all Nuxt plugins
217
216
  async configResolved(config) {
218
217
  const plugins = config.plugins || [];
@@ -768,17 +767,9 @@ async function updateGitignore(nuxt, answers) {
768
767
  async function setupDevTools(vitestWrapper, nuxt = useNuxt()) {
769
768
  const iframeSrc = "/__test_utils_vitest__/";
770
769
  const updateTabs = debounce(() => {
771
- nuxt.callHook("devtools:customTabs:refresh");
770
+ refreshCustomTabs(nuxt);
772
771
  }, 100);
773
- nuxt.hook("devtools:customTabs", (tabs) => {
774
- const tab = createVitestCustomTab(vitestWrapper, { iframeSrc });
775
- const index = tabs.findIndex(({ name }) => tab.name === name);
776
- if (index === -1) {
777
- tabs.push(tab);
778
- } else {
779
- tabs.splice(index, 1, tab);
780
- }
781
- });
772
+ addCustomTab(() => createVitestCustomTab(vitestWrapper, { iframeSrc }), nuxt);
782
773
  addDevServerHandler({
783
774
  route: iframeSrc,
784
775
  handler: Object.assign(() => iframeContentHtml(vitestWrapper.uiUrl), { __is_handler__: true })
@@ -961,7 +952,7 @@ function vitestWrapper(options) {
961
952
  };
962
953
  }
963
954
 
964
- const version = "3.23.0";
955
+ const version = "4.0.1";
965
956
  const pkg = {
966
957
  version: version};
967
958
 
@@ -1007,9 +998,9 @@ const module$1 = defineNuxtModule({
1007
998
  if (!nuxt.options.dev) return;
1008
999
  if (process.env.TEST || process.env.VITE_TEST) return;
1009
1000
  const vitestWrapper2 = createVitestWrapper(options, nuxt);
1010
- nuxt.hook("devtools:before", async () => {
1001
+ onDevToolsInitialized(async () => {
1011
1002
  await setupDevTools(vitestWrapper2, nuxt);
1012
- });
1003
+ }, nuxt);
1013
1004
  if (options.startOnBoot) {
1014
1005
  vitestWrapper2.start();
1015
1006
  }
@@ -1,7 +1,7 @@
1
1
  import * as _playwright_test from '@playwright/test';
2
2
  export { expect } from '@playwright/test';
3
3
  import { Response } from 'playwright-core';
4
- import { T as TestOptions$1, G as GotoOptions, a as TestHooks } from './shared/test-utils.C9GKP_T5.mjs';
4
+ import { T as TestOptions$1, G as GotoOptions, a as TestHooks } from './shared/test-utils.BLyxqr96.mjs';
5
5
  import '@nuxt/schema';
6
6
  import 'tinyexec';
7
7
  import 'ofetch';
@@ -1,10 +1,10 @@
1
1
  import defu from 'defu';
2
2
  import { test as test$1 } from '@playwright/test';
3
3
  export { expect } from '@playwright/test';
4
- import { w as waitForHydration, d as createTest } from './shared/test-utils.5cnw0YZR.mjs';
4
+ import { isWindows } from 'std-env';
5
+ import { w as waitForHydration, d as createTest } from './shared/test-utils.E_cAGA8l.mjs';
5
6
  import 'node:path';
6
7
  import 'ufo';
7
- import 'std-env';
8
8
  import 'consola';
9
9
  import 'node:fs';
10
10
  import 'destr';
@@ -19,6 +19,7 @@ import 'tinyexec';
19
19
  import 'get-port-please';
20
20
  import 'ofetch';
21
21
 
22
+ const FIXTURE_TIMEOUT = isWindows ? 12e4 : 6e4;
22
23
  const test = test$1.extend({
23
24
  nuxt: [void 0, { option: true, scope: "worker" }],
24
25
  defaults: [{ nuxt: void 0 }, { option: true, scope: "worker" }],
@@ -29,7 +30,7 @@ const test = test$1.extend({
29
30
  await use(hooks);
30
31
  await hooks.afterAll();
31
32
  },
32
- { scope: "worker" }
33
+ { scope: "worker", timeout: FIXTURE_TIMEOUT }
33
34
  ],
34
35
  baseURL: async ({ _nuxtHooks }, use) => {
35
36
  _nuxtHooks.beforeEach();
@@ -1,8 +1,5 @@
1
1
  import environmentOptions from "nuxt-vitest-environment-options";
2
2
  import { setupNuxt } from "./shared/nuxt.mjs";
3
3
  import { setupWindow } from "./shared/environment.mjs";
4
- const el = document.querySelector(environmentOptions.nuxt.rootId || "nuxt-test");
5
- if (!el) {
6
- await setupWindow(window, environmentOptions);
7
- await setupNuxt();
8
- }
4
+ await setupWindow(window, environmentOptions);
5
+ await setupNuxt();
@@ -1,7 +1,8 @@
1
- import { vi } from "vitest";
1
+ import { beforeAll } from "vitest";
2
2
  import { setupNuxt } from "./shared/nuxt.mjs";
3
3
  if (typeof window !== "undefined" && window.__NUXT_VITEST_ENVIRONMENT__) {
4
- await setupNuxt();
5
- vi.resetModules();
4
+ beforeAll(async () => {
5
+ await setupNuxt();
6
+ });
6
7
  }
7
8
  export {};