diff --git a/examples/advanced/testing/package.json b/examples/advanced/testing/package.json index 5c011ec5478..57273de7051 100644 --- a/examples/advanced/testing/package.json +++ b/examples/advanced/testing/package.json @@ -5,7 +5,7 @@ "build": "nuxi build", "dev": "nuxi dev", "start": "nuxi preview", - "test": "vitest run" + "test": "nuxi test" }, "devDependencies": { "@nuxt/test-utils": "^3.0.0-rc.13", diff --git a/examples/advanced/testing/tests/basic.test.ts b/examples/advanced/testing/tests/basic.test.ts index 9768bca1bd8..696e3ec9404 100644 --- a/examples/advanced/testing/tests/basic.test.ts +++ b/examples/advanced/testing/tests/basic.test.ts @@ -1,13 +1,7 @@ -import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' -import { setup, $fetch, isDev } from '@nuxt/test-utils' - -describe('example', async () => { - await setup({ - rootDir: fileURLToPath(new URL('..', import.meta.url)), - server: true - }) +import { $fetch, isDev } from '@nuxt/test-utils' +describe('example', () => { it('Renders Hello Nuxt', async () => { expect(await $fetch('/')).toMatch('Hello Nuxt!') }) diff --git a/packages/nuxi/src/commands/test.ts b/packages/nuxi/src/commands/test.ts index ad6e94ae148..1761dc634f2 100644 --- a/packages/nuxi/src/commands/test.ts +++ b/packages/nuxi/src/commands/test.ts @@ -33,7 +33,9 @@ async function importTestUtils (): Promise { throw new Error('Invalid version of `@nuxt/test-utils` is installed!') } return exports - } catch (_err) { err = _err } + } catch (_err) { + err = _err + } } console.error(err) throw new Error('`@nuxt/test-utils-edge` seems missing. Run `npm i -D @nuxt/test-utils-edge` or `yarn add -D @nuxt/test-utils-edge` to install.') diff --git a/packages/test-utils/build.config.ts b/packages/test-utils/build.config.ts index 586a5fe31d7..4b6640762b1 100644 --- a/packages/test-utils/build.config.ts +++ b/packages/test-utils/build.config.ts @@ -3,7 +3,8 @@ import { defineBuildConfig } from 'unbuild' export default defineBuildConfig({ declaration: true, entries: [ - 'src/index' + 'src/index', + { input: 'src/runtime/', outDir: 'dist/runtime', format: 'esm' } ], externals: [ 'vitest', diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index c30a3256201..af19621e5d2 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -20,7 +20,8 @@ "execa": "^6.1.0", "get-port-please": "^2.6.1", "jiti": "^1.16.0", - "ohmyfetch": "^0.4.21" + "ohmyfetch": "^0.4.21", + "pathe": "^0.3.8" }, "devDependencies": { "playwright": "^1.27.1", diff --git a/packages/test-utils/src/context.ts b/packages/test-utils/src/context.ts index 0e8da939e7f..849ff4d1591 100644 --- a/packages/test-utils/src/context.ts +++ b/packages/test-utils/src/context.ts @@ -28,6 +28,7 @@ export function createTestContext (options: Partial): TestContext { } export function useTestContext (): TestContext { + recoverContextFromEnv() if (!currentContext) { throw new Error('No context is available. (Forgot calling setup or createContext?)') } @@ -45,3 +46,14 @@ export function isDev () { const ctx = useTestContext() return ctx.options.dev } + +export function recoverContextFromEnv () { + if (!currentContext && process.env.NUXT_TEST_CONTEXT) { + setTestContext(JSON.parse(process.env.NUXT_TEST_CONTEXT || '{}')) + } +} + +export function exposeContextToEnv () { + const { options, browser, url } = currentContext! + process.env.NUXT_TEST_CONTEXT = JSON.stringify({ options, browser, url }) +} diff --git a/packages/test-utils/src/dirs.ts b/packages/test-utils/src/dirs.ts new file mode 100644 index 00000000000..6eacc10603d --- /dev/null +++ b/packages/test-utils/src/dirs.ts @@ -0,0 +1,5 @@ +import { fileURLToPath } from 'node:url' +import { dirname, resolve } from 'pathe' + +export const distDir = dirname(fileURLToPath(import.meta.url)) +export const pkgDir = resolve(distDir, '..') diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts index 3238c8d5203..f55ad8e5696 100644 --- a/packages/test-utils/src/index.ts +++ b/packages/test-utils/src/index.ts @@ -5,3 +5,4 @@ export * from './nuxt' export * from './server' export * from './setup' export * from './run' +export * from './types' diff --git a/packages/test-utils/src/run.ts b/packages/test-utils/src/run.ts index e1cbe847492..6229ef0f3b4 100644 --- a/packages/test-utils/src/run.ts +++ b/packages/test-utils/src/run.ts @@ -1,12 +1,17 @@ +import { resolve } from 'pathe' +import { distDir } from './dirs' + export interface RunTestOptions { rootDir: string, dev?: boolean, watch?: boolean runner?: 'vitest' + globalSetup?: boolean } const RunTestDefaults: Partial = { - runner: 'vitest' + runner: 'vitest', + globalSetup: true } export async function runTests (opts: RunTestOptions) { @@ -21,6 +26,9 @@ export async function runTests (opts: RunTestOptions) { process.env.NUXT_TEST_DEV = 'true' } + // Consumed by recoverContextFromEnv() + process.env.NUXT_TEST_OPTIONS = JSON.stringify(opts) + const { startVitest } = await import('vitest/node') const succeeded = await startVitest( 'test', @@ -37,6 +45,20 @@ export async function runTests (opts: RunTestOptions) { { esbuild: { tsconfigRaw: '{}' + }, + test: { + dir: opts.rootDir, + deps: { + inline: [ + distDir, + '@nuxt/test-utils', + '@nuxt/test-utils-edge' + ] + }, + globals: true, + globalSetup: [ + ...opts.globalSetup ? [resolve(distDir, './runtime/global-setup')] : [] + ] } } ) diff --git a/packages/test-utils/src/runtime/global-setup.ts b/packages/test-utils/src/runtime/global-setup.ts new file mode 100644 index 00000000000..5dcfed31592 --- /dev/null +++ b/packages/test-utils/src/runtime/global-setup.ts @@ -0,0 +1,12 @@ +import { createTest, exposeContextToEnv } from '@nuxt/test-utils' + +const hooks = createTest(JSON.parse(process.env.NUXT_TEST_OPTIONS || '{}')) + +export const setup = async () => { + await hooks.setup() + exposeContextToEnv() +} + +export const teardown = async () => { + await hooks.afterAll() +} diff --git a/packages/test-utils/src/setup/index.ts b/packages/test-utils/src/setup/index.ts index 5b33673c87f..aa0b368cbb8 100644 --- a/packages/test-utils/src/setup/index.ts +++ b/packages/test-utils/src/setup/index.ts @@ -67,7 +67,7 @@ export function createTest (options: Partial): TestHooks { } } -export async function setup (options: Partial) { +export async function setup (options: Partial = {}) { const hooks = createTest(options) const setupFn = setupMaps[hooks.ctx.options.runner] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d993709b88..9e74ab5a57d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -557,6 +557,7 @@ importers: get-port-please: ^2.6.1 jiti: ^1.16.0 ohmyfetch: ^0.4.21 + pathe: ^0.3.8 playwright: ^1.27.1 unbuild: ^0.9.4 vitest: ^0.25.1 @@ -569,6 +570,7 @@ importers: get-port-please: 2.6.1 jiti: 1.16.0 ohmyfetch: 0.4.21 + pathe: 0.3.9 devDependencies: playwright: 1.27.1 unbuild: 0.9.4