Skip to content

Commit

Permalink
fix: added creating screenshots even crop fails (#7267)
Browse files Browse the repository at this point in the history
* test: added test Should throw warning if the crop fails

* fix: added creating screenshot even crop was failed

* test: added deleting file after test

* test: removed only

* test: fixed tests

* fix: removed unnecessary if
  • Loading branch information
Aleksey28 authored Sep 9, 2022
1 parent 108a8b2 commit 4d90206
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 86 deletions.
13 changes: 11 additions & 2 deletions src/screenshots/capturer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import {
} from 'path';

import { generateThumbnail } from 'testcafe-browser-tools';
import { cropScreenshot } from './crop';
import {
cropScreenshot,
calculateMarkPosition,
markSeedToId,
} from './crop';
import { isInQueue, addToQueue } from '../utils/async-queue';
import WARNING_MESSAGE from '../notifications/warning-message';
import escapeUserAgent from '../utils/escape-user-agent';
Expand Down Expand Up @@ -156,8 +160,13 @@ export default class Capturer {

const image = await readPngFile(tempPath);

const markSeedPosition = markSeed ? calculateMarkPosition(image, markSeed) : null;

if (markSeed && !markSeedPosition)
this.warningLog.addWarning(WARNING_MESSAGE.screenshotMarkNotFound, tempPath, markSeedToId(markSeed));

const croppedImage = await cropScreenshot(image, {
markSeed,
markSeedPosition,
clientAreaDimensions,
path: tempPath,
cropDimensions: Capturer._getCropDimensions(cropDimensions, pageDimensions),
Expand Down
27 changes: 8 additions & 19 deletions src/screenshots/crop.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { copyImagePart } from './utils';
import limitNumber from '../utils/limit-number';
import renderTemplate from '../utils/render-template';
import { deleteFile } from '../utils/promisified-functions';
import { InvalidElementScreenshotDimensionsError } from '../errors/test-run/';
import {
Expand All @@ -9,13 +8,11 @@ import {
MARK_BYTES_PER_PIXEL,
} from './constants';

import WARNING_MESSAGES from '../notifications/warning-message';

const MARK_SEED_ERROR_THRESHOLD = 10;
const WHITE_COLOR_PART = 255;
const BLACK_COLOR_PART = 0;

function markSeedToId (markSeed) {
export function markSeedToId (markSeed) {
let id = 0;

for (let i = 0; i < MARK_LENGTH; i++)
Expand Down Expand Up @@ -102,38 +99,30 @@ export function getClipInfoByCropDimensions ({ clipRight, clipLeft, clipBottom,
};
}

export function calculateClipInfo (pngImage, path, markSeed, clientAreaDimensions, cropDimensions) {
export function calculateClipInfo (pngImage, markSeedPosition, 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(renderTemplate(WARNING_MESSAGES.screenshotMarkNotFound, path, markSeedToId(markSeed)));

clipInfo = getClipInfoByMarkPosition(markPosition, clientAreaDimensions);
}
if (markSeedPosition && clientAreaDimensions)
clipInfo = getClipInfoByMarkPosition(markSeedPosition, clientAreaDimensions);

clipInfo = getClipInfoByCropDimensions(clipInfo, cropDimensions);

if (markPosition && markPosition.y === clipInfo.clipBottom)
if (markSeedPosition && markSeedPosition.y === clipInfo.clipBottom)
clipInfo.clipBottom--;

return clipInfo;
}

export async function cropScreenshot (image, { path, markSeed, clientAreaDimensions, cropDimensions }) {
if (!markSeed && !cropDimensions)
export async function cropScreenshot (image, { path, markSeedPosition, clientAreaDimensions, cropDimensions }) {
if (!markSeedPosition && !cropDimensions)
return null;

const clip = calculateClipInfo(image, path, markSeed, clientAreaDimensions, cropDimensions);
const clip = calculateClipInfo(image, markSeedPosition, clientAreaDimensions, cropDimensions);

await validateClipInfo(clip, path);

Expand Down
13 changes: 1 addition & 12 deletions src/test-run/browser-manipulation-queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { isServiceCommand } from './commands/utils';
import COMMAND_TYPE from './commands/type';
import WARNING_MESSAGE from '../notifications/warning-message';
import { WindowDimensionsOverflowError } from '../errors/test-run/';
import { TEST_RUN_ERRORS } from '../errors/types';


export default class BrowserManipulationQueue {
constructor (browserConnection, screenshotCapturer, warningLog) {
Expand Down Expand Up @@ -51,16 +49,7 @@ export default class BrowserManipulationQueue {
}

async _takeScreenshot (capture) {
try {
return await capture();
}
catch (err) {
if (err.code === TEST_RUN_ERRORS.invalidElementScreenshotDimensionsError)
throw err;

this.warningLog.addWarning(WARNING_MESSAGE.screenshotError, err.stack);
return null;
}
return capture();
}

async _executeCommand (driverMsg) {
Expand Down
63 changes: 63 additions & 0 deletions test/server/capturer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ const { statSync } = require('fs');
const Capturer = require('../../lib/screenshots/capturer');
const TestRunController = require('../../lib/runner/test-run-controller');
const Screenshots = require('../../lib/screenshots');
const {
writePng,
deleteFile,
readPng,
} = require('../../lib/utils/promisified-functions');
const WarningLog = require('../../lib/notifications/warning-log');


const filePath = resolve(process.cwd(), `temp${nanoid(7)}`, 'temp.png');
Expand Down Expand Up @@ -111,4 +117,61 @@ describe('Capturer', () => {
takenOnFail: false,
});
});

it('Should not delete screenshot if unable to locate the page area', async () => {
const warningLog = new WarningLog();
const customPath = `${nanoid(7)}screenshot.png`;

const screenshots = new ScreenshotsMock({
enabled: true,
path: process.cwd(),
pathPattern: '',
fullPage: false,
});

const providerMock = {
takeScreenshot: async (_, path) => {
const image = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg==', 'base64');
const png = await readPng(image);

await writePng(path, png);
},
};

const testRunControllerMock = {
_screenshots: screenshots,
test: { fixture: {} },
emit: noop,
_warningLog: warningLog,
_testRunCtor: function ({ browserConnection }) {
this.id = 'test-run-id';
this.browserConnection = browserConnection;
this.initialize = noop;
},
};

await screenshots._onMessageBusStart();

await TestRunController.prototype._createTestRun.call(testRunControllerMock, {
id: 'browser-connection-id',
provider: providerMock,
browserInfo: {
parsedUserAgent: {
os: {
name: 'os-name',
},
},
},
});

await screenshots.capturer._capture(false, {
actionId: 'action-id',
markSeed: Buffer.from([255, 255, 255, 255]),
customPath,
});

expect(warningLog.messages[0]).contain('Unable to locate the page area in the browser window screenshot at');

await deleteFile(customPath);
});
});
58 changes: 5 additions & 53 deletions test/server/crop-test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
const { nanoid } = require('nanoid');
const expect = require('chai').expect;
const { resolve } = require('path');

const { writePng, readPng, deleteFile, readPngFile } = require('../../lib/utils/promisified-functions');

const image = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg==', 'base64');
const screenshotPath = resolve(process.cwd(), `temp${nanoid(7)}.png`);

const {
cropScreenshot,
getClipInfoByCropDimensions,
calculateMarkPosition,
getClipInfoByMarkPosition,
Expand Down Expand Up @@ -138,61 +130,21 @@ describe('Crop images', () => {
bottom: 850,
};

expect(calculateClipInfo(getPngMock(), 'path', markSeed, clientAreaDimensions)).eql({
const pngImage = getPngMock();
const markPosition = calculateMarkPosition(pngImage, markSeed);

expect(calculateClipInfo(pngImage, markPosition, clientAreaDimensions)).eql({
clipLeft: 0,
clipTop: 0,
clipRight: 1820,
clipBottom: 953,
});

expect(calculateClipInfo(getPngMock(), 'path', markSeed, clientAreaDimensions, cropDimensions)).eql({
expect(calculateClipInfo(pngImage, markPosition, clientAreaDimensions, cropDimensions)).eql({
clipLeft: 20,
clipTop: 20,
clipRight: 1800,
clipBottom: 850,
});
});

it('Throw error if mark is not found', () => {
let err = null;

try {
calculateClipInfo(getPngMock(), 'path', '+', { width: 1620, height: 854 });
}
catch (e) {
err = e;
}
finally {
expect(err.message).is.not.null;
expect(err.message).contains(
'Unable to locate the page area in the browser window screenshot at path, ' +
'because the page area mark with ID 2147483648 ' +
'is not found in the screenshot.');
}
});

it('Should not delete screenshot if unable to locate the page area', async () => {
let err = null;
const png = await readPng(image);

await writePng(screenshotPath, png);

const clientAreaDimensions = { width: 1620, height: 854 };

try {
await cropScreenshot(png, { path: screenshotPath, markSeed: '+', clientAreaDimensions });
}
catch (e) {
err = e;
}
finally {
expect(err.message).contains('Unable to locate the page area in the browser window screenshot');

const file = await readPngFile(screenshotPath);

expect(file).is.not.null;

await deleteFile(screenshotPath);
}
});
});

0 comments on commit 4d90206

Please sign in to comment.