[verified] fix: use system Chrome for PDF generation
This commit is contained in:
@@ -114,6 +114,32 @@ describe('PdfGenerationService P0 contract', () => {
|
||||
expect(html).not.toContain('Ingen materialelinjer registreret');
|
||||
});
|
||||
|
||||
test('uses a configured Chrome executable for Puppeteer', () => {
|
||||
const fs = require('fs');
|
||||
const previousPath = process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
process.env.PUPPETEER_EXECUTABLE_PATH = '/custom/chrome';
|
||||
const exists = jest.spyOn(fs, 'existsSync').mockImplementation(filePath => filePath === '/custom/chrome');
|
||||
expect(service.resolvePuppeteerExecutablePath()).toBe('/custom/chrome');
|
||||
exists.mockRestore();
|
||||
if (previousPath === undefined) delete process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
else process.env.PUPPETEER_EXECUTABLE_PATH = previousPath;
|
||||
});
|
||||
|
||||
test('discovers Chrome from PATH', () => {
|
||||
const fs = require('fs');
|
||||
const previousExecutable = process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
const previousPath = process.env.PATH;
|
||||
delete process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
process.env.PATH = '/custom/bin';
|
||||
const exists = jest.spyOn(fs, 'existsSync').mockImplementation(filePath => filePath === '/custom/bin/google-chrome');
|
||||
expect(service.resolvePuppeteerExecutablePath()).toBe('/custom/bin/google-chrome');
|
||||
exists.mockRestore();
|
||||
if (previousPath === undefined) delete process.env.PATH;
|
||||
else process.env.PATH = previousPath;
|
||||
if (previousExecutable === undefined) delete process.env.PUPPETEER_EXECUTABLE_PATH;
|
||||
else process.env.PUPPETEER_EXECUTABLE_PATH = previousExecutable;
|
||||
});
|
||||
|
||||
test('converts Puppeteer Uint8Array output to a raw PDF Buffer', async () => {
|
||||
const pdfBytes = new Uint8Array(Buffer.from('%PDF-1.7\nfixture'));
|
||||
const close = jest.fn();
|
||||
@@ -124,11 +150,13 @@ describe('PdfGenerationService P0 contract', () => {
|
||||
}),
|
||||
close
|
||||
});
|
||||
jest.spyOn(service, 'resolvePuppeteerExecutablePath').mockReturnValue('/resolved/chrome');
|
||||
|
||||
const result = await service.generateQuotePdf(buildData());
|
||||
|
||||
expect(Buffer.isBuffer(result)).toBe(true);
|
||||
expect(result.subarray(0, 5).toString()).toBe('%PDF-');
|
||||
expect(puppeteer.launch).toHaveBeenCalledWith(expect.objectContaining({ executablePath: '/resolved/chrome' }));
|
||||
expect(close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,23 @@ class PdfGenerationService {
|
||||
this.maxPages = 3;
|
||||
}
|
||||
|
||||
resolvePuppeteerExecutablePath() {
|
||||
const browserNames = ['google-chrome-stable', 'google-chrome', 'chromium', 'chromium-browser'];
|
||||
const pathCandidates = String(process.env.PATH || '')
|
||||
.split(path.delimiter)
|
||||
.filter(Boolean)
|
||||
.flatMap(directory => browserNames.map(browserName => path.join(directory, browserName)));
|
||||
const candidates = [
|
||||
process.env.PUPPETEER_EXECUTABLE_PATH,
|
||||
...pathCandidates,
|
||||
'/usr/bin/google-chrome-stable',
|
||||
'/usr/bin/google-chrome',
|
||||
'/usr/bin/chromium',
|
||||
'/usr/bin/chromium-browser'
|
||||
];
|
||||
return candidates.find(candidate => candidate && fs.existsSync(candidate));
|
||||
}
|
||||
|
||||
// Convert image to base64
|
||||
async imageToBase64(imagePath) {
|
||||
try {
|
||||
@@ -768,8 +785,10 @@ class PdfGenerationService {
|
||||
const html = await this.generatePdfHtml(data);
|
||||
|
||||
// Launch puppeteer with better error handling
|
||||
const executablePath = this.resolvePuppeteerExecutablePath();
|
||||
browser = await puppeteer.launch({
|
||||
headless: 'new',
|
||||
...(executablePath ? { executablePath } : {}),
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
|
||||
Reference in New Issue
Block a user