UNPKG

@nuxt/test-utils

Version:
201 lines (193 loc) 6.26 kB
import { u as useTestContext, d as url, c as createTestContext, a as startServer, b as stopServer, s as setTestContext } from './test-utils.CHPAu7TP.mjs'; import { existsSync, promises } from 'node:fs'; import { resolve } from 'node:path'; import { defu } from 'defu'; import * as _kit from '@nuxt/kit'; async function createBrowser() { const ctx = useTestContext(); let playwright; try { playwright = await import( /* vite-ignore */ 'playwright-core' ); } catch { throw new Error(` The dependency 'playwright-core' not found. Please run 'yarn add --dev playwright-core' or 'npm install --save-dev playwright-core' `); } const { type, launch } = ctx.options.browserOptions; if (!playwright[type]) { throw new Error(`Invalid browser '${type}'`); } ctx.browser = await playwright[type].launch(launch); } async function getBrowser() { const ctx = useTestContext(); if (!ctx.browser) { await createBrowser(); } return ctx.browser; } async function createPage(path, options) { const browser = await getBrowser(); const page = await browser.newPage(options); const _goto = page.goto.bind(page); page.goto = async (url2, options2) => { const waitUntil = options2?.waitUntil; if (waitUntil && ["hydration", "route"].includes(waitUntil)) { delete options2.waitUntil; } const res = await _goto(url2, options2); await waitForHydration(page, url2, waitUntil); return res; }; if (path) { await page.goto(url(path), options?.javaScriptEnabled === false ? {} : { waitUntil: "hydration" }); } return page; } async function waitForHydration(page, url2, waitUntil) { if (waitUntil === "hydration") { await page.waitForFunction(() => window.useNuxtApp?.().isHydrating === false); } else if (waitUntil === "route") { await page.waitForFunction((route) => window.useNuxtApp?.()._route.fullPath === route, url2); } } const kit = _kit.default || _kit; const isNuxtApp = (dir) => { 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"))); }; const resolveRootDir = () => { const { options } = useTestContext(); const dirs = [ options.rootDir, resolve(options.testDir, options.fixture), process.cwd() ]; for (const dir of dirs) { if (dir && isNuxtApp(dir)) { return dir; } } throw new Error("Invalid nuxt app. (Please explicitly set `options.rootDir` pointing to a valid nuxt app)"); }; async function loadFixture() { const ctx = useTestContext(); ctx.options.rootDir = resolveRootDir(); if (!ctx.options.dev) { const randomId = Math.random().toString(36).slice(2, 8); const buildDir = ctx.options.buildDir || resolve(ctx.options.rootDir, ".nuxt", "test", randomId); ctx.options.nuxtConfig = defu(ctx.options.nuxtConfig, { buildDir, nitro: { output: { dir: resolve(buildDir, "output") } } }); } if (ctx.options.build) { ctx.nuxt = await kit.loadNuxt({ cwd: ctx.options.rootDir, dev: ctx.options.dev, overrides: ctx.options.nuxtConfig, configFile: ctx.options.configFile }); const buildDir = ctx.nuxt.options.buildDir; if (!existsSync(buildDir)) { await promises.mkdir(buildDir, { recursive: true }); ctx.teardown = ctx.teardown || []; ctx.teardown.push(() => promises.rm(buildDir, { recursive: true, force: true })); } } } async function buildFixture() { const ctx = useTestContext(); const prevLevel = kit.logger.level; kit.logger.level = ctx.options.logLevel; await kit.buildNuxt(ctx.nuxt); kit.logger.level = prevLevel; } async function setupCucumber(hooks) { const { After, AfterAll, Before, BeforeAll } = await import('@cucumber/cucumber'); BeforeAll({ timeout: hooks.ctx.options.setupTimeout }, hooks.setup); Before(hooks.beforeEach); After(hooks.afterEach); AfterAll(hooks.afterAll); } async function setupJest(hooks) { const { jest, test, beforeEach, afterAll, afterEach } = await import('@jest/globals'); hooks.ctx.mockFn = jest.fn; test("setup", hooks.setup, hooks.ctx.options.setupTimeout); beforeEach(hooks.beforeEach); afterEach(hooks.afterEach); afterAll(hooks.afterAll, hooks.ctx.options.teardownTimeout); } async function setupVitest(hooks) { const vitest = await import('vitest'); hooks.ctx.mockFn = vitest.vi.fn; vitest.beforeAll(hooks.setup, hooks.ctx.options.setupTimeout); vitest.beforeEach(hooks.beforeEach); vitest.afterEach(hooks.afterEach); vitest.afterAll(hooks.afterAll, hooks.ctx.options.teardownTimeout); } const setupMaps = { cucumber: setupCucumber, jest: setupJest, vitest: setupVitest }; function createTest(options) { const ctx = createTestContext(options); const beforeEach = () => { setTestContext(ctx); }; const afterEach = () => { setTestContext(void 0); }; const afterAll = async () => { if (ctx.serverProcess) { setTestContext(ctx); await stopServer(); setTestContext(void 0); } if (ctx.nuxt && ctx.nuxt.options.dev) { await ctx.nuxt.close(); } if (ctx.browser) { await ctx.browser.close(); } await Promise.all(!ctx.teardown ? [] : ctx.teardown.map((fn) => fn())); }; const setup2 = async () => { if (ctx.options.fixture) { await loadFixture(); } if (ctx.options.build) { await buildFixture(); } if (ctx.options.server) { await startServer(ctx.options.env); } if (ctx.options.waitFor) { await new Promise((resolve) => setTimeout(resolve, ctx.options.waitFor)); } if (ctx.options.browser) { await createBrowser(); } }; return { beforeEach, afterEach, afterAll, setup: setup2, ctx }; } async function setup(options = {}) { const hooks = createTest(options); const setupFn = setupMaps[hooks.ctx.options.runner]; await setupFn(hooks); } export { createPage as a, buildFixture as b, createBrowser as c, createTest as d, setup as e, getBrowser as g, loadFixture as l, setupMaps as s, waitForHydration as w };