@nuxt/test-utils-nightly 0.0.0 β 3.8.0-28285359.eb40409f
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/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/experimental.d.mts +7 -0
- package/dist/experimental.d.ts +7 -0
- package/dist/experimental.mjs +24 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.mjs +236 -0
- package/dist/runtime/global-setup.d.ts +2 -0
- package/dist/runtime/global-setup.mjs +14 -0
- package/dist/shared/test-utils-nightly.8f432eb9.mjs +131 -0
- package/package.json +58 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016-present - Nuxt Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[](https://nuxt.com)
|
|
2
|
+
|
|
3
|
+
# Nuxt
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/v/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Version"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/nuxt"><img src="https://img.shields.io/npm/dm/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="Downloads"></a>
|
|
8
|
+
<a href="./LICENSE"><img src="https://img.shields.io/github/license/nuxt/nuxt.svg?style=flat&colorA=18181B&colorB=28CF8D" alt="License"></a>
|
|
9
|
+
<a href="https://nuxt.com"><img src="https://img.shields.io/badge/Nuxt%20Docs-18181B?logo=nuxt.js" alt="Website"></a>
|
|
10
|
+
<a href="https://chat.nuxt.dev"><img src="https://img.shields.io/badge/Nuxt%20Discord-18181B?logo=discord" alt="Discord"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.
|
|
14
|
+
|
|
15
|
+
It provides a number of features that make it easy to build fast, SEO-friendly, and scalable web applications, including:
|
|
16
|
+
- Server-side rendering, Static Site Generation or Hybrid Rendering
|
|
17
|
+
- Automatic routing with code-splitting
|
|
18
|
+
- State management
|
|
19
|
+
- SEO Optimization
|
|
20
|
+
- Extensible with [100+ modules](https://nuxt.com/modules)
|
|
21
|
+
- Deployment to a variety of hosting platforms
|
|
22
|
+
- ...[and much more](https://nuxt.com) π
|
|
23
|
+
|
|
24
|
+
## Getting Started
|
|
25
|
+
|
|
26
|
+
Use the following command to create a new starter project. This will create a starter project with all the necessary files and dependencies:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx nuxi@latest init <my-project>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Discover also [nuxt.new](https://nuxt.new): Open a Nuxt starter on CodeSandbox, StackBlitz or locally to get up and running in a few seconds.
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
We highly recommend you take a look at the [Nuxt documentation](https://nuxt.com/docs) to level up. Itβs a great resource for learning more about the framework. It covers everything from getting started to advanced topics.
|
|
37
|
+
|
|
38
|
+
## Modules
|
|
39
|
+
|
|
40
|
+
Discover our [list of modules](https://nuxt.com/modules) to supercharge your Nuxt project, created by the Nuxt team and community.
|
|
41
|
+
|
|
42
|
+
## Contribute
|
|
43
|
+
|
|
44
|
+
We invite you to contribute and help improve Nuxt π
|
|
45
|
+
|
|
46
|
+
Here are a few ways you can get involved:
|
|
47
|
+
- **Reporting Bugs:** If you come across any bugs or issues, please check out the [reporting bugs guide](https://nuxt.com/docs/community/reporting-bugs) to learn how to submit a bug report.
|
|
48
|
+
- **Suggestions:** Have ideas to enhance Nuxt? We'd love to hear them! Check out the [contribution guide](https://nuxt.com/docs/community/contribution#creating-an-issue) to share your suggestions.
|
|
49
|
+
- **Questions:** If you have questions or need assistance, the [getting help guide](https://nuxt.com/docs/community/getting-help) provides resources to help you out.
|
|
50
|
+
|
|
51
|
+
## Local Development
|
|
52
|
+
|
|
53
|
+
Follow the docs to [Set Up Your Local Development Environment](https://nuxt.com/docs/community/framework-contribution#set-up-your-local-development-environment) to contribute to the framework and documentation.
|
|
54
|
+
|
|
55
|
+
## Nuxt 2
|
|
56
|
+
|
|
57
|
+
You can find the code for Nuxt 2 on the [`2.x` branch](https://github.com/nuxt/nuxt/tree/2.x) and the documentation at [v2.nuxt.com](https://v2.nuxt.com).
|
|
58
|
+
|
|
59
|
+
## Follow us
|
|
60
|
+
|
|
61
|
+
<p valign="center">
|
|
62
|
+
<a href="https://chat.nuxt.dev"><img width="20px" src="./.github/assets/discord.svg" alt="Discord"></a> <a href="https://twitter.nuxt.dev"><img width="20px" src="./.github/assets/twitter.svg" alt="Twitter"></a> <a href="https://github.nuxt.dev"><img width="20px" src="./.github/assets/github.svg" alt="GitHub"></a>
|
|
63
|
+
</p>
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
[MIT](./LICENSE)
|
|
68
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a function to render a component directly with the Nuxt server.
|
|
3
|
+
*/
|
|
4
|
+
declare function $fetchComponent(filepath: string, props?: Record<string, any>): Promise<any>;
|
|
5
|
+
declare function componentTestUrl(filepath: string, props?: Record<string, any>): string;
|
|
6
|
+
|
|
7
|
+
export { $fetchComponent, componentTestUrl };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a function to render a component directly with the Nuxt server.
|
|
3
|
+
*/
|
|
4
|
+
declare function $fetchComponent(filepath: string, props?: Record<string, any>): Promise<any>;
|
|
5
|
+
declare function componentTestUrl(filepath: string, props?: Record<string, any>): string;
|
|
6
|
+
|
|
7
|
+
export { $fetchComponent, componentTestUrl };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { resolve } from 'pathe';
|
|
2
|
+
import { stringifyQuery } from 'ufo';
|
|
3
|
+
import { $ as $fetch, u as useTestContext } from './shared/test-utils-nightly.8f432eb9.mjs';
|
|
4
|
+
import 'execa';
|
|
5
|
+
import 'get-port-please';
|
|
6
|
+
import 'ofetch';
|
|
7
|
+
import '@nuxt/kit';
|
|
8
|
+
import 'node:path';
|
|
9
|
+
import 'defu';
|
|
10
|
+
|
|
11
|
+
function $fetchComponent(filepath, props) {
|
|
12
|
+
return $fetch(componentTestUrl(filepath, props));
|
|
13
|
+
}
|
|
14
|
+
function componentTestUrl(filepath, props) {
|
|
15
|
+
const ctx = useTestContext();
|
|
16
|
+
filepath = resolve(ctx.options.rootDir, filepath);
|
|
17
|
+
const path = stringifyQuery({
|
|
18
|
+
path: filepath,
|
|
19
|
+
props: JSON.stringify(props)
|
|
20
|
+
});
|
|
21
|
+
return `/__nuxt_component_test__/?${path}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { $fetchComponent, componentTestUrl };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as playwright_core from 'playwright-core';
|
|
2
|
+
import { Browser, BrowserContextOptions, LaunchOptions } from 'playwright-core';
|
|
3
|
+
import { NuxtConfig, Nuxt } from '@nuxt/schema';
|
|
4
|
+
import { ExecaChildProcess } from 'execa';
|
|
5
|
+
import { FetchOptions } from 'ofetch';
|
|
6
|
+
|
|
7
|
+
declare function createBrowser(): Promise<void>;
|
|
8
|
+
declare function getBrowser(): Promise<Browser>;
|
|
9
|
+
declare function createPage(path?: string, options?: BrowserContextOptions): Promise<playwright_core.Page>;
|
|
10
|
+
|
|
11
|
+
type TestRunner = 'vitest' | 'jest';
|
|
12
|
+
interface TestOptions {
|
|
13
|
+
testDir: string;
|
|
14
|
+
fixture: string;
|
|
15
|
+
configFile: string;
|
|
16
|
+
rootDir: string;
|
|
17
|
+
buildDir: string;
|
|
18
|
+
nuxtConfig: NuxtConfig;
|
|
19
|
+
build: boolean;
|
|
20
|
+
dev: boolean;
|
|
21
|
+
setupTimeout: number;
|
|
22
|
+
waitFor: number;
|
|
23
|
+
browser: boolean;
|
|
24
|
+
runner: TestRunner;
|
|
25
|
+
logLevel: number;
|
|
26
|
+
browserOptions: {
|
|
27
|
+
type: 'chromium' | 'firefox' | 'webkit';
|
|
28
|
+
launch?: LaunchOptions;
|
|
29
|
+
};
|
|
30
|
+
server: boolean;
|
|
31
|
+
port?: number;
|
|
32
|
+
}
|
|
33
|
+
interface TestContext {
|
|
34
|
+
options: TestOptions;
|
|
35
|
+
nuxt?: Nuxt;
|
|
36
|
+
browser?: Browser;
|
|
37
|
+
url?: string;
|
|
38
|
+
serverProcess?: ExecaChildProcess;
|
|
39
|
+
mockFn?: Function;
|
|
40
|
+
}
|
|
41
|
+
interface TestHooks {
|
|
42
|
+
beforeEach: () => void;
|
|
43
|
+
afterEach: () => void;
|
|
44
|
+
afterAll: () => void;
|
|
45
|
+
setup: () => void;
|
|
46
|
+
ctx: TestContext;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare function createTestContext(options: Partial<TestOptions>): TestContext;
|
|
50
|
+
declare function useTestContext(): TestContext;
|
|
51
|
+
declare function setTestContext(context: TestContext): TestContext;
|
|
52
|
+
declare function setTestContext(context?: TestContext): TestContext | undefined;
|
|
53
|
+
declare function isDev(): boolean;
|
|
54
|
+
declare function recoverContextFromEnv(): void;
|
|
55
|
+
declare function exposeContextToEnv(): void;
|
|
56
|
+
|
|
57
|
+
declare function mockFn(): Function | undefined;
|
|
58
|
+
declare function mockLogger(): Record<string, Function>;
|
|
59
|
+
|
|
60
|
+
declare function loadFixture(): Promise<void>;
|
|
61
|
+
declare function buildFixture(): Promise<void>;
|
|
62
|
+
|
|
63
|
+
declare function startServer(): Promise<void>;
|
|
64
|
+
declare function stopServer(): Promise<void>;
|
|
65
|
+
declare function fetch(path: string, options?: any): Promise<Response>;
|
|
66
|
+
declare function $fetch(path: string, options?: FetchOptions): Promise<any>;
|
|
67
|
+
declare function url(path: string): string;
|
|
68
|
+
|
|
69
|
+
declare function setupJest(hooks: TestHooks): Promise<void>;
|
|
70
|
+
|
|
71
|
+
declare function setupVitest(hooks: TestHooks): Promise<void>;
|
|
72
|
+
|
|
73
|
+
declare const setupMaps: {
|
|
74
|
+
jest: typeof setupJest;
|
|
75
|
+
vitest: typeof setupVitest;
|
|
76
|
+
};
|
|
77
|
+
declare function createTest(options: Partial<TestOptions>): TestHooks;
|
|
78
|
+
declare function setup(options?: Partial<TestOptions>): Promise<void>;
|
|
79
|
+
|
|
80
|
+
interface RunTestOptions {
|
|
81
|
+
rootDir: string;
|
|
82
|
+
dev?: boolean;
|
|
83
|
+
watch?: boolean;
|
|
84
|
+
runner?: 'vitest';
|
|
85
|
+
globalSetup?: boolean;
|
|
86
|
+
}
|
|
87
|
+
declare function runTests(opts: RunTestOptions): Promise<void>;
|
|
88
|
+
|
|
89
|
+
export { $fetch, type RunTestOptions, type TestContext, type TestHooks, type TestOptions, type TestRunner, buildFixture, createBrowser, createPage, createTest, createTestContext, exposeContextToEnv, fetch, getBrowser, isDev, loadFixture, mockFn, mockLogger, recoverContextFromEnv, runTests, setTestContext, setup, setupMaps, startServer, stopServer, url, useTestContext };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as playwright_core from 'playwright-core';
|
|
2
|
+
import { Browser, BrowserContextOptions, LaunchOptions } from 'playwright-core';
|
|
3
|
+
import { NuxtConfig, Nuxt } from '@nuxt/schema';
|
|
4
|
+
import { ExecaChildProcess } from 'execa';
|
|
5
|
+
import { FetchOptions } from 'ofetch';
|
|
6
|
+
|
|
7
|
+
declare function createBrowser(): Promise<void>;
|
|
8
|
+
declare function getBrowser(): Promise<Browser>;
|
|
9
|
+
declare function createPage(path?: string, options?: BrowserContextOptions): Promise<playwright_core.Page>;
|
|
10
|
+
|
|
11
|
+
type TestRunner = 'vitest' | 'jest';
|
|
12
|
+
interface TestOptions {
|
|
13
|
+
testDir: string;
|
|
14
|
+
fixture: string;
|
|
15
|
+
configFile: string;
|
|
16
|
+
rootDir: string;
|
|
17
|
+
buildDir: string;
|
|
18
|
+
nuxtConfig: NuxtConfig;
|
|
19
|
+
build: boolean;
|
|
20
|
+
dev: boolean;
|
|
21
|
+
setupTimeout: number;
|
|
22
|
+
waitFor: number;
|
|
23
|
+
browser: boolean;
|
|
24
|
+
runner: TestRunner;
|
|
25
|
+
logLevel: number;
|
|
26
|
+
browserOptions: {
|
|
27
|
+
type: 'chromium' | 'firefox' | 'webkit';
|
|
28
|
+
launch?: LaunchOptions;
|
|
29
|
+
};
|
|
30
|
+
server: boolean;
|
|
31
|
+
port?: number;
|
|
32
|
+
}
|
|
33
|
+
interface TestContext {
|
|
34
|
+
options: TestOptions;
|
|
35
|
+
nuxt?: Nuxt;
|
|
36
|
+
browser?: Browser;
|
|
37
|
+
url?: string;
|
|
38
|
+
serverProcess?: ExecaChildProcess;
|
|
39
|
+
mockFn?: Function;
|
|
40
|
+
}
|
|
41
|
+
interface TestHooks {
|
|
42
|
+
beforeEach: () => void;
|
|
43
|
+
afterEach: () => void;
|
|
44
|
+
afterAll: () => void;
|
|
45
|
+
setup: () => void;
|
|
46
|
+
ctx: TestContext;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare function createTestContext(options: Partial<TestOptions>): TestContext;
|
|
50
|
+
declare function useTestContext(): TestContext;
|
|
51
|
+
declare function setTestContext(context: TestContext): TestContext;
|
|
52
|
+
declare function setTestContext(context?: TestContext): TestContext | undefined;
|
|
53
|
+
declare function isDev(): boolean;
|
|
54
|
+
declare function recoverContextFromEnv(): void;
|
|
55
|
+
declare function exposeContextToEnv(): void;
|
|
56
|
+
|
|
57
|
+
declare function mockFn(): Function | undefined;
|
|
58
|
+
declare function mockLogger(): Record<string, Function>;
|
|
59
|
+
|
|
60
|
+
declare function loadFixture(): Promise<void>;
|
|
61
|
+
declare function buildFixture(): Promise<void>;
|
|
62
|
+
|
|
63
|
+
declare function startServer(): Promise<void>;
|
|
64
|
+
declare function stopServer(): Promise<void>;
|
|
65
|
+
declare function fetch(path: string, options?: any): Promise<Response>;
|
|
66
|
+
declare function $fetch(path: string, options?: FetchOptions): Promise<any>;
|
|
67
|
+
declare function url(path: string): string;
|
|
68
|
+
|
|
69
|
+
declare function setupJest(hooks: TestHooks): Promise<void>;
|
|
70
|
+
|
|
71
|
+
declare function setupVitest(hooks: TestHooks): Promise<void>;
|
|
72
|
+
|
|
73
|
+
declare const setupMaps: {
|
|
74
|
+
jest: typeof setupJest;
|
|
75
|
+
vitest: typeof setupVitest;
|
|
76
|
+
};
|
|
77
|
+
declare function createTest(options: Partial<TestOptions>): TestHooks;
|
|
78
|
+
declare function setup(options?: Partial<TestOptions>): Promise<void>;
|
|
79
|
+
|
|
80
|
+
interface RunTestOptions {
|
|
81
|
+
rootDir: string;
|
|
82
|
+
dev?: boolean;
|
|
83
|
+
watch?: boolean;
|
|
84
|
+
runner?: 'vitest';
|
|
85
|
+
globalSetup?: boolean;
|
|
86
|
+
}
|
|
87
|
+
declare function runTests(opts: RunTestOptions): Promise<void>;
|
|
88
|
+
|
|
89
|
+
export { $fetch, type RunTestOptions, type TestContext, type TestHooks, type TestOptions, type TestRunner, buildFixture, createBrowser, createPage, createTest, createTestContext, exposeContextToEnv, fetch, getBrowser, isDev, loadFixture, mockFn, mockLogger, recoverContextFromEnv, runTests, setTestContext, setup, setupMaps, startServer, stopServer, url, useTestContext };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
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.8f432eb9.mjs';
|
|
2
|
+
export { $ as $fetch, e as exposeContextToEnv, f as fetch, i as isDev, r as recoverContextFromEnv } from './shared/test-utils-nightly.8f432eb9.mjs';
|
|
3
|
+
import { consola } from 'consola';
|
|
4
|
+
import { promises, existsSync } from 'node:fs';
|
|
5
|
+
import { resolve } from 'node:path';
|
|
6
|
+
import { defu } from 'defu';
|
|
7
|
+
import * as _kit from '@nuxt/kit';
|
|
8
|
+
import { dirname, resolve as resolve$1 } from 'pathe';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import 'execa';
|
|
11
|
+
import 'get-port-please';
|
|
12
|
+
import 'ofetch';
|
|
13
|
+
|
|
14
|
+
async function createBrowser() {
|
|
15
|
+
const ctx = useTestContext();
|
|
16
|
+
let playwright;
|
|
17
|
+
try {
|
|
18
|
+
playwright = await import(String("playwright-core"));
|
|
19
|
+
} catch {
|
|
20
|
+
throw new Error(`
|
|
21
|
+
The dependency 'playwright-core' not found.
|
|
22
|
+
Please run 'yarn add --dev playwright-core' or 'npm install --save-dev playwright-core'
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
const { type, launch } = ctx.options.browserOptions;
|
|
26
|
+
if (!playwright[type]) {
|
|
27
|
+
throw new Error(`Invalid browser '${type}'`);
|
|
28
|
+
}
|
|
29
|
+
ctx.browser = await playwright[type].launch(launch);
|
|
30
|
+
}
|
|
31
|
+
async function getBrowser() {
|
|
32
|
+
const ctx = useTestContext();
|
|
33
|
+
if (!ctx.browser) {
|
|
34
|
+
await createBrowser();
|
|
35
|
+
}
|
|
36
|
+
return ctx.browser;
|
|
37
|
+
}
|
|
38
|
+
async function createPage(path, options) {
|
|
39
|
+
const browser = await getBrowser();
|
|
40
|
+
const page = await browser.newPage(options);
|
|
41
|
+
if (path) {
|
|
42
|
+
await page.goto(url(path));
|
|
43
|
+
}
|
|
44
|
+
return page;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function mockFn() {
|
|
48
|
+
const ctx = useTestContext();
|
|
49
|
+
return ctx.mockFn;
|
|
50
|
+
}
|
|
51
|
+
function mockLogger() {
|
|
52
|
+
const mocks = {};
|
|
53
|
+
consola.mockTypes((type) => {
|
|
54
|
+
mocks[type] = mockFn();
|
|
55
|
+
return mocks[type];
|
|
56
|
+
});
|
|
57
|
+
return mocks;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const kit = _kit.default || _kit;
|
|
61
|
+
const isNuxtApp = (dir) => {
|
|
62
|
+
return existsSync(dir) && (existsSync(resolve(dir, "pages")) || existsSync(resolve(dir, "nuxt.config.js")) || existsSync(resolve(dir, "nuxt.config.mjs")) || existsSync(resolve(dir, "nuxt.config.cjs")) || existsSync(resolve(dir, "nuxt.config.ts")));
|
|
63
|
+
};
|
|
64
|
+
const resolveRootDir = () => {
|
|
65
|
+
const { options } = useTestContext();
|
|
66
|
+
const dirs = [
|
|
67
|
+
options.rootDir,
|
|
68
|
+
resolve(options.testDir, options.fixture),
|
|
69
|
+
process.cwd()
|
|
70
|
+
];
|
|
71
|
+
for (const dir of dirs) {
|
|
72
|
+
if (dir && isNuxtApp(dir)) {
|
|
73
|
+
return dir;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
throw new Error("Invalid nuxt app. (Please explicitly set `options.rootDir` pointing to a valid nuxt app)");
|
|
77
|
+
};
|
|
78
|
+
async function loadFixture() {
|
|
79
|
+
const ctx = useTestContext();
|
|
80
|
+
ctx.options.rootDir = resolveRootDir();
|
|
81
|
+
if (!ctx.options.dev) {
|
|
82
|
+
const randomId = Math.random().toString(36).slice(2, 8);
|
|
83
|
+
const buildDir = resolve(ctx.options.rootDir, ".nuxt", randomId);
|
|
84
|
+
ctx.options.nuxtConfig = defu(ctx.options.nuxtConfig, {
|
|
85
|
+
buildDir,
|
|
86
|
+
nitro: {
|
|
87
|
+
output: {
|
|
88
|
+
dir: resolve(buildDir, "output")
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
ctx.nuxt = await kit.loadNuxt({
|
|
94
|
+
cwd: ctx.options.rootDir,
|
|
95
|
+
dev: ctx.options.dev,
|
|
96
|
+
overrides: ctx.options.nuxtConfig,
|
|
97
|
+
configFile: ctx.options.configFile
|
|
98
|
+
});
|
|
99
|
+
await promises.mkdir(ctx.nuxt.options.buildDir, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
async function buildFixture() {
|
|
102
|
+
const ctx = useTestContext();
|
|
103
|
+
const prevLevel = kit.logger.level;
|
|
104
|
+
kit.logger.level = ctx.options.logLevel;
|
|
105
|
+
await kit.buildNuxt(ctx.nuxt);
|
|
106
|
+
kit.logger.level = prevLevel;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function setupJest(hooks) {
|
|
110
|
+
const { jest, test, beforeEach, afterAll, afterEach } = await import('@jest/globals');
|
|
111
|
+
hooks.ctx.mockFn = jest.fn;
|
|
112
|
+
test("setup", hooks.setup, hooks.ctx.options.setupTimeout);
|
|
113
|
+
beforeEach(hooks.beforeEach);
|
|
114
|
+
afterEach(hooks.afterEach);
|
|
115
|
+
afterAll(hooks.afterAll);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function setupVitest(hooks) {
|
|
119
|
+
const vitest = await import('vitest');
|
|
120
|
+
hooks.ctx.mockFn = vitest.vi.fn;
|
|
121
|
+
vitest.beforeAll(hooks.setup, hooks.ctx.options.setupTimeout);
|
|
122
|
+
vitest.beforeEach(hooks.beforeEach);
|
|
123
|
+
vitest.afterEach(hooks.afterEach);
|
|
124
|
+
vitest.afterAll(hooks.afterAll);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const setupMaps = {
|
|
128
|
+
jest: setupJest,
|
|
129
|
+
vitest: setupVitest
|
|
130
|
+
};
|
|
131
|
+
function createTest(options) {
|
|
132
|
+
const ctx = createTestContext(options);
|
|
133
|
+
const beforeEach = () => {
|
|
134
|
+
setTestContext(ctx);
|
|
135
|
+
};
|
|
136
|
+
const afterEach = () => {
|
|
137
|
+
setTestContext(void 0);
|
|
138
|
+
};
|
|
139
|
+
const afterAll = async () => {
|
|
140
|
+
if (ctx.serverProcess) {
|
|
141
|
+
setTestContext(ctx);
|
|
142
|
+
await stopServer();
|
|
143
|
+
setTestContext(void 0);
|
|
144
|
+
}
|
|
145
|
+
if (ctx.nuxt && ctx.nuxt.options.dev) {
|
|
146
|
+
await ctx.nuxt.close();
|
|
147
|
+
}
|
|
148
|
+
if (ctx.browser) {
|
|
149
|
+
await ctx.browser.close();
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const setup2 = async () => {
|
|
153
|
+
if (ctx.options.fixture) {
|
|
154
|
+
await loadFixture();
|
|
155
|
+
}
|
|
156
|
+
if (ctx.options.build) {
|
|
157
|
+
await buildFixture();
|
|
158
|
+
}
|
|
159
|
+
if (ctx.options.server) {
|
|
160
|
+
await startServer();
|
|
161
|
+
}
|
|
162
|
+
if (ctx.options.waitFor) {
|
|
163
|
+
await new Promise((resolve) => setTimeout(resolve, ctx.options.waitFor));
|
|
164
|
+
}
|
|
165
|
+
if (ctx.options.browser) {
|
|
166
|
+
await createBrowser();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return {
|
|
170
|
+
beforeEach,
|
|
171
|
+
afterEach,
|
|
172
|
+
afterAll,
|
|
173
|
+
setup: setup2,
|
|
174
|
+
ctx
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function setup(options = {}) {
|
|
178
|
+
const hooks = createTest(options);
|
|
179
|
+
const setupFn = setupMaps[hooks.ctx.options.runner];
|
|
180
|
+
await setupFn(hooks);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const distDir = dirname(fileURLToPath(import.meta.url));
|
|
184
|
+
|
|
185
|
+
const RunTestDefaults = {
|
|
186
|
+
runner: "vitest",
|
|
187
|
+
globalSetup: true
|
|
188
|
+
};
|
|
189
|
+
async function runTests(opts) {
|
|
190
|
+
opts = { ...RunTestDefaults, ...opts };
|
|
191
|
+
if (opts.runner !== "vitest") {
|
|
192
|
+
throw new Error(`Unsupported runner: ${opts.runner}. Currently only vitest runner is supported.`);
|
|
193
|
+
}
|
|
194
|
+
if (opts.dev) {
|
|
195
|
+
process.env.NUXT_TEST_DEV = "true";
|
|
196
|
+
}
|
|
197
|
+
process.env.NUXT_TEST_OPTIONS = JSON.stringify(opts);
|
|
198
|
+
const { startVitest } = await import('vitest/node');
|
|
199
|
+
const succeeded = await startVitest(
|
|
200
|
+
"test",
|
|
201
|
+
[],
|
|
202
|
+
// Vitest options
|
|
203
|
+
{
|
|
204
|
+
root: opts.rootDir,
|
|
205
|
+
run: !opts.watch,
|
|
206
|
+
deps: {
|
|
207
|
+
inline: [/@nuxt\/test-utils/]
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
// Vite options
|
|
211
|
+
{
|
|
212
|
+
esbuild: {
|
|
213
|
+
tsconfigRaw: "{}"
|
|
214
|
+
},
|
|
215
|
+
test: {
|
|
216
|
+
dir: opts.rootDir,
|
|
217
|
+
deps: {
|
|
218
|
+
inline: [
|
|
219
|
+
distDir,
|
|
220
|
+
"@nuxt/test-utils",
|
|
221
|
+
"@nuxt/test-utils-edge"
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
globals: true,
|
|
225
|
+
globalSetup: [
|
|
226
|
+
...opts.globalSetup ? [resolve$1(distDir, "./runtime/global-setup")] : []
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
if (!succeeded) {
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export { buildFixture, createBrowser, createPage, createTest, createTestContext, getBrowser, loadFixture, mockFn, mockLogger, runTests, setTestContext, setup, setupMaps, startServer, stopServer, url, useTestContext };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as _kit from "@nuxt/kit";
|
|
2
|
+
import { createTest, exposeContextToEnv } from "@nuxt/test-utils";
|
|
3
|
+
const kit = _kit.default || _kit;
|
|
4
|
+
const options = JSON.parse(process.env.NUXT_TEST_OPTIONS || "{}");
|
|
5
|
+
const hooks = createTest(options);
|
|
6
|
+
export const setup = async () => {
|
|
7
|
+
kit.logger.info("Building Nuxt app...");
|
|
8
|
+
await hooks.setup();
|
|
9
|
+
exposeContextToEnv();
|
|
10
|
+
kit.logger.info("Running tests...");
|
|
11
|
+
};
|
|
12
|
+
export const teardown = async () => {
|
|
13
|
+
await hooks.afterAll();
|
|
14
|
+
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { getRandomPort, waitForPort } from 'get-port-please';
|
|
3
|
+
import { fetch as fetch$1, $fetch as $fetch$1 } from 'ofetch';
|
|
4
|
+
import * as _kit from '@nuxt/kit';
|
|
5
|
+
import { resolve as resolve$1 } from 'pathe';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
import { defu } from 'defu';
|
|
8
|
+
|
|
9
|
+
let currentContext;
|
|
10
|
+
function createTestContext(options) {
|
|
11
|
+
const _options = defu(options, {
|
|
12
|
+
testDir: resolve(process.cwd(), "test"),
|
|
13
|
+
fixture: "fixture",
|
|
14
|
+
configFile: "nuxt.config",
|
|
15
|
+
setupTimeout: 120 * 1e3,
|
|
16
|
+
dev: !!JSON.parse(process.env.NUXT_TEST_DEV || "false"),
|
|
17
|
+
logLevel: 1,
|
|
18
|
+
server: true,
|
|
19
|
+
build: options.browser !== false || options.server !== false,
|
|
20
|
+
nuxtConfig: {},
|
|
21
|
+
// TODO: auto detect based on process.env
|
|
22
|
+
runner: "vitest",
|
|
23
|
+
browserOptions: {
|
|
24
|
+
type: "chromium"
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return setTestContext({
|
|
28
|
+
options: _options
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function useTestContext() {
|
|
32
|
+
recoverContextFromEnv();
|
|
33
|
+
if (!currentContext) {
|
|
34
|
+
throw new Error("No context is available. (Forgot calling setup or createContext?)");
|
|
35
|
+
}
|
|
36
|
+
return currentContext;
|
|
37
|
+
}
|
|
38
|
+
function setTestContext(context) {
|
|
39
|
+
currentContext = context;
|
|
40
|
+
return currentContext;
|
|
41
|
+
}
|
|
42
|
+
function isDev() {
|
|
43
|
+
const ctx = useTestContext();
|
|
44
|
+
return ctx.options.dev;
|
|
45
|
+
}
|
|
46
|
+
function recoverContextFromEnv() {
|
|
47
|
+
if (!currentContext && process.env.NUXT_TEST_CONTEXT) {
|
|
48
|
+
setTestContext(JSON.parse(process.env.NUXT_TEST_CONTEXT || "{}"));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function exposeContextToEnv() {
|
|
52
|
+
const { options, browser, url } = currentContext;
|
|
53
|
+
process.env.NUXT_TEST_CONTEXT = JSON.stringify({ options, browser, url });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const kit = _kit.default || _kit;
|
|
57
|
+
async function startServer() {
|
|
58
|
+
const ctx = useTestContext();
|
|
59
|
+
await stopServer();
|
|
60
|
+
const host = "127.0.0.1";
|
|
61
|
+
const port = ctx.options.port || await getRandomPort(host);
|
|
62
|
+
ctx.url = `http://${host}:${port}`;
|
|
63
|
+
if (ctx.options.dev) {
|
|
64
|
+
const nuxiCLI = await kit.resolvePath("nuxi/cli");
|
|
65
|
+
ctx.serverProcess = execa(nuxiCLI, ["_dev"], {
|
|
66
|
+
cwd: ctx.nuxt.options.rootDir,
|
|
67
|
+
stdio: "inherit",
|
|
68
|
+
env: {
|
|
69
|
+
...process.env,
|
|
70
|
+
_PORT: String(port),
|
|
71
|
+
// Used by internal _dev command
|
|
72
|
+
PORT: String(port),
|
|
73
|
+
HOST: host,
|
|
74
|
+
NODE_ENV: "development"
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
await waitForPort(port, { retries: 32, host }).catch(() => {
|
|
78
|
+
});
|
|
79
|
+
let lastError;
|
|
80
|
+
for (let i = 0; i < 150; i++) {
|
|
81
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
82
|
+
try {
|
|
83
|
+
const res = await $fetch(ctx.nuxt.options.app.baseURL);
|
|
84
|
+
if (!res.includes("__NUXT_LOADING__")) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
} catch (e) {
|
|
88
|
+
lastError = e;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
ctx.serverProcess.kill();
|
|
92
|
+
throw lastError || new Error("Timeout waiting for dev server!");
|
|
93
|
+
} else {
|
|
94
|
+
ctx.serverProcess = execa("node", [
|
|
95
|
+
resolve$1(ctx.nuxt.options.nitro.output.dir, "server/index.mjs")
|
|
96
|
+
], {
|
|
97
|
+
stdio: "inherit",
|
|
98
|
+
env: {
|
|
99
|
+
...process.env,
|
|
100
|
+
PORT: String(port),
|
|
101
|
+
HOST: host,
|
|
102
|
+
NODE_ENV: "test"
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
await waitForPort(port, { retries: 20, host });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function stopServer() {
|
|
109
|
+
const ctx = useTestContext();
|
|
110
|
+
if (ctx.serverProcess) {
|
|
111
|
+
await ctx.serverProcess.kill();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function fetch(path, options) {
|
|
115
|
+
return fetch$1(url(path), options);
|
|
116
|
+
}
|
|
117
|
+
function $fetch(path, options) {
|
|
118
|
+
return $fetch$1(url(path), options);
|
|
119
|
+
}
|
|
120
|
+
function url(path) {
|
|
121
|
+
const ctx = useTestContext();
|
|
122
|
+
if (!ctx.url) {
|
|
123
|
+
throw new Error("url is not available (is server option enabled?)");
|
|
124
|
+
}
|
|
125
|
+
if (path.startsWith(ctx.url)) {
|
|
126
|
+
return path;
|
|
127
|
+
}
|
|
128
|
+
return ctx.url + path;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { $fetch as $, url as a, stopServer as b, createTestContext as c, startServer as d, exposeContextToEnv as e, fetch as f, isDev as i, recoverContextFromEnv as r, setTestContext as s, useTestContext as u };
|
package/package.json
CHANGED
|
@@ -1,4 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt/test-utils-nightly",
|
|
3
|
-
"version": "
|
|
4
|
-
|
|
3
|
+
"version": "3.8.0-28285359.eb40409f",
|
|
4
|
+
"repository": "nuxt/nuxt",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"./experimental": {
|
|
14
|
+
"types": "./dist/experimental.d.ts",
|
|
15
|
+
"import": "./dist/experimental.mjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@nuxt/kit": "npm:@nuxt/kit-nightly@3.8.0-28285359.eb40409f",
|
|
23
|
+
"@nuxt/schema": "npm:@nuxt/schema-nightly@3.8.0-28285359.eb40409f",
|
|
24
|
+
"consola": "^3.2.3",
|
|
25
|
+
"defu": "^6.1.2",
|
|
26
|
+
"execa": "^7.2.0",
|
|
27
|
+
"get-port-please": "^3.1.1",
|
|
28
|
+
"ofetch": "^1.3.3",
|
|
29
|
+
"pathe": "^1.1.1",
|
|
30
|
+
"ufo": "^1.3.1"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@jest/globals": "29.7.0",
|
|
34
|
+
"playwright-core": "1.38.1",
|
|
35
|
+
"unbuild": "latest",
|
|
36
|
+
"vitest": "0.33.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@jest/globals": "^29.5.0",
|
|
40
|
+
"playwright-core": "^1.34.3",
|
|
41
|
+
"vitest": "^0.30.0 || ^0.31.0 || ^0.32.0 || ^0.33.0",
|
|
42
|
+
"vue": "^3.3.4"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@jest/globals": {
|
|
46
|
+
"optional": true
|
|
47
|
+
},
|
|
48
|
+
"playwright-core": {
|
|
49
|
+
"optional": true
|
|
50
|
+
},
|
|
51
|
+
"vitest": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": "^14.18.0 || >=16.10.0"
|
|
57
|
+
},
|
|
58
|
+
"_name": "@nuxt/test-utils",
|
|
59
|
+
"scripts": {}
|
|
60
|
+
}
|