jest-environment-puppeteer
Version:
Puppeteer environment for Jest.
166 lines (158 loc) • 5.58 kB
JavaScript
;
var jestDevServer = require('jest-dev-server');
var chalk = require('chalk');
var node_os = require('node:os');
var cosmiconfig = require('cosmiconfig');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
const getPuppeteer = ()=>{
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require("puppeteer");
} catch {
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require("puppeteer-core");
}
};
const getWorkersCount = (jestConfig)=>{
if (jestConfig.maxWorkers != null) return Number(jestConfig.maxWorkers);
if (jestConfig.watch || jestConfig.watchAll) return 1;
return node_os.cpus().length - 1;
};
const openBrowser = async (config)=>{
const puppeteer = 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, jestConfig })=>{
const workersCount = getWorkersCount(jestConfig);
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.cosmiconfig("jest-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.JEST_PUPPETEER_CONFIG, searchFrom);
if (!config) return defaultConfig;
return {
...defaultConfig,
...config
};
};
const setup = async (jestConfig)=>{
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,
jestConfig
});
ctx.browsers = browsers;
}
if (config.server && !ctx.servers) {
try {
const servers = await jestDevServer.setup(config.server);
ctx.servers = servers;
} catch (error) {
/* eslint-disable no-fallthrough */ switch(error.code){
case jestDevServer.ERROR_TIMEOUT:
{
console.log("");
console.error(chalk__default.default.red(error.message));
console.error(chalk__default.default.blue(`\n☝️ You can set "server.launchTimeout" in jest-puppeteer.config.js`));
process.exit(1);
}
case jestDevServer.ERROR_NO_COMMAND:
{
console.log("");
console.error(chalk__default.default.red(error.message));
console.error(chalk__default.default.blue(`\n☝️ You must set "server.command" in jest-puppeteer.config.js`));
process.exit(1);
}
default:
{
throw error;
}
}
/* eslint-enable no-fallthrough */ }
}
};
const teardown = async (jestConfig)=>{
const ctx = globalThis.__jestPptr;
if (!ctx || !ctx.config) return;
if (ctx.browsers) {
await closeBrowsers(ctx.config, ctx.browsers);
delete ctx.browsers;
}
if (!jestConfig.watch && !jestConfig.watchAll && ctx.servers) {
await jestDevServer.teardown(ctx.servers);
delete ctx.servers;
}
};
exports.setup = setup;
exports.teardown = teardown;