flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
92 lines • 3.95 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImageCompare = void 0;
const fs = require("fs-extra");
const path_1 = require("path");
const pngjs_1 = require("pngjs");
const util_1 = require("../util");
const flagpole_execution_1 = require("../flagpole-execution");
const pixelmatch = require("pixelmatch");
class ImageCompare {
constructor(context, input, control) {
this._context = context;
this._autoCreateIfNotExists =
typeof control === "string" &&
control.startsWith("@") &&
control.length > 1;
this._inputImage = this._getImage(input);
this._control = control;
this._controlImage = this._getImage(control);
}
compare(opts) {
this._createControlImageIfNotExists();
if (this._inputImage === null) {
throw new Error("Input image is invalid.");
}
if (this._controlImage === null) {
throw new Error("Control image is invalid.");
}
const { width, height } = this._inputImage;
if (width !== this._controlImage.width ||
height !== this._controlImage.height) {
throw new Error(`Dimensions did not match. ${width}x${height} and ${this._controlImage.width}x${this._controlImage.height}`);
}
const diff = new pngjs_1.PNG({ width, height });
const pixelsDifferent = pixelmatch(this._inputImage.data, this._controlImage.data, diff.data, width, height, opts);
return {
pixelsDifferent: pixelsDifferent,
percentDifferent: (pixelsDifferent / (width * height)) * 100,
diffPath: pixelsDifferent > 0 ? this._writeDiffFile(diff) : null,
};
}
_writeDiffFile(diff) {
const cacheFolder = this._context.executionOptions.config.getCacheFolder();
if (!cacheFolder) {
throw new Error("Flagpole cache folder path not found.");
}
util_1.ensureFolderExists(cacheFolder);
const diffFile = path_1.resolve(cacheFolder, `diff.${Date.now()}.${Math.round(Math.random() * 100000)}.png`);
fs.writeFileSync(diffFile, pngjs_1.PNG.sync.write(diff));
return diffFile;
}
_createControlImageIfNotExists() {
if (this._controlImage === null &&
this._inputImage !== null &&
this._autoCreateIfNotExists) {
const imagesFolder = flagpole_execution_1.FlagpoleExecution.global.config.getImagesFolder();
if (!imagesFolder) {
throw "Flagpole image folder path not found.";
}
util_1.ensureFolderExists(imagesFolder);
const imageFilePath = path_1.resolve(imagesFolder, `${this._control.substring(1)}.png`);
fs.ensureFileSync(imageFilePath);
fs.writeFileSync(imageFilePath, pngjs_1.PNG.sync.write(this._inputImage));
this._controlImage = this._inputImage;
}
}
_getImage(image) {
const type = util_1.toType(image);
if (type == "buffer") {
return pngjs_1.PNG.sync.read(image);
}
if (typeof image === "string" &&
image.startsWith("@") &&
image.length > 1) {
const imagesFolder = this._context.executionOptions.config.getImagesFolder();
fs.ensureDirSync(imagesFolder);
const imageFilePath = path_1.resolve(imagesFolder, `${image.substring(1)}.png`);
if (fs.existsSync(imageFilePath)) {
return pngjs_1.PNG.sync.read(fs.readFileSync(imageFilePath));
}
}
if (type == "string") {
const imageFilePath = path_1.resolve(image);
if (fs.existsSync(imageFilePath)) {
return pngjs_1.PNG.sync.read(fs.readFileSync(imageFilePath));
}
}
return null;
}
}
exports.ImageCompare = ImageCompare;
//# sourceMappingURL=image-compare.js.map
;