testcafe
Version:
Automated browser testing for the modern web development stack.
105 lines • 14.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
const limit_number_1 = __importDefault(require("../utils/limit-number"));
const render_template_1 = __importDefault(require("../utils/render-template"));
const test_run_1 = require("../errors/test-run/");
const constants_1 = require("./constants");
const warning_message_1 = __importDefault(require("../notifications/warning-message"));
const MARK_SEED_ERROR_THRESHOLD = 10;
const WHITE_COLOR_PART = 255;
const BLACK_COLOR_PART = 0;
function markSeedToId(markSeed) {
let id = 0;
for (let i = 0; i < constants_1.MARK_LENGTH; i++)
id = id * 2 + (markSeed[i * constants_1.MARK_BYTES_PER_PIXEL] ? 1 : 0);
return id;
}
function getCorrectedColorPart(colorPart) {
const isWhite = colorPart > WHITE_COLOR_PART - MARK_SEED_ERROR_THRESHOLD;
const isBlack = colorPart < MARK_SEED_ERROR_THRESHOLD;
if (isBlack)
return BLACK_COLOR_PART;
if (isWhite)
return WHITE_COLOR_PART;
return colorPart;
}
function calculateMarkPosition(pngImage, markSeed) {
const mark = Buffer.from(markSeed);
const filtImg = Buffer.from(pngImage.data);
for (let i = 0; i < filtImg.length; i++)
filtImg[i] = getCorrectedColorPart(filtImg[i]);
const markIndex = filtImg.indexOf(mark);
if (markIndex < 0)
return null;
const endPosition = markIndex / constants_1.MARK_BYTES_PER_PIXEL + constants_1.MARK_LENGTH + constants_1.MARK_RIGHT_MARGIN;
const x = endPosition % pngImage.width || pngImage.width;
const y = (endPosition - x) / pngImage.width + 1;
return { x, y };
}
exports.calculateMarkPosition = calculateMarkPosition;
function getClipInfoByMarkPosition(markPosition, { width, height }) {
const { x, y } = markPosition;
const clipRight = x;
const clipBottom = y;
const clipLeft = clipRight - width;
const clipTop = clipBottom - height;
return {
clipLeft,
clipTop,
clipRight,
clipBottom
};
}
exports.getClipInfoByMarkPosition = getClipInfoByMarkPosition;
function getClipInfoByCropDimensions({ clipRight, clipLeft, clipBottom, clipTop }, cropDimensions) {
if (cropDimensions) {
const { right, top, bottom, left } = cropDimensions;
clipRight = limit_number_1.default(clipLeft + right, clipLeft, clipRight);
clipBottom = limit_number_1.default(clipTop + bottom, clipTop, clipBottom);
clipLeft = limit_number_1.default(clipLeft + left, clipLeft, clipRight);
clipTop = limit_number_1.default(clipTop + top, clipTop, clipBottom);
}
return {
clipLeft,
clipTop,
clipRight,
clipBottom
};
}
exports.getClipInfoByCropDimensions = getClipInfoByCropDimensions;
function calculateClipInfo(pngImage, path, markSeed, clientAreaDimensions, cropDimensions) {
let clipInfo = {
clipRight: pngImage.width,
clipBottom: pngImage.height,
clipLeft: 0,
clipTop: 0
};
let markPosition = null;
if (markSeed && clientAreaDimensions) {
markPosition = calculateMarkPosition(pngImage, markSeed);
if (!markPosition)
throw new Error(render_template_1.default(warning_message_1.default.screenshotMarkNotFound, path, markSeedToId(markSeed)));
clipInfo = getClipInfoByMarkPosition(markPosition, clientAreaDimensions);
}
clipInfo = getClipInfoByCropDimensions(clipInfo, cropDimensions);
if (markPosition && markPosition.y === clipInfo.clipBottom)
clipInfo.clipBottom--;
const clipWidth = clipInfo.clipRight - clipInfo.clipLeft;
const clipHeight = clipInfo.clipBottom - clipInfo.clipTop;
if (clipWidth <= 0 || clipHeight <= 0)
throw new test_run_1.InvalidElementScreenshotDimensionsError(clipWidth, clipHeight);
return clipInfo;
}
exports.calculateClipInfo = calculateClipInfo;
async function cropScreenshot(image, { path, markSeed, clientAreaDimensions, cropDimensions }) {
if (!markSeed && !cropDimensions)
return null;
const clip = calculateClipInfo(image, path, markSeed, clientAreaDimensions, cropDimensions);
return utils_1.copyImagePart(image, clip);
}
exports.cropScreenshot = cropScreenshot;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JlZW5zaG90cy9jcm9wLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQXdDO0FBQ3hDLHlFQUFnRDtBQUNoRCwrRUFBc0Q7QUFDdEQsa0RBQThFO0FBQzlFLDJDQUFtRjtBQUNuRix1RkFBZ0U7QUFFaEUsTUFBTSx5QkFBeUIsR0FBRyxFQUFFLENBQUM7QUFDckMsTUFBTSxnQkFBZ0IsR0FBWSxHQUFHLENBQUM7QUFDdEMsTUFBTSxnQkFBZ0IsR0FBWSxDQUFDLENBQUM7QUFFcEMsU0FBUyxZQUFZLENBQUUsUUFBUTtJQUMzQixJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFFWCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsdUJBQVcsRUFBRSxDQUFDLEVBQUU7UUFDaEMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLGdDQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFL0QsT0FBTyxFQUFFLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxxQkFBcUIsQ0FBRSxTQUFTO0lBQ3JDLE1BQU0sT0FBTyxHQUFHLFNBQVMsR0FBRyxnQkFBZ0IsR0FBRyx5QkFBeUIsQ0FBQztJQUN6RSxNQUFNLE9BQU8sR0FBRyxTQUFTLEdBQUcseUJBQXlCLENBQUM7SUFFdEQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxnQkFBZ0IsQ0FBQztJQUU1QixJQUFJLE9BQU87UUFDUCxPQUFPLGdCQUFnQixDQUFDO0lBRTVCLE9BQU8sU0FBUyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxTQUFnQixxQkFBcUIsQ0FBRSxRQUFRLEVBQUUsUUFBUTtJQUNyRCxNQUFNLElBQUksR0FBTSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lB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b250ZW50IjpbImltcG9ydCB7IGNvcHlJbWFnZVBhcnQgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCBsaW1pdE51bWJlciBmcm9tICcuLi91dGlscy9saW1pdC1udW1iZXInO1xuaW1wb3J0IHJlbmRlclRlbXBsYXRlIGZyb20gJy4uL3V0aWxzL3JlbmRlci10ZW1wbGF0ZSc7XG5pbXBvcnQgeyBJbnZhbGlkRWxlbWVudFNjcmVlbnNob3REaW1lbnNpb25zRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvdGVzdC1ydW4vJztcbmltcG9ydCB7IE1BUktfTEVOR1RILCBNQVJLX1JJR0hUX01BUkdJTiwgTUFSS19CWVRFU19QRVJfUElYRUwgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgV0FSTklOR19NRVNTQUdFUyBmcm9tICcuLi9ub3RpZmljYXRpb25zL3dhcm5pbmctbWVzc2FnZSc7XG5cbmNvbnN0IE1BUktfU0VFRF9FUlJPUl9USFJFU0hPTEQgPSAxMDtcbmNvbnN0IFdISVRFX0NPTE9SX1BBUlQgICAgICAgICAgPSAyNTU7XG5jb25zdCBCTEFDS19DT0xPUl9QQVJUICAgICAgICAgID0gMDtcblxuZnVuY3Rpb24gbWFya1NlZWRUb0lkIChtYXJrU2VlZCkge1xuICAgIGxldCBpZCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE1BUktfTEVOR1RIOyBpKyspXG4gICAgICAgIGlkID0gaWQgKiAyICsgKG1hcmtTZWVkW2kgKiBNQVJLX0JZVEVTX1BFUl9QSVhFTF0gPyAxIDogMCk7XG5cbiAgICByZXR1cm4gaWQ7XG59XG5cbmZ1bmN0aW9uIGdldENvcnJlY3RlZENvbG9yUGFydCAoY29sb3JQYXJ0KSB7XG4gICAgY29uc3QgaXNXaGl0ZSA9IGNvbG9yUGFydCA+IFdISVRFX0NPTE9SX1BBUlQgLSBNQVJLX1NFRURfRVJST1JfVEhSRVNIT0xEO1xuICAgIGNvbnN0IGlzQmxhY2sgPSBjb2xvclBhcnQgPCBNQVJLX1NFRURfRVJST1JfVEhSRVNIT0xEO1xuXG4gICAgaWYgKGlzQmxhY2spXG4gICAgICAgIHJldHVybiBCTEFDS19DT0xPUl9QQVJUO1xuXG4gICAgaWYgKGlzV2hpdGUpXG4gICAgICAgIHJldHVybiBXSElURV9DT0xPUl9QQVJUO1xuXG4gICAgcmV0dXJuIGNvbG9yUGFydDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZU1hcmtQb3NpdGlvbiAocG5nSW1hZ2UsIG1hcmtTZWVkKSB7XG4gICAgY29uc3QgbWFyayAgICA9IEJ1ZmZlci5mcm9tKG1hcmtTZWVkKTtcbiAgICBjb25zdCBmaWx0SW1nID0gQnVmZmVyLmZyb20ocG5nSW1hZ2UuZGF0YSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpbHRJbWcubGVuZ3RoOyBpKyspXG4gICAgICAgIGZpbHRJbWdbaV0gPSBnZXRDb3JyZWN0ZWRDb2xvclBhcnQoZmlsdEltZ1tpXSk7XG5cbiAgICBjb25zdCBtYXJrSW5kZXggPSBmaWx0SW1nLmluZGV4T2YobWFyayk7XG5cbiAgICBpZiAobWFya0luZGV4IDwgMClcbiAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IG1hcmtJbmRleCAvIE1BUktfQllURVNfUEVSX1BJWEVMICsgTUFSS19MRU5HVEggKyBNQVJLX1JJR0hUX01BUkdJTjtcblxuICAgIGNvbnN0IHggPSBlbmRQb3NpdGlvbiAlIHBuZ0ltYWdlLndpZHRoIHx8IHBuZ0ltYWdlLndpZHRoO1xuICAgIGNvbnN0IHkgPSAoZW5kUG9zaXRpb24gLSB4KSAvIHBuZ0ltYWdlLndpZHRoICsgMTtcblxuICAgIHJldHVybiB7IHgsIHkgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsaXBJbmZvQnlNYXJrUG9zaXRpb24gKG1hcmtQb3NpdGlvbiwgeyB3aWR0aCwgaGVpZ2h0IH0pIHtcbiAgICBjb25zdCB7IHgsIHkgfSA9IG1hcmtQb3NpdGlvbjtcblxuICAgIGNvbnN0IGNsaXBSaWdodCAgPSB4O1xuICAgIGNvbnN0IGNsaXBCb3R0b20gPSB5O1xuICAgIGNvbnN0IGNsaXBMZWZ0ICAgPSBjbGlwUmlnaHQgLSB3aWR0aDtcbiAgICBjb25zdCBjbGlwVG9wICAgID0gY2xpcEJvdHRvbSAtIGhlaWdodDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGNsaXBMZWZ0LFxuICAgICAgICBjbGlwVG9wLFxuICAgICAgICBjbGlwUmlnaHQsXG4gICAgICAgIGNsaXBCb3R0b21cbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xpcEluZm9CeUNyb3BEaW1lbnNpb25zICh7IGNsaXBSaWdodCwgY2xpcExlZnQsIGNsaXBCb3R0b20sIGNsaXBUb3AgfSwgY3JvcERpbWVuc2lvbnMpIHtcbiAgICBpZiAoY3JvcERpbWVuc2lvbnMpIHtcbiAgICAgICAgY29uc3QgeyByaWdodCwgdG9wLCBib3R0b20sIGxlZnQgfSA9IGNyb3BEaW1lbnNpb25zO1xuXG4gICAgICAgIGNsaXBSaWdodCAgPSBsaW1pdE51bWJlcihjbGlwTGVmdCArIHJpZ2h0LCBjbGlwTGVmdCwgY2xpcFJpZ2h0KTtcbiAgICAgICAgY2xpcEJvdHRvbSA9IGxpbWl0TnVtYmVyKGNsaXBUb3AgKyBib3R0b20sIGNsaXBUb3AsIGNsaXBCb3R0b20pO1xuICAgICAgICBjbGlwTGVmdCAgID0gbGltaXROdW1iZXIoY2xpcExlZnQgKyBsZWZ0LCBjbGlwTGVmdCwgY2xpcFJpZ2h0KTtcbiAgICAgICAgY2xpcFRvcCAgICA9IGxpbWl0TnVtYmVyKGNsaXBUb3AgKyB0b3AsIGNsaXBUb3AsIGNsaXBCb3R0b20pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGNsaXBMZWZ0LFxuICAgICAgICBjbGlwVG9wLFxuICAgICAgICBjbGlwUmlnaHQsXG4gICAgICAgIGNsaXBCb3R0b21cbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQ2xpcEluZm8gKHBuZ0ltYWdlLCBwYXRoLCBtYXJrU2VlZCwgY2xpZW50QXJlYURpbWVuc2lvbnMsIGNyb3BEaW1lbnNpb25zKSB7XG4gICAgbGV0IGNsaXBJbmZvID0ge1xuICAgICAgICBjbGlwUmlnaHQ6ICBwbmdJbWFnZS53aWR0aCxcbiAgICAgICAgY2xpcEJvdHRvbTogcG5nSW1hZ2UuaGVpZ2h0LFxuICAgICAgICBjbGlwTGVmdDogICAwLFxuICAgICAgICBjbGlwVG9wOiAgICAwXG4gICAgfTtcblxuICAgIGxldCBtYXJrUG9zaXRpb24gPSBudWxsO1xuXG4gICAgaWYgKG1hcmtTZWVkICYmIGNsaWVudEFyZWFEaW1lbnNpb25zKSB7XG4gICAgICAgIG1hcmtQb3NpdGlvbiA9IGNhbGN1bGF0ZU1hcmtQb3NpdGlvbihwbmdJbWFnZSwgbWFya1NlZWQpO1xuXG4gICAgICAgIGlmICghbWFya1Bvc2l0aW9uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlbmRlclRlbXBsYXRlKFdBUk5JTkdfTUVTU0FHRVMuc2NyZWVuc2hvdE1hcmtOb3RGb3VuZCwgcGF0aCwgbWFya1NlZWRUb0lkKG1hcmtTZWVkKSkpO1xuXG4gICAgICAgIGNsaXBJbmZvID0gZ2V0Q2xpcEluZm9CeU1hcmtQb3NpdGlvbihtYXJrUG9zaXRpb24sIGNsaWVudEFyZWFEaW1lbnNpb25zKTtcbiAgICB9XG5cbiAgICBjbGlwSW5mbyA9IGdldENsaXBJbmZvQnlDcm9wRGltZW5zaW9ucyhjbGlwSW5mbywgY3JvcERpbWVuc2lvbnMpO1xuXG4gICAgaWYgKG1hcmtQb3NpdGlvbiAmJiBtYXJrUG9zaXRpb24ueSA9PT0gY2xpcEluZm8uY2xpcEJvdHRvbSlcbiAgICAgICAgY2xpcEluZm8uY2xpcEJvdHRvbS0tO1xuXG4gICAgY29uc3QgY2xpcFdpZHRoICA9IGNsaXBJbmZvLmNsaXBSaWdodCAtIGNsaXBJbmZvLmNsaXBMZWZ0O1xuICAgIGNvbnN0IGNsaXBIZWlnaHQgPSBjbGlwSW5mby5jbGlwQm90dG9tIC0gY2xpcEluZm8uY2xpcFRvcDtcblxuICAgIGlmIChjbGlwV2lkdGggPD0gMCB8fCBjbGlwSGVpZ2h0IDw9IDApXG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkRWxlbWVudFNjcmVlbnNob3REaW1lbnNpb25zRXJyb3IoY2xpcFdpZHRoLCBjbGlwSGVpZ2h0KTtcblxuICAgIHJldHVybiBjbGlwSW5mbztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyb3BTY3JlZW5zaG90IChpbWFnZSwgeyBwYXRoLCBtYXJrU2VlZCwgY2xpZW50QXJlYURpbWVuc2lvbnMsIGNyb3BEaW1lbnNpb25zIH0pIHtcbiAgICBpZiAoIW1hcmtTZWVkICYmICFjcm9wRGltZW5zaW9ucylcbiAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBjbGlwID0gY2FsY3VsYXRlQ2xpcEluZm8oaW1hZ2UsIHBhdGgsIG1hcmtTZWVkLCBjbGllbnRBcmVhRGltZW5zaW9ucywgY3JvcERpbWVuc2lvbnMpO1xuXG4gICAgcmV0dXJuIGNvcHlJbWFnZVBhcnQoaW1hZ2UsIGNsaXApO1xufVxuIl19