@brightspace-ui/testing 1.37.3 → 1.38.1

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/README.md CHANGED
@@ -343,6 +343,8 @@ class SlowElem extends LitElement {
343
343
  }
344
344
  ```
345
345
 
346
+ The [`LoadingCompleteMixin` in `@brightspace-ui/core`](https://github.com/BrightspaceUI/core/tree/main/mixins/loading-complete) has been added to make implementing this even simpler.
347
+
346
348
  To bypass waiting for `getLoadingComplete()`, set the `awaitLoadingComplete` configuration option to `false`:
347
349
 
348
350
  ```javascript
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.37.3",
5
+ "version": "1.38.1",
6
6
  "repository": "https://github.com/BrightspaceUI/testing.git",
7
7
  "scripts": {
8
8
  "lint": "npm run lint:eslint && npm run lint:style",
@@ -82,13 +82,14 @@ async function waitForElem(elem, awaitLoadingComplete = true) {
82
82
  *
83
83
  * @param {*} element
84
84
  * @param {{
85
- * awaitLoadingComplete: boolean,
86
- * lang: string,
85
+ * awaitLoadingComplete: boolean,
86
+ * colorMode: string,
87
+ * lang: string,
87
88
  * mathjax: {renderLatex: boolean},
88
89
  * rtl: boolean,
89
90
  * pagePadding: boolean,
90
91
  * media: string,
91
- * viewport: { height: number, width: number }
92
+ * viewport: { height: number, width: number }
92
93
  * }} opts
93
94
  */
94
95
  export async function fixture(element, opts = {}) {
@@ -4,6 +4,7 @@ import { nextFrame } from '@open-wc/testing';
4
4
 
5
5
  const DEFAULT_PAGE_PADDING = true,
6
6
  DEFAULT_LANG = 'en',
7
+ DEFAULT_COLOR_MODE = undefined,
7
8
  DEFAULT_MATHJAX_RENDER_LATEX = false,
8
9
  DEFAULT_MEDIA = 'screen',
9
10
  DEFAULT_VIEWPORT = {
@@ -18,6 +19,7 @@ let
18
19
  currentMathjaxRenderLatex = DEFAULT_MATHJAX_RENDER_LATEX,
19
20
  currentMedia = DEFAULT_MEDIA,
20
21
  currentRtl = false,
22
+ currentColorMode = DEFAULT_COLOR_MODE,
21
23
  currentViewportHeight = 0,
22
24
  currentViewportWidth = 0,
23
25
  shouldResetMouse = false;
@@ -47,6 +49,7 @@ export async function reset(opts = {}) {
47
49
  lang: DEFAULT_LANG,
48
50
  mathjax: {},
49
51
  rtl: !!opts.lang?.startsWith('ar'),
52
+ colorMode: DEFAULT_COLOR_MODE,
50
53
  pagePadding: DEFAULT_PAGE_PADDING,
51
54
  media: DEFAULT_MEDIA
52
55
  };
@@ -89,6 +92,17 @@ export async function reset(opts = {}) {
89
92
  currentRtl = opts.rtl;
90
93
  }
91
94
 
95
+ if (opts.colorMode !== currentColorMode) {
96
+ const colorMode = ['light', 'dark'].includes(opts.colorMode) ? opts.colorMode : DEFAULT_COLOR_MODE;
97
+ if (!colorMode) {
98
+ document.documentElement.removeAttribute('data-color-mode');
99
+ } else {
100
+ document.documentElement.setAttribute('data-color-mode', colorMode);
101
+ }
102
+ awaitNextFrame = true;
103
+ currentColorMode = colorMode;
104
+ }
105
+
92
106
  opts.lang ??= '';
93
107
  if (documentLocaleSettings.language !== opts.lang) {
94
108
  document.documentElement.lang = opts.lang;
@@ -0,0 +1,30 @@
1
+ const testInfoMap = new Map();
2
+
3
+ export class TestInfoManager {
4
+ constructor(session, fullTitle) {
5
+ this.key = `${session.browser.name.toLowerCase()}|${session.testFile}|${fullTitle}`;
6
+ }
7
+ get() {
8
+ return testInfoMap.get(this.key);
9
+ }
10
+
11
+ set(testInfo) {
12
+ if (testInfoMap.has(this.key)) {
13
+ const info = this.get();
14
+ testInfo.slowDuration = info.slowDuration;
15
+
16
+ if (info.golden || testInfo.golden) {
17
+ testInfo.golden = { ...info.golden, ...testInfo.golden };
18
+ }
19
+ if (info.new || testInfo.new) {
20
+ testInfo.new = { ...info.new, ...testInfo.new };
21
+ }
22
+ testInfo.diff = testInfo.diff || info.diff;
23
+ }
24
+ testInfoMap.set(this.key, testInfo);
25
+ }
26
+ }
27
+
28
+ export function getTestInfo(session, fullTitle) {
29
+ return new TestInfoManager(session, fullTitle).get();
30
+ }
@@ -4,6 +4,7 @@ import { env } from 'node:process';
4
4
  import { PATHS } from './paths.js';
5
5
  import pixelmatch from 'pixelmatch';
6
6
  import { PNG } from 'pngjs';
7
+ import { TestInfoManager } from './visual-diff-info.js';
7
8
 
8
9
  const isCI = !!env['CI'];
9
10
  const DEFAULT_TOLERANCE = 0; // TODO: Support tolerance override?
@@ -105,29 +106,6 @@ function extractTestPartsFromName(name) {
105
106
  };
106
107
  }
107
108
 
108
- const testInfoMap = new Map();
109
- export function getTestInfo(session, fullTitle) {
110
- return testInfoMap.get(getTestInfoKey(session, fullTitle));
111
- }
112
- function getTestInfoKey(session, fullTitle) {
113
- return `${session.browser.name.toLowerCase()}|${session.testFile}|${fullTitle}`;
114
- }
115
- function setTestInfo(session, fullTitle, testInfo) {
116
- const key = getTestInfoKey(session, fullTitle);
117
- if (testInfoMap.has(key)) {
118
- const info = testInfoMap.get(key);
119
- testInfo.slowDuration = info.slowDuration;
120
- if (info.golden || testInfo.golden) {
121
- testInfo.golden = { ...info.golden, ...testInfo.golden };
122
- }
123
- if (info.new || testInfo.new) {
124
- testInfo.new = { ...info.new, ...testInfo.new };
125
- }
126
- testInfo.diff = testInfo.diff || info.diff;
127
- }
128
- testInfoMap.set(key, testInfo);
129
- }
130
-
131
109
  export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
132
110
  let currentRun = 0,
133
111
  rootDir;
@@ -142,6 +120,7 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
142
120
  await clearAllDirs(updateGoldens, join(rootDir, PATHS.VDIFF_ROOT));
143
121
  },
144
122
  async executeCommand({ command, payload, session }) {
123
+ const infoManager = new TestInfoManager(session, payload.name);
145
124
 
146
125
  if (session.browser.type !== 'playwright') {
147
126
  throw new Error('Visual-diff is only supported for browser type Playwright.');
@@ -190,28 +169,23 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
190
169
 
191
170
  const screenshotFileBuffer = await readFile(screenshotFileName);
192
171
  const screenshotImage = PNG.sync.read(screenshotFileBuffer);
193
- setTestInfo(session, payload.name, {
172
+ infoManager.set({
194
173
  slowDuration: payload.slowDuration,
195
174
  new: {
196
175
  height: screenshotImage.height,
197
- path: passFileName.substring(rootLength),
176
+ path: screenshotFileName.substring(rootLength),
198
177
  width: screenshotImage.width
199
178
  }
200
179
  });
201
180
 
202
181
  const goldenExists = await checkFileExists(goldenFileName);
203
182
  if (!goldenExists) {
204
- setTestInfo(session, payload.name, {
205
- new: {
206
- path: `${screenshotFile.substring(rootLength)}.png`
207
- }
208
- });
209
183
  return { pass: false, message: 'No golden exists. Use the "--golden" CLI flag to re-run and re-generate goldens.' };
210
184
  }
211
185
 
212
186
  const goldenFileBuffer = await readFile(goldenFileName);
213
187
  const goldenImage = PNG.sync.read(goldenFileBuffer);
214
- setTestInfo(session, payload.name, {
188
+ infoManager.set({
215
189
  golden: {
216
190
  height: goldenImage.height,
217
191
  path: goldenFileName.substring(rootLength),
@@ -225,6 +199,11 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
225
199
  if (goldenSize === screenshotSize && screenshotFileBuffer.equals(goldenFileBuffer)) {
226
200
  const success = await tryMoveFile(screenshotFileName, passFileName);
227
201
  if (!success) return { pass: false, message: 'Problem moving file to "pass" directory.' };
202
+ infoManager.set({
203
+ new: {
204
+ path: passFileName.substring(rootLength)
205
+ }
206
+ });
228
207
  return { pass: true };
229
208
  }
230
209
 
@@ -234,22 +213,18 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
234
213
  );
235
214
 
236
215
  if (pixelsDiff !== 0) {
237
- setTestInfo(session, payload.name, {
216
+ infoManager.set({
238
217
  diff: `${screenshotFile.substring(rootLength)}-diff.png`,
239
- new: {
240
- path: `${screenshotFile.substring(rootLength)}.png`
241
- },
242
218
  pixelsDiff
243
219
  });
244
220
  await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(diff));
245
221
  return { pass: false, message: `Image does not match golden. ${pixelsDiff} pixels are different.` };
246
222
  } else {
247
- setTestInfo(session, payload.name, {
223
+ infoManager.set({
248
224
  golden: {
249
225
  byteSize: goldenSize
250
226
  },
251
227
  new: {
252
- path: `${screenshotFile.substring(rootLength)}.png`,
253
228
  byteSize: screenshotSize
254
229
  },
255
230
  pixelsDiff
@@ -291,7 +266,7 @@ export function visualDiff({ updateGoldens = false, runSubset = false } = {}) {
291
266
  await writeFile(`${screenshotFile}-diff.png`, PNG.sync.write(bestDiffImage));
292
267
 
293
268
  const rootLength = join(rootDir, PATHS.VDIFF_ROOT).length + 1;
294
- setTestInfo(session, payload.name, {
269
+ infoManager.set({
295
270
  diff: `${screenshotFile.substring(rootLength)}-diff.png`,
296
271
  golden: {
297
272
  path: `${screenshotFile.substring(rootLength)}-resized-golden.png`
@@ -4,7 +4,7 @@ import { dirname, join } from 'node:path';
4
4
  import { env } from 'node:process';
5
5
  import { execSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
- import { getTestInfo } from './visual-diff-plugin.js';
7
+ import { getTestInfo } from './visual-diff-info.js';
8
8
  import { PATHS } from './paths.js';
9
9
 
10
10
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -89,6 +89,9 @@ export class WTRConfig {
89
89
  --d2l-inline-start: left;
90
90
  --d2l-length-factor: 1;
91
91
  --d2l-mirror-transform: none;
92
+ --d2l-theme-background-color-base: #ffffff;
93
+ --d2l-theme-text-color-static-standard: #202122;
94
+ font-size: 20px;
92
95
  }
93
96
 
94
97
  html[dir="rtl"] * {
@@ -101,6 +104,11 @@ export class WTRConfig {
101
104
  --d2l-mirror-transform: scale(-1, 1);
102
105
  }
103
106
 
107
+ html[data-color-mode="dark"] {
108
+ --d2l-theme-background-color-base: #161718;
109
+ --d2l-theme-text-color-static-standard: #cdd5dc;
110
+ }
111
+
104
112
  @font-face {
105
113
  font-family: 'Lato';
106
114
  font-style: normal;
@@ -114,12 +122,9 @@ export class WTRConfig {
114
122
  src: url(${FONT_ASSETS}Lato-700.woff2) format('woff2');
115
123
  }
116
124
 
117
- html {
118
- font-size: 20px;
119
- }
120
125
  body {
121
- background-color: #ffffff;
122
- color: var(--d2l-color-ferrite, #202122);
126
+ background-color: var(--d2l-theme-background-color-base);
127
+ color: var(--d2l-theme-text-color-static-standard);
123
128
  font-family: 'Lato', sans-serif;
124
129
  letter-spacing: 0.01rem;
125
130
  font-size: 0.95rem;