@btravers/pdf-snapshot-jest
Version:
Jest extension
160 lines (159 loc) • 6.88 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = __importStar(require("node:path"));
const fs = __importStar(require("node:fs"));
const node_fetch_commonjs_1 = __importDefault(require("node-fetch-commonjs"));
const client_1 = require("@trpc/client");
const lodash_1 = __importDefault(require("lodash"));
const dedent_1 = __importDefault(require("dedent"));
const process = __importStar(require("process"));
const globalAny = global;
globalAny.fetch = node_fetch_commonjs_1.default;
expect.extend({
async toMatchPdfSnapshot(pdf, options) {
var _a;
const { testPath, currentTestName, isNot, snapshotState } = this;
if (isNot) {
throw new Error('Jest: `.not` cannot be used with `.toMatchPdfSnapshot()`.');
}
const snapshotsDirectory = path.join(path.dirname(testPath !== null && testPath !== void 0 ? testPath : ''), '__pdf_snapshots__');
await fs.promises.mkdir(snapshotsDirectory, {
recursive: true,
});
const diffFilesToRemove = (await fs.promises.readdir(snapshotsDirectory)).filter((file) => file.endsWith('-diff.png'));
await Promise.all(diffFilesToRemove.map((file) => fs.promises.rm(path.join(snapshotsDirectory, file))));
function snapshotIdentifier(pageNumber) {
return `${pageNumber.toString().padStart(2, '0')}_${lodash_1.default.kebabCase(currentTestName)}-snap`;
}
async function writeFile(data, filePath) {
const decodedData = Buffer.from(data, 'base64');
await fs.promises.writeFile(filePath, decodedData);
}
async function getSnapshots() {
const result = [];
let i = 1;
do {
const snapshotPath = path.join(snapshotsDirectory, `${snapshotIdentifier(i)}.png`);
try {
result.push(await fs.promises.readFile(snapshotPath));
}
catch (e) {
break;
}
i++;
} while (true);
return result;
}
const trpc = (0, client_1.createTRPCProxyClient)({
links: [
(0, client_1.httpBatchLink)({
url: (_a = process.env.PDF_SNAPSHOT_SERVER_URL) !== null && _a !== void 0 ? _a : 'http://localhost:3000',
}),
],
});
const snapshots = (await getSnapshots()).map((snapshot) => snapshot.toString('base64'));
const { results } = await trpc.matchPdfSnapshot.mutate({
pdf: pdf.toString('base64'),
snapshots,
options: {
scale: options === null || options === void 0 ? void 0 : options.scale,
failureThreshold: options === null || options === void 0 ? void 0 : options.failureThreshold,
},
});
if (lodash_1.default.every(results, 'pass')) {
snapshotState.matched++;
return {
pass: true,
message: () => '',
};
}
if (lodash_1.default.every(results, 'added')) {
snapshotState.added++;
await Promise.all(results.map(async (result, index) => {
if ('newPage' in result) {
const snapshotPath = path.join(snapshotsDirectory, `${snapshotIdentifier(index + 1)}.png`);
await writeFile(result.newPage, snapshotPath);
}
}));
return {
pass: true,
message: () => '',
};
}
if (snapshotState._updateSnapshot === 'all') {
snapshotState.updated++;
await Promise.all(results.map(async (result, index) => {
if ('pass' in result && result.pass) {
return;
}
const pageNumber = index + 1;
const snapshotPath = path.join(snapshotsDirectory, `${snapshotIdentifier(pageNumber)}.png`);
if ('deleted' in result && result.deleted) {
await fs.promises.rm(snapshotPath);
return;
}
if ('newPage' in result) {
await writeFile(result.newPage, snapshotPath);
return;
}
}));
return {
pass: true,
message: () => '',
};
}
snapshotState.unmatched++;
const resultDetails = await Promise.all(results.map(async (result, index) => {
const pageNumber = index + 1;
const diffOutputPath = path.join(snapshotsDirectory, `${snapshotIdentifier(pageNumber)}-diff.png`);
if ('added' in result && result.added) {
return `[Page ${pageNumber}] - Added`;
}
if ('deleted' in result && result.deleted) {
return `[Page ${pageNumber}] - Deleted`;
}
if ('pass' in result && result.pass) {
return `[Page ${pageNumber}] - Pass - diffRatio ${result.diffRatio}`;
}
if ('pass' in result && !result.pass) {
await writeFile(result.diffImage, diffOutputPath);
return `[Page ${pageNumber}] - Does not match snapshot - diffRatio ${result.diffRatio}`;
}
return `[Page ${pageNumber}] - Unhandled result`;
}));
return {
pass: false,
message: () => (0, dedent_1.default) `
Does not match with snapshot.
${resultDetails.join('\n')}
`,
};
},
});
//# sourceMappingURL=toMatchPdfSnapshot.js.map