@brightspace-ui/testing 1.19.0 → 1.21.0

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
@@ -4,7 +4,7 @@
4
4
 
5
5
  Testing utilities which are specifically designed and configured for Brightspace UI components and applications.
6
6
 
7
- > **Migrating from `@open-wc/testing` and/or `@brightspace-ui/visual-diff`?**
7
+ > **Migrating from `@open-wc/testing`/`@web/test-runner`?**
8
8
  > Refer to the [Migration Guide](docs/migration-guide.md) for help migrating a repo to `@brightspace-ui/testing`.
9
9
 
10
10
  Install from NPM:
@@ -479,6 +479,7 @@ Vdiff tests are written [just like other tests](#writing-tests), and the same ut
479
479
  Use the asynchronous `.to.be.golden()` Chai assertion to take a vdiff snapshot and [compare it against its golden](#generating-the-goldens).
480
480
 
481
481
  ```javascript
482
+ import './my-elem.js';
482
483
  import { fixture, html } from '@brightspace-ui/testing';
483
484
 
484
485
  describe('my-elem', () => {
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import commandLineArgs from 'command-line-args';
3
- import { execSync } from 'node:child_process';
4
3
  import process from 'node:process';
5
4
  import { runner } from '../src/server/cli/test-runner.js';
6
5
 
@@ -19,21 +18,6 @@ if (cli.subcommand === 'vdiff') {
19
18
  } else if (vdiff.subcommand === 'report') {
20
19
  const { report } = await import('../src/server/cli/vdiff/report.js');
21
20
  await report.start();
22
- } else if (vdiff.subcommand === 'migrate') {
23
- const { migrate } = await import('../src/server/cli/vdiff/migrate.js');
24
- await migrate.start(vdiff._unknown);
25
- } else if (vdiff.subcommand === 'migrate-local') {
26
-
27
- const { pattern = './**' } = commandLineArgs({ name: 'pattern', type: String, defaultOption: true }, { partial: true, argv: vdiff._unknown || [] });
28
-
29
- stdout.write('\nInstalling @brightspace-ui/visual-diff\n');
30
- execSync('npm install @brightspace-ui/visual-diff@14 --no-save');
31
- stdout.write(`\nRunning existing tests for pattern '${pattern}/*.visual-diff.js'\n`);
32
- execSync(`npx mocha '${pattern}/*.visual-diff.js' -t 10000 --golden`);
33
- stdout.write('\nTest run complete.\n');
34
-
35
- const { migrate } = await import('../src/server/cli/vdiff/migrate.js');
36
- await migrate.start(vdiff._unknown, true);
37
21
  } else {
38
22
  stdout.write(`\nfatal: unknown subcommand: ${vdiff.subcommand}\n`);
39
23
  }
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.19.0",
5
+ "version": "1.21.0",
6
6
  "repository": "https://github.com/BrightspaceUI/testing.git",
7
7
  "scripts": {
8
8
  "lint": "npm run lint:eslint && npm run lint:style",
@@ -159,14 +159,6 @@ async function getTestRunnerOptions(argv = []) {
159
159
  {
160
160
  example: 'vdiff golden',
161
161
  desc: 'Generate new golden screenshots'
162
- },
163
- {
164
- example: 'vdiff migrate [directory]',
165
- desc: 'Migrate from @brightspace-ui/visual-diff. Restrict which goldens are migrated with a directory glob.'
166
- },
167
- {
168
- example: 'vdiff migrate-local [directory]',
169
- desc: 'Generate goldens with @brightspace-ui/visual-diff for local comparison while migrating tests. Restrict which goldens are generated with a directory glob.'
170
162
  }]
171
163
  }
172
164
  ]);
@@ -121,7 +121,7 @@ class App extends LitElement {
121
121
  constructor() {
122
122
  super();
123
123
  this._filterBrowsers = data.browsers.map(b => b.name);
124
- this._filterStatus = data.numFailed > 0 ? FILTER_STATUS.FAILED : FILTER_STATUS.ALL;
124
+ this._filterStatus = data.numFailed > 0 ? FILTER_STATUS.FAILED : (data.numByteDiff > 0 ? FILTER_STATUS.BYTEDIFF : FILTER_STATUS.ALL);
125
125
  this._fullMode = FULL_MODE.GOLDEN.value;
126
126
  this._layout = LAYOUTS.SPLIT.value;
127
127
  this._overlay = true;
@@ -146,7 +146,10 @@ class App extends LitElement {
146
146
  }
147
147
  if (searchParams.has('status')) {
148
148
  let filterStatus = searchParams.get('status');
149
- if (filterStatus === FILTER_STATUS.FAILED && data.numFailed === 0) filterStatus = FILTER_STATUS.ALL;
149
+ if (filterStatus === FILTER_STATUS.FAILED && data.numFailed === 0 ||
150
+ filterStatus === FILTER_STATUS.BYTEDIFF && data.numByteDiff === 0) {
151
+ filterStatus = FILTER_STATUS.ALL;
152
+ }
150
153
  this._filterStatus = filterStatus;
151
154
  }
152
155
  if (searchParams.has('browsers')) {
@@ -198,7 +201,8 @@ class App extends LitElement {
198
201
 
199
202
  const statusFilters = [
200
203
  { name: FILTER_STATUS.FAILED, count: data.numFailed },
201
- { name: FILTER_STATUS.PASSED, count: data.numTests - data.numFailed },
204
+ { name: FILTER_STATUS.BYTEDIFF, count: data.numByteDiff },
205
+ { name: FILTER_STATUS.PASSED, count: data.numTests - data.numFailed - data.numByteDiff },
202
206
  { name: FILTER_STATUS.ALL, count: data.numTests }
203
207
  ];
204
208
 
@@ -434,7 +438,8 @@ class App extends LitElement {
434
438
  if (this._filterBrowsers.includes(r.name) &&
435
439
  (this._filterStatus === FILTER_STATUS.ALL ||
436
440
  r.passed && this._filterStatus === FILTER_STATUS.PASSED ||
437
- !r.passed && this._filterStatus === FILTER_STATUS.FAILED)) numStatusMatch++;
441
+ r.bytediff && this._filterStatus === FILTER_STATUS.BYTEDIFF ||
442
+ !r.bytediff && !r.passed && this._filterStatus === FILTER_STATUS.FAILED)) numStatusMatch++;
438
443
  });
439
444
  if (numStatusMatch > 0) {
440
445
  if (lookingForNextTest) {
@@ -77,7 +77,8 @@ export const COMMON_STYLE = css`
77
77
  export const FILTER_STATUS = {
78
78
  ALL: 'All',
79
79
  PASSED: 'Passed',
80
- FAILED: 'Failed'
80
+ FAILED: 'Failed',
81
+ BYTEDIFF: 'Byte Diff'
81
82
  };
82
83
 
83
84
  export const FULL_MODE = {
@@ -175,7 +175,7 @@ function renderResult(resultData, options) {
175
175
  let newPart;
176
176
  if (resultData.passed) {
177
177
  newPart = html`<div class="result-graphic padding">${ICON_TADA}<p>Hooray! No changes here.</p></div>`;
178
- } else if (!resultData.info.diff && resultData.info.pixelsDiff === 0) {
178
+ } else if (resultData.bytediff) {
179
179
  newPart = html`<div class="result-graphic padding">${ICON_BYTES}
180
180
  <p>No pixels have changed, but the bytes are different.</p>
181
181
  <p class="details">
@@ -27,6 +27,7 @@ function createData(rootDir, updateGoldens, sessions) {
27
27
  const prevBrowser = metadata.browsers?.find(b => b.name === browserName);
28
28
  browsers.set(browserName, {
29
29
  name: browserName,
30
+ numByteDiff: 0,
30
31
  numFailed: 0,
31
32
  version: parseInt(s.browser.browser.version()),
32
33
  previousVersion: prevBrowser?.version
@@ -36,14 +37,14 @@ function createData(rootDir, updateGoldens, sessions) {
36
37
 
37
38
  const fileName = s.testFile.substring(rootDir.length + 1);
38
39
  if (!files.has(fileName)) {
39
- files.set(fileName, { name: fileName, numFailed: 0, tests: new Map() });
40
+ files.set(fileName, { name: fileName, numByteDiff: 0, numFailed: 0, tests: new Map() });
40
41
  }
41
42
  const fileData = files.get(fileName);
42
43
  flattenResults(s, browserData, fileData);
43
44
 
44
45
  });
45
46
 
46
- let numTests = 0, numFailed = 0;
47
+ let numTests = 0, numFailed = 0, numByteDiff = 0;
47
48
  files.forEach(f => {
48
49
  numTests += f.tests.size;
49
50
  f.tests.forEach(t => {
@@ -51,6 +52,10 @@ function createData(rootDir, updateGoldens, sessions) {
51
52
  f.numFailed++;
52
53
  numFailed++;
53
54
  }
55
+ if (t.numByteDiff > 0) {
56
+ f.numByteDiff++;
57
+ numByteDiff++;
58
+ }
54
59
  });
55
60
  });
56
61
 
@@ -61,7 +66,7 @@ function createData(rootDir, updateGoldens, sessions) {
61
66
  writeFileSync(metadataPath, `${JSON.stringify(metadata, undefined, '\t')}\n`);
62
67
  }
63
68
 
64
- return { browsers, files, numFailed, numTests };
69
+ return { browsers, files, numByteDiff, numFailed, numTests };
65
70
 
66
71
  }
67
72
 
@@ -79,20 +84,28 @@ function flattenResults(session, browserData, fileData) {
79
84
  if (!fileData.tests.has(testName)) {
80
85
  fileData.tests.set(testName, {
81
86
  name: testName,
87
+ numByteDiff: 0,
82
88
  numFailed: 0,
83
89
  results: []
84
90
  });
85
91
  }
86
92
  const testData = fileData.tests.get(testName);
93
+ const bytediff = !t.passed && !info.diff && info.pixelsDiff === 0;
87
94
  if (!t.passed) {
88
- browserData.numFailed++;
89
- testData.numFailed++;
95
+ if (bytediff) {
96
+ browserData.numByteDiff++;
97
+ testData.numByteDiff++;
98
+ } else {
99
+ browserData.numFailed++;
100
+ testData.numFailed++;
101
+ }
90
102
  }
91
103
  testData.results.push({
92
104
  name: browserData.name,
93
105
  duration: t.duration,
94
106
  error: t.error?.message,
95
107
  passed: t.passed,
108
+ bytediff,
96
109
  info: info
97
110
  });
98
111
  });
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env node
2
- import { appendFile, mkdir, readFile, rename, rm } from 'node:fs/promises';
3
- import { join, normalize, parse } from 'node:path';
4
- import commandLineArgs from 'command-line-args';
5
- import { glob } from 'glob';
6
- import { PATHS } from '../../paths.js';
7
- import { stdout } from 'node:process';
8
-
9
- async function start(argv = [], local = false) {
10
- const { pattern = './**' } = commandLineArgs({ name: 'pattern', type: String, defaultOption: true }, { partial: true, argv });
11
- const oldSuffix = local ? 'screenshots/golden' : 'screenshots/ci/golden';
12
-
13
- stdout.write(`\nMigrating goldens for pattern '${pattern}/${oldSuffix}'\n`);
14
- const dirs = await glob(`${pattern}/${oldSuffix}`, { ignore: 'node_modules/**', posix: true });
15
- let fileCount = 0;
16
-
17
- const gitignore = await readFile('.gitignore', { encoding: 'UTF8' }).catch(() => '');
18
- if (!new RegExp(`${PATHS.VDIFF_ROOT}/(\n|$)`).test(gitignore)) {
19
- const newline = gitignore.endsWith('\n') ? '' : '\n';
20
- await appendFile('.gitignore', `${newline}${PATHS.VDIFF_ROOT}/\n`);
21
- }
22
-
23
- await Promise.all(dirs.map(async dir => {
24
- const files = await glob(`${dir}/*/*.png`, { posix: true });
25
-
26
- await Promise.all(files.map(async file => {
27
- fileCount += 1;
28
- const { base: name, dir } = parse(file);
29
- const dirName = parse(dir).name;
30
-
31
- const newName = name
32
- .replace(/^d2l-/, '')
33
- .replace(new RegExp(`^${dirName}-`), '');
34
-
35
- const newDir = local ?
36
- `${PATHS.VDIFF_ROOT}/${dir.replace(`${oldSuffix}/${dirName}`, `${dirName}/${PATHS.GOLDEN}/chromium`)}` :
37
- dir.replace(`${oldSuffix}/${dirName}`, `${PATHS.GOLDEN}/${dirName}/chromium`);
38
-
39
- await mkdir(newDir, { recursive: true });
40
- return rename(file, join(newDir, newName));
41
- }));
42
-
43
- if (!local) {
44
- return rm(normalize(join(dir, '..', '..')), { recursive: true });
45
- }
46
- }));
47
-
48
- stdout.write(`\nMigrated ${fileCount} ${fileCount === 1 ? 'golden' : 'goldens'} found in ${dirs.length} test ${dirs.length === 1 ? 'directory' : 'directories'}\n`);
49
- }
50
-
51
- export const migrate = {
52
- start
53
- };