@browserstack/testcafe
Version:
Automated browser testing for the modern web development stack.
111 lines • 15.3 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 promisified_functions_1 = require("../utils/promisified-functions");
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;
}
async function validateClipInfo(clipInfo, path) {
const clipWidth = clipInfo.clipRight - clipInfo.clipLeft;
const clipHeight = clipInfo.clipBottom - clipInfo.clipTop;
if (clipWidth <= 0 || clipHeight <= 0) {
await promisified_functions_1.deleteFile(path);
throw new test_run_1.InvalidElementScreenshotDimensionsError(clipWidth, clipHeight);
}
}
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--;
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);
await validateClipInfo(clip, path);
return utils_1.copyImagePart(image, clip);
}
exports.cropScreenshot = cropScreenshot;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JlZW5zaG90cy9jcm9wLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQXdDO0FBQ3hDLHlFQUFnRDtBQUNoRCwrRUFBc0Q7QUFDdEQsMEVBQTREO0FBQzVELGtEQUE4RTtBQUM5RSwyQ0FBbUY7QUFDbkYsdUZBQWdFO0FBRWhFLE1BQU0seUJBQXlCLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLE1BQU0sZ0JBQWdCLEdBQVksR0FBRyxDQUFDO0FBQ3RDLE1BQU0sZ0JBQWdCLEdBQVksQ0FBQyxDQUFDO0FBRXBDLFNBQVMsWUFBWSxDQUFFLFFBQVE7SUFDM0IsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRVgsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLHVCQUFXLEVBQUUsQ0FBQyxFQUFFO1FBQ2hDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxnQ0FBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRS9ELE9BQU8sRUFBRSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUUsU0FBUztJQUNyQyxNQUFNLE9BQU8sR0FBRyxTQUFTLEdBQUcsZ0JBQWdCLEdBQUcseUJBQXlCLENBQUM7SUFDekUsTUFBTSxPQUFPLEdBQUcsU0FBUyxHQUFHLHlCQUF5QixDQUFDO0lBRXRELElBQUksT0FBTztRQUNQLE9BQU8sZ0JBQWdCLENBQUM7SUFFNUIsSUFBSSxPQUFPO1FBQ1AsT0FBTyxnQkFBZ0IsQ0FBQztJQUU1QixPQUFPLFNBQVMsQ0FBQztBQUNyQixDQUFDO0FBRUQsS0FBSyxVQUFVLGdCQUFnQixDQUFFLFFBQVEsRUFBRSxJQUFJO0lBQzNDLE1BQU0sU0FBUyxHQUFJLFFBQVEsQ0FBQyxTQUFTLEdBQUcs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USxFQUFFLG9CQUFvQixFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBRTVGLE1BQU0sZ0JBQWdCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRW5DLE9BQU8scUJBQWEsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQVRELHdDQVNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29weUltYWdlUGFydCB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IGxpbWl0TnVtYmVyIGZyb20gJy4uL3V0aWxzL2xpbWl0LW51bWJlcic7XG5pbXBvcnQgcmVuZGVyVGVtcGxhdGUgZnJvbSAnLi4vdXRpbHMvcmVuZGVyLXRlbXBsYXRlJztcbmltcG9ydCB7IGRlbGV0ZUZpbGUgfSBmcm9tICcuLi91dGlscy9wcm9taXNpZmllZC1mdW5jdGlvbnMnO1xuaW1wb3J0IHsgSW52YWxpZEVsZW1lbnRTY3JlZW5zaG90RGltZW5zaW9uc0Vycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3Rlc3QtcnVuLyc7XG5pbXBvcnQgeyBNQVJLX0xFTkdUSCwgTUFSS19SSUdIVF9NQVJHSU4sIE1BUktfQllURVNfUEVSX1BJWEVMIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IFdBUk5JTkdfTUVTU0FHRVMgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuXG5jb25zdCBNQVJLX1NFRURfRVJST1JfVEhSRVNIT0xEID0gMTA7XG5jb25zdCBXSElURV9DT0xPUl9QQVJUICAgICAgICAgID0gMjU1O1xuY29uc3QgQkxBQ0tfQ09MT1JfUEFSVCAgICAgICAgICA9IDA7XG5cbmZ1bmN0aW9uIG1hcmtTZWVkVG9JZCAobWFya1NlZWQpIHtcbiAgICBsZXQgaWQgPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNQVJLX0xFTkdUSDsgaSsrKVxuICAgICAgICBpZCA9IGlkICogMiArIChtYXJrU2VlZFtpICogTUFSS19CWVRFU19QRVJfUElYRUxdID8gMSA6IDApO1xuXG4gICAgcmV0dXJuIGlkO1xufVxuXG5mdW5jdGlvbiBnZXRDb3JyZWN0ZWRDb2xvclBhcnQgKGNvbG9yUGFydCkge1xuICAgIGNvbnN0IGlzV2hpdGUgPSBjb2xvclBhcnQgPiBXSElURV9DT0xPUl9QQVJUIC0gTUFSS19TRUVEX0VSUk9SX1RIUkVTSE9MRDtcbiAgICBjb25zdCBpc0JsYWNrID0gY29sb3JQYXJ0IDwgTUFSS19TRUVEX0VSUk9SX1RIUkVTSE9MRDtcblxuICAgIGlmIChpc0JsYWNrKVxuICAgICAgICByZXR1cm4gQkxBQ0tfQ09MT1JfUEFSVDtcblxuICAgIGlmIChpc1doaXRlKVxuICAgICAgICByZXR1cm4gV0hJVEVfQ09MT1JfUEFSVDtcblxuICAgIHJldHVybiBjb2xvclBhcnQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlQ2xpcEluZm8gKGNsaXBJbmZvLCBwYXRoKSB7XG4gICAgY29uc3QgY2xpcFdpZHRoICA9IGNsaXBJbmZvLmNsaXBSaWdodCAtIGNsaXBJbmZvLmNsaXBMZWZ0O1xuICAgIGNvbnN0IGNsaXBIZWlnaHQgPSBjbGlwSW5mby5jbGlwQm90dG9tIC0gY2xpcEluZm8uY2xpcFRvcDtcblxuICAgIGlmIChjbGlwV2lkdGggPD0gMCB8fCBjbGlwSGVpZ2h0IDw9IDApIHtcbiAgICAgICAgYXdhaXQgZGVsZXRlRmlsZShwYXRoKTtcblxuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEVsZW1lbnRTY3JlZW5zaG90RGltZW5zaW9uc0Vycm9yKGNsaXBXaWR0aCwgY2xpcEhlaWdodCk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlTWFya1Bvc2l0aW9uIChwbmdJbWFnZSwgbWFya1NlZWQpIHtcbiAgICBjb25zdCBtYXJrICAgID0gQnVmZmVyLmZyb20obWFya1NlZWQpO1xuICAgIGNvbnN0IGZpbHRJbWcgPSBCdWZmZXIuZnJvbShwbmdJbWFnZS5kYXRhKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsdEltZy5sZW5ndGg7IGkrKylcbiAgICAgICAgZmlsdEltZ1tpXSA9IGdldENvcnJlY3RlZENvbG9yUGFydChmaWx0SW1nW2ldKTtcblxuICAgIGNvbnN0IG1hcmtJbmRleCA9IGZpbHRJbWcuaW5kZXhPZihtYXJrKTtcblxuICAgIGlmIChtYXJrSW5kZXggPCAwKVxuICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gbWFya0luZGV4IC8gTUFSS19CWVRFU19QRVJfUElYRUwgKyBNQVJLX0xFTkdUSCArIE1BUktfUklHSFRfTUFSR0lOO1xuXG4gICAgY29uc3QgeCA9IGVuZFBvc2l0aW9uICUgcG5nSW1hZ2Uud2lkdGggfHwgcG5nSW1hZ2Uud2lkdGg7XG4gICAgY29uc3QgeSA9IChlbmRQb3NpdGlvbiAtIHgpIC8gcG5nSW1hZ2Uud2lkdGggKyAxO1xuXG4gICAgcmV0dXJuIHsgeCwgeSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xpcEluZm9CeU1hcmtQb3NpdGlvbiAobWFya1Bvc2l0aW9uLCB7IHdpZHRoLCBoZWlnaHQgfSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gbWFya1Bvc2l0aW9uO1xuXG4gICAgY29uc3QgY2xpcFJpZ2h0ICA9IHg7XG4gICAgY29uc3QgY2xpcEJvdHRvbSA9IHk7XG4gICAgY29uc3QgY2xpcExlZnQgICA9IGNsaXBSaWdodCAtIHdpZHRoO1xuICAgIGNvbnN0IGNsaXBUb3AgICAgPSBjbGlwQm90dG9tIC0gaGVpZ2h0O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2xpcExlZnQsXG4gICAgICAgIGNsaXBUb3AsXG4gICAgICAgIGNsaXBSaWdodCxcbiAgICAgICAgY2xpcEJvdHRvbVxuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGlwSW5mb0J5Q3JvcERpbWVuc2lvbnMgKHsgY2xpcFJpZ2h0LCBjbGlwTGVmdCwgY2xpcEJvdHRvbSwgY2xpcFRvcCB9LCBjcm9wRGltZW5zaW9ucykge1xuICAgIGlmIChjcm9wRGltZW5zaW9ucykge1xuICAgICAgICBjb25zdCB7IHJpZ2h0LCB0b3AsIGJvdHRvbSwgbGVmdCB9ID0gY3JvcERpbWVuc2lvbnM7XG5cbiAgICAgICAgY2xpcFJpZ2h0ICA9IGxpbWl0TnVtYmVyKGNsaXBMZWZ0ICsgcmlnaHQsIGNsaXBMZWZ0LCBjbGlwUmlnaHQpO1xuICAgICAgICBjbGlwQm90dG9tID0gbGltaXROdW1iZXIoY2xpcFRvcCArIGJvdHRvbSwgY2xpcFRvcCwgY2xpcEJvdHRvbSk7XG4gICAgICAgIGNsaXBMZWZ0ICAgPSBsaW1pdE51bWJlcihjbGlwTGVmdCArIGxlZnQsIGNsaXBMZWZ0LCBjbGlwUmlnaHQpO1xuICAgICAgICBjbGlwVG9wICAgID0gbGltaXROdW1iZXIoY2xpcFRvcCArIHRvcCwgY2xpcFRvcCwgY2xpcEJvdHRvbSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2xpcExlZnQsXG4gICAgICAgIGNsaXBUb3AsXG4gICAgICAgIGNsaXBSaWdodCxcbiAgICAgICAgY2xpcEJvdHRvbVxuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVDbGlwSW5mbyAocG5nSW1hZ2UsIHBhdGgsIG1hcmtTZWVkLCBjbGllbnRBcmVhRGltZW5zaW9ucywgY3JvcERpbWVuc2lvbnMpIHtcbiAgICBsZXQgY2xpcEluZm8gPSB7XG4gICAgICAgIGNsaXBSaWdodDogIHBuZ0ltYWdlLndpZHRoLFxuICAgICAgICBjbGlwQm90dG9tOiBwbmdJbWFnZS5oZWlnaHQsXG4gICAgICAgIGNsaXBMZWZ0OiAgIDAsXG4gICAgICAgIGNsaXBUb3A6ICAgIDBcbiAgICB9O1xuXG4gICAgbGV0IG1hcmtQb3NpdGlvbiA9IG51bGw7XG5cbiAgICBpZiAobWFya1NlZWQgJiYgY2xpZW50QXJlYURpbWVuc2lvbnMpIHtcbiAgICAgICAgbWFya1Bvc2l0aW9uID0gY2FsY3VsYXRlTWFya1Bvc2l0aW9uKHBuZ0ltYWdlLCBtYXJrU2VlZCk7XG5cbiAgICAgICAgaWYgKCFtYXJrUG9zaXRpb24pXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVuZGVyVGVtcGxhdGUoV0FSTklOR19NRVNTQUdFUy5zY3JlZW5zaG90TWFya05vdEZvdW5kLCBwYXRoLCBtYXJrU2VlZFRvSWQobWFya1NlZWQpKSk7XG5cbiAgICAgICAgY2xpcEluZm8gPSBnZXRDbGlwSW5mb0J5TWFya1Bvc2l0aW9uKG1hcmtQb3NpdGlvbiwgY2xpZW50QXJlYURpbWVuc2lvbnMpO1xuICAgIH1cblxuICAgIGNsaXBJbmZvID0gZ2V0Q2xpcEluZm9CeUNyb3BEaW1lbnNpb25zKGNsaXBJbmZvLCBjcm9wRGltZW5zaW9ucyk7XG5cbiAgICBpZiAobWFya1Bvc2l0aW9uICYmIG1hcmtQb3NpdGlvbi55ID09PSBjbGlwSW5mby5jbGlwQm90dG9tKVxuICAgICAgICBjbGlwSW5mby5jbGlwQm90dG9tLS07XG5cbiAgICByZXR1cm4gY2xpcEluZm87XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcm9wU2NyZWVuc2hvdCAoaW1hZ2UsIHsgcGF0aCwgbWFya1NlZWQsIGNsaWVudEFyZWFEaW1lbnNpb25zLCBjcm9wRGltZW5zaW9ucyB9KSB7XG4gICAgaWYgKCFtYXJrU2VlZCAmJiAhY3JvcERpbWVuc2lvbnMpXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgY2xpcCA9IGNhbGN1bGF0ZUNsaXBJbmZvKGltYWdlLCBwYXRoLCBtYXJrU2VlZCwgY2xpZW50QXJlYURpbWVuc2lvbnMsIGNyb3BEaW1lbnNpb25zKTtcblxuICAgIGF3YWl0IHZhbGlkYXRlQ2xpcEluZm8oY2xpcCwgcGF0aCk7XG5cbiAgICByZXR1cm4gY29weUltYWdlUGFydChpbWFnZSwgY2xpcCk7XG59XG4iXX0=