-
Notifications
You must be signed in to change notification settings - Fork 39
/
LocalCompare.js
110 lines (88 loc) · 3.34 KB
/
LocalCompare.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import fs from 'fs-extra';
import resemble from 'node-resemble-js';
import BaseCompare from './BaseCompare';
import debug from 'debug';
import _ from 'lodash';
const log = debug('wdio-visual-regression-service:LocalCompare');
export default class LocalCompare extends BaseCompare {
constructor(options = {}) {
super();
this.getScreenshotFile = options.screenshotName;
this.getReferencefile = options.referenceName;
this.getDiffFile = options.diffName;
this.misMatchTolerance = _.get(options, 'misMatchTolerance', 0.01);
}
async afterScreenshot(context, base64Screenshot) {
const screenshotPath = this.getScreenshotFile(context);
const referencePath = this.getReferencefile(context);
await fs.outputFile(screenshotPath, base64Screenshot, 'base64');
const referenceExists = await fs.exists(referencePath);
if (referenceExists) {
log('reference exists, compare it with the taken now');
const captured = new Buffer(base64Screenshot, 'base64');
const compareData = await this.compareImages(referencePath, captured);
const { isSameDimensions } = compareData;
const misMatchPercentage = Number(compareData.misMatchPercentage);
const misMatchTolerance = _.get(context, 'options.misMatchTolerance', this.misMatchTolerance);
const diffPath = this.getDiffFile(context);
if (misMatchPercentage > misMatchTolerance) {
log(`Image is different! ${misMatchPercentage}%`);
const png = compareData.getDiffImage().pack();
await this.writeDiff(png, diffPath);
return this.createResultReport(misMatchPercentage, false, isSameDimensions);
} else {
log(`Image is within tolerance or the same`);
await fs.remove(diffPath);
return this.createResultReport(misMatchPercentage, true, isSameDimensions);
}
} else {
log('first run - create reference file');
await fs.outputFile(referencePath, base64Screenshot, 'base64');
return this.createResultReport(0, true, true);
}
}
/**
* Compares two images with resemble
* @param {Buffer|string} reference path to reference file or buffer
* @param {Buffer|string} screenshot path to file or buffer to compare with reference
* @return {{misMatchPercentage: Number, isSameDimensions:Boolean, getImageDataUrl: function}}
*/
async compareImages(reference, screenshot, ignore = '') {
return await new Promise((resolve) => {
const image = resemble(reference).compareTo(screenshot);
switch(ignore) {
case 'colors':
image.ignoreColors();
break;
case 'antialiasing':
image.ignoreAntialiasing();
break;
}
image.onComplete((data) => {
resolve(data);
});
});
}
/**
* Writes provided diff by resemble as png
* @param {Stream} png node-png file Stream.
* @return {Promise}
*/
async writeDiff(png, filepath) {
await new Promise((resolve, reject) => {
const chunks = [];
png.on('data', function(chunk) {
chunks.push(chunk);
});
png.on('end', () => {
const buffer = Buffer.concat(chunks);
Promise
.resolve()
.then(() => fs.outputFile(filepath, buffer.toString('base64'), 'base64'))
.then(() => resolve())
.catch(reject);
});
png.on('error', (err) => reject(err));
});
}
}