From f98ec55899ab86aa3024c85053e58dd618f90945 Mon Sep 17 00:00:00 2001 From: Jonatas Kirsch Date: Mon, 27 Apr 2020 12:20:32 +0200 Subject: [PATCH 1/6] Issue #60 - Prepare all baselines of test by setting parameter in config (#65) Co-authored-by: Jonatas Kirsch --- README.md | 18 ++++++++++++------ index.js | 9 +++++++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bc75a17..6bb2c7f 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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. diff --git a/index.js b/index.js index ecb5383..0c47aa2 100644 --- a/index.js +++ b/index.js @@ -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) { @@ -177,7 +178,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} */ @@ -296,6 +297,10 @@ class ResembleHelper extends Helper { options.tolerance = 0; } + if (this.prepareBaseImage) { + options.prepareBaseImage = true; + } + const awsC = this.config.aws; if (awsC !== undefined && options.prepareBaseImage === false) { @@ -426,4 +431,4 @@ class ResembleHelper extends Helper { } } -module.exports = ResembleHelper; \ No newline at end of file +module.exports = ResembleHelper; From 714c79a2b6a3cd69443abb9d57f92a07b5b1f631 Mon Sep 17 00:00:00 2001 From: Puneet Kala Date: Mon, 27 Apr 2020 15:51:31 +0530 Subject: [PATCH 2/6] Update Dependecies, Fix Fatal Error with mkdirp and Mac (#66) * Update Dependencies * Fix Error on Mac --- index.js | 6 +++--- package.json | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 0c47aa2..cde2125 100644 --- a/index.js +++ b/index.js @@ -77,9 +77,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); diff --git a/package.json b/package.json index d203268..86daff0 100644 --- a/package.json +++ b/package.json @@ -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": "git@github.com: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", From 373267086bc3ca447907d1d553f52bc74f3d6210 Mon Sep 17 00:00:00 2001 From: Jonatas Kirsch Date: Mon, 27 Apr 2020 12:24:19 +0200 Subject: [PATCH 3/6] 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 --- README.md | 9 +++++++++ index.js | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6bb2c7f..8abff09 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,15 @@ 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`. +### 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 diff --git a/index.js b/index.js index cde2125..ca3110d 100644 --- a/index.js +++ b/index.js @@ -326,7 +326,10 @@ class ResembleHelper extends Helper { } this.debug("MisMatch Percentage Calculated is " + misMatch); - assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch); + + if (options.skipFailure === false) { + assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch); + } } /** From e8a87df702197aaff4f498f3de6fe64a810bcbf5 Mon Sep 17 00:00:00 2001 From: Guillaume Camus Date: Mon, 27 Apr 2020 12:38:37 +0200 Subject: [PATCH 4/6] feat(testcafe): add the support for testcafe (#62) --- index.js | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index ca3110d..f4ccfb6 100644 --- a/index.js +++ b/index.js @@ -126,7 +126,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."); } /** @@ -302,25 +309,18 @@ class ResembleHelper extends Helper { } 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) } @@ -377,17 +377,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(); } @@ -396,6 +403,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!"); @@ -429,8 +439,11 @@ 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'); } } From c0d999e6112a0150f9b1173d8f940641f3671b5e Mon Sep 17 00:00:00 2001 From: yankydoo Date: Tue, 28 Apr 2020 08:29:33 +0200 Subject: [PATCH 5/6] passing through output settings to resemble.js (#59) Co-authored-by: JANK Michael --- README.md | 16 +++++++++++++++- index.js | 6 +++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8abff09..e7519f9 100644 --- a/README.md +++ b/README.md @@ -108,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, @@ -121,6 +121,19 @@ 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`: @@ -130,6 +143,7 @@ I.seeVisualDiff("image.png", {prepareBaseImage: true, tolerance: 1, skipFailure: 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 diff --git a/index.js b/index.js index f4ccfb6..e24bee8 100644 --- a/index.js +++ b/index.js @@ -58,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); From c5d70b9fd5ccd597d7e9c1ac75b8484a84f556a1 Mon Sep 17 00:00:00 2001 From: Jonatas Kirsch Date: Wed, 29 Apr 2020 06:00:38 +0200 Subject: [PATCH 6/6] Issue 48 - Add custom assert message (#64) Co-authored-by: Jonatas Kirsch --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index e24bee8..8e0e182 100644 --- a/index.js +++ b/index.js @@ -329,10 +329,10 @@ class ResembleHelper extends Helper { await this._upload(awsC.accessKeyId, awsC.secretAccessKey, awsC.region, awsC.bucketName, baseImage, options.prepareBaseImage) } - this.debug("MisMatch Percentage Calculated is " + misMatch); + this.debug("MisMatch Percentage Calculated is " + misMatch + " for baseline " + baseImage); if (options.skipFailure === false) { - assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch); + assert(misMatch <= options.tolerance, "Screenshot does not match with the baseline " + baseImage + " when MissMatch Percentage is " + misMatch); } }