Skip to content

Commit

Permalink
Merge pull request #2 from puneet0191/master
Browse files Browse the repository at this point in the history
PMM-3410 Updating with new release changes
  • Loading branch information
puneet0191 authored Jan 14, 2019
2 parents 1b4ed37 + a376311 commit b61b292
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 66 deletions.
61 changes: 29 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,55 +28,48 @@ Example:
}
```
To use the Helper, users must provide the three parameters:

`screenshotFolder` : This will always have the same value as `output` in Codecept configuration, this is the folder where webdriverIO
saves a screenshot when using `I.saveScreenshot` method

`baseFolder`: 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,
Please remember to create empty folder if you don't have one already

Usage, these are major functions that help in visual testing

First one is the `verifyMisMatchPercentage` which basically takes several parameters including tolerance and PrepareBase
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
2) `options` options can be passed which include `prepaseBaseImage` and `tolerance`

```js
/**
* Mis Match Percentage Verification
* Check Visual Difference for Base and Screenshot Image
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
* @param diffImageName Name of the Diff Image which will be saved after comparison (Diff Image path is taken from Configuration)
* @param tolerance Tolerance Percentage, default value 10
* @param prepareBase True | False, depending on the requirement if the base images are missing
* @param selector CSS|XPath|id, If provided locator will be used to fetch Bounding Box of the element and only that element is compared on two images
* @param options Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
* @returns {Promise<void>}
*/
async verifyMisMatchPercentage(baseImage, screenShotImage, diffImageName, tolerance = 10, prepareBase = false, selector, options){
```
Second one is the `PrepareBase` which basically prepares all the base images in case they are not available
```js
/**
* Function to prepare Base Images from Screenshots
*
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
*/
prepareBaseImage(baseImage, screenShotImage) {}
async seeVisualDiff(baseImage, options) {}
```
Third function is to fetch the boundingBox of an element using selector, this boundingBox is then provided to resemble
so that only that element is compared on the images.
Second one is the `seeVisualDiffForElement` which basically compares elements on the screenshot, Selector for element must be provided

It is exactly same as `seeVisualDiff` function, only an additional `selector` CSS|XPath|ID locators is provided
```js
/**
* Function to fetch Bounding box for an element, fetched using selector
* See Visual Diff for an Element on a Page
*
* @param selector CSS|XPath|ID locators
* @returns {Promise<{boundingBox: {left: *, top: *, right: *, bottom: *}}>}
* @param selector Selector which has to be compared, CSS|XPath|ID
* @param baseImage Base Image for comparison
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
* @returns {Promise<void>}
*/
async getBoundingBox(selector){
async seeVisualDiffForElement(selector, baseImage, options){}
```
Users can make use of the boundingBox feature by providing a selector to `verifyMisMatchPercentage` function, it will internally
check if a locator is provided, fetch it's bounding-box and compare only that element on both the images.
> Note:
`seeVisualDiffForElement` only works when the page for baseImage is open in the browser, so that webdriver can fetch coordinates of the provided selector



Finally to use the helper in your test, you can write something like this:

Expand All @@ -85,17 +78,21 @@ Feature('to verify monitoried Remote Db instances');
Scenario('Open the System Overview Dashboard', async (I, adminPage, loginPage) => {
adminPage.navigateToDashboard("OS", "System Overview");
I.saveScreenshot("Complete_Dashboard_Image.png");
adminPage.applyTimer("1m");
adminPage.viewMetric("CPU Usage");
I.saveScreenshot("System_Overview_CPU_Usage.png");
I.saveScreenshot("Complete_Metric_Image.png");
});
Scenario('Compare CPU Usage Images', async (I) => {
// passing TRUE to let the helper know to prepare base images
I.verifyMisMatchPercentage("System_Overview_CPU_Usage.png", "System_Overview_CPU_Usage.png", "DiffImage_SystemOverview_CPU_USAGE_Dashboard", 10, true);
// setting tolerance and prepareBaseImage in the options array
I.seeVisualDiff("Complete_Metric_Image.png", {prepareBaseImage: false, tolerance: 5});
// passing a selector, to only compare that element on both the images now
I.verifyMisMatchPercentage("System_Overview_CPU_Usage.png", "System_Overview_CPU_Usage.png", "DiffImage_SystemOverview_CPU_USAGE_Panel", 10, false, "//div[@class='panel-container']");
// We need to navigate to that page first, so that webdriver can fetch coordinates for the selector
adminPage.navigateToDashboard("OS", "System Overview");
I.seeVisualDiffForElement("//div[@class='panel-container']", "Complete_Dashboard_Image.png", {prepareBaseImage: false, tolerance: 3});
});
```
92 changes: 59 additions & 33 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,43 @@ const fs = require('fs');
let assert = require('assert');
const mkdirp = require('mkdirp');
const getDirName = require('path').dirname;

/**
* Resemble.js helper class for CodeceptJS, this allows screen comparison
* @author Puneet Kala
*/

class ResembleHelper extends Helper {

constructor(config) {
super(config);
}

/**
*
* Compare Images
* @param image1
* @param image2
* @param diffImage
* @param tolerance
* @param options
* @returns {Promise<any | never>}
*/
async _compareImages (image1, image2, diffImage, tolerance, options) {
async _compareImages (image1, image2, diffImage, options) {
image1 = this.config.baseFolder + image1;
image2 = this.config.screenshotFolder + image2;

return new Promise((resolve, reject) => {
if (options !== undefined)
if (options.boundingBox !== undefined)
{
resemble.outputSettings({
boundingBox: options.boundingBox
});
}

if (options.tolerance !== undefined)
{
console.log("Tolerance Level Provided " + options.tolerance);
var tolerance = options.tolerance;
}
resemble.compare(image1, image2, options, (err, data) => {
if (err) {
reject(err);
Expand All @@ -61,63 +68,82 @@ class ResembleHelper extends Helper {
/**
*
* @param image1
* @param image2
* @param diffImage
* @param tolerance
* @param options
* @returns {Promise<*>}
*/
async _fetchMisMatchPercentage (image1, image2, diffImage, tolerance, options) {
var result = this._compareImages(image1, image2, diffImage, tolerance, options);
async _fetchMisMatchPercentage (image1, options) {
var image2 = image1;
var diffImage = "Diff_" + image1.split(".")[0];
var result = this._compareImages(image1, image2, diffImage, options);
var data = await Promise.resolve(result);
return data.misMatchPercentage;
}

/**
* Mis Match Percentage Verification
* Check Visual Difference for Base and Screenshot Image
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
* @param diffImageName Name of the Diff Image which will be saved after comparison (Diff Image path is taken from Configuration)
* @param tolerance Tolerance Percentage, default value 10
* @param prepareBase True | False, depending on the requirement if the base images are missing
* @param selector If set, passed selector will be used to fetch Bouding Box and compared on two images
* @param options Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
* @returns {Promise<void>}
*/
async verifyMisMatchPercentage(baseImage, screenShotImage, diffImageName, tolerance = 10, prepareBase = false, selector, options){
if (prepareBase)
async seeVisualDiff(baseImage, options) {
if (options == undefined)
{
options = {};
options.tolerance = 0;
}

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

var misMatch = await this._fetchMisMatchPercentage(baseImage, options);
console.log("MisMatch Percentage Calculated is " + misMatch);
assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch);
}

/**
* See Visual Diff for an Element on a Page
*
* @param selector Selector which has to be compared expects these -> CSS|XPath|ID
* @param baseImage Base Image for comparison
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
* @returns {Promise<void>}
*/
async seeVisualDiffForElement(selector, baseImage, options){

if (selector !== undefined)
{
if (options !== undefined)
if (options == undefined)
{
options.boundingBox = await this.getBoundingBox(selector);
options = {};
options.tolerance = 0;
}
else

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

var misMatch = await this._fetchMisMatchPercentage(baseImage, screenShotImage, diffImageName, tolerance, options);
console.log("MisMatch Percentage Calculated is " + misMatch);
assert.ok(misMatch < tolerance, "MissMatch Percentage " + misMatch);
options.boundingBox = await this._getBoundingBox(selector);
var misMatch = await this._fetchMisMatchPercentage(baseImage, options);
console.log("MisMatch Percentage Calculated is " + misMatch);
assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch);
}
else {
return null;
}
}

/**
* Function to prepare Base Images from Screenshots
*
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
*/
async prepareBaseImage(baseImage, screenShotImage) {
async _prepareBaseImage(screenShotImage) {
var configuration = this.config;

await this._createDir(configuration.baseFolder + baseImage);
await this._createDir(configuration.baseFolder + screenShotImage);

fs.access(configuration.screenshotFolder + screenShotImage, fs.constants.F_OK | fs.constants.W_OK, (err) => {
if (err) {
Expand All @@ -133,7 +159,7 @@ class ResembleHelper extends Helper {
}
});

fs.copyFileSync(configuration.screenshotFolder + screenShotImage, configuration.baseFolder + baseImage);
fs.copyFileSync(configuration.screenshotFolder + screenShotImage, configuration.baseFolder + screenShotImage);
}

/**
Expand All @@ -152,7 +178,7 @@ class ResembleHelper extends Helper {
* @param selector CSS|XPath|ID selector
* @returns {Promise<{boundingBox: {left: *, top: *, right: *, bottom: *}}>}
*/
async getBoundingBox(selector){
async _getBoundingBox(selector){
const browser = this._getBrowser();

var ele = await browser.element(selector)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codeceptjs-resemblehelper",
"version": "1.2.1",
"version": "1.4.0",
"description": "Resemble Js helper for CodeceptJS, with WebdriverIO",
"repository": {
"type": "git",
Expand Down

0 comments on commit b61b292

Please sign in to comment.