Refactor Puppeteer launch options for improved configurability
All checks were successful
farmcontrol/farmcontrol-api/pipeline/head This commit looks good

This update introduces a new module, `puppeteerLaunchOptions.js`, which centralizes the Puppeteer launch configuration. The `getPuppeteerLaunchOptions` function is added to provide customizable launch arguments, enhancing the flexibility of browser instantiation in both `mailworker.js` and `pdffactory.js`. This refactor improves code maintainability and allows for easier adjustments to Puppeteer settings in the future.
This commit is contained in:
Tom Butcher 2026-08-19 22:19:05 +01:00
parent 5cbcdacd3b
commit 0b94774443
4 changed files with 23 additions and 14 deletions

View File

@ -7,6 +7,7 @@ import puppeteer from 'puppeteer';
import nodemailer from 'nodemailer';
import log4js from 'log4js';
import config from './config.js';
import { getPuppeteerLaunchOptions } from './puppeteerLaunchOptions.js';
const baseUrl = (urlClient) => (urlClient || 'http://localhost:3000').replace(/\/$/, '');
@ -77,14 +78,9 @@ async function sendEmail(payload) {
let html = '';
let browser;
try {
browser = await puppeteer.launch({
headless: 'new',
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-features=SameSiteByDefaultCookies',
],
});
browser = await puppeteer.launch(
getPuppeteerLaunchOptions(['--disable-features=SameSiteByDefaultCookies'])
);
const page = await browser.newPage();
page.on('console', (msg) => {
const text = msg.text();

View File

@ -0,0 +1,16 @@
import puppeteer from 'puppeteer';
const BASE_ARGS = ['--no-sandbox', '--disable-setuid-sandbox'];
/**
* Puppeteer launch options using the Chrome downloaded to the Puppeteer cache
* (e.g. /home/farmcontrol/.cache/puppeteer on Linux), not a system-installed browser.
*/
export function getPuppeteerLaunchOptions(extraArgs = []) {
return {
executablePath:
process.env.PUPPETEER_EXECUTABLE_PATH || puppeteer.executablePath(),
headless: true,
args: [...BASE_ARGS, ...extraArgs],
};
}

View File

@ -16,6 +16,7 @@ const browserInstance = {
const puppeteer = {
launch: jest.fn().mockResolvedValue(browserInstance),
executablePath: jest.fn().mockReturnValue('/fake/puppeteer/chrome'),
};
jest.unstable_mockModule('puppeteer', () => ({

View File

@ -1,15 +1,11 @@
import log4js from 'log4js';
import puppeteer from 'puppeteer';
import config from '../config.js';
import { getPuppeteerLaunchOptions } from '../puppeteerLaunchOptions.js';
const logger = log4js.getLogger('PDF Factory');
logger.level = config.server.logLevel;
const LAUNCH_OPTIONS = {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
};
let browser = null;
let launchPromise = null;
let shutdownRegistered = false;
@ -20,7 +16,7 @@ function isBrowserConnected() {
async function launchBrowser() {
logger.info('Launching persistent Puppeteer browser...');
const instance = await puppeteer.launch(LAUNCH_OPTIONS);
const instance = await puppeteer.launch(getPuppeteerLaunchOptions());
instance.on('disconnected', () => {
if (browser === instance) {
logger.warn('Puppeteer browser disconnected');