creevey
Version:
creevey is a tool for automated visual testing, that tightly integrated with storybook
115 lines (92 loc) • 15.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _pngjs = require("pngjs");
var _pixelmatch = _interopRequireDefault(require("pixelmatch"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function normalizeImageSize(image, width, height) {
const normalizedImage = new Buffer(4 * width * height);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const i = (y * width + x) * 4;
if (x < image.width && y < image.height) {
const j = (y * image.width + x) * 4;
normalizedImage[i + 0] = image.data[j + 0];
normalizedImage[i + 1] = image.data[j + 1];
normalizedImage[i + 2] = image.data[j + 2];
normalizedImage[i + 3] = image.data[j + 3];
} else {
normalizedImage[i + 0] = 0;
normalizedImage[i + 1] = 0;
normalizedImage[i + 2] = 0;
normalizedImage[i + 3] = 0;
}
}
}
return normalizedImage;
}
function hasDiffPixels(diff) {
for (let i = 0; i < diff.length; i += 4) {
if (diff[i + 0] == 255 && diff[i + 1] == 0 && diff[i + 2] == 0 && diff[i + 3] == 255) return true;
}
return false;
}
function compareImages(expect, actual, diffOptions) {
const expectImage = _pngjs.PNG.sync.read(expect);
const actualImage = _pngjs.PNG.sync.read(actual);
const width = Math.max(actualImage.width, expectImage.width);
const height = Math.max(actualImage.height, expectImage.height);
const diffImage = new _pngjs.PNG({
width,
height
});
let actualImageData = actualImage.data;
if (actualImage.width < width || actualImage.height < height) {
actualImageData = normalizeImageSize(actualImage, width, height);
}
let expectImageData = expectImage.data;
if (expectImage.width < width || expectImage.height < height) {
expectImageData = normalizeImageSize(expectImage, width, height);
}
(0, _pixelmatch.default)(expectImageData, actualImageData, diffImage.data, width, height, diffOptions);
return {
isEqual: !hasDiffPixels(diffImage.data),
diff: _pngjs.PNG.sync.write(diffImage)
};
}
function _default(getExpected, diffOptions) {
return function chaiImage({
Assertion
}, utils) {
async function assertImage(actual, imageName) {
let onCompare = () => Promise.resolve();
let expected = await getExpected(imageName);
if (!(expected instanceof Buffer) && expected != null) ({
expected,
onCompare
} = expected);
if (expected == null) {
await onCompare(actual);
throw new Error(imageName ? `Expected image '${imageName}' does not exists` : 'Expected image does not exists');
}
if (actual.equals(expected)) return await onCompare(actual);
const {
isEqual,
diff
} = compareImages(expected, actual, diffOptions);
if (isEqual) return await onCompare(actual);
await onCompare(actual, expected, diff); // TODO rewrite message
throw new Error(imageName ? `Expected image '${imageName}' to match` : 'Expected image to match');
}
utils.addMethod(Assertion.prototype, 'matchImage', async function matchImage(imageName) {
const actual = utils.flag(this, 'object');
await assertImage(typeof actual == 'string' ? Buffer.from(actual, 'base64') : actual, imageName);
});
utils.addMethod(Assertion.prototype, 'matchImages', async function matchImages() {
await Promise.all(Object.entries(utils.flag(this, 'object')).map(([imageName, imageOrBase64]) => assertImage(typeof imageOrBase64 == 'string' ? Buffer.from(imageOrBase64, 'base64') : imageOrBase64, imageName)));
});
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jaGFpLWltYWdlLnRzIl0sIm5hbWVzIjpbIm5vcm1hbGl6ZUltYWdlU2l6ZSIsImltYWdlIiwid2lkdGgiLCJoZWlnaHQiLCJub3JtYWxpemVkSW1hZ2UiLCJCdWZmZXIiLCJ5IiwieCIsImkiLCJqIiwiZGF0YSIsImhhc0RpZmZQaXhlbHMiLCJkaWZmIiwibGVuZ3RoIiwiY29tcGFyZUltYWdlcyIsImV4cGVjdCIsImFjdHVhbCIsImRpZmZPcHRpb25zIiwiZXhwZWN0SW1hZ2UiLCJQTkciLCJzeW5jIiwicmVhZCIsImFjdHVhbEltYWdlIiwiTWF0aCIsIm1heCIsImRpZmZJbWFnZSIsImFjdHVhbEltYWdlRGF0YSIsImV4cGVjdEltYWdlRGF0YSIsImlzRXF1YWwiLCJ3cml0ZSIsImdldEV4cGVjdGVkIiwiY2hhaUltYWdlIiwiQXNzZXJ0aW9uIiwidXRpbHMiLCJhc3NlcnRJbWFnZSIsImltYWdlTmFtZSIsIm9uQ29tcGFyZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXhwZWN0ZWQiLCJFcnJvciIsImVxdWFscyIsImFkZE1ldGhvZCIsInByb3RvdHlwZSIsIm1hdGNoSW1hZ2UiLCJmbGFnIiwiZnJvbSIsIm1hdGNoSW1hZ2VzIiwiYWxsIiwiT2JqZWN0IiwiZW50cmllcyIsIm1hcCIsImltYWdlT3JCYXNlNjQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7OztBQUlBLFNBQVNBLGtCQUFULENBQTRCQyxLQUE1QixFQUF3Q0MsS0FBeEMsRUFBdURDLE1BQXZELEVBQStFO0FBQzdFLFFBQU1DLGVBQWUsR0FBRyxJQUFJQyxNQUFKLENBQVcsSUFBSUgsS0FBSixHQUFZQyxNQUF2QixDQUF4Qjs7QUFFQSxPQUFLLElBQUlHLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdILE1BQXBCLEVBQTRCRyxDQUFDLEVBQTdCLEVBQWlDO0FBQy9CLFNBQUssSUFBSUMsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0wsS0FB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QWpCO0FBQ0QsS0FKRDtBQU1BRixJQUFBQSxLQUFLLENBQUNTLFNBQU4sQ0FBZ0JWLFNBQVMsQ0FBQ1csU0FBMUIsRUFBcUMsYUFBckMsRUFBb0QsZUFBZUksV0FBZixHQUF5QztBQUMzRixZQUFNVixPQUFPLENBQUNXLEdBQVIsQ0FDSkMsTUFBTSxDQUFDQyxPQUFQLENBQWdDakIsS0FBSyxDQUFDWSxJQUFOLENBQVcsSUFBWCxFQUFpQixRQUFqQixDQUFoQyxFQUE0RE0sR0FBNUQsQ0FBZ0UsQ0FBQyxDQUFDaEIsU0FBRCxFQUFZaUIsYUFBWixDQUFELEtBQzlEbEIsV0FBVyxDQUNULE9BQU9rQixhQUFQLElBQXdCLFFBQXhCLEdBQW1DL0MsTUFBTSxDQUFDeUMsSUFBUCxDQUFZTSxhQUFaLEVBQTJCLFFBQTNCLENBQW5DLEdBQTBFQSxhQURqRSxFQUVUakIsU0FGUyxDQURiLENBREksQ0FBTjtBQVFELEtBVEQ7QUFVRCxHQXZDRDtBQXdDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBORyB9IGZyb20gJ3BuZ2pzJztcbmltcG9ydCBwaXhlbG1hdGNoIGZyb20gJ3BpeGVsbWF0Y2gnO1xuXG5pbXBvcnQgeyBEaWZmT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuXG5mdW5jdGlvbiBub3JtYWxpemVJbWFnZVNpemUoaW1hZ2U6IFBORywgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBCdWZmZXIge1xuICBjb25zdCBub3JtYWxpemVkSW1hZ2UgPSBuZXcgQnVmZmVyKDQgKiB3aWR0aCAqIGhlaWdodCk7XG5cbiAgZm9yIChsZXQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykge1xuICAgIGZvciAobGV0IHggPSAwOyB4IDwgd2lkdGg7IHgrKykge1xuICAgICAgY29uc3QgaSA9ICh5ICogd2lkdGggKyB4KSAqIDQ7XG4gICAgICBpZiAoeCA8IGltYWdlLndpZHRoICYmIHkgPCBpbWFnZS5oZWlnaHQpIHtcbiAgICAgICAgY29uc3QgaiA9ICh5ICogaW1hZ2Uud2lkdGggKyB4KSAqIDQ7XG4gICAgICAgIG5vcm1hbGl6ZWRJbWFnZVtpICsgMF0gPSBpbWFnZS5kYXRhW2ogKyAwXTtcbiAgICAgICAgbm9ybWFsaXplZEltYWdlW2kgKyAxXSA9IGltYWdlLmRhdGFbaiArIDFdO1xuICAgICAgICBub3JtYWxpemVkSW1hZ2VbaSArIDJdID0gaW1hZ2UuZGF0YVtqICsgMl07XG4gICAgICAgIG5vcm1hbGl6ZWRJbWFnZVtpICsgM10gPSBpbWFnZS5kYXRhW2ogKyAzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1hbGl6ZWRJbWFnZVtpICsgMF0gPSAwO1xuICAgICAgICBub3JtYWxpemVkSW1hZ2VbaSArIDFdID0gMDtcbiAgICAgICAgbm9ybWFsaXplZEltYWdlW2kgKyAyXSA9IDA7XG4gICAgICAgIG5vcm1hbGl6ZWRJbWFnZVtpICsgM10gPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbm9ybWFsaXplZEltYWdlO1xufVxuXG5mdW5jdGlvbiBoYXNEaWZmUGl4ZWxzKGRpZmY6IEJ1ZmZlcik6IGJvb2xlYW4ge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZmYubGVuZ3RoOyBpICs9IDQpIHtcbiAgICBpZiAoZGlmZltpICsgMF0gPT0gMjU1ICYmIGRpZmZbaSArIDFdID09IDAgJiYgZGlmZltpICsgMl0gPT0gMCAmJiBkaWZmW2kgKyAzXSA9PSAyNTUpIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29tcGFyZUltYWdlcyhleHBlY3Q6IEJ1ZmZlciwgYWN0dWFsOiBCdWZmZXIsIGRpZmZPcHRpb25zOiBEaWZmT3B0aW9ucyk6IHsgaXNFcXVhbDogYm9vbGVhbjsgZGlmZjogQnVmZmVyIH0ge1xuICBjb25zdCBleHBlY3RJbWFnZSA9IFBORy5zeW5jLnJlYWQoZXhwZWN0KTtcbiAgY29uc3QgYWN0dWFsSW1hZ2UgPSBQTkcuc3luYy5yZWFkKGFjdHVhbCk7XG5cbiAgY29uc3Qgd2lkdGggPSBNYXRoLm1heChhY3R1YWxJbWFnZS53aWR0aCwgZXhwZWN0SW1hZ2Uud2lkdGgpO1xuICBjb25zdCBoZWlnaHQgPSBNYXRoLm1heChhY3R1YWxJbWFnZS5oZWlnaHQsIGV4cGVjdEltYWdlLmhlaWdodCk7XG5cbiAgY29uc3QgZGlmZkltYWdlID0gbmV3IFBORyh7IHdpZHRoLCBoZWlnaHQgfSk7XG5cbiAgbGV0IGFjdHVhbEltYWdlRGF0YSA9IGFjdHVhbEltYWdlLmRhdGE7XG4gIGlmIChhY3R1YWxJbWFnZS53aWR0aCA8IHdpZHRoIHx8IGFjdHVhbEltYWdlLmhlaWdodCA8IGhlaWdodCkge1xuICAgIGFjdHVhbEltYWdlRGF0YSA9IG5vcm1hbGl6ZUltYWdlU2l6ZShhY3R1YWxJbWFnZSwgd2lkdGgsIGhlaWdodCk7XG4gIH1cblxuICBsZXQgZXhwZWN0SW1hZ2VEYXRhID0gZXhwZWN0SW1hZ2UuZGF0YTtcbiAgaWYgKGV4cGVjdEltYWdlLndpZHRoIDwgd2lkdGggfHwgZXhwZWN0SW1hZ2UuaGVpZ2h0IDwgaGVpZ2h0KSB7XG4gICAgZXhwZWN0SW1hZ2VEYXRhID0gbm9ybWFsaXplSW1hZ2VTaXplKGV4cGVjdEltYWdlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuXG4gIHBpeGVsbWF0Y2goZXhwZWN0SW1hZ2VEYXRhLCBhY3R1YWxJbWFnZURhdGEsIGRpZmZJbWFnZS5kYXRhLCB3aWR0aCwgaGVpZ2h0LCBkaWZmT3B0aW9ucyk7XG5cbiAgcmV0dXJuIHtcbiAgICBpc0VxdWFsOiAhaGFzRGlmZlBpeGVscyhkaWZmSW1hZ2UuZGF0YSksXG4gICAgZGlmZjogUE5HLnN5bmMud3JpdGUoZGlmZkltYWdlKSxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKFxuICBnZXRFeHBlY3RlZDogKFxuICAgIGltYWdlTmFtZT86IHN0cmluZyxcbiAgKSA9PiBQcm9taXNlPFxuICAgIHwgeyBleHBlY3RlZDogQnVmZmVyIHwgbnVsbDsgb25Db21wYXJlOiAoYWN0dWFsOiBCdWZmZXIsIGV4cGVjdD86IEJ1ZmZlciwgZGlmZj86IEJ1ZmZlcikgPT4gUHJvbWlzZTx2b2lkPiB9XG4gICAgfCBCdWZmZXJcbiAgICB8IG51bGxcbiAgPixcbiAgZGlmZk9wdGlvbnM6IERpZmZPcHRpb25zLFxuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBjaGFpSW1hZ2UoeyBBc3NlcnRpb24gfTogQ2hhaS5DaGFpU3RhdGljLCB1dGlsczogQ2hhaS5DaGFpVXRpbHMpIHtcbiAgICBhc3luYyBmdW5jdGlvbiBhc3NlcnRJbWFnZShhY3R1YWw6IEJ1ZmZlciwgaW1hZ2VOYW1lPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBsZXQgb25Db21wYXJlOiAoYWN0dWFsOiBCdWZmZXIsIGV4cGVjdD86IEJ1ZmZlciwgZGlmZj86IEJ1ZmZlcikgPT4gUHJvbWlzZTx2b2lkPiA9ICgpID0+IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgbGV0IGV4cGVjdGVkID0gYXdhaXQgZ2V0RXhwZWN0ZWQoaW1hZ2VOYW1lKTtcbiAgICAgIGlmICghKGV4cGVjdGVkIGluc3RhbmNlb2YgQnVmZmVyKSAmJiBleHBlY3RlZCAhPSBudWxsKSAoeyBleHBlY3RlZCwgb25Db21wYXJlIH0gPSBleHBlY3RlZCk7XG5cbiAgICAgIGlmIChleHBlY3RlZCA9PSBudWxsKSB7XG4gICAgICAgIGF3YWl0IG9uQ29tcGFyZShhY3R1YWwpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoaW1hZ2VOYW1lID8gYEV4cGVjdGVkIGltYWdlICcke2ltYWdlTmFtZX0nIGRvZXMgbm90IGV4aXN0c2AgOiAnRXhwZWN0ZWQgaW1hZ2UgZG9lcyBub3QgZXhpc3RzJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhY3R1YWwuZXF1YWxzKGV4cGVjdGVkKSkgcmV0dXJuIGF3YWl0IG9uQ29tcGFyZShhY3R1YWwpO1xuXG4gICAgICBjb25zdCB7IGlzRXF1YWwsIGRpZmYgfSA9IGNvbXBhcmVJbWFnZXMoZXhwZWN0ZWQsIGFjdHVhbCwgZGlmZk9wdGlvbnMpO1xuXG4gICAgICBpZiAoaXNFcXVhbCkgcmV0dXJuIGF3YWl0IG9uQ29tcGFyZShhY3R1YWwpO1xuXG4gICAgICBhd2FpdCBvbkNvbXBhcmUoYWN0dWFsLCBleHBlY3RlZCwgZGlmZik7XG5cbiAgICAgIC8vIFRPRE8gcmV3cml0ZSBtZXNzYWdlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoaW1hZ2VOYW1lID8gYEV4cGVjdGVkIGltYWdlICcke2ltYWdlTmFtZX0nIHRvIG1hdGNoYCA6ICdFeHBlY3RlZCBpbWFnZSB0byBtYXRjaCcpO1xuICAgIH1cblxuICAgIHV0aWxzLmFkZE1ldGhvZChBc3NlcnRpb24ucHJvdG90eXBlLCAnbWF0Y2hJbWFnZScsIGFzeW5jIGZ1bmN0aW9uIG1hdGNoSW1hZ2UodGhpczogb2JqZWN0LCBpbWFnZU5hbWU/OiBzdHJpbmcpIHtcbiAgICAgIGNvbnN0IGFjdHVhbDogc3RyaW5nIHwgQnVmZmVyID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG5cbiAgICAgIGF3YWl0IGFzc2VydEltYWdlKHR5cGVvZiBhY3R1YWwgPT0gJ3N0cmluZycgPyBCdWZmZXIuZnJvbShhY3R1YWwsICdiYXNlNjQnKSA6IGFjdHVhbCwgaW1hZ2VOYW1lKTtcbiAgICB9KTtcblxuICAgIHV0aWxzLmFkZE1ldGhvZChBc3NlcnRpb24ucHJvdG90eXBlLCAnbWF0Y2hJbWFnZXMnLCBhc3luYyBmdW5jdGlvbiBtYXRjaEltYWdlcyh0aGlzOiBvYmplY3QpIHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBPYmplY3QuZW50cmllczxzdHJpbmcgfCBCdWZmZXI+KHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpKS5tYXAoKFtpbWFnZU5hbWUsIGltYWdlT3JCYXNlNjRdKSA9PlxuICAgICAgICAgIGFzc2VydEltYWdlKFxuICAgICAgICAgICAgdHlwZW9mIGltYWdlT3JCYXNlNjQgPT0gJ3N0cmluZycgPyBCdWZmZXIuZnJvbShpbWFnZU9yQmFzZTY0LCAnYmFzZTY0JykgOiBpbWFnZU9yQmFzZTY0LFxuICAgICAgICAgICAgaW1hZ2VOYW1lLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH0pO1xuICB9O1xufVxuIl19