UNPKG

vitest-environment-puppeteer

Version:
159 lines (154 loc) 5.22 kB
import { setup as setup$1, ERROR_NO_COMMAND, ERROR_TIMEOUT, teardown as teardown$1 } from 'vitest-dev-server'; import chalk from 'chalk'; import { cpus } from 'node:os'; import { cosmiconfig } from 'cosmiconfig'; const getPuppeteer = async ()=>{ try { // @ts-expect-error Puppeteer docs say this will return PuppeteerNode return import('puppeteer'); } catch { // @ts-expect-error Puppeteer docs say this will return PuppeteerNode return import('puppeteer-core'); } }; const getWorkersCount = (viConfig)=>{ if (viConfig.maxWorkers != null) return Number(viConfig.maxWorkers); if (viConfig.watch) return 1; return cpus().length - 1; }; const openBrowser = async (config)=>{ const puppeteer = await getPuppeteer(); if (config.connect) { return puppeteer.connect(config.connect); } return puppeteer.launch(config.launch); }; const closeBrowser = async (config, browser)=>{ if (config.connect) { return browser.disconnect(); } return browser.close(); }; const saveWorkersCount = (workersCount)=>{ process.env.WORKERS_COUNT = workersCount.toString(); }; const saveWsEndpoints = (wsEndpoints)=>{ process.env.PUPPETEER_WS_ENDPOINTS = JSON.stringify(wsEndpoints); }; const startBrowsers = async ({ config, viConfig })=>{ const workersCount = getWorkersCount(viConfig); saveWorkersCount(workersCount); if (config.connect?.browserWSEndpoint) { if (workersCount > 1) { throw new Error("Cannot use `connect.browserWSEndpoint` with multiple workers. Set Jest `maxWorkers` to 1."); } saveWsEndpoints([ config.connect.browserWSEndpoint ]); return []; } const browsers = await Promise.all(Array.from({ length: workersCount }).map(()=>openBrowser(config))); const wsEndpoints = browsers.map((browser)=>browser.wsEndpoint()); saveWsEndpoints(wsEndpoints); return browsers; }; const closeBrowsers = async (config, browsers)=>{ await Promise.all(browsers.map(async (browser)=>closeBrowser(config, browser))); }; const DEFAULT_CONFIG = { browserContext: "default", exitOnPageError: true }; const explorer = cosmiconfig("vitest-puppeteer"); const getDefaultConfig = ()=>{ if (process.env.CI) { return { ...DEFAULT_CONFIG, launch: { args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-background-timer-throttling", "--disable-backgrounding-occluded-windows", "--disable-renderer-backgrounding" ] } }; } return DEFAULT_CONFIG; }; const readConfigFile = async (configFile, searchFrom)=>{ if (!configFile) { const result = await explorer.search(searchFrom); return result ? result.config : null; } const result = await explorer.load(configFile); return result ? result.config : null; }; const readConfig = async (searchFrom)=>{ const defaultConfig = getDefaultConfig(); const config = await readConfigFile(process.env.VITEST_PUPPETEER_CONFIG, searchFrom); if (!config) return defaultConfig; return { ...defaultConfig, ...config }; }; const setup = async ({ config: viConfig })=>{ globalThis.__jestPptr = globalThis.__jestPptr || {}; const ctx = globalThis.__jestPptr; if (!ctx.config) { const config = await readConfig(); ctx.config = config; } const config = ctx.config; if (!ctx.browsers) { const browsers = await startBrowsers({ config, viConfig }); ctx.browsers = browsers; } if (config.server && !ctx.servers) { try { const servers = await setup$1(config.server); ctx.servers = servers; } catch (error) { /* eslint-disable no-fallthrough */ switch(error.code){ case ERROR_TIMEOUT: { console.log(""); console.error(chalk.red(error.message)); console.error(chalk.blue(`\n☝️ You can set "server.launchTimeout" in vitest-puppeteer.config.js`)); process.exit(1); } case ERROR_NO_COMMAND: { console.log(""); console.error(chalk.red(error.message)); console.error(chalk.blue(`\n☝️ You must set "server.command" in vitest-puppeteer.config.js`)); process.exit(1); } default: { throw error; } } /* eslint-enable no-fallthrough */ } } }; const teardown = async ()=>{ const ctx = globalThis.__jestPptr; if (!ctx || !ctx.config) return; if (ctx.browsers) { await closeBrowsers(ctx.config, ctx.browsers); delete ctx.browsers; } if (ctx.servers) { await teardown$1(ctx.servers); delete ctx.servers; } }; export { setup, teardown };