vitest-environment-puppeteer
Version:
Puppeteer environment for Vitest.
159 lines (154 loc) • 5.22 kB
JavaScript
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 };