Skip to content

Commit

Permalink
Prepare 1.9.1 release (#68)
Browse files Browse the repository at this point in the history
* Issue #60 - Prepare all baselines of test by setting parameter in config (#65)

Co-authored-by: Jonatas Kirsch <[email protected]>

* Update Dependecies, Fix Fatal Error with mkdirp and Mac (#66)

* Update Dependencies

* Fix Error on Mac

* Avoid failing the test for a given threshold but yet generating the difference image (#63)

* Option bypassFailure allowing the user to avoid failing the test for a given threshold but yet generating the difference image

* Renamed option to skipFailure

Co-authored-by: Jonatas Kirsch <[email protected]>

* feat(testcafe): add the support for testcafe (#62)

* passing through output settings to resemble.js (#59)

Co-authored-by: JANK Michael <[email protected]>

* Issue 48 - Add custom assert message (#64)

Co-authored-by: Jonatas Kirsch <[email protected]>

Co-authored-by: Jonatas Kirsch <[email protected]>
Co-authored-by: Jonatas Kirsch <[email protected]>
Co-authored-by: Guillaume Camus <[email protected]>
Co-authored-by: yankydoo <[email protected]>
Co-authored-by: JANK Michael <[email protected]>
  • Loading branch information
6 people authored May 16, 2020
1 parent f2eb5b2 commit 99b6845
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 33 deletions.
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# codeceptjs-resemblehelper
Helper for resemble.js, used for image comparison in tests with WebdriverIO.
Helper for resemble.js, used for image comparison in tests with WebdriverIO or Puppeteer.

codeceptjs-resemblehelper is a [CodeceptJS](https://codecept.io/) helper which can be used to compare screenshots and make the tests fail/pass based on the tolerance allowed.

Expand All @@ -21,19 +21,25 @@ Example:
"ResembleHelper" : {
"require": "codeceptjs-resemblehelper",
"baseFolder": "./tests/screenshots/base/",
"diffFolder": "./tests/screenshots/diff/"
"diffFolder": "./tests/screenshots/diff/",
"prepareBaseImage": true
}
}
}
```

To use the Helper, users must provide the two parameters:
To use the Helper, users may provide the parameters:

`baseFolder`: This is the folder for base images, which will be used with screenshot for comparison.
`baseFolder`: Mandatory. This is the folder for base images, which will be used with screenshot for comparison.

`diffFolder`: This will the folder where resemble would try to store the difference image, which can be viewed later.
`diffFolder`: Mandatory. This will the folder where resemble would try to store the difference image, which can be viewed later.

Usage, these are major functions that help in visual testing
`prepareBaseImage`: Optional. When `true` then the system replaces all of the baselines related to the test case(s) you ran. This is equivalent of setting the option `prepareBaseImage: true` in all verifications of the test file.


### Usage

These are the major functions that help in visual testing:

First one is the `seeVisualDiff` which basically takes two parameters
1) `baseImage` Name of the base image, this will be the image used for comparison with the screenshot image. It is mandatory to have the same image file names for base and screenshot image.
Expand Down Expand Up @@ -102,7 +108,7 @@ Scenario('Compare CPU Usage Images', async (I) => {
### Ignored Box
You can also exclude part of the image from comparison, by specifying the excluded area in pixels from the top left.
Just declare an object and pass it in options as `ignoredBox`:
```
```js
const box = {
left: 0,
top: 10,
Expand All @@ -115,6 +121,29 @@ I.seeVisualDiff("image.png", {prepareBaseImage: true, tolerance: 1, ignoredBox:
After this, that specific mentioned part will be ignored while comparison.
This works for `seeVisualDiff` and `seeVisualDiffForElement`.

### resemble.js Output Settings
You can set further output settings used by resemble.js. Declare an object specifying them and pass it in the options as `outputSettings`:

```js
const outputSettings = {
ignoreAreasColoredWith: {r: 250, g: 250, b: 250, a: 0},
// read more here: https://github.com/rsmbl/Resemble.js
};
I.seeVisualDiff("image.png", {prepareBaseImage: true, tolerance: 1, outputSettings: outputSettings});
```

Refer to the [resemble.js](https://github.com/rsmbl/Resemble.js) documentation for available output settings.

### Skip Failure
You can avoid the test fails for a given threshold but yet generates the difference image.
Just declare an object and pass it in options as `skipFailure`:
```
I.seeVisualDiff("image.png", {prepareBaseImage: true, tolerance: 1, skipFailure: true});
```
After this, the system generates the difference image but does not fail the test.
This works for `seeVisualDiff` and `seeVisualDiffForElement`.


### Allure Reporter
Allure reports may also be generated directly from the tool. To do so, add

Expand Down
63 changes: 44 additions & 19 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ResembleHelper extends Helper {
this.baseFolder = this.resolvePath(config.baseFolder);
this.diffFolder = this.resolvePath(config.diffFolder);
this.screenshotFolder = global.output_dir + "/";
this.prepareBaseImage = config.prepareBaseImage;
}

resolvePath(folderPath) {
Expand Down Expand Up @@ -57,9 +58,13 @@ class ResembleHelper extends Helper {

return new Promise((resolve, reject) => {

if (!options.outputSettings) {
options.outputSettings = {};
}
resemble.outputSettings({
boundingBox: options.boundingBox,
ignoredBox: options.ignoredBox
ignoredBox: options.ignoredBox,
...options.outputSettings,
});

this.debug("Tolerance Level Provided " + options.tolerance);
Expand All @@ -76,9 +81,9 @@ class ResembleHelper extends Helper {
}
resolve(data);
if (data.misMatchPercentage >= tolerance) {
mkdirp(getDirName(this.diffFolder + diffImage), function (error) {
if (error) return cb(error);
});
if (!fs.existsSync(getDirName(this.diffFolder + diffImage))) {
fs.mkdirSync(getDirName(this.diffFolder + diffImage));
}
fs.writeFileSync(this.diffFolder + diffImage + '.png', data.getBuffer());
const diffImagePath = path.join(process.cwd(), this.diffFolder + diffImage + '.png');
this.debug("Diff Image File Saved to: " + diffImagePath);
Expand Down Expand Up @@ -125,7 +130,14 @@ class ResembleHelper extends Helper {
const el = els[0];

await el.saveScreenshot(this.screenshotFolder + name + '.png');
} else throw new Error("Method only works with Puppeteer and WebDriver helpers.");
} else if (this.helpers['TestCafe']) {
await helper.waitForVisible(selector);
const els = await helper._locate(selector);
if (!await els.count) throw new Error(`Element ${selector} couldn't be located`);
const { t } = this.helpers['TestCafe'];

await t.takeElementScreenshot(els, name);
} else throw new Error("Method only works with Puppeteer, WebDriver or TestCafe helpers.");
}

/**
Expand Down Expand Up @@ -177,7 +189,7 @@ class ResembleHelper extends Helper {
* @param region
* @param bucketName
* @param baseImage
* @param ifBaseImage - tells if the prepareBaseImage is true or false. If false, then it won't upload the baseImage.
* @param ifBaseImage - tells if the prepareBaseImage is true or false. If false, then it won't upload the baseImage. However, this parameter is not considered if the config file has a prepareBaseImage set to true.
* @returns {Promise<void>}
*/

Expand Down Expand Up @@ -296,32 +308,32 @@ class ResembleHelper extends Helper {
options.tolerance = 0;
}

const awsC = this.config.aws;
if (this.prepareBaseImage) {
options.prepareBaseImage = true;
}

const awsC = this.config.aws;
if (awsC !== undefined && options.prepareBaseImage === false) {
await this._download(awsC.accessKeyId, awsC.secretAccessKey, awsC.region, awsC.bucketName, baseImage);
}

if (options.prepareBaseImage !== undefined && options.prepareBaseImage) {
await this._prepareBaseImage(baseImage);
}

if (selector) {
options.boundingBox = await this._getBoundingBox(selector);
}

const misMatch = await this._fetchMisMatchPercentage(baseImage, options);

this._addAttachment(baseImage, misMatch, options.tolerance);

this._addMochaContext(baseImage, misMatch, options.tolerance);

if (awsC !== undefined) {
await this._upload(awsC.accessKeyId, awsC.secretAccessKey, awsC.region, awsC.bucketName, baseImage, options.prepareBaseImage)
}

this.debug("MisMatch Percentage Calculated is " + misMatch);
assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch);
this.debug("MisMatch Percentage Calculated is " + misMatch + " for baseline " + baseImage);

if (options.skipFailure === false) {
assert(misMatch <= options.tolerance, "Screenshot does not match with the baseline " + baseImage + " when MissMatch Percentage is " + misMatch);
}
}

/**
Expand Down Expand Up @@ -369,17 +381,24 @@ class ResembleHelper extends Helper {
const helper = this._getHelper();
await helper.waitForVisible(selector);
const els = await helper._locate(selector);
if (!els.length) throw new Error(`Element ${selector} couldn't be located`);
const el = els[0];

if (this.helpers['TestCafe']) {
if (await els.count != 1) throw new Error(`Element ${selector} couldn't be located or isn't unique on the page`);
}
else {
if (!els.length) throw new Error(`Element ${selector} couldn't be located`);
}

let location, size;

if (this.helpers['Puppeteer']) {
const el = els[0];
const box = await el.boundingBox();
size = location = box;
}

if (this.helpers['WebDriver'] || this.helpers['Appium']) {
const el = els[0];
location = await el.getLocation();
size = await el.getSize();
}
Expand All @@ -388,6 +407,9 @@ class ResembleHelper extends Helper {
location = await helper.browser.getLocation(selector);
size = await helper.browser.getElementSize(selector);
}
if (this.helpers['TestCafe']) {
return await els.boundingClientRect;
}

if (!size) {
throw new Error("Cannot get element size!");
Expand Down Expand Up @@ -421,9 +443,12 @@ class ResembleHelper extends Helper {
if (this.helpers['WebDriverIO']) {
return this.helpers['WebDriverIO'];
}
if (this.helpers['TestCafe']) {
return this.helpers['TestCafe'];
}

throw new Error('No matching helper found. Supported helpers: WebDriver/Appium/Puppeteer');
throw new Error('No matching helper found. Supported helpers: WebDriver/Appium/Puppeteer/TestCafe');
}
}

module.exports = ResembleHelper;
module.exports = ResembleHelper;
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"name": "codeceptjs-resemblehelper",
"version": "1.9.0",
"version": "1.9.1",
"description": "Resemble Js helper for CodeceptJS, with Support for Webdriver, Puppeteer & Appium",
"repository": {
"type": "git",
"url": "[email protected]:Percona-Lab/codeceptjs-resemblehelper.git"
},
"dependencies": {
"assert": "^1.4.1",
"canvas": "^2.2.0",
"assert": "^1.5.0",
"canvas": "^2.6.1",
"mz": "^2.7.0",
"resemblejs": "^3.0.0",
"mkdirp": "^0.5.1",
"resemblejs": "^3.2.4",
"mkdirp": "^1.0.4",
"path": "^0.12.7",
"aws-sdk": "^2.476.0",
"image-size": "^0.7.4"
"aws-sdk": "^2.662.0",
"image-size": "^0.8.3"
},
"devDependencies": {
"allure-commandline": "^2.13.0",
Expand Down

0 comments on commit 99b6845

Please sign in to comment.