@brightspace-ui/testing 1.38.2 → 1.38.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/browser/vdiff.js +2 -5
- package/src/server/visual-diff-plugin.js +127 -125
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@brightspace-ui/testing",
|
|
3
3
|
"description": "Utilities for testing front-end components and applications",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "1.38.
|
|
5
|
+
"version": "1.38.3",
|
|
6
6
|
"repository": "https://github.com/BrightspaceUI/testing.git",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"lint": "npm run lint:eslint && npm run lint:style",
|
package/src/browser/vdiff.js
CHANGED
|
@@ -90,11 +90,8 @@ async function ScreenshotAndCompare(opts = {}) {
|
|
|
90
90
|
}
|
|
91
91
|
const slowDuration = this.test.slow();
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.test.timeout(0);
|
|
96
|
-
result = await executeServerCommand('brightspace-visual-diff-compare-resize', { name });
|
|
97
|
-
}
|
|
93
|
+
this.test.timeout(0);
|
|
94
|
+
const result = await executeServerCommand('brightspace-visual-diff-compare', { name, fullPage, rect, slowDuration });
|
|
98
95
|
|
|
99
96
|
if (window.d2lTest) document.documentElement.classList.remove('screenshot');
|
|
100
97
|
|
|
@@ -67,6 +67,35 @@ function getResizedPng(xName, yName, original, newSize) {
|
|
|
67
67
|
return resized;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
async function getBestResizePng(screenshotImage, goldenImage) {
|
|
71
|
+
const newWidth = Math.max(screenshotImage.width, goldenImage.width);
|
|
72
|
+
const newHeight = Math.max(screenshotImage.height, goldenImage.height);
|
|
73
|
+
const newSize = { width: newWidth, height: newHeight };
|
|
74
|
+
|
|
75
|
+
const newScreenshots = await createComparisonPNGs(screenshotImage, newSize);
|
|
76
|
+
const newGoldens = await createComparisonPNGs(goldenImage, newSize);
|
|
77
|
+
|
|
78
|
+
let bestIndex = -1;
|
|
79
|
+
let bestDiffImage = null;
|
|
80
|
+
let bestPixelsDiff = Number.MAX_SAFE_INTEGER;
|
|
81
|
+
for (let i = 0; i < newScreenshots.length; i++) {
|
|
82
|
+
const { diff, pixelsDiff } = getPixelsDiff(newScreenshots[i].png, newGoldens[i].png);
|
|
83
|
+
|
|
84
|
+
if (pixelsDiff < bestPixelsDiff) {
|
|
85
|
+
bestIndex = i;
|
|
86
|
+
bestDiffImage = diff;
|
|
87
|
+
bestPixelsDiff = pixelsDiff;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
screenshot: newScreenshots[bestIndex],
|
|
93
|
+
golden: newGoldens[bestIndex],
|
|
94
|
+
diff: bestDiffImage,
|
|
95
|
+
pixelsDiff: bestPixelsDiff
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
70
99
|
async function createComparisonPNGs(original, newSize) {
|
|
71
100
|
const resizedPNGs = [];
|
|
72
101
|
[ 'top', 'center', 'bottom' ].forEach(y => {
|
|
@@ -150,151 +179,124 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
|
|
|
150
179
|
const screenshotFile = join(newPath, PATHS.FAIL, browser, newName);
|
|
151
180
|
const screenshotFileName = `${screenshotFile}.png`;
|
|
152
181
|
|
|
153
|
-
if (command
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
182
|
+
if (command !== 'brightspace-visual-diff-compare') return;
|
|
183
|
+
if (!isCI) { // CI will be a fresh .vdiff folder each time and only one run
|
|
184
|
+
if (session.testRun !== currentRun) {
|
|
185
|
+
currentRun = session.testRun;
|
|
186
|
+
clearedDirs.clear();
|
|
187
|
+
}
|
|
159
188
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
await clearedDirs.get(newPath);
|
|
189
|
+
if (runSubset || currentRun > 0) {
|
|
190
|
+
if (!clearedDirs.has(newPath)) {
|
|
191
|
+
clearedDirs.set(newPath, clearDir(updateGoldens, newPath));
|
|
165
192
|
}
|
|
193
|
+
await clearedDirs.get(newPath);
|
|
166
194
|
}
|
|
195
|
+
}
|
|
167
196
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
197
|
+
const screenshotOpts = {
|
|
198
|
+
animations: 'disabled'
|
|
199
|
+
};
|
|
171
200
|
|
|
172
|
-
|
|
173
|
-
|
|
201
|
+
if (payload.fullPage) screenshotOpts.fullPage = true;
|
|
202
|
+
if (payload.rect) screenshotOpts.clip = payload.rect;
|
|
174
203
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
204
|
+
async function takeScreenshot() {
|
|
205
|
+
const path = updateGoldens ? goldenFileName : screenshotFileName;
|
|
206
|
+
const page = session.browser.getPage(session.id);
|
|
207
|
+
return await page.screenshot({ path, ...screenshotOpts });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const screenshotFileBuffer = await takeScreenshot();
|
|
211
|
+
|
|
212
|
+
if (updateGoldens) {
|
|
213
|
+
return { pass: true };
|
|
214
|
+
}
|
|
180
215
|
|
|
181
|
-
|
|
216
|
+
const rootLength = join(rootDir, PATHS.VDIFF_ROOT).length + 1;
|
|
182
217
|
|
|
183
|
-
|
|
184
|
-
|
|
218
|
+
async function runCompareTest() {
|
|
219
|
+
const screenshotImage = PNG.sync.read(screenshotFileBuffer);
|
|
220
|
+
infoManager.set({
|
|
221
|
+
slowDuration: payload.slowDuration,
|
|
222
|
+
new: {
|
|
223
|
+
height: screenshotImage.height,
|
|
224
|
+
path: screenshotFileName.substring(rootLength),
|
|
225
|
+
width: screenshotImage.width
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const goldenExists = await checkFileExists(goldenFileName);
|
|
230
|
+
if (!goldenExists) {
|
|
231
|
+
return { pass: false, message: 'No golden exists. Use the "--golden" CLI flag to re-run and re-generate goldens.' };
|
|
185
232
|
}
|
|
186
233
|
|
|
187
|
-
const
|
|
234
|
+
const goldenFileBuffer = await readFile(goldenFileName);
|
|
235
|
+
const goldenImage = PNG.sync.read(goldenFileBuffer);
|
|
236
|
+
infoManager.set({
|
|
237
|
+
golden: {
|
|
238
|
+
height: goldenImage.height,
|
|
239
|
+
path: goldenFileName.substring(rootLength),
|
|
240
|
+
width: goldenImage.width
|
|
241
|
+
}
|
|
242
|
+
});
|
|
188
243
|
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
244
|
+
if (screenshotImage.width === goldenImage.width && screenshotImage.height === goldenImage.height) {
|
|
245
|
+
const goldenSize = (await stat(goldenFileName)).size;
|
|
246
|
+
const screenshotSize = (await stat(screenshotFileName)).size;
|
|
247
|
+
if (goldenSize === screenshotSize && screenshotFileBuffer.equals(goldenFileBuffer)) {
|
|
248
|
+
const success = await tryMoveFile(screenshotFileName, passFileName);
|
|
249
|
+
if (!success) return { pass: false, message: 'Problem moving file to "pass" directory.' };
|
|
250
|
+
infoManager.set({
|
|
251
|
+
new: {
|
|
252
|
+
path: passFileName.substring(rootLength)
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
return { pass: true };
|
|
256
|
+
}
|
|
199
257
|
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
258
|
+
const { diff, pixelsDiff } = getPixelsDiff(screenshotImage, goldenImage);
|
|
259
|
+
|
|
260
|
+
if (pixelsDiff !== 0) {
|
|
261
|
+
infoManager.set({
|
|
262
|
+
diff: `${screenshotFile.substring(rootLength)}-diff.png`,
|
|
263
|
+
pixelsDiff
|
|
264
|
+
});
|
|
265
|
+
await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(diff));
|
|
266
|
+
return { pass: false, message: `Image does not match golden. ${pixelsDiff} pixels are different.` };
|
|
267
|
+
} else {
|
|
268
|
+
infoManager.set({
|
|
269
|
+
golden: {
|
|
270
|
+
byteSize: goldenSize
|
|
271
|
+
},
|
|
272
|
+
new: {
|
|
273
|
+
byteSize: screenshotSize
|
|
274
|
+
},
|
|
275
|
+
pixelsDiff
|
|
276
|
+
});
|
|
277
|
+
return { pass: false, message: 'Image diff is clean but the images do not have the same bytes.' };
|
|
203
278
|
}
|
|
279
|
+
} else {
|
|
280
|
+
const { screenshot, golden, diff, pixelsDiff } = await getBestResizePng(screenshotImage, goldenImage);
|
|
204
281
|
|
|
205
|
-
|
|
206
|
-
|
|
282
|
+
await writeFile(`${screenshotFile}-resized-screenshot.png`, PNG.sync.write(screenshot.png));
|
|
283
|
+
await writeFile(`${screenshotFile}-resized-golden.png`, PNG.sync.write(golden.png));
|
|
284
|
+
await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(diff));
|
|
207
285
|
infoManager.set({
|
|
286
|
+
diff: `${screenshotFile.substring(rootLength)}-diff.png`,
|
|
208
287
|
golden: {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
288
|
+
path: `${screenshotFile.substring(rootLength)}-resized-golden.png`
|
|
289
|
+
},
|
|
290
|
+
new: {
|
|
291
|
+
path: `${screenshotFile.substring(rootLength)}-resized-screenshot.png`
|
|
292
|
+
},
|
|
293
|
+
pixelsDiff
|
|
213
294
|
});
|
|
214
295
|
|
|
215
|
-
|
|
216
|
-
const goldenSize = (await stat(goldenFileName)).size;
|
|
217
|
-
const screenshotSize = (await stat(screenshotFileName)).size;
|
|
218
|
-
if (goldenSize === screenshotSize && screenshotFileBuffer.equals(goldenFileBuffer)) {
|
|
219
|
-
const success = await tryMoveFile(screenshotFileName, passFileName);
|
|
220
|
-
if (!success) return { pass: false, message: 'Problem moving file to "pass" directory.' };
|
|
221
|
-
infoManager.set({
|
|
222
|
-
new: {
|
|
223
|
-
path: passFileName.substring(rootLength)
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
return { pass: true };
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const { diff, pixelsDiff } = getPixelsDiff(screenshotImage, goldenImage);
|
|
230
|
-
|
|
231
|
-
if (pixelsDiff !== 0) {
|
|
232
|
-
infoManager.set({
|
|
233
|
-
diff: `${screenshotFile.substring(rootLength)}-diff.png`,
|
|
234
|
-
pixelsDiff
|
|
235
|
-
});
|
|
236
|
-
await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(diff));
|
|
237
|
-
return { pass: false, message: `Image does not match golden. ${pixelsDiff} pixels are different.` };
|
|
238
|
-
} else {
|
|
239
|
-
infoManager.set({
|
|
240
|
-
golden: {
|
|
241
|
-
byteSize: goldenSize
|
|
242
|
-
},
|
|
243
|
-
new: {
|
|
244
|
-
byteSize: screenshotSize
|
|
245
|
-
},
|
|
246
|
-
pixelsDiff
|
|
247
|
-
});
|
|
248
|
-
return { pass: false, message: 'Image diff is clean but the images do not have the same bytes.' };
|
|
249
|
-
}
|
|
250
|
-
} else {
|
|
251
|
-
return { resizeRequired: true };
|
|
252
|
-
}
|
|
296
|
+
return { pass: false, message: `Images are not the same size. When resized, ${pixelsDiff} pixels are different.` };
|
|
253
297
|
}
|
|
254
|
-
return await runCompareTest();
|
|
255
|
-
} else if (command === 'brightspace-visual-diff-compare-resize') {
|
|
256
|
-
const screenshotImage = PNG.sync.read(await readFile(screenshotFileName));
|
|
257
|
-
const goldenImage = PNG.sync.read(await readFile(goldenFileName));
|
|
258
|
-
|
|
259
|
-
const newWidth = Math.max(screenshotImage.width, goldenImage.width);
|
|
260
|
-
const newHeight = Math.max(screenshotImage.height, goldenImage.height);
|
|
261
|
-
const newSize = { width: newWidth, height: newHeight };
|
|
262
|
-
|
|
263
|
-
const newScreenshots = await createComparisonPNGs(screenshotImage, newSize);
|
|
264
|
-
const newGoldens = await createComparisonPNGs(goldenImage, newSize);
|
|
265
|
-
|
|
266
|
-
let bestIndex = -1;
|
|
267
|
-
let bestDiffImage = null;
|
|
268
|
-
let bestPixelsDiff = Number.MAX_SAFE_INTEGER;
|
|
269
|
-
for (let i = 0; i < newScreenshots.length; i++) {
|
|
270
|
-
const { diff, pixelsDiff } = getPixelsDiff(newScreenshots[i].png, newGoldens[i].png);
|
|
271
|
-
|
|
272
|
-
if (pixelsDiff < bestPixelsDiff) {
|
|
273
|
-
bestIndex = i;
|
|
274
|
-
bestDiffImage = diff;
|
|
275
|
-
bestPixelsDiff = pixelsDiff;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
await writeFile(`${screenshotFile}-resized-screenshot.png`, PNG.sync.write(newScreenshots[bestIndex].png));
|
|
280
|
-
await writeFile(`${screenshotFile}-resized-golden.png`, PNG.sync.write(newGoldens[bestIndex].png));
|
|
281
|
-
await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(bestDiffImage));
|
|
282
|
-
|
|
283
|
-
const rootLength = join(rootDir, PATHS.VDIFF_ROOT).length + 1;
|
|
284
|
-
infoManager.set({
|
|
285
|
-
diff: `${screenshotFile.substring(rootLength)}-diff.png`,
|
|
286
|
-
golden: {
|
|
287
|
-
path: `${screenshotFile.substring(rootLength)}-resized-golden.png`
|
|
288
|
-
},
|
|
289
|
-
new: {
|
|
290
|
-
path: `${screenshotFile.substring(rootLength)}-resized-screenshot.png`
|
|
291
|
-
},
|
|
292
|
-
pixelsDiff: bestPixelsDiff
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
return { pass: false, message: `Images are not the same size. When resized, ${bestPixelsDiff} pixels are different.` };
|
|
296
298
|
}
|
|
297
|
-
|
|
299
|
+
return await runCompareTest();
|
|
298
300
|
}
|
|
299
301
|
};
|
|
300
302
|
}
|