-
-
Notifications
You must be signed in to change notification settings - Fork 294
/
visualDiffCommand.ts
144 lines (121 loc) · 3.65 KB
/
visualDiffCommand.ts
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import path from 'path';
import { VisualRegressionPluginOptions, DiffResult } from './config';
import { VisualRegressionError } from './VisualRegressionError';
function resolveImagePath(baseDir: string, name: string) {
const finalName = path.extname(name) ? name : `${name}.png`;
if (path.isAbsolute(finalName)) {
return finalName;
}
return path.join(baseDir, finalName);
}
export interface VisualDiffCommandResult {
errorMessage?: string;
diffPercentage: number;
passed: boolean;
}
export interface VisualDiffCommandContext {
browser: string;
testFile: string;
}
function passesFailureThreshold(
{ diffPercentage, diffPixels }: DiffResult,
{ failureThresholdType, failureThreshold }: VisualRegressionPluginOptions,
): { passed: boolean; message?: string } {
if (failureThresholdType === 'percent') {
return diffPercentage <= failureThreshold
? { passed: true }
: {
passed: false,
// if diff is suitably small, output raw value, otherwise to two decimal points.
// this avoids outputting a failure value of "0.00%"
message: `${diffPercentage < 0.005 ? diffPercentage : diffPercentage.toFixed(2)}%`,
};
}
if (failureThresholdType === 'pixel') {
return diffPixels <= failureThreshold
? { passed: true }
: { passed: false, message: `${diffPixels} pixels` };
}
throw new VisualRegressionError(`Unrecognized failureThresholdType: ${failureThresholdType}`);
}
export async function visualDiffCommand(
options: VisualRegressionPluginOptions,
image: Buffer,
name: string,
{ browser, testFile }: VisualDiffCommandContext,
): Promise<VisualDiffCommandResult> {
const baseDir = path.resolve(options.baseDir);
const baselineName = options.getBaselineName({ browser, name, testFile });
const baselineImage = await options.getBaseline({
filePath: resolveImagePath(baseDir, baselineName),
baseDir,
name: baselineName,
});
if (options.update) {
await options.saveBaseline({
filePath: resolveImagePath(baseDir, baselineName),
baseDir,
name: baselineName,
content: image,
});
return { diffPercentage: -1, passed: true };
}
const diffName = options.getDiffName({ browser, name, testFile });
const failedName = options.getFailedName({ browser, name, testFile });
const diffFilePath = resolveImagePath(baseDir, diffName);
const saveFailed = async () => {
await options.saveFailed({
filePath: resolveImagePath(baseDir, failedName),
baseDir,
name: failedName,
content: image,
});
};
const saveDiff = async () => {
await options.saveDiff({
filePath: diffFilePath,
baseDir,
name: diffName,
content: diffImage,
});
};
if (!baselineImage) {
await saveFailed();
return {
errorMessage: 'There was no baseline image to compare against.',
diffPercentage: -1,
passed: false,
};
}
const result = await options.getImageDiff({
name,
baselineImage,
image,
options: options.diffOptions,
});
const { error, diffImage } = result;
if (error) {
// The diff has failed, be sure to save the new image.
await saveFailed();
await saveDiff();
return {
passed: false,
errorMessage: error,
diffPercentage: -1,
};
}
const { passed, message } = passesFailureThreshold(result, options);
if (!passed) {
await saveDiff();
}
if (!passed || options.buildCache) {
await saveFailed();
}
return {
errorMessage: !passed
? `Visual diff failed. New screenshot is ${message} different.\nSee diff for details: ${diffFilePath}`
: undefined,
diffPercentage: -1,
passed,
};
}