@brightspace-ui/testing 1.38.1 → 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 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.1",
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",
@@ -90,11 +90,8 @@ async function ScreenshotAndCompare(opts = {}) {
90
90
  }
91
91
  const slowDuration = this.test.slow();
92
92
 
93
- let result = await executeServerCommand('brightspace-visual-diff-compare', { name, fullPage, rect, slowDuration });
94
- if (result.resizeRequired) {
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
 
@@ -51,24 +51,60 @@ async function clearDiffPaths(dir) {
51
51
  }
52
52
  }
53
53
 
54
+ function getResizedPng(xName, yName, original, newSize) {
55
+ const xOffsets = {
56
+ left: 0,
57
+ center: Math.floor((newSize.width - original.width) / 2),
58
+ right: newSize.width - original.width
59
+ };
60
+ const yOffsets = {
61
+ top: 0,
62
+ center: Math.floor((newSize.height - original.height) / 2),
63
+ bottom: newSize.height - original.height
64
+ };
65
+ const resized = new PNG(newSize);
66
+ PNG.bitblt(original, resized, 0, 0, original.width, original.height, xOffsets[xName], yOffsets[yName]);
67
+ return resized;
68
+ }
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
+
54
99
  async function createComparisonPNGs(original, newSize) {
55
100
  const resizedPNGs = [];
56
- [
57
- { name: 'top', coord: 0 },
58
- { name: 'center', coord: Math.floor((newSize.height - original.height) / 2) },
59
- { name: 'bottom', coord: newSize.height - original.height }
60
- ].forEach(y => {
61
- [
62
- { name: 'left', coord: 0 },
63
- { name: 'center', coord: Math.floor((newSize.width - original.width) / 2) },
64
- { name: 'right', coord: newSize.width - original.width }
65
- ].forEach(x => { // TODO: position added for reports, remove/adjust as needed
101
+ [ 'top', 'center', 'bottom' ].forEach(y => {
102
+ ['left', 'center', 'right'].forEach(x => {
66
103
  if (original.width === newSize.width && original.height === newSize.height) {
67
- resizedPNGs.push({ png: original, position: `${y.name}-${x.name}` });
104
+ resizedPNGs.push({ png: original, position: `${y}-${x}` });
68
105
  } else {
69
- const resized = new PNG(newSize);
70
- PNG.bitblt(original, resized, 0, 0, original.width, original.height, x.coord, y.coord);
71
- resizedPNGs.push({ png: resized, position: `${y.name}-${x.name}` });
106
+ const resized = getResizedPng(x, y, original, newSize);
107
+ resizedPNGs.push({ png: resized, position: `${y}-${x}` });
72
108
  }
73
109
  });
74
110
  });
@@ -76,6 +112,14 @@ async function createComparisonPNGs(original, newSize) {
76
112
  return resizedPNGs;
77
113
  }
78
114
 
115
+ function getPixelsDiff(screenshotImage, goldenImage) {
116
+ const diff = new PNG({ width: screenshotImage.width, height: screenshotImage.height });
117
+ const pixelsDiff = pixelmatch(
118
+ screenshotImage.data, goldenImage.data, diff.data, screenshotImage.width, screenshotImage.height, { diffMask: true, threshold: DEFAULT_TOLERANCE }
119
+ );
120
+ return { diff, pixelsDiff };
121
+ }
122
+
79
123
  async function tryMoveFile(srcFileName, destFileName) {
80
124
  await mkdir(dirname(destFileName), { recursive: true });
81
125
  try {
@@ -135,39 +179,43 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
135
179
  const screenshotFile = join(newPath, PATHS.FAIL, browser, newName);
136
180
  const screenshotFileName = `${screenshotFile}.png`;
137
181
 
138
- if (command === 'brightspace-visual-diff-compare') {
139
- if (!isCI) { // CI will be a fresh .vdiff folder each time and only one run
140
- if (session.testRun !== currentRun) {
141
- currentRun = session.testRun;
142
- clearedDirs.clear();
143
- }
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
+ }
144
188
 
145
- if (runSubset || currentRun > 0) {
146
- if (!clearedDirs.has(newPath)) {
147
- clearedDirs.set(newPath, clearDir(updateGoldens, newPath));
148
- }
149
- await clearedDirs.get(newPath);
189
+ if (runSubset || currentRun > 0) {
190
+ if (!clearedDirs.has(newPath)) {
191
+ clearedDirs.set(newPath, clearDir(updateGoldens, newPath));
150
192
  }
193
+ await clearedDirs.get(newPath);
151
194
  }
195
+ }
152
196
 
153
- const screenshotOpts = {
154
- animations: 'disabled',
155
- path: updateGoldens ? goldenFileName : screenshotFileName
156
- };
197
+ const screenshotOpts = {
198
+ animations: 'disabled'
199
+ };
157
200
 
158
- if (payload.fullPage) screenshotOpts.fullPage = true;
159
- if (payload.rect) screenshotOpts.clip = payload.rect;
201
+ if (payload.fullPage) screenshotOpts.fullPage = true;
202
+ if (payload.rect) screenshotOpts.clip = payload.rect;
160
203
 
204
+ async function takeScreenshot() {
205
+ const path = updateGoldens ? goldenFileName : screenshotFileName;
161
206
  const page = session.browser.getPage(session.id);
162
- await page.screenshot(screenshotOpts);
207
+ return await page.screenshot({ path, ...screenshotOpts });
208
+ }
163
209
 
164
- if (updateGoldens) {
165
- return { pass: true };
166
- }
210
+ const screenshotFileBuffer = await takeScreenshot();
167
211
 
168
- const rootLength = join(rootDir, PATHS.VDIFF_ROOT).length + 1;
212
+ if (updateGoldens) {
213
+ return { pass: true };
214
+ }
215
+
216
+ const rootLength = join(rootDir, PATHS.VDIFF_ROOT).length + 1;
169
217
 
170
- const screenshotFileBuffer = await readFile(screenshotFileName);
218
+ async function runCompareTest() {
171
219
  const screenshotImage = PNG.sync.read(screenshotFileBuffer);
172
220
  infoManager.set({
173
221
  slowDuration: payload.slowDuration,
@@ -207,10 +255,7 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
207
255
  return { pass: true };
208
256
  }
209
257
 
210
- const diff = new PNG({ width: screenshotImage.width, height: screenshotImage.height });
211
- const pixelsDiff = pixelmatch(
212
- screenshotImage.data, goldenImage.data, diff.data, screenshotImage.width, screenshotImage.height, { diffMask: true, threshold: DEFAULT_TOLERANCE }
213
- );
258
+ const { diff, pixelsDiff } = getPixelsDiff(screenshotImage, goldenImage);
214
259
 
215
260
  if (pixelsDiff !== 0) {
216
261
  infoManager.set({
@@ -232,54 +277,26 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
232
277
  return { pass: false, message: 'Image diff is clean but the images do not have the same bytes.' };
233
278
  }
234
279
  } else {
235
- return { resizeRequired: true };
236
- }
237
- } else if (command === 'brightspace-visual-diff-compare-resize') {
238
- const screenshotImage = PNG.sync.read(await readFile(screenshotFileName));
239
- const goldenImage = PNG.sync.read(await readFile(goldenFileName));
240
-
241
- const newWidth = Math.max(screenshotImage.width, goldenImage.width);
242
- const newHeight = Math.max(screenshotImage.height, goldenImage.height);
243
- const newSize = { width: newWidth, height: newHeight };
244
-
245
- const newScreenshots = await createComparisonPNGs(screenshotImage, newSize);
246
- const newGoldens = await createComparisonPNGs(goldenImage, newSize);
247
-
248
- let bestIndex = -1;
249
- let bestDiffImage = null;
250
- let pixelsDiff = Number.MAX_SAFE_INTEGER;
251
- for (let i = 0; i < newScreenshots.length; i++) {
252
- const currentDiff = new PNG(newSize);
253
- const currentPixelsDiff = pixelmatch(
254
- newScreenshots[i].png.data, newGoldens[i].png.data, currentDiff.data, currentDiff.width, currentDiff.height, { diffMask: true, threshold: DEFAULT_TOLERANCE }
255
- );
256
-
257
- if (currentPixelsDiff < pixelsDiff) {
258
- bestIndex = i;
259
- bestDiffImage = currentDiff;
260
- pixelsDiff = currentPixelsDiff;
261
- }
280
+ const { screenshot, golden, diff, pixelsDiff } = await getBestResizePng(screenshotImage, goldenImage);
281
+
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));
285
+ infoManager.set({
286
+ diff: `${screenshotFile.substring(rootLength)}-diff.png`,
287
+ golden: {
288
+ path: `${screenshotFile.substring(rootLength)}-resized-golden.png`
289
+ },
290
+ new: {
291
+ path: `${screenshotFile.substring(rootLength)}-resized-screenshot.png`
292
+ },
293
+ pixelsDiff
294
+ });
295
+
296
+ return { pass: false, message: `Images are not the same size. When resized, ${pixelsDiff} pixels are different.` };
262
297
  }
263
-
264
- await writeFile(`${screenshotFile}-resized-screenshot.png`, PNG.sync.write(newScreenshots[bestIndex].png));
265
- await writeFile(`${screenshotFile}-resized-golden.png`, PNG.sync.write(newGoldens[bestIndex].png));
266
- await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(bestDiffImage));
267
-
268
- const rootLength = join(rootDir, PATHS.VDIFF_ROOT).length + 1;
269
- infoManager.set({
270
- diff: `${screenshotFile.substring(rootLength)}-diff.png`,
271
- golden: {
272
- path: `${screenshotFile.substring(rootLength)}-resized-golden.png`
273
- },
274
- new: {
275
- path: `${screenshotFile.substring(rootLength)}-resized-screenshot.png`
276
- },
277
- pixelsDiff
278
- });
279
-
280
- return { pass: false, message: `Images are not the same size. When resized, ${pixelsDiff} pixels are different.` };
281
298
  }
282
-
299
+ return await runCompareTest();
283
300
  }
284
301
  };
285
302
  }