UNPKG

15.4 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const utils_1 = require("./utils");
7const limit_number_1 = __importDefault(require("../utils/limit-number"));
8const render_template_1 = __importDefault(require("../utils/render-template"));
9const promisified_functions_1 = require("../utils/promisified-functions");
10const test_run_1 = require("../errors/test-run/");
11const constants_1 = require("./constants");
12const warning_message_1 = __importDefault(require("../notifications/warning-message"));
13const MARK_SEED_ERROR_THRESHOLD = 10;
14const WHITE_COLOR_PART = 255;
15const BLACK_COLOR_PART = 0;
16function markSeedToId(markSeed) {
17 let id = 0;
18 for (let i = 0; i < constants_1.MARK_LENGTH; i++)
19 id = id * 2 + (markSeed[i * constants_1.MARK_BYTES_PER_PIXEL] ? 1 : 0);
20 return id;
21}
22function getCorrectedColorPart(colorPart) {
23 const isWhite = colorPart > WHITE_COLOR_PART - MARK_SEED_ERROR_THRESHOLD;
24 const isBlack = colorPart < MARK_SEED_ERROR_THRESHOLD;
25 if (isBlack)
26 return BLACK_COLOR_PART;
27 if (isWhite)
28 return WHITE_COLOR_PART;
29 return colorPart;
30}
31async function validateClipInfo(clipInfo, path) {
32 const clipWidth = clipInfo.clipRight - clipInfo.clipLeft;
33 const clipHeight = clipInfo.clipBottom - clipInfo.clipTop;
34 if (clipWidth <= 0 || clipHeight <= 0) {
35 await promisified_functions_1.deleteFile(path);
36 throw new test_run_1.InvalidElementScreenshotDimensionsError(clipWidth, clipHeight);
37 }
38}
39function calculateMarkPosition(pngImage, markSeed) {
40 const mark = Buffer.from(markSeed);
41 const filtImg = Buffer.from(pngImage.data);
42 for (let i = 0; i < filtImg.length; i++)
43 filtImg[i] = getCorrectedColorPart(filtImg[i]);
44 const markIndex = filtImg.indexOf(mark);
45 if (markIndex < 0)
46 return null;
47 const endPosition = markIndex / constants_1.MARK_BYTES_PER_PIXEL + constants_1.MARK_LENGTH + constants_1.MARK_RIGHT_MARGIN;
48 const x = endPosition % pngImage.width || pngImage.width;
49 const y = (endPosition - x) / pngImage.width + 1;
50 return { x, y };
51}
52exports.calculateMarkPosition = calculateMarkPosition;
53function getClipInfoByMarkPosition(markPosition, { width, height }) {
54 const { x, y } = markPosition;
55 const clipRight = x;
56 const clipBottom = y;
57 const clipLeft = clipRight - width;
58 const clipTop = clipBottom - height;
59 return {
60 clipLeft,
61 clipTop,
62 clipRight,
63 clipBottom
64 };
65}
66exports.getClipInfoByMarkPosition = getClipInfoByMarkPosition;
67function getClipInfoByCropDimensions({ clipRight, clipLeft, clipBottom, clipTop }, cropDimensions) {
68 if (cropDimensions) {
69 const { right, top, bottom, left } = cropDimensions;
70 clipRight = limit_number_1.default(clipLeft + right, clipLeft, clipRight);
71 clipBottom = limit_number_1.default(clipTop + bottom, clipTop, clipBottom);
72 clipLeft = limit_number_1.default(clipLeft + left, clipLeft, clipRight);
73 clipTop = limit_number_1.default(clipTop + top, clipTop, clipBottom);
74 }
75 return {
76 clipLeft,
77 clipTop,
78 clipRight,
79 clipBottom
80 };
81}
82exports.getClipInfoByCropDimensions = getClipInfoByCropDimensions;
83function calculateClipInfo(pngImage, path, markSeed, clientAreaDimensions, cropDimensions) {
84 let clipInfo = {
85 clipRight: pngImage.width,
86 clipBottom: pngImage.height,
87 clipLeft: 0,
88 clipTop: 0
89 };
90 let markPosition = null;
91 if (markSeed && clientAreaDimensions) {
92 markPosition = calculateMarkPosition(pngImage, markSeed);
93 if (!markPosition)
94 throw new Error(render_template_1.default(warning_message_1.default.screenshotMarkNotFound, path, markSeedToId(markSeed)));
95 clipInfo = getClipInfoByMarkPosition(markPosition, clientAreaDimensions);
96 }
97 clipInfo = getClipInfoByCropDimensions(clipInfo, cropDimensions);
98 if (markPosition && markPosition.y === clipInfo.clipBottom)
99 clipInfo.clipBottom--;
100 return clipInfo;
101}
102exports.calculateClipInfo = calculateClipInfo;
103async function cropScreenshot(image, { path, markSeed, clientAreaDimensions, cropDimensions }) {
104 if (!markSeed && !cropDimensions)
105 return null;
106 const clip = calculateClipInfo(image, path, markSeed, clientAreaDimensions, cropDimensions);
107 await validateClipInfo(clip, path);
108 return utils_1.copyImagePart(image, clip);
109}
110exports.cropScreenshot = cropScreenshot;
111//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JlZW5zaG90cy9jcm9wLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQXdDO0FBQ3hDLHlFQUFnRDtBQUNoRCwrRUFBc0Q7QUFDdEQsMEVBQTREO0FBQzVELGtEQUE4RTtBQUM5RSwyQ0FBbUY7QUFDbkYsdUZBQWdFO0FBRWhFLE1BQU0seUJBQXlCLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLE1BQU0sZ0JBQWdCLEdBQVksR0FBRyxDQUFDO0FBQ3RDLE1BQU0sZ0JBQWdCLEdBQVksQ0FBQyxDQUFDO0FBRXBDLFNBQVMsWUFBWSxDQUFFLFFBQVE7SUFDM0IsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRVgsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLHVCQUFXLEVBQUUsQ0FBQyxFQUFFO1FBQ2hDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxnQ0FBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRS9ELE9BQU8sRUFBRSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUUsU0FBUztJQUNyQyxNQUFNLE9BQU8sR0FBRyxTQUFTLEdBQUcsZ0JBQWdCLEdBQUcseUJBQXlCLENBQUM7SUFDekUsTUFBTSxPQUFPLEdBQUcsU0FBUyxHQUFHLHlCQUF5QixDQUFDO0lBRXRELElBQUksT0FBTztRQUNQLE9BQU8sZ0JBQWdCLENBQUM7SUFFNUIsSUFBSSxPQUFPO1FBQ1AsT0FBTyxnQkFBZ0IsQ0FBQztJQUU1QixPQUFPLFNBQVMsQ0FBQztBQUNyQixDQUFDO0FBRUQsS0FBSyxVQUFVLGdCQUFnQixDQUFFLFFBQVEsRUFBRSxJQUFJO0lBQzNDLE1BQU0sU0FBUyxHQUFJLFFBQVEsQ0FBQyxTQUFTLEdBQUcs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USxFQUFFLG9CQUFvQixFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBRTVGLE1BQU0sZ0JBQWdCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRW5DLE9BQU8scUJBQWEsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQVRELHdDQVNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29weUltYWdlUGFydCB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IGxpbWl0TnVtYmVyIGZyb20gJy4uL3V0aWxzL2xpbWl0LW51bWJlcic7XG5pbXBvcnQgcmVuZGVyVGVtcGxhdGUgZnJvbSAnLi4vdXRpbHMvcmVuZGVyLXRlbXBsYXRlJztcbmltcG9ydCB7IGRlbGV0ZUZpbGUgfSBmcm9tICcuLi91dGlscy9wcm9taXNpZmllZC1mdW5jdGlvbnMnO1xuaW1wb3J0IHsgSW52YWxpZEVsZW1lbnRTY3JlZW5zaG90RGltZW5zaW9uc0Vycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3Rlc3QtcnVuLyc7XG5pbXBvcnQgeyBNQVJLX0xFTkdUSCwgTUFSS19SSUdIVF9NQVJHSU4sIE1BUktfQllURVNfUEVSX1BJWEVMIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IFdBUk5JTkdfTUVTU0FHRVMgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuXG5jb25zdCBNQVJLX1NFRURfRVJST1JfVEhSRVNIT0xEID0gMTA7XG5jb25zdCBXSElURV9DT0xPUl9QQVJUICAgICAgICAgID0gMjU1O1xuY29uc3QgQkxBQ0tfQ09MT1JfUEFSVCAgICAgICAgICA9IDA7XG5cbmZ1bmN0aW9uIG1hcmtTZWVkVG9JZCAobWFya1NlZWQpIHtcbiAgICBsZXQgaWQgPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNQVJLX0xFTkdUSDsgaSsrKVxuICAgICAgICBpZCA9IGlkICogMiArIChtYXJrU2VlZFtpICogTUFSS19CWVRFU19QRVJfUElYRUxdID8gMSA6IDApO1xuXG4gICAgcmV0dXJuIGlkO1xufVxuXG5mdW5jdGlvbiBnZXRDb3JyZWN0ZWRDb2xvclBhcnQgKGNvbG9yUGFydCkge1xuICAgIGNvbnN0IGlzV2hpdGUgPSBjb2xvclBhcnQgPiBXSElURV9DT0xPUl9QQVJUIC0gTUFSS19TRUVEX0VSUk9SX1RIUkVTSE9MRDtcbiAgICBjb25zdCBpc0JsYWNrID0gY29sb3JQYXJ0IDwgTUFSS19TRUVEX0VSUk9SX1RIUkVTSE9MRDtcblxuICAgIGlmIChpc0JsYWNrKVxuICAgICAgICByZXR1cm4gQkxBQ0tfQ09MT1JfUEFSVDtcblxuICAgIGlmIChpc1doaXRlKVxuICAgICAgICByZXR1cm4gV0hJVEVfQ09MT1JfUEFSVDtcblxuICAgIHJldHVybiBjb2xvclBhcnQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlQ2xpcEluZm8gKGNsaXBJbmZvLCBwYXRoKSB7XG4gICAgY29uc3QgY2xpcFdpZHRoICA9IGNsaXBJbmZvLmNsaXBSaWdodCAtIGNsaXBJbmZvLmNsaXBMZWZ0O1xuICAgIGNvbnN0IGNsaXBIZWlnaHQgPSBjbGlwSW5mby5jbGlwQm90dG9tIC0gY2xpcEluZm8uY2xpcFRvcDtcblxuICAgIGlmIChjbGlwV2lkdGggPD0gMCB8fCBjbGlwSGVpZ2h0IDw9IDApIHtcbiAgICAgICAgYXdhaXQgZGVsZXRlRmlsZShwYXRoKTtcblxuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEVsZW1lbnRTY3JlZW5zaG90RGltZW5zaW9uc0Vycm9yKGNsaXBXaWR0aCwgY2xpcEhlaWdodCk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlTWFya1Bvc2l0aW9uIChwbmdJbWFnZSwgbWFya1NlZWQpIHtcbiAgICBjb25zdCBtYXJrICAgID0gQnVmZmVyLmZyb20obWFya1NlZWQpO1xuICAgIGNvbnN0IGZpbHRJbWcgPSBCdWZmZXIuZnJvbShwbmdJbWFnZS5kYXRhKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsdEltZy5sZW5ndGg7IGkrKylcbiAgICAgICAgZmlsdEltZ1tpXSA9IGdldENvcnJlY3RlZENvbG9yUGFydChmaWx0SW1nW2ldKTtcblxuICAgIGNvbnN0IG1hcmtJbmRleCA9IGZpbHRJbWcuaW5kZXhPZihtYXJrKTtcblxuICAgIGlmIChtYXJrSW5kZXggPCAwKVxuICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gbWFya0luZGV4IC8gTUFSS19CWVRFU19QRVJfUElYRUwgKyBNQVJLX0xFTkdUSCArIE1BUktfUklHSFRfTUFSR0lOO1xuXG4gICAgY29uc3QgeCA9IGVuZFBvc2l0aW9uICUgcG5nSW1hZ2Uud2lkdGggfHwgcG5nSW1hZ2Uud2lkdGg7XG4gICAgY29uc3QgeSA9IChlbmRQb3NpdGlvbiAtIHgpIC8gcG5nSW1hZ2Uud2lkdGggKyAxO1xuXG4gICAgcmV0dXJuIHsgeCwgeSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xpcEluZm9CeU1hcmtQb3NpdGlvbiAobWFya1Bvc2l0aW9uLCB7IHdpZHRoLCBoZWlnaHQgfSkge1xuICAgIGNvbnN0IHsgeCwgeSB9ID0gbWFya1Bvc2l0aW9uO1xuXG4gICAgY29uc3QgY2xpcFJpZ2h0ICA9IHg7XG4gICAgY29uc3QgY2xpcEJvdHRvbSA9IHk7XG4gICAgY29uc3QgY2xpcExlZnQgICA9IGNsaXBSaWdodCAtIHdpZHRoO1xuICAgIGNvbnN0IGNsaXBUb3AgICAgPSBjbGlwQm90dG9tIC0gaGVpZ2h0O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2xpcExlZnQsXG4gICAgICAgIGNsaXBUb3AsXG4gICAgICAgIGNsaXBSaWdodCxcbiAgICAgICAgY2xpcEJvdHRvbVxuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGlwSW5mb0J5Q3JvcERpbWVuc2lvbnMgKHsgY2xpcFJpZ2h0LCBjbGlwTGVmdCwgY2xpcEJvdHRvbSwgY2xpcFRvcCB9LCBjcm9wRGltZW5zaW9ucykge1xuICAgIGlmIChjcm9wRGltZW5zaW9ucykge1xuICAgICAgICBjb25zdCB7IHJpZ2h0LCB0b3AsIGJvdHRvbSwgbGVmdCB9ID0gY3JvcERpbWVuc2lvbnM7XG5cbiAgICAgICAgY2xpcFJpZ2h0ICA9IGxpbWl0TnVtYmVyKGNsaXBMZWZ0ICsgcmlnaHQsIGNsaXBMZWZ0LCBjbGlwUmlnaHQpO1xuICAgICAgICBjbGlwQm90dG9tID0gbGltaXROdW1iZXIoY2xpcFRvcCArIGJvdHRvbSwgY2xpcFRvcCwgY2xpcEJvdHRvbSk7XG4gICAgICAgIGNsaXBMZWZ0ICAgPSBsaW1pdE51bWJlcihjbGlwTGVmdCArIGxlZnQsIGNsaXBMZWZ0LCBjbGlwUmlnaHQpO1xuICAgICAgICBjbGlwVG9wICAgID0gbGltaXROdW1iZXIoY2xpcFRvcCArIHRvcCwgY2xpcFRvcCwgY2xpcEJvdHRvbSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2xpcExlZnQsXG4gICAgICAgIGNsaXBUb3AsXG4gICAgICAgIGNsaXBSaWdodCxcbiAgICAgICAgY2xpcEJvdHRvbVxuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVDbGlwSW5mbyAocG5nSW1hZ2UsIHBhdGgsIG1hcmtTZWVkLCBjbGllbnRBcmVhRGltZW5zaW9ucywgY3JvcERpbWVuc2lvbnMpIHtcbiAgICBsZXQgY2xpcEluZm8gPSB7XG4gICAgICAgIGNsaXBSaWdodDogIHBuZ0ltYWdlLndpZHRoLFxuICAgICAgICBjbGlwQm90dG9tOiBwbmdJbWFnZS5oZWlnaHQsXG4gICAgICAgIGNsaXBMZWZ0OiAgIDAsXG4gICAgICAgIGNsaXBUb3A6ICAgIDBcbiAgICB9O1xuXG4gICAgbGV0IG1hcmtQb3NpdGlvbiA9IG51bGw7XG5cbiAgICBpZiAobWFya1NlZWQgJiYgY2xpZW50QXJlYURpbWVuc2lvbnMpIHtcbiAgICAgICAgbWFya1Bvc2l0aW9uID0gY2FsY3VsYXRlTWFya1Bvc2l0aW9uKHBuZ0ltYWdlLCBtYXJrU2VlZCk7XG5cbiAgICAgICAgaWYgKCFtYXJrUG9zaXRpb24pXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVuZGVyVGVtcGxhdGUoV0FSTklOR19NRVNTQUdFUy5zY3JlZW5zaG90TWFya05vdEZvdW5kLCBwYXRoLCBtYXJrU2VlZFRvSWQobWFya1NlZWQpKSk7XG5cbiAgICAgICAgY2xpcEluZm8gPSBnZXRDbGlwSW5mb0J5TWFya1Bvc2l0aW9uKG1hcmtQb3NpdGlvbiwgY2xpZW50QXJlYURpbWVuc2lvbnMpO1xuICAgIH1cblxuICAgIGNsaXBJbmZvID0gZ2V0Q2xpcEluZm9CeUNyb3BEaW1lbnNpb25zKGNsaXBJbmZvLCBjcm9wRGltZW5zaW9ucyk7XG5cbiAgICBpZiAobWFya1Bvc2l0aW9uICYmIG1hcmtQb3NpdGlvbi55ID09PSBjbGlwSW5mby5jbGlwQm90dG9tKVxuICAgICAgICBjbGlwSW5mby5jbGlwQm90dG9tLS07XG5cbiAgICByZXR1cm4gY2xpcEluZm87XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcm9wU2NyZWVuc2hvdCAoaW1hZ2UsIHsgcGF0aCwgbWFya1NlZWQsIGNsaWVudEFyZWFEaW1lbnNpb25zLCBjcm9wRGltZW5zaW9ucyB9KSB7XG4gICAgaWYgKCFtYXJrU2VlZCAmJiAhY3JvcERpbWVuc2lvbnMpXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgY2xpcCA9IGNhbGN1bGF0ZUNsaXBJbmZvKGltYWdlLCBwYXRoLCBtYXJrU2VlZCwgY2xpZW50QXJlYURpbWVuc2lvbnMsIGNyb3BEaW1lbnNpb25zKTtcblxuICAgIGF3YWl0IHZhbGlkYXRlQ2xpcEluZm8oY2xpcCwgcGF0aCk7XG5cbiAgICByZXR1cm4gY29weUltYWdlUGFydChpbWFnZSwgY2xpcCk7XG59XG4iXX0=
\No newline at end of file