@nuxt/test-utils-nightly 4.0.0-1701501480.7490334 → 4.0.0-1702910449.8cf01bd
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 +1 -1
- package/dist/config.d.mts +13 -1
- package/dist/config.d.ts +13 -1
- package/dist/config.mjs +88 -27
- package/dist/{index.d.mts → e2e.d.mts} +5 -0
- package/dist/{index.d.ts → e2e.d.ts} +5 -0
- package/dist/{index.mjs → e2e.mjs} +13 -7
- package/dist/experimental.mjs +1 -1
- package/dist/module.mjs +18 -13
- package/dist/runtime/entry.mjs +1 -0
- package/dist/runtime/global-setup.mjs +1 -1
- package/dist/{runtime-utils.d.ts → runtime-utils/index.d.mts} +5 -5
- package/dist/{runtime-utils.d.mts → runtime-utils/index.d.ts} +5 -5
- package/dist/{runtime-utils.mjs → runtime-utils/index.mjs} +26 -15
- package/dist/shared/{test-utils-nightly.ddf5bsCK.mjs → test-utils-nightly.B1uaYm8K.mjs} +1 -2
- package/e2e.d.ts +1 -0
- package/package.json +29 -22
- package/runtime.d.ts +1 -0
- package/runtime-utils.d.ts +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
Nuxt offers first-class support for e2e and unit testing of your Nuxt applications.
|
|
7
|
+
Nuxt offers first-class support for e2e and unit testing of your Nuxt applications.
|
|
8
8
|
|
|
9
9
|
Nuxt Test Utils is currently powering [the tests we use on Nuxt itself](https://github.com/nuxt/nuxt/tree/main/test), as well as tests used throughout the module ecosystem.
|
|
10
10
|
|
package/dist/config.d.mts
CHANGED
|
@@ -2,12 +2,17 @@ import * as vite from 'vite';
|
|
|
2
2
|
import { InlineConfig } from 'vite';
|
|
3
3
|
import { NuxtConfig, Nuxt } from '@nuxt/schema';
|
|
4
4
|
import { InlineConfig as InlineConfig$1 } from 'vitest';
|
|
5
|
+
import { DotenvOptions } from 'c12';
|
|
5
6
|
|
|
6
7
|
interface GetVitestConfigOptions {
|
|
7
8
|
nuxt: Nuxt;
|
|
8
9
|
viteConfig: InlineConfig;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
interface LoadNuxtOptions {
|
|
12
|
+
dotenv?: Partial<DotenvOptions>;
|
|
13
|
+
overrides?: Partial<NuxtConfig>;
|
|
14
|
+
}
|
|
15
|
+
declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, loadNuxtOptions?: LoadNuxtOptions): Promise<InlineConfig & {
|
|
11
16
|
test: InlineConfig$1;
|
|
12
17
|
}>;
|
|
13
18
|
declare function defineVitestConfig(config?: InlineConfig & {
|
|
@@ -22,6 +27,13 @@ declare module 'vitest' {
|
|
|
22
27
|
* @default {http://localhost:3000}
|
|
23
28
|
*/
|
|
24
29
|
url?: string;
|
|
30
|
+
/**
|
|
31
|
+
* You can define how environment options are read when loading the Nuxt configuration.
|
|
32
|
+
*/
|
|
33
|
+
dotenv?: Partial<DotenvOptions>;
|
|
34
|
+
/**
|
|
35
|
+
* Configuration that will override the values in your `nuxt.config` file.
|
|
36
|
+
*/
|
|
25
37
|
overrides?: NuxtConfig;
|
|
26
38
|
/**
|
|
27
39
|
* The id of the root div to which the app should be mounted. You should also set `app.rootId` to the same value.
|
package/dist/config.d.ts
CHANGED
|
@@ -2,12 +2,17 @@ import * as vite from 'vite';
|
|
|
2
2
|
import { InlineConfig } from 'vite';
|
|
3
3
|
import { NuxtConfig, Nuxt } from '@nuxt/schema';
|
|
4
4
|
import { InlineConfig as InlineConfig$1 } from 'vitest';
|
|
5
|
+
import { DotenvOptions } from 'c12';
|
|
5
6
|
|
|
6
7
|
interface GetVitestConfigOptions {
|
|
7
8
|
nuxt: Nuxt;
|
|
8
9
|
viteConfig: InlineConfig;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
interface LoadNuxtOptions {
|
|
12
|
+
dotenv?: Partial<DotenvOptions>;
|
|
13
|
+
overrides?: Partial<NuxtConfig>;
|
|
14
|
+
}
|
|
15
|
+
declare function getVitestConfigFromNuxt(options?: GetVitestConfigOptions, loadNuxtOptions?: LoadNuxtOptions): Promise<InlineConfig & {
|
|
11
16
|
test: InlineConfig$1;
|
|
12
17
|
}>;
|
|
13
18
|
declare function defineVitestConfig(config?: InlineConfig & {
|
|
@@ -22,6 +27,13 @@ declare module 'vitest' {
|
|
|
22
27
|
* @default {http://localhost:3000}
|
|
23
28
|
*/
|
|
24
29
|
url?: string;
|
|
30
|
+
/**
|
|
31
|
+
* You can define how environment options are read when loading the Nuxt configuration.
|
|
32
|
+
*/
|
|
33
|
+
dotenv?: Partial<DotenvOptions>;
|
|
34
|
+
/**
|
|
35
|
+
* Configuration that will override the values in your `nuxt.config` file.
|
|
36
|
+
*/
|
|
25
37
|
overrides?: NuxtConfig;
|
|
26
38
|
/**
|
|
27
39
|
* The id of the root div to which the app should be mounted. You should also set `app.rootId` to the same value.
|
package/dist/config.mjs
CHANGED
|
@@ -1,24 +1,61 @@
|
|
|
1
1
|
import { defineConfig } from 'vite';
|
|
2
|
+
import { setupDotenv } from 'c12';
|
|
2
3
|
import { defu } from 'defu';
|
|
3
4
|
import { createResolver } from '@nuxt/kit';
|
|
5
|
+
import destr from 'destr';
|
|
6
|
+
import { snakeCase } from 'scule';
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
function getEnv(key, opts) {
|
|
9
|
+
const env = opts.env ?? process.env;
|
|
10
|
+
const envKey = snakeCase(key).toUpperCase();
|
|
11
|
+
return destr(
|
|
12
|
+
env[opts.prefix + envKey] ?? env[opts.altPrefix + envKey]
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
function _isObject(input) {
|
|
16
|
+
return typeof input === "object" && !Array.isArray(input);
|
|
17
|
+
}
|
|
18
|
+
function applyEnv(obj, opts, parentKey = "") {
|
|
19
|
+
for (const key in obj) {
|
|
20
|
+
const subKey = parentKey ? `${parentKey}_${key}` : key;
|
|
21
|
+
const envValue = getEnv(subKey, opts);
|
|
22
|
+
if (_isObject(obj[key])) {
|
|
23
|
+
if (_isObject(envValue)) {
|
|
24
|
+
obj[key] = { ...obj[key], ...envValue };
|
|
25
|
+
applyEnv(obj[key], opts, subKey);
|
|
26
|
+
} else if (envValue === void 0) {
|
|
27
|
+
applyEnv(obj[key], opts, subKey);
|
|
28
|
+
} else {
|
|
29
|
+
obj[key] = envValue ?? obj[key];
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
obj[key] = envValue ?? obj[key];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return obj;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function startNuxtAndGetViteConfig(rootDir = process.cwd(), options = {}) {
|
|
6
39
|
const { loadNuxt, buildNuxt } = await import('@nuxt/kit');
|
|
7
40
|
const nuxt = await loadNuxt({
|
|
8
41
|
cwd: rootDir,
|
|
9
42
|
dev: false,
|
|
43
|
+
dotenv: defu(options.dotenv, {
|
|
44
|
+
cwd: rootDir,
|
|
45
|
+
fileName: ".env.test"
|
|
46
|
+
}),
|
|
10
47
|
overrides: defu(
|
|
11
48
|
{
|
|
12
49
|
ssr: false,
|
|
13
50
|
test: true,
|
|
14
51
|
modules: ["@nuxt/test-utils/module"]
|
|
15
52
|
},
|
|
16
|
-
overrides
|
|
53
|
+
options.overrides
|
|
17
54
|
)
|
|
18
55
|
});
|
|
19
56
|
if (!nuxt.options._installedModules.find((i) => i?.meta?.name === "@nuxt/test-utils")) {
|
|
20
57
|
throw new Error(
|
|
21
|
-
"Failed to load nuxt-
|
|
58
|
+
"Failed to load `@nuxt/test-utils/module`. You may need to add it to your nuxt.config."
|
|
22
59
|
);
|
|
23
60
|
}
|
|
24
61
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -36,19 +73,22 @@ async function startNuxtAndGetViteConfig(rootDir = process.cwd(), overrides) {
|
|
|
36
73
|
}).finally(() => nuxt.close());
|
|
37
74
|
return promise;
|
|
38
75
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
76
|
+
const excludedPlugins = [
|
|
77
|
+
"nuxt:import-protection",
|
|
78
|
+
"vite-plugin-checker"
|
|
79
|
+
];
|
|
80
|
+
async function getVitestConfigFromNuxt(options, loadNuxtOptions = {}) {
|
|
81
|
+
const { rootDir = process.cwd(), ..._overrides } = loadNuxtOptions.overrides || {};
|
|
42
82
|
if (!options) {
|
|
43
83
|
options = await startNuxtAndGetViteConfig(rootDir, {
|
|
44
|
-
|
|
45
|
-
|
|
84
|
+
dotenv: loadNuxtOptions.dotenv,
|
|
85
|
+
overrides: {
|
|
86
|
+
test: true,
|
|
87
|
+
..._overrides
|
|
88
|
+
}
|
|
46
89
|
});
|
|
47
90
|
}
|
|
48
|
-
|
|
49
|
-
options.viteConfig.plugins = options.viteConfig.plugins?.filter(
|
|
50
|
-
(p) => p?.name !== "nuxt:import-protection"
|
|
51
|
-
);
|
|
91
|
+
options.viteConfig.plugins = (options.viteConfig.plugins || []).filter((p) => !excludedPlugins.includes(p?.name));
|
|
52
92
|
const resolvedConfig = defu(
|
|
53
93
|
// overrides
|
|
54
94
|
{
|
|
@@ -58,7 +98,13 @@ async function getVitestConfigFromNuxt(options, overrides) {
|
|
|
58
98
|
test: {
|
|
59
99
|
dir: process.cwd(),
|
|
60
100
|
environmentOptions: {
|
|
61
|
-
nuxtRuntimeConfig: options.nuxt.options.runtimeConfig,
|
|
101
|
+
nuxtRuntimeConfig: applyEnv(structuredClone(options.nuxt.options.runtimeConfig), {
|
|
102
|
+
prefix: "NUXT_",
|
|
103
|
+
env: await setupDotenv(defu(loadNuxtOptions.dotenv, {
|
|
104
|
+
cwd: rootDir,
|
|
105
|
+
fileName: ".env.test"
|
|
106
|
+
}))
|
|
107
|
+
}),
|
|
62
108
|
nuxtRouteRules: defu(
|
|
63
109
|
{},
|
|
64
110
|
options.nuxt.options.routeRules,
|
|
@@ -69,20 +115,29 @@ async function getVitestConfigFromNuxt(options, overrides) {
|
|
|
69
115
|
["**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}", "nuxt"],
|
|
70
116
|
["{test,tests}/nuxt/**.*", "nuxt"]
|
|
71
117
|
],
|
|
118
|
+
server: {
|
|
119
|
+
deps: {
|
|
120
|
+
inline: [
|
|
121
|
+
// vite-node defaults
|
|
122
|
+
/\/node_modules\/(.*\/)?(nuxt|nuxt3|nuxt-nightly)\//,
|
|
123
|
+
/^#/,
|
|
124
|
+
// additional deps
|
|
125
|
+
"@nuxt/test-utils",
|
|
126
|
+
"@nuxt/test-utils-nightly",
|
|
127
|
+
"@nuxt/test-utils-edge",
|
|
128
|
+
"vitest-environment-nuxt",
|
|
129
|
+
...options.nuxt.options.build.transpile.filter(
|
|
130
|
+
(r) => typeof r === "string" || r instanceof RegExp
|
|
131
|
+
)
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
},
|
|
72
135
|
deps: {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"@nuxt/test-utils",
|
|
79
|
-
"@nuxt/test-utils-nightly",
|
|
80
|
-
"@nuxt/test-utils-edge",
|
|
81
|
-
"vitest-environment-nuxt",
|
|
82
|
-
...options.nuxt.options.build.transpile.filter(
|
|
83
|
-
(r) => typeof r === "string" || r instanceof RegExp
|
|
84
|
-
)
|
|
85
|
-
]
|
|
136
|
+
optimizer: {
|
|
137
|
+
web: {
|
|
138
|
+
enabled: false
|
|
139
|
+
}
|
|
140
|
+
}
|
|
86
141
|
}
|
|
87
142
|
}
|
|
88
143
|
},
|
|
@@ -134,9 +189,15 @@ function defineVitestConfig(config = {}) {
|
|
|
134
189
|
return config;
|
|
135
190
|
const overrides = config.test?.environmentOptions?.nuxt?.overrides || {};
|
|
136
191
|
overrides.rootDir = config.test?.environmentOptions?.nuxt?.rootDir;
|
|
192
|
+
if (config.test?.setupFiles && !Array.isArray(config.test.setupFiles)) {
|
|
193
|
+
config.test.setupFiles = [config.test.setupFiles].filter(Boolean);
|
|
194
|
+
}
|
|
137
195
|
return defu(
|
|
138
196
|
config,
|
|
139
|
-
await getVitestConfigFromNuxt(void 0,
|
|
197
|
+
await getVitestConfigFromNuxt(void 0, {
|
|
198
|
+
dotenv: config.test?.environmentOptions?.nuxt?.dotenv,
|
|
199
|
+
overrides: structuredClone(overrides)
|
|
200
|
+
})
|
|
140
201
|
);
|
|
141
202
|
});
|
|
142
203
|
}
|
|
@@ -37,6 +37,11 @@ interface TestContext {
|
|
|
37
37
|
url?: string;
|
|
38
38
|
serverProcess?: ExecaChildProcess;
|
|
39
39
|
mockFn?: Function;
|
|
40
|
+
/**
|
|
41
|
+
* Functions to run on the vitest `afterAll` hook.
|
|
42
|
+
* Useful for removing anything created during the test.
|
|
43
|
+
*/
|
|
44
|
+
teardown?: (() => void)[];
|
|
40
45
|
}
|
|
41
46
|
interface TestHooks {
|
|
42
47
|
beforeEach: () => void;
|
|
@@ -37,6 +37,11 @@ interface TestContext {
|
|
|
37
37
|
url?: string;
|
|
38
38
|
serverProcess?: ExecaChildProcess;
|
|
39
39
|
mockFn?: Function;
|
|
40
|
+
/**
|
|
41
|
+
* Functions to run on the vitest `afterAll` hook.
|
|
42
|
+
* Useful for removing anything created during the test.
|
|
43
|
+
*/
|
|
44
|
+
teardown?: (() => void)[];
|
|
40
45
|
}
|
|
41
46
|
interface TestHooks {
|
|
42
47
|
beforeEach: () => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { u as useTestContext, a as url, c as createTestContext, s as setTestContext, b as stopServer, d as startServer } from './shared/test-utils-nightly.
|
|
2
|
-
export { $ as $fetch, e as exposeContextToEnv, f as fetch, i as isDev, r as recoverContextFromEnv } from './shared/test-utils-nightly.
|
|
1
|
+
import { u as useTestContext, a as url, c as createTestContext, s as setTestContext, b as stopServer, d as startServer } from './shared/test-utils-nightly.B1uaYm8K.mjs';
|
|
2
|
+
export { $ as $fetch, e as exposeContextToEnv, f as fetch, i as isDev, r as recoverContextFromEnv } from './shared/test-utils-nightly.B1uaYm8K.mjs';
|
|
3
3
|
import { consola } from 'consola';
|
|
4
|
-
import {
|
|
4
|
+
import { existsSync, promises } from 'node:fs';
|
|
5
5
|
import { resolve } from 'node:path';
|
|
6
6
|
import { defu } from 'defu';
|
|
7
7
|
import * as _kit from '@nuxt/kit';
|
|
@@ -83,12 +83,12 @@ async function loadFixture() {
|
|
|
83
83
|
ctx.options.rootDir = resolveRootDir();
|
|
84
84
|
if (!ctx.options.dev) {
|
|
85
85
|
const randomId = Math.random().toString(36).slice(2, 8);
|
|
86
|
-
const
|
|
86
|
+
const buildDir2 = ctx.options.buildDir || resolve(ctx.options.rootDir, ".nuxt", "test", randomId);
|
|
87
87
|
ctx.options.nuxtConfig = defu(ctx.options.nuxtConfig, {
|
|
88
|
-
buildDir,
|
|
88
|
+
buildDir: buildDir2,
|
|
89
89
|
nitro: {
|
|
90
90
|
output: {
|
|
91
|
-
dir: resolve(
|
|
91
|
+
dir: resolve(buildDir2, "output")
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
});
|
|
@@ -99,7 +99,12 @@ async function loadFixture() {
|
|
|
99
99
|
overrides: ctx.options.nuxtConfig,
|
|
100
100
|
configFile: ctx.options.configFile
|
|
101
101
|
});
|
|
102
|
-
|
|
102
|
+
const buildDir = ctx.nuxt.options.buildDir;
|
|
103
|
+
if (!existsSync(buildDir)) {
|
|
104
|
+
await promises.mkdir(buildDir, { recursive: true });
|
|
105
|
+
ctx.teardown = ctx.teardown || [];
|
|
106
|
+
ctx.teardown.push(() => promises.rm(buildDir, { recursive: true, force: true }));
|
|
107
|
+
}
|
|
103
108
|
}
|
|
104
109
|
async function buildFixture() {
|
|
105
110
|
const ctx = useTestContext();
|
|
@@ -151,6 +156,7 @@ function createTest(options) {
|
|
|
151
156
|
if (ctx.browser) {
|
|
152
157
|
await ctx.browser.close();
|
|
153
158
|
}
|
|
159
|
+
await Promise.all((ctx.teardown || []).map((fn) => fn()));
|
|
154
160
|
};
|
|
155
161
|
const setup2 = async () => {
|
|
156
162
|
if (ctx.options.fixture) {
|
package/dist/experimental.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolve } from 'pathe';
|
|
2
2
|
import { stringifyQuery } from 'ufo';
|
|
3
|
-
import { $ as $fetch, u as useTestContext } from './shared/test-utils-nightly.
|
|
3
|
+
import { $ as $fetch, u as useTestContext } from './shared/test-utils-nightly.B1uaYm8K.mjs';
|
|
4
4
|
import 'execa';
|
|
5
5
|
import 'get-port-please';
|
|
6
6
|
import 'ofetch';
|
package/dist/module.mjs
CHANGED
|
@@ -12,6 +12,10 @@ import MagicString from 'magic-string';
|
|
|
12
12
|
import { normalize, resolve } from 'node:path';
|
|
13
13
|
import { createUnplugin } from 'unplugin';
|
|
14
14
|
import { readFileSync } from 'node:fs';
|
|
15
|
+
import { extname, join, dirname } from 'pathe';
|
|
16
|
+
import 'c12';
|
|
17
|
+
import 'destr';
|
|
18
|
+
import 'scule';
|
|
15
19
|
|
|
16
20
|
const PLUGIN_NAME$1 = "nuxt:vitest:mock-transform";
|
|
17
21
|
const HELPER_MOCK_IMPORT = "mockNuxtImport";
|
|
@@ -224,7 +228,7 @@ const createMockPlugin = (ctx) => createUnplugin(() => {
|
|
|
224
228
|
resolvedFirstSetupFile = await resolvePath(normalize(resolve(firstSetupFile)));
|
|
225
229
|
}
|
|
226
230
|
const plugins = config.plugins || [];
|
|
227
|
-
const vitestPlugins = plugins.filter((p) => p.name === "vite:mocks" || p.name.startsWith("vitest:"));
|
|
231
|
+
const vitestPlugins = plugins.filter((p) => (p.name === "vite:mocks" || p.name.startsWith("vitest:")) && (p.enforce || p.order) === "post");
|
|
228
232
|
const lastNuxt = findLastIndex(
|
|
229
233
|
plugins,
|
|
230
234
|
(i) => i.name?.startsWith("nuxt:")
|
|
@@ -300,18 +304,20 @@ function setupImportMocking() {
|
|
|
300
304
|
}
|
|
301
305
|
|
|
302
306
|
const PLUGIN_NAME = "nuxt:vitest:nuxt-root-stub";
|
|
307
|
+
const STUB_ID = "nuxt-vitest-app-entry";
|
|
303
308
|
const NuxtRootStubPlugin = createUnplugin((options) => {
|
|
309
|
+
const STUB_ID_WITH_EXT = STUB_ID + extname(options.entry);
|
|
304
310
|
return {
|
|
305
311
|
name: PLUGIN_NAME,
|
|
306
312
|
enforce: "pre",
|
|
307
313
|
vite: {
|
|
308
|
-
async resolveId(id) {
|
|
309
|
-
if (id.endsWith(
|
|
310
|
-
return id;
|
|
314
|
+
async resolveId(id, importer) {
|
|
315
|
+
if (id.endsWith(STUB_ID) || id.endsWith(STUB_ID_WITH_EXT)) {
|
|
316
|
+
return importer?.endsWith("index.html") ? id : join(dirname(options.entry), STUB_ID_WITH_EXT);
|
|
311
317
|
}
|
|
312
318
|
},
|
|
313
319
|
async load(id) {
|
|
314
|
-
if (id.endsWith(
|
|
320
|
+
if (id.endsWith(STUB_ID) || id.endsWith(STUB_ID_WITH_EXT)) {
|
|
315
321
|
const entryContents = readFileSync(options.entry, "utf-8");
|
|
316
322
|
return entryContents.replace("#build/root-component.mjs", options.rootStubPath);
|
|
317
323
|
}
|
|
@@ -320,7 +326,7 @@ const NuxtRootStubPlugin = createUnplugin((options) => {
|
|
|
320
326
|
};
|
|
321
327
|
});
|
|
322
328
|
|
|
323
|
-
const vitePluginBlocklist = ["vite-plugin-vue-inspector", "vite-plugin-inspect"];
|
|
329
|
+
const vitePluginBlocklist = ["vite-plugin-vue-inspector", "vite-plugin-vue-inspector:post", "vite-plugin-inspect"];
|
|
324
330
|
const module = defineNuxtModule({
|
|
325
331
|
meta: {
|
|
326
332
|
name: "@nuxt/test-utils",
|
|
@@ -341,9 +347,6 @@ const module = defineNuxtModule({
|
|
|
341
347
|
}));
|
|
342
348
|
if (!nuxt.options.dev)
|
|
343
349
|
return;
|
|
344
|
-
if (nuxt.options.test && nuxt.options.app.rootId === "__nuxt") {
|
|
345
|
-
nuxt.options.app.rootId = "nuxt-test";
|
|
346
|
-
}
|
|
347
350
|
if (process.env.TEST || process.env.VITE_TEST)
|
|
348
351
|
return;
|
|
349
352
|
const rawViteConfigPromise = new Promise((resolve) => {
|
|
@@ -354,8 +357,6 @@ const module = defineNuxtModule({
|
|
|
354
357
|
});
|
|
355
358
|
});
|
|
356
359
|
});
|
|
357
|
-
const PORT = await getPort({ port: 15555 });
|
|
358
|
-
const URL = `http://localhost:${PORT}/__vitest__/`;
|
|
359
360
|
let loaded = false;
|
|
360
361
|
let promise;
|
|
361
362
|
let ctx = void 0;
|
|
@@ -363,6 +364,7 @@ const module = defineNuxtModule({
|
|
|
363
364
|
const updateTabs = debounce(() => {
|
|
364
365
|
nuxt.callHook("devtools:customTabs:refresh");
|
|
365
366
|
}, 100);
|
|
367
|
+
let URL;
|
|
366
368
|
async function start() {
|
|
367
369
|
const rawViteConfig = mergeConfig({}, await rawViteConfigPromise);
|
|
368
370
|
const viteConfig = await getVitestConfigFromNuxt({ nuxt, viteConfig: defu({ test: options.vitestConfig }, rawViteConfig) });
|
|
@@ -385,6 +387,9 @@ const module = defineNuxtModule({
|
|
|
385
387
|
}
|
|
386
388
|
};
|
|
387
389
|
const watchMode = !process.env.NUXT_VITEST_DEV_TEST && !isCI;
|
|
390
|
+
const PORT = await getPort({ port: 15555 });
|
|
391
|
+
const PROTOCOL = nuxt.options.devServer.https ? "https" : "http";
|
|
392
|
+
URL = `${PROTOCOL}://localhost:${PORT}/__vitest__/`;
|
|
388
393
|
const overrides = watchMode ? {
|
|
389
394
|
passWithNoTests: true,
|
|
390
395
|
reporters: options.logToConsole ? [
|
|
@@ -403,10 +408,10 @@ const module = defineNuxtModule({
|
|
|
403
408
|
promise2.catch(() => process.exit(1));
|
|
404
409
|
if (watchMode) {
|
|
405
410
|
logger.info(`Vitest UI starting on ${URL}`);
|
|
411
|
+
nuxt.hook("close", () => promise2.then((v) => v?.close()));
|
|
406
412
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
407
413
|
} else {
|
|
408
|
-
promise2.then((v) => v?.close()).then(() => process.exit());
|
|
409
|
-
promise2.catch(() => process.exit(1));
|
|
414
|
+
promise2.then((v) => nuxt.close().then(() => v?.close()).then(() => process.exit()));
|
|
410
415
|
}
|
|
411
416
|
loaded = true;
|
|
412
417
|
}
|
package/dist/runtime/entry.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
if (typeof window !== "undefined" && // @ts-expect-error undefined property
|
|
2
2
|
window.__NUXT_VITEST_ENVIRONMENT__) {
|
|
3
|
+
const { useRouter } = await import("#app/composables/router");
|
|
3
4
|
await import("#app/nuxt-vitest-app-entry").then((r) => r.default());
|
|
4
5
|
const nuxtApp = useNuxtApp();
|
|
5
6
|
await nuxtApp.callHook("page:finish");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _kit from "@nuxt/kit";
|
|
2
|
-
import { createTest, exposeContextToEnv } from "@nuxt/test-utils";
|
|
2
|
+
import { createTest, exposeContextToEnv } from "@nuxt/test-utils/e2e";
|
|
3
3
|
const kit = _kit.default || _kit;
|
|
4
4
|
const options = JSON.parse(process.env.NUXT_TEST_OPTIONS || "{}");
|
|
5
5
|
const hooks = createTest(options);
|
|
@@ -13,7 +13,7 @@ type OptionalFunction<T> = T | (() => Awaitable<T>);
|
|
|
13
13
|
* @param options - factory function that returns the mocked data or an object containing both the `handler` and the `method` properties.
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
16
|
-
* import { registerEndpoint } from '@nuxt/test-utils/runtime
|
|
16
|
+
* import { registerEndpoint } from '@nuxt/test-utils/runtime'
|
|
17
17
|
*
|
|
18
18
|
* registerEndpoint("/test/", () => {
|
|
19
19
|
* test: "test-field"
|
|
@@ -31,7 +31,7 @@ declare function registerEndpoint(url: string, options: EventHandler | {
|
|
|
31
31
|
* @param _factory - factory function that returns mocked import.
|
|
32
32
|
* @example
|
|
33
33
|
* ```ts
|
|
34
|
-
* import { mockNuxtImport } from '@nuxt/test-utils/runtime
|
|
34
|
+
* import { mockNuxtImport } from '@nuxt/test-utils/runtime'
|
|
35
35
|
*
|
|
36
36
|
* mockNuxtImport('useStorage', () => {
|
|
37
37
|
* return () => {
|
|
@@ -48,7 +48,7 @@ declare function mockNuxtImport<T = any>(_name: string, _factory: () => T | Prom
|
|
|
48
48
|
* @param setup - factory function that returns the mocked component.
|
|
49
49
|
* @example
|
|
50
50
|
* ```ts
|
|
51
|
-
* import { mockComponent } from '@nuxt/test-utils/runtime
|
|
51
|
+
* import { mockComponent } from '@nuxt/test-utils/runtime'
|
|
52
52
|
*
|
|
53
53
|
* mockComponent('MyComponent', {
|
|
54
54
|
* props: {
|
|
@@ -123,7 +123,7 @@ type RenderOptions = RenderOptions$1 & {
|
|
|
123
123
|
*
|
|
124
124
|
* ```ts
|
|
125
125
|
* // tests/components/SomeComponents.nuxt.spec.ts
|
|
126
|
-
* import { renderSuspended } from '@nuxt/test-utils/runtime
|
|
126
|
+
* import { renderSuspended } from '@nuxt/test-utils/runtime'
|
|
127
127
|
*
|
|
128
128
|
* it('can render some component', async () => {
|
|
129
129
|
* const { html } = await renderSuspended(SomeComponent)
|
|
@@ -134,7 +134,7 @@ type RenderOptions = RenderOptions$1 & {
|
|
|
134
134
|
* })
|
|
135
135
|
*
|
|
136
136
|
* // tests/App.nuxt.spec.ts
|
|
137
|
-
* import { renderSuspended } from '@nuxt/test-utils/runtime
|
|
137
|
+
* import { renderSuspended } from '@nuxt/test-utils/runtime'
|
|
138
138
|
* import { screen } from '@testing-library/vue'
|
|
139
139
|
*
|
|
140
140
|
* it('can also mount an app', async () => {
|
|
@@ -13,7 +13,7 @@ type OptionalFunction<T> = T | (() => Awaitable<T>);
|
|
|
13
13
|
* @param options - factory function that returns the mocked data or an object containing both the `handler` and the `method` properties.
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
16
|
-
* import { registerEndpoint } from '@nuxt/test-utils/runtime
|
|
16
|
+
* import { registerEndpoint } from '@nuxt/test-utils/runtime'
|
|
17
17
|
*
|
|
18
18
|
* registerEndpoint("/test/", () => {
|
|
19
19
|
* test: "test-field"
|
|
@@ -31,7 +31,7 @@ declare function registerEndpoint(url: string, options: EventHandler | {
|
|
|
31
31
|
* @param _factory - factory function that returns mocked import.
|
|
32
32
|
* @example
|
|
33
33
|
* ```ts
|
|
34
|
-
* import { mockNuxtImport } from '@nuxt/test-utils/runtime
|
|
34
|
+
* import { mockNuxtImport } from '@nuxt/test-utils/runtime'
|
|
35
35
|
*
|
|
36
36
|
* mockNuxtImport('useStorage', () => {
|
|
37
37
|
* return () => {
|
|
@@ -48,7 +48,7 @@ declare function mockNuxtImport<T = any>(_name: string, _factory: () => T | Prom
|
|
|
48
48
|
* @param setup - factory function that returns the mocked component.
|
|
49
49
|
* @example
|
|
50
50
|
* ```ts
|
|
51
|
-
* import { mockComponent } from '@nuxt/test-utils/runtime
|
|
51
|
+
* import { mockComponent } from '@nuxt/test-utils/runtime'
|
|
52
52
|
*
|
|
53
53
|
* mockComponent('MyComponent', {
|
|
54
54
|
* props: {
|
|
@@ -123,7 +123,7 @@ type RenderOptions = RenderOptions$1 & {
|
|
|
123
123
|
*
|
|
124
124
|
* ```ts
|
|
125
125
|
* // tests/components/SomeComponents.nuxt.spec.ts
|
|
126
|
-
* import { renderSuspended } from '@nuxt/test-utils/runtime
|
|
126
|
+
* import { renderSuspended } from '@nuxt/test-utils/runtime'
|
|
127
127
|
*
|
|
128
128
|
* it('can render some component', async () => {
|
|
129
129
|
* const { html } = await renderSuspended(SomeComponent)
|
|
@@ -134,7 +134,7 @@ type RenderOptions = RenderOptions$1 & {
|
|
|
134
134
|
* })
|
|
135
135
|
*
|
|
136
136
|
* // tests/App.nuxt.spec.ts
|
|
137
|
-
* import { renderSuspended } from '@nuxt/test-utils/runtime
|
|
137
|
+
* import { renderSuspended } from '@nuxt/test-utils/runtime'
|
|
138
138
|
* import { screen } from '@testing-library/vue'
|
|
139
139
|
*
|
|
140
140
|
* it('can also mount an app', async () => {
|
|
@@ -102,19 +102,21 @@ async function mountSuspended(component, options) {
|
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
default: () => h$1({
|
|
105
|
+
name: "MountSuspendedHelper",
|
|
105
106
|
async setup() {
|
|
106
107
|
const router = useRouter();
|
|
107
108
|
await router.replace(route);
|
|
108
109
|
const clonedComponent = {
|
|
110
|
+
name: "MountSuspendedComponent",
|
|
109
111
|
...component,
|
|
110
|
-
render: render ? (_ctx, ...args)
|
|
111
|
-
for (const key in
|
|
112
|
+
render: render ? function(_ctx, ...args) {
|
|
113
|
+
for (const key in props || {}) {
|
|
112
114
|
renderContext[key] = _ctx[key];
|
|
113
115
|
}
|
|
114
|
-
|
|
115
|
-
renderContext
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
for (const key in setupState || {}) {
|
|
117
|
+
renderContext[key] = setupState[key];
|
|
118
|
+
}
|
|
119
|
+
return render.call(this, renderContext, ...args);
|
|
118
120
|
} : void 0,
|
|
119
121
|
setup: setup ? (props2) => wrappedSetup(props2, setupContext) : void 0
|
|
120
122
|
};
|
|
@@ -124,16 +126,24 @@ async function mountSuspended(component, options) {
|
|
|
124
126
|
}
|
|
125
127
|
)
|
|
126
128
|
},
|
|
127
|
-
defu(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
defu(
|
|
130
|
+
_options,
|
|
131
|
+
{
|
|
132
|
+
slots,
|
|
133
|
+
global: {
|
|
134
|
+
config: {
|
|
135
|
+
globalProperties: vueApp.config.globalProperties
|
|
136
|
+
},
|
|
137
|
+
provide: vueApp._context.provides,
|
|
138
|
+
stubs: {
|
|
139
|
+
Suspense: false,
|
|
140
|
+
MountSuspendedHelper: false,
|
|
141
|
+
[typeof component.name === "string" ? component.name : "MountSuspendedComponent"]: false
|
|
142
|
+
},
|
|
143
|
+
components: { RouterLink }
|
|
144
|
+
}
|
|
135
145
|
}
|
|
136
|
-
|
|
146
|
+
)
|
|
137
147
|
);
|
|
138
148
|
}
|
|
139
149
|
);
|
|
@@ -151,6 +161,7 @@ async function renderSuspended(component, options) {
|
|
|
151
161
|
const { render: renderFromTestingLibrary } = await import('@testing-library/vue');
|
|
152
162
|
const { vueApp } = globalThis.__unctx__.get("nuxt-app").tryUse();
|
|
153
163
|
const { render, setup } = component;
|
|
164
|
+
document.querySelector(`#${WRAPPER_EL_ID}`)?.remove();
|
|
154
165
|
let setupContext;
|
|
155
166
|
return new Promise((resolve) => {
|
|
156
167
|
const utils = renderFromTestingLibrary(
|
|
@@ -18,8 +18,7 @@ function createTestContext(options) {
|
|
|
18
18
|
server: true,
|
|
19
19
|
build: options.browser !== false || options.server !== false,
|
|
20
20
|
nuxtConfig: {},
|
|
21
|
-
|
|
22
|
-
runner: "vitest",
|
|
21
|
+
runner: process.env.VITEST === "true" ? "vitest" : "jest",
|
|
23
22
|
browserOptions: {
|
|
24
23
|
type: "chromium"
|
|
25
24
|
}
|
package/e2e.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/e2e'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt/test-utils-nightly",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-1702910449.8cf01bd",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/nuxt/test-utils.git"
|
|
@@ -8,21 +8,23 @@
|
|
|
8
8
|
"description": "Test utilities for Nuxt",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"type": "module",
|
|
11
|
-
"types": "./dist/
|
|
11
|
+
"types": "./dist/e2e.d.ts",
|
|
12
12
|
"exports": {
|
|
13
|
-
".": "./dist/
|
|
13
|
+
".": "./dist/e2e.mjs",
|
|
14
14
|
"./config": "./dist/config.mjs",
|
|
15
|
+
"./e2e": "./dist/e2e.mjs",
|
|
15
16
|
"./experimental": "./dist/experimental.mjs",
|
|
16
17
|
"./module": "./dist/module.mjs",
|
|
17
|
-
"./runtime
|
|
18
|
+
"./runtime": "./dist/runtime-utils/index.mjs",
|
|
18
19
|
"./vitest-environment": "./dist/vitest-environment.mjs"
|
|
19
20
|
},
|
|
20
21
|
"files": [
|
|
21
22
|
"dist",
|
|
22
23
|
"config.d.ts",
|
|
24
|
+
"e2e.d.ts",
|
|
23
25
|
"experimental.d.ts",
|
|
24
26
|
"module.d.ts",
|
|
25
|
-
"runtime
|
|
27
|
+
"runtime.d.ts",
|
|
26
28
|
"vitest-environment.d.ts"
|
|
27
29
|
],
|
|
28
30
|
"scripts": {
|
|
@@ -38,8 +40,10 @@
|
|
|
38
40
|
"dependencies": {
|
|
39
41
|
"@nuxt/kit": "^3.8.2",
|
|
40
42
|
"@nuxt/schema": "^3.8.2",
|
|
43
|
+
"c12": "^1.5.1",
|
|
41
44
|
"consola": "^3.2.3",
|
|
42
45
|
"defu": "^6.1.3",
|
|
46
|
+
"destr": "^2.0.2",
|
|
43
47
|
"estree-walker": "^3.0.3",
|
|
44
48
|
"execa": "^8.0.1",
|
|
45
49
|
"fake-indexeddb": "^5.0.1",
|
|
@@ -51,50 +55,54 @@
|
|
|
51
55
|
"pathe": "^1.1.1",
|
|
52
56
|
"perfect-debounce": "^1.0.0",
|
|
53
57
|
"radix3": "^1.1.0",
|
|
58
|
+
"scule": "^1.1.1",
|
|
54
59
|
"std-env": "^3.6.0",
|
|
55
60
|
"ufo": "^1.3.2",
|
|
56
61
|
"unenv": "^1.8.0",
|
|
57
62
|
"unplugin": "^1.5.1",
|
|
58
|
-
"vitest-environment-nuxt": "0.
|
|
63
|
+
"vitest-environment-nuxt": "1.0.0-alpha.1"
|
|
59
64
|
},
|
|
60
65
|
"devDependencies": {
|
|
61
66
|
"@jest/globals": "29.7.0",
|
|
62
|
-
"@nuxt/devtools": "1.0.
|
|
67
|
+
"@nuxt/devtools": "1.0.6",
|
|
63
68
|
"@nuxt/eslint-config": "0.2.0",
|
|
64
69
|
"@nuxt/module-builder": "0.5.4",
|
|
65
70
|
"@testing-library/vue": "8.0.1",
|
|
66
71
|
"@types/estree": "1.0.5",
|
|
67
72
|
"@types/jsdom": "21.1.6",
|
|
68
|
-
"@
|
|
73
|
+
"@types/semver": "7.5.6",
|
|
74
|
+
"@vitest/ui": "1.0.4",
|
|
69
75
|
"@vue/test-utils": "2.4.3",
|
|
70
76
|
"changelogen": "0.5.5",
|
|
71
|
-
"eslint": "8.
|
|
72
|
-
"eslint-plugin-import": "2.29.
|
|
73
|
-
"eslint-plugin-jsdoc": "46.9.
|
|
77
|
+
"eslint": "8.56.0",
|
|
78
|
+
"eslint-plugin-import": "2.29.1",
|
|
79
|
+
"eslint-plugin-jsdoc": "46.9.1",
|
|
74
80
|
"eslint-plugin-no-only-tests": "3.1.0",
|
|
75
81
|
"eslint-plugin-unicorn": "49.0.0",
|
|
76
82
|
"h3": "1.9.0",
|
|
83
|
+
"jiti": "1.21.0",
|
|
77
84
|
"nuxt": "3.8.2",
|
|
78
85
|
"playwright-core": "1.40.1",
|
|
79
|
-
"rollup": "4.
|
|
86
|
+
"rollup": "4.9.1",
|
|
87
|
+
"semver": "7.5.4",
|
|
80
88
|
"unbuild": "latest",
|
|
81
|
-
"unimport": "3.6.
|
|
82
|
-
"vite": "5.0.
|
|
83
|
-
"vitest": "0.
|
|
89
|
+
"unimport": "3.6.1",
|
|
90
|
+
"vite": "5.0.10",
|
|
91
|
+
"vitest": "1.0.4",
|
|
84
92
|
"vue-router": "4.2.5",
|
|
85
|
-
"vue-tsc": "1.8.
|
|
93
|
+
"vue-tsc": "1.8.25"
|
|
86
94
|
},
|
|
87
95
|
"peerDependencies": {
|
|
88
96
|
"@jest/globals": "^29.5.0",
|
|
89
97
|
"@testing-library/vue": "^7.0.0 || ^8.0.1",
|
|
90
|
-
"@vitest/ui": "0.
|
|
98
|
+
"@vitest/ui": "^0.34.6 || ^1.0.0",
|
|
91
99
|
"@vue/test-utils": "^2.4.2",
|
|
92
100
|
"h3": "*",
|
|
93
101
|
"happy-dom": "^9.10.9 || ^10.0.0 || ^11.0.0 || ^12.0.0",
|
|
94
102
|
"jsdom": "^22.0.0 || ^23.0.0",
|
|
95
103
|
"playwright-core": "^1.34.3",
|
|
96
104
|
"vite": "*",
|
|
97
|
-
"vitest": "^0.
|
|
105
|
+
"vitest": "^0.34.6 || ^1.0.0",
|
|
98
106
|
"vue": "^3.3.4",
|
|
99
107
|
"vue-router": "^4.0.0"
|
|
100
108
|
},
|
|
@@ -126,12 +134,11 @@
|
|
|
126
134
|
},
|
|
127
135
|
"resolutions": {
|
|
128
136
|
"@nuxt/test-utils": "workspace:*",
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
"vite": "5.0.4"
|
|
137
|
+
"rollup": "4.9.1",
|
|
138
|
+
"vite": "5.0.10"
|
|
132
139
|
},
|
|
133
140
|
"engines": {
|
|
134
141
|
"node": "^14.18.0 || >=16.10.0"
|
|
135
142
|
},
|
|
136
|
-
"packageManager": "pnpm@8.
|
|
143
|
+
"packageManager": "pnpm@8.12.1"
|
|
137
144
|
}
|
package/runtime.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/runtime-utils/index.mjs'
|
package/runtime-utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './dist/runtime-utils'
|