UNPKG

pdf-visual-compare

Version:

Visual regression testing library for PDFs in Js/Ts without binary and OS dependencies.

86 lines (85 loc) 4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.comparePdf = comparePdf; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const pdf_to_png_converter_1 = require("pdf-to-png-converter"); const png_visual_compare_1 = require("png-visual-compare"); const const_js_1 = require("./const.js"); /** * Compares two PDF files or buffers and returns a boolean indicating whether they are similar. * * @param actualPdf - The file path or buffer of the actual PDF to compare. * @param expectedPdf - The file path or buffer of the expected PDF to compare against. * @param opts - Optional comparison options. * @returns A promise that resolves to a boolean indicating whether the PDFs are similar. * @throws Will throw an error if the compare threshold is less than 0. */ async function comparePdf(actualPdf, expectedPdf, opts = {}) { // Validate input file types validateInputFileType(actualPdf); validateInputFileType(expectedPdf); // Set default options const pdfToPngConvertOpts = { ...opts.pdfToPngConvertOptions }; if (!pdfToPngConvertOpts.viewportScale) { pdfToPngConvertOpts.viewportScale = 2.0; } if (!pdfToPngConvertOpts.outputFileMaskFunc) { pdfToPngConvertOpts.outputFileMaskFunc = (pageNumber) => `comparePdf_${pageNumber}.png`; } const diffsOutputFolder = opts?.diffsOutputFolder ?? const_js_1.DEFAULT_DIFFS_FOLDER; const compareThreshold = opts?.compareThreshold ?? 0; const excludedAreas = opts?.excludedAreas ?? []; if (compareThreshold < 0) { throw Error('Compare Threshold cannot be less than 0.'); } // Convert PDFs to PNGs let [actualPdfPngPages, expectedPdfPngPages] = await Promise.all([ (0, pdf_to_png_converter_1.pdfToPng)(actualPdf, pdfToPngConvertOpts), (0, pdf_to_png_converter_1.pdfToPng)(expectedPdf, pdfToPngConvertOpts), ]); // Ensure actualPdfPngPages is always the longer array to avoid index out of bounds errors if (actualPdfPngPages.length < expectedPdfPngPages.length) { [actualPdfPngPages, expectedPdfPngPages] = [expectedPdfPngPages, actualPdfPngPages]; } let documentCompareResult = true; actualPdfPngPages.forEach((pngPage, index) => { const comparePngOpts = { ...opts?.pdfToPngConvertOptions, ...excludedAreas[index], throwErrorOnInvalidInputData: false, }; comparePngOpts.diffFilePath = (0, node_path_1.resolve)(diffsOutputFolder, `diff_${pngPage.name}`); const pngPageOutputToCompareWith = expectedPdfPngPages.find((p) => p.name === pngPage.name); const pageCompareResult = (0, png_visual_compare_1.comparePng)(pngPage.content, pngPageOutputToCompareWith?.content ?? '', comparePngOpts); if (pageCompareResult > compareThreshold) { documentCompareResult = false; } }); return documentCompareResult; } /** * Validates the type of the input file. The input file can either be a Buffer or a string representing a file path. * If the input file is a Buffer, the function returns without any error. * If the input file is a string, the function checks if the file exists at the given path. * If the file does not exist, an error is thrown. * If the input file is neither a Buffer nor a string, an error is thrown. * * @param inputFile - The input file to validate. It can be a Buffer or a string representing a file path. * @throws {Error} If the input file is a string and the file does not exist. * @throws {Error} If the input file is neither a Buffer nor a string. */ function validateInputFileType(inputFile) { if (Buffer.isBuffer(inputFile)) { return; } if (typeof inputFile === 'string') { if ((0, node_fs_1.existsSync)(inputFile)) { return; } else { throw Error(`PDF file not found: ${inputFile}`); } } throw Error(`Unknown input file type.`); }