@freelancercom/blue-harvest
Version:
protractor helpers
104 lines (95 loc) • 3.73 kB
text/typescript
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as looksSame from 'looks-same';
import { browser, ElementFinder, WebElement } from 'protractor';
let mask_fn = require('./mask').MASK_FN;
/**
* Compare a screenshot to a reference, or "golden" image.
* Returns a Promise that resolves to whether or not the
* screenshot is a match. If the UPDATE_SCREENSHOTS environment
* variable is set, the promise resolves to true and the
* golden image is updated.
*
* @param data - The screenshot image data.
* @param golden - The path to the golden image to compare to.
* @param outputFolder - The destination path for saving the diff. if it is not provided, the difference image will not be
* saved.
*/
export async function compareScreenshot(data, golden, outputFolder = undefined, looksSameOptions: looksSame.LooksSameOptions = {}): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
const tempFolder = createTempFolder();
const screenshotPath = await writeScreenshot(tempFolder, data);
// check if goldens need to be updated
const update = process.env['UPDATE_GOLDENS'] === '1' || process.env['UPDATE_GOLDENS'] === 'true';
if (update && !fs.existsSync(golden)) {
fs.writeFileSync(golden, fs.readFileSync(screenshotPath));
resolve('Reference image ' + golden + ' was successfully updated.');
return;
}
const goldenName = path.basename(golden);
looksSame(screenshotPath, golden, {
...{
strict: false,
tolerance: 5.0,
},
...looksSameOptions,
}, async (error, equal) => {
if (error) {
reject("There has been an error. Error: " + error);
return;
}
if (!equal) {
if (update) {
fs.writeFileSync(golden, fs.readFileSync(screenshotPath));
resolve('Reference image ' + golden + ' was successfully updated.');
} else if (outputFolder) {
const diffPath = path.join(outputFolder, `diff-${goldenName}`);
looksSame.createDiff({
reference: golden,
current: screenshotPath,
diff: diffPath,
highlightColor: '#ff00ff', // color to highlight the differences
}, (err) => {
if (err) {
reject('An error occurred while saving the diff image: ' + err);
return;
}
const currentPath = path.join(outputFolder, `current-${goldenName}`);
fs.writeFileSync(currentPath, fs.readFileSync(screenshotPath));
reject(`Screenshot ${currentPath} do not match for ${golden}. Difference picture is saved as ${diffPath}.`);
});
} else { reject(`Screenshots do not match for ${golden}.`); }
} else {
resolve('The test passed. ');
}
});
});
}
function createTempFolder() {
return fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
}
/**
* Write a screenshot to disk in a new temporary path.
*/
async function writeScreenshot(folder, data) {
let screenshotFile = path.join(folder, 'new.png');
fs.writeFileSync(screenshotFile, data, 'base64');
return screenshotFile;
}
export async function addMask(el: ElementFinder, color, zIndex = 10000, xOffset = 0, yOffset = 0, sizeMultiplier = 1.0) {
let rect = await el.getRect();
const mask: WebElement = <WebElement> await browser.executeScript(
mask_fn,
rect.x + xOffset,
rect.y + yOffset,
rect.width * sizeMultiplier,
rect.height * sizeMultiplier,
color,
zIndex
);
return mask;
}
export async function removeMask(mask: WebElement) {
await browser.executeScript("arguments[0].parentNode.removeChild(arguments[0])", mask);
}