Skip to content

Commit

Permalink
Improving puppeteer usage for testing to avoid spawning many browsers (
Browse files Browse the repository at this point in the history
  • Loading branch information
ecamellini authored Jun 13, 2024
1 parent a757068 commit 44b4f5b
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 304 deletions.
2 changes: 1 addition & 1 deletion packages/agreement-process/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"pagopa-interop-commons-test": "workspace:*",
"pg-promise": "11.8.0",
"prettier": "2.8.8",
"puppeteer": "22.10.0",
"puppeteer": "22.11.0",
"testcontainers": "10.9.0",
"ts-node": "10.9.2",
"typescript": "5.4.5",
Expand Down
10 changes: 8 additions & 2 deletions packages/agreement-process/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import {
Attribute,
toReadModelAttribute,
} from "pagopa-interop-models";
import { genericLogger, initPDFGenerator } from "pagopa-interop-commons";
import {
genericLogger,
initPDFGenerator,
puppeteerLaunchOptions,
} from "pagopa-interop-commons";
import { SelfcareV2Client } from "pagopa-interop-selfcare-v2-client";
import puppeteer, { Browser } from "puppeteer";
import { agreementServiceBuilder } from "../src/services/agreementService.js";
Expand All @@ -43,7 +47,9 @@ export const { cleanup, readModelRepository, postgresDB, fileManager } =

afterEach(cleanup);

const testBrowserInstance: Browser = await puppeteer.launch();
const testBrowserInstance: Browser = await puppeteer.launch(
puppeteerLaunchOptions({ pipe: true })
);
const closeTestBrowserInstance = async (): Promise<void> =>
await testBrowserInstance.close();

Expand Down
2 changes: 1 addition & 1 deletion packages/commons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"pagopa-interop-models": "workspace:*",
"pg-promise": "11.8.0",
"ts-pattern": "5.1.2",
"puppeteer": "22.10.1",
"puppeteer": "22.11.0",
"uuid": "10.0.0",
"winston": "3.13.0",
"zod": "3.23.8",
Expand Down
47 changes: 31 additions & 16 deletions packages/commons/src/pdf-generator/pdfGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,50 @@ export interface PDFGenerator {
) => Promise<Buffer>;
}

/* Exporting a function for the launch options of puppeteer instead
of the launchBrowser function itself. This avoids exporting the puppeteer
module types, that cause ESLint to reach max heap size and crash.
These reaused to launch puppeteer for testing
with the same params used in production, but allowing to set
pipe option to true. Pipe true allows test suites to run
without spawning a new browser instance for each test.
*/
export const puppeteerLaunchOptions = (
options: { pipe: boolean } = { pipe: false }
): object => ({
...options,
/* the following args allow file:// usages for
resources files in template's folder */
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-gpu",
"--disable-dev-shm-usage",
"--allow-file-access-from-files",
"--enable-local-file-accesses",
],
});

const launchBrowser = (): Promise<Browser> =>
puppeteer.launch(puppeteerLaunchOptions());

export async function initPDFGenerator(): Promise<PDFGenerator> {
const templateService = buildHTMLTemplateService();
let browserInstance = await puppeteer.launch({
/* NOTE
those configurations allow link (file://) usages for
resources files in template's folder
*/
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-gpu",
"--disable-dev-shm-usage",
"--allow-file-access-from-files",
"--enable-local-file-accesses",
],
});
let browserInstance = await launchBrowser();

const getBrowser = async (): Promise<Browser> => {
if (browserInstance?.connected) {
return browserInstance;
} else {
browserInstance = await puppeteer.launch();
browserInstance = await launchBrowser();
return browserInstance;
}
};

// During unexpected browser crash restarts browser handling "disconnected" event
browserInstance.on("disconnected", async () => {
browserInstance = await puppeteer.launch();
browserInstance = await launchBrowser();
});

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/purpose-process/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"cpx2": "7.0.1",
"pagopa-interop-commons-test": "workspace:*",
"prettier": "2.8.8",
"puppeteer": "22.10.1",
"puppeteer": "22.11.0",
"testcontainers": "10.9.0",
"ts-node": "10.9.2",
"typescript": "5.4.5",
Expand Down
5 changes: 4 additions & 1 deletion packages/purpose-process/test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import {
initPDFGenerator,
puppeteerLaunchOptions,
riskAnalysisFormToRiskAnalysisFormToValidate,
} from "pagopa-interop-commons";
import {
Expand Down Expand Up @@ -52,7 +53,9 @@ export const purposes = readModelRepository.purposes;

export const readModelService = readModelServiceBuilder(readModelRepository);

const testBrowserInstance: Browser = await puppeteer.launch({ pipe: true });
const testBrowserInstance: Browser = await puppeteer.launch(
puppeteerLaunchOptions({ pipe: true })
);
const closeTestBrowserInstance = async (): Promise<void> =>
await testBrowserInstance.close();

Expand Down
Loading

0 comments on commit 44b4f5b

Please sign in to comment.