Skip to content

Commit b61b292

Browse files
authored
Merge pull request #2 from puneet0191/master
PMM-3410 Updating with new release changes
2 parents 1b4ed37 + a376311 commit b61b292

File tree

3 files changed

+89
-66
lines changed

3 files changed

+89
-66
lines changed

README.md

+29-32
Original file line numberDiff line numberDiff line change
@@ -28,55 +28,48 @@ Example:
2828
}
2929
```
3030
To use the Helper, users must provide the three parameters:
31+
3132
`screenshotFolder` : This will always have the same value as `output` in Codecept configuration, this is the folder where webdriverIO
3233
saves a screenshot when using `I.saveScreenshot` method
3334

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

3637
`diffFolder`: This will the folder where resemble would try to store the difference image, which can be viewed later,
37-
Please remember to create empty folder if you don't have one already
3838

3939
Usage, these are major functions that help in visual testing
4040

41-
First one is the `verifyMisMatchPercentage` which basically takes several parameters including tolerance and PrepareBase
41+
First one is the `seeVisualDiff` which basically takes two parameters
42+
1) `baseImage` Name of the base image, this will be the image used for comparison with the screenshot image,
43+
it is mandatory to have the same image file names for base and screenshot image
44+
2) `options` options can be passed which include `prepaseBaseImage` and `tolerance`
45+
4246
```js
4347
/**
44-
* Mis Match Percentage Verification
48+
* Check Visual Difference for Base and Screenshot Image
4549
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
46-
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
47-
* @param diffImageName Name of the Diff Image which will be saved after comparison (Diff Image path is taken from Configuration)
48-
* @param tolerance Tolerance Percentage, default value 10
49-
* @param prepareBase True | False, depending on the requirement if the base images are missing
50-
* @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
51-
* @param options Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
50+
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
5251
* @returns {Promise<void>}
5352
*/
54-
async verifyMisMatchPercentage(baseImage, screenShotImage, diffImageName, tolerance = 10, prepareBase = false, selector, options){
55-
```
56-
Second one is the `PrepareBase` which basically prepares all the base images in case they are not available
57-
```js
58-
/**
59-
* Function to prepare Base Images from Screenshots
60-
*
61-
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
62-
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
63-
*/
64-
prepareBaseImage(baseImage, screenShotImage) {}
53+
async seeVisualDiff(baseImage, options) {}
6554
```
66-
Third function is to fetch the boundingBox of an element using selector, this boundingBox is then provided to resemble
67-
so that only that element is compared on the images.
55+
Second one is the `seeVisualDiffForElement` which basically compares elements on the screenshot, Selector for element must be provided
6856

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

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

@@ -85,17 +78,21 @@ Feature('to verify monitoried Remote Db instances');
8578
8679
Scenario('Open the System Overview Dashboard', async (I, adminPage, loginPage) => {
8780
adminPage.navigateToDashboard("OS", "System Overview");
81+
I.saveScreenshot("Complete_Dashboard_Image.png");
8882
adminPage.applyTimer("1m");
8983
adminPage.viewMetric("CPU Usage");
90-
I.saveScreenshot("System_Overview_CPU_Usage.png");
84+
I.saveScreenshot("Complete_Metric_Image.png");
9185
});
9286
9387
Scenario('Compare CPU Usage Images', async (I) => {
9488
95-
// passing TRUE to let the helper know to prepare base images
96-
I.verifyMisMatchPercentage("System_Overview_CPU_Usage.png", "System_Overview_CPU_Usage.png", "DiffImage_SystemOverview_CPU_USAGE_Dashboard", 10, true);
89+
// setting tolerance and prepareBaseImage in the options array
90+
I.seeVisualDiff("Complete_Metric_Image.png", {prepareBaseImage: false, tolerance: 5});
9791
9892
// passing a selector, to only compare that element on both the images now
99-
I.verifyMisMatchPercentage("System_Overview_CPU_Usage.png", "System_Overview_CPU_Usage.png", "DiffImage_SystemOverview_CPU_USAGE_Panel", 10, false, "//div[@class='panel-container']");
93+
94+
// We need to navigate to that page first, so that webdriver can fetch coordinates for the selector
95+
adminPage.navigateToDashboard("OS", "System Overview");
96+
I.seeVisualDiffForElement("//div[@class='panel-container']", "Complete_Dashboard_Image.png", {prepareBaseImage: false, tolerance: 3});
10097
});
10198
```

index.js

+59-33
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,43 @@ const fs = require('fs');
66
let assert = require('assert');
77
const mkdirp = require('mkdirp');
88
const getDirName = require('path').dirname;
9+
910
/**
1011
* Resemble.js helper class for CodeceptJS, this allows screen comparison
1112
* @author Puneet Kala
1213
*/
14+
1315
class ResembleHelper extends Helper {
1416

1517
constructor(config) {
1618
super(config);
1719
}
1820

1921
/**
20-
*
22+
* Compare Images
2123
* @param image1
2224
* @param image2
2325
* @param diffImage
24-
* @param tolerance
2526
* @param options
2627
* @returns {Promise<any | never>}
2728
*/
28-
async _compareImages (image1, image2, diffImage, tolerance, options) {
29+
async _compareImages (image1, image2, diffImage, options) {
2930
image1 = this.config.baseFolder + image1;
3031
image2 = this.config.screenshotFolder + image2;
3132

3233
return new Promise((resolve, reject) => {
33-
if (options !== undefined)
34+
if (options.boundingBox !== undefined)
3435
{
3536
resemble.outputSettings({
3637
boundingBox: options.boundingBox
3738
});
3839
}
40+
41+
if (options.tolerance !== undefined)
42+
{
43+
console.log("Tolerance Level Provided " + options.tolerance);
44+
var tolerance = options.tolerance;
45+
}
3946
resemble.compare(image1, image2, options, (err, data) => {
4047
if (err) {
4148
reject(err);
@@ -61,63 +68,82 @@ class ResembleHelper extends Helper {
6168
/**
6269
*
6370
* @param image1
64-
* @param image2
65-
* @param diffImage
66-
* @param tolerance
6771
* @param options
6872
* @returns {Promise<*>}
6973
*/
70-
async _fetchMisMatchPercentage (image1, image2, diffImage, tolerance, options) {
71-
var result = this._compareImages(image1, image2, diffImage, tolerance, options);
74+
async _fetchMisMatchPercentage (image1, options) {
75+
var image2 = image1;
76+
var diffImage = "Diff_" + image1.split(".")[0];
77+
var result = this._compareImages(image1, image2, diffImage, options);
7278
var data = await Promise.resolve(result);
7379
return data.misMatchPercentage;
7480
}
7581

7682
/**
77-
* Mis Match Percentage Verification
83+
* Check Visual Difference for Base and Screenshot Image
7884
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
79-
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
80-
* @param diffImageName Name of the Diff Image which will be saved after comparison (Diff Image path is taken from Configuration)
81-
* @param tolerance Tolerance Percentage, default value 10
82-
* @param prepareBase True | False, depending on the requirement if the base images are missing
83-
* @param selector If set, passed selector will be used to fetch Bouding Box and compared on two images
84-
* @param options Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
85+
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
8586
* @returns {Promise<void>}
8687
*/
87-
async verifyMisMatchPercentage(baseImage, screenShotImage, diffImageName, tolerance = 10, prepareBase = false, selector, options){
88-
if (prepareBase)
88+
async seeVisualDiff(baseImage, options) {
89+
if (options == undefined)
90+
{
91+
options = {};
92+
options.tolerance = 0;
93+
}
94+
95+
if (options.prepareBaseImage !== undefined && options.prepareBaseImage)
8996
{
90-
await this.prepareBaseImage(baseImage, screenShotImage);
97+
await this._prepareBaseImage(baseImage);
9198
}
9299

100+
var misMatch = await this._fetchMisMatchPercentage(baseImage, options);
101+
console.log("MisMatch Percentage Calculated is " + misMatch);
102+
assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch);
103+
}
104+
105+
/**
106+
* See Visual Diff for an Element on a Page
107+
*
108+
* @param selector Selector which has to be compared expects these -> CSS|XPath|ID
109+
* @param baseImage Base Image for comparison
110+
* @param options Options ex {prepareBaseImage: true, tolerance: 5} along with Resemble JS Options, read more here: https://github.com/rsmbl/Resemble.js
111+
* @returns {Promise<void>}
112+
*/
113+
async seeVisualDiffForElement(selector, baseImage, options){
114+
93115
if (selector !== undefined)
94116
{
95-
if (options !== undefined)
117+
if (options == undefined)
96118
{
97-
options.boundingBox = await this.getBoundingBox(selector);
119+
options = {};
120+
options.tolerance = 0;
98121
}
99-
else
122+
123+
if (options.prepareBaseImage !== undefined && options.prepareBaseImage)
100124
{
101-
var options = {};
102-
options.boundingBox = await this.getBoundingBox(selector);
125+
await this._prepareBaseImage(baseImage);
103126
}
104-
}
105127

106-
var misMatch = await this._fetchMisMatchPercentage(baseImage, screenShotImage, diffImageName, tolerance, options);
107-
console.log("MisMatch Percentage Calculated is " + misMatch);
108-
assert.ok(misMatch < tolerance, "MissMatch Percentage " + misMatch);
128+
options.boundingBox = await this._getBoundingBox(selector);
129+
var misMatch = await this._fetchMisMatchPercentage(baseImage, options);
130+
console.log("MisMatch Percentage Calculated is " + misMatch);
131+
assert(misMatch <= options.tolerance, "MissMatch Percentage " + misMatch);
132+
}
133+
else {
134+
return null;
135+
}
109136
}
110137

111138
/**
112139
* Function to prepare Base Images from Screenshots
113140
*
114-
* @param baseImage Name of the Base Image (Base Image path is taken from Configuration)
115141
* @param screenShotImage Name of the screenshot Image (Screenshot Image Path is taken from Configuration)
116142
*/
117-
async prepareBaseImage(baseImage, screenShotImage) {
143+
async _prepareBaseImage(screenShotImage) {
118144
var configuration = this.config;
119145

120-
await this._createDir(configuration.baseFolder + baseImage);
146+
await this._createDir(configuration.baseFolder + screenShotImage);
121147

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

136-
fs.copyFileSync(configuration.screenshotFolder + screenShotImage, configuration.baseFolder + baseImage);
162+
fs.copyFileSync(configuration.screenshotFolder + screenShotImage, configuration.baseFolder + screenShotImage);
137163
}
138164

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

158184
var ele = await browser.element(selector)

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codeceptjs-resemblehelper",
3-
"version": "1.2.1",
3+
"version": "1.4.0",
44
"description": "Resemble Js helper for CodeceptJS, with WebdriverIO",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)