@matter/testing 0.15.1 → 0.15.2-alpha.0-20250703-2e16aba2b

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.
Files changed (84) hide show
  1. package/dist/cjs/chai.d.ts +9 -0
  2. package/dist/cjs/chai.d.ts.map +1 -0
  3. package/dist/cjs/chai.js +66 -0
  4. package/dist/cjs/chai.js.map +6 -0
  5. package/dist/cjs/failure-detail.d.ts +1 -0
  6. package/dist/cjs/failure-detail.d.ts.map +1 -1
  7. package/dist/cjs/failure-detail.js +12 -4
  8. package/dist/cjs/failure-detail.js.map +1 -1
  9. package/dist/cjs/failure-reporter.js +5 -1
  10. package/dist/cjs/failure-reporter.js.map +1 -1
  11. package/dist/cjs/global-declarations.d.ts +8 -1
  12. package/dist/cjs/global-declarations.d.ts.map +1 -1
  13. package/dist/cjs/global-definitions.js +0 -1
  14. package/dist/cjs/global-definitions.js.map +1 -1
  15. package/dist/cjs/index.d.ts +2 -0
  16. package/dist/cjs/index.d.ts.map +1 -1
  17. package/dist/cjs/index.js +2 -0
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/mocha.d.ts.map +1 -1
  20. package/dist/cjs/mocha.js +1 -0
  21. package/dist/cjs/mocha.js.map +1 -1
  22. package/dist/cjs/mocks/time.d.ts +7 -0
  23. package/dist/cjs/mocks/time.d.ts.map +1 -1
  24. package/dist/cjs/mocks/time.js +13 -1
  25. package/dist/cjs/mocks/time.js.map +1 -1
  26. package/dist/cjs/runner.d.ts +5 -1
  27. package/dist/cjs/runner.d.ts.map +1 -1
  28. package/dist/cjs/runner.js +24 -6
  29. package/dist/cjs/runner.js.map +1 -1
  30. package/dist/cjs/util/files.d.ts.map +1 -1
  31. package/dist/cjs/util/files.js +1 -0
  32. package/dist/cjs/util/files.js.map +1 -1
  33. package/dist/cjs/web.d.ts +3 -0
  34. package/dist/cjs/web.d.ts.map +1 -1
  35. package/dist/cjs/web.js +7 -4
  36. package/dist/cjs/web.js.map +1 -1
  37. package/dist/esm/chai.d.ts +9 -0
  38. package/dist/esm/chai.d.ts.map +1 -0
  39. package/dist/esm/chai.js +40 -0
  40. package/dist/esm/chai.js.map +6 -0
  41. package/dist/esm/failure-detail.d.ts +1 -0
  42. package/dist/esm/failure-detail.d.ts.map +1 -1
  43. package/dist/esm/failure-detail.js +12 -4
  44. package/dist/esm/failure-detail.js.map +1 -1
  45. package/dist/esm/failure-reporter.js +5 -1
  46. package/dist/esm/failure-reporter.js.map +1 -1
  47. package/dist/esm/global-declarations.d.ts +8 -1
  48. package/dist/esm/global-declarations.d.ts.map +1 -1
  49. package/dist/esm/global-definitions.js +0 -1
  50. package/dist/esm/global-definitions.js.map +1 -1
  51. package/dist/esm/index.d.ts +2 -0
  52. package/dist/esm/index.d.ts.map +1 -1
  53. package/dist/esm/index.js +2 -0
  54. package/dist/esm/index.js.map +1 -1
  55. package/dist/esm/mocha.d.ts.map +1 -1
  56. package/dist/esm/mocha.js +1 -0
  57. package/dist/esm/mocha.js.map +1 -1
  58. package/dist/esm/mocks/time.d.ts +7 -0
  59. package/dist/esm/mocks/time.d.ts.map +1 -1
  60. package/dist/esm/mocks/time.js +13 -1
  61. package/dist/esm/mocks/time.js.map +1 -1
  62. package/dist/esm/runner.d.ts +5 -1
  63. package/dist/esm/runner.d.ts.map +1 -1
  64. package/dist/esm/runner.js +24 -6
  65. package/dist/esm/runner.js.map +1 -1
  66. package/dist/esm/util/files.d.ts.map +1 -1
  67. package/dist/esm/util/files.js +1 -0
  68. package/dist/esm/util/files.js.map +1 -1
  69. package/dist/esm/web.d.ts +3 -0
  70. package/dist/esm/web.d.ts.map +1 -1
  71. package/dist/esm/web.js +7 -4
  72. package/dist/esm/web.js.map +1 -1
  73. package/package.json +2 -2
  74. package/src/chai.ts +50 -0
  75. package/src/failure-detail.ts +14 -4
  76. package/src/failure-reporter.ts +9 -1
  77. package/src/global-declarations.ts +17 -1
  78. package/src/global-definitions.ts +2 -1
  79. package/src/index.ts +2 -0
  80. package/src/mocha.ts +2 -0
  81. package/src/mocks/time.ts +15 -1
  82. package/src/runner.ts +31 -6
  83. package/src/util/files.ts +1 -0
  84. package/src/web.ts +20 -12
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/util/files.ts"],
4
- "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAEpB,SAAS,iBAAiB,SAAS,OAAO;AAC7C,QAAM,QAAQ,MAAc;AAG5B,QAAM,UAAU,QAAQ,MAAM,YAAY,iBAAiB;AAC3D,QAAM,KAAK,QAAQ,QAAQ,gCAAgC,CAAC;AAC5D,QAAM,KAAK,QAAQ,QAAQ,yBAAyB,CAAC;AAGrD,QAAM,SAAS,IAAI,QAAQ,EAAE,QAAQ,SAAS,MAAM,sBAAsB;AAC1E,MAAI,WAAW,MAAM,GAAG;AACpB,UAAM,KAAK,MAAM;AAAA,EACrB;AAEA,SAAO;AACX;",
4
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAEpB,SAAS,iBAAiB,SAAS,OAAO;AAC7C,QAAM,QAAQ,MAAc;AAG5B,QAAM,UAAU,QAAQ,MAAM,YAAY,iBAAiB;AAC3D,QAAM,KAAK,QAAQ,QAAQ,gCAAgC,CAAC;AAC5D,QAAM,KAAK,QAAQ,QAAQ,kBAAkB,CAAC;AAC9C,QAAM,KAAK,QAAQ,QAAQ,yBAAyB,CAAC;AAGrD,QAAM,SAAS,IAAI,QAAQ,EAAE,QAAQ,SAAS,MAAM,sBAAsB;AAC1E,MAAI,WAAW,MAAM,GAAG;AACpB,UAAM,KAAK,MAAM;AAAA,EACrB;AAEA,SAAO;AACX;",
5
5
  "names": []
6
6
  }
package/dist/esm/web.d.ts CHANGED
@@ -5,4 +5,7 @@
5
5
  */
6
6
  import type { TestRunner } from "./runner.js";
7
7
  export declare function testWeb(runner: TestRunner, manual: boolean): Promise<void>;
8
+ export declare namespace testWeb {
9
+ var entrypointPreprocessor: ((lines: string[]) => void) | undefined;
10
+ }
8
11
  //# sourceMappingURL=web.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,wBAAsB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,iBA4ChE"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,wBAAsB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,iBA4ChE;yBA5CqB,OAAO;yCAmDsC,MAAM,EAAE,KAAK,IAAI"}
package/dist/esm/web.js CHANGED
@@ -12,7 +12,7 @@ import { chromium } from "playwright";
12
12
  import { WebReporter } from "./web-reporter.js";
13
13
  async function testWeb(runner, manual) {
14
14
  const files = await runner.loadFiles("esm");
15
- const bundlePath = await bundle(files, runner.pkg);
15
+ const bundlePath = await bundle(files, runner);
16
16
  const server = await new Promise((resolve, reject) => {
17
17
  try {
18
18
  const server2 = express().use(express.static(Package.workspace.resolve("node_modules"))).use(express.static(Package.workspace.path)).get("/", (_, res) => {
@@ -44,6 +44,7 @@ async function testWeb(runner, manual) {
44
44
  }
45
45
  });
46
46
  }
47
+ testWeb.entrypointPreprocessor = void 0;
47
48
  async function testInBrowser(url, reporter, options) {
48
49
  async function setup() {
49
50
  const browser = await chromium.launch();
@@ -104,7 +105,7 @@ function buildIndex(bundlePath) {
104
105
  </body>
105
106
  </html>`;
106
107
  }
107
- async function bundle(files, pkg) {
108
+ async function bundle(files, { pkg, entrypointPreprocessor }) {
108
109
  const entrypointPath = pkg.resolve("build/esm/test-entrypoint.js");
109
110
  const bundlePath = pkg.resolve("build/cjs/test-bundle.js");
110
111
  const entrypoint = files.map((path) => {
@@ -113,8 +114,9 @@ async function bundle(files, pkg) {
113
114
  path = `./${path}`;
114
115
  }
115
116
  return `import ${JSON.stringify(path)}`;
116
- }).join("\n");
117
- await writeFile(pkg.resolve("build/esm/test-entrypoint.js"), entrypoint);
117
+ });
118
+ entrypointPreprocessor?.(entrypoint);
119
+ await writeFile(pkg.resolve("build/esm/test-entrypoint.js"), entrypoint.join("\n"));
118
120
  await build({
119
121
  entryPoints: [entrypointPath],
120
122
  bundle: true,
@@ -122,6 +124,7 @@ async function bundle(files, pkg) {
122
124
  outfile: bundlePath,
123
125
  external: ["wtfnode"],
124
126
  keepNames: true,
127
+ conditions: ["static-load"],
125
128
  // This doesn't work...
126
129
  // logOverride: {
127
130
  // "direct-eval": "silent",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/web.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": ["server", "options"]
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matter/testing",
3
- "version": "0.15.1",
3
+ "version": "0.15.2-alpha.0-20250703-2e16aba2b",
4
4
  "description": "Test harness for running JavaScript and Matter certification tests",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -45,7 +45,7 @@
45
45
  "#tools/ansi-text": "@matter/tools/ansi-text"
46
46
  },
47
47
  "dependencies": {
48
- "@matter/tools": "0.15.1",
48
+ "@matter/tools": "0.15.2-alpha.0-20250703-2e16aba2b",
49
49
  "@types/express": "^5.0.3",
50
50
  "ansi-colors": "^4.1.3",
51
51
  "chai": "^4.5.0",
package/src/chai.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import Chai from "chai";
8
+ import "./global-definitions.js";
9
+
10
+ export interface DiffMarker {}
11
+
12
+ Chai.config.truncateThreshold = 200;
13
+
14
+ function createDiffMarker(title: string) {
15
+ return {
16
+ toString() {
17
+ return `<<${title}>>`;
18
+ },
19
+ } as DiffMarker;
20
+ }
21
+
22
+ expect.IGNORE = createDiffMarker("ignore");
23
+ expect.BIGINT = createDiffMarker("bigint");
24
+ expect.BYTES = createDiffMarker("bytes");
25
+ expect.NUMBER = createDiffMarker("number");
26
+ expect.STRING = createDiffMarker("string");
27
+
28
+ (Chai.config as any).deepEqual = (expected: unknown, actual: unknown) => {
29
+ return (Chai.util as any).eql(expected, actual, {
30
+ comparator(expected: unknown, actual: unknown) {
31
+ switch (expected) {
32
+ case expect.IGNORE:
33
+ return true;
34
+
35
+ case expect.BIGINT:
36
+ return typeof actual === "bigint";
37
+
38
+ case expect.NUMBER:
39
+ return typeof actual === "number";
40
+
41
+ case expect.STRING:
42
+ return typeof actual === "string";
43
+
44
+ case expect.BYTES:
45
+ return actual instanceof Uint8Array;
46
+ }
47
+ return null;
48
+ },
49
+ });
50
+ };
@@ -13,6 +13,7 @@ export interface FailureDetail {
13
13
  expected?: string;
14
14
  logs?: string;
15
15
  cause?: FailureDetail;
16
+ secondary?: FailureDetail;
16
17
  errors?: FailureDetail[];
17
18
  }
18
19
 
@@ -20,7 +21,7 @@ export interface FailureDetail {
20
21
  * Captures all pertinent information about a failed test.
21
22
  */
22
23
  export function FailureDetail(error: any, id?: string, logs?: string[], parentStack?: string[]) {
23
- const { message, stack, stackLines, cause, errors } = parseError(error, parentStack);
24
+ const { message, stack, stackLines, cause, errors, secondary } = parseError(error, parentStack);
24
25
  const result = { message } as FailureDetail;
25
26
 
26
27
  if (stack) {
@@ -35,6 +36,9 @@ export function FailureDetail(error: any, id?: string, logs?: string[], parentSt
35
36
  if (cause) {
36
37
  result.cause = cause;
37
38
  }
39
+ if (secondary) {
40
+ result.secondary = secondary;
41
+ }
38
42
  if (errors) {
39
43
  result.errors = errors;
40
44
  }
@@ -89,19 +93,25 @@ function messageAndStackFor(
89
93
  }
90
94
 
91
95
  function parseError(error: Error, parentStack?: string[]) {
96
+ let secondary: FailureDetail | undefined;
97
+ if ("error" in error && "suppressed" in error) {
98
+ secondary = FailureDetail(error.error);
99
+ error = error.suppressed as Error;
100
+ }
101
+
92
102
  const { message, id, stack, stackLines } = messageAndStackFor(error, parentStack);
93
103
 
94
104
  let cause: FailureDetail | undefined, errors: FailureDetail[] | undefined;
95
105
 
96
106
  const errorCause = error.cause;
97
107
  if (errorCause) {
98
- cause = FailureDetail(errorCause, undefined, stackLines);
108
+ cause = FailureDetail(errorCause, id, undefined, stackLines);
99
109
  }
100
110
 
101
111
  const errorErrors = (error as AggregateError).errors;
102
112
  if (Array.isArray(errorErrors)) {
103
- errors = errorErrors.map(e => FailureDetail(e, undefined, stackLines));
113
+ errors = errorErrors.map(e => FailureDetail(e, id, undefined, stackLines));
104
114
  }
105
115
 
106
- return { message, id, stack, stackLines, cause, errors };
116
+ return { message, id, stack, stackLines, cause, errors, secondary };
107
117
  }
@@ -32,7 +32,10 @@ function dumpCause(out: Printer, failure: FailureDetail) {
32
32
  });
33
33
  }
34
34
 
35
- function dumpDetails(out: Printer, { message, id, actual, expected, stack, cause, errors, logs }: FailureDetail) {
35
+ function dumpDetails(
36
+ out: Printer,
37
+ { message, id, actual, expected, stack, cause, errors, secondary, logs }: FailureDetail,
38
+ ) {
36
39
  out("\n", ansi.bright.red(id ? `[${ansi.bold(id)}] ${message}` : message), "\n");
37
40
 
38
41
  if (actual !== undefined && expected !== undefined) {
@@ -60,6 +63,11 @@ function dumpDetails(out: Printer, { message, id, actual, expected, stack, cause
60
63
  }
61
64
  }
62
65
 
66
+ if (secondary) {
67
+ out("\n", ansi.bold("Secondary error during disposal:"), "\n");
68
+ dumpCause(out, secondary);
69
+ }
70
+
63
71
  if (logs) {
64
72
  out("\n", logs, "\n");
65
73
  }
@@ -6,13 +6,29 @@
6
6
 
7
7
  import type Chai from "chai";
8
8
  import "chai-as-promised";
9
+ import type { DiffMarker } from "./chai.js";
9
10
  import type { DiagnosticMessageLike, MockLogger } from "./mocks/logging.js";
10
11
  import type { MockTime } from "./mocks/time.js";
11
12
  import type { TestDescriptor, TestSuiteDescriptor } from "./test-descriptor.js";
12
13
 
13
14
  declare global {
14
15
  // Expose Chai globally
15
- const expect: typeof Chai.expect;
16
+ const expect: typeof Chai.expect & {
17
+ // Ignores for purposes of deep comparison
18
+ IGNORE: DiffMarker;
19
+
20
+ // Matches any bigint for purposes of deep comparison
21
+ BIGINT: DiffMarker;
22
+
23
+ // Matches any byte array for purposes of deep comparison
24
+ BYTES: DiffMarker;
25
+
26
+ // Matches any number for purposes of deep comparison
27
+ NUMBER: DiffMarker;
28
+
29
+ // Matches any string for purposes of deep comparison
30
+ STRING: DiffMarker;
31
+ };
16
32
 
17
33
  // Expose API for controlling time
18
34
  let MockTime: MockTime;
@@ -9,12 +9,13 @@
9
9
 
10
10
  import Chai from "chai";
11
11
  import ChaiAsPromised from "chai-as-promised";
12
+
12
13
  import { browserSetup, extendApi, generalSetup } from "./mocha.js";
13
14
  import { bootSetup } from "./mocks/boot.js";
14
15
  import { MockLogger, loggerSetup } from "./mocks/logging.js";
15
16
  import { timeSetup } from "./mocks/time.js";
16
17
 
17
- Chai.config.truncateThreshold = 200;
18
+ // This must go here so it initializes early
18
19
  Chai.use(ChaiAsPromised);
19
20
 
20
21
  Object.assign(globalThis, {
package/src/index.ts CHANGED
@@ -4,11 +4,13 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import "./chai.js";
7
8
  import "./global-declarations.js";
8
9
  export * from "./chip/index.js";
9
10
  export * from "./device/index.js";
10
11
  export * from "./docker/index.js";
11
12
  export { afterRun } from "./mocha.js";
12
13
  export * from "./mocharc.cjs";
14
+ export * from "./runner.js";
13
15
  export * from "./util/heap.js";
14
16
  export * from "./util/wtf.js";
package/src/mocha.ts CHANGED
@@ -89,6 +89,8 @@ export function generalSetup(mocha: Mocha) {
89
89
  }
90
90
 
91
91
  export function extendApi(Mocha: typeof MochaType) {
92
+ (Mocha.reporters.Base as any).maxDiffSize = 0xffff;
93
+
92
94
  const descriptors = new WeakMap<Mocha.Suite | Mocha.Test, TestDescriptor>();
93
95
 
94
96
  Object.defineProperty(Mocha.Suite.prototype, "descriptor", {
package/src/mocks/time.ts CHANGED
@@ -84,6 +84,7 @@ let callbacks = new Array<{ atMs: number; callback: TimerCallback }>();
84
84
  let nowMs = 0;
85
85
  let real = undefined as unknown;
86
86
  let enabled = false;
87
+ let defaultToMacrotasks = false;
87
88
 
88
89
  /**
89
90
  * An arbitrary start for our mock timeline. Starting at zero causes problems with Matter dates that cannot encode back
@@ -121,6 +122,7 @@ export const MockTime = {
121
122
  reset(time: ConstructorParameters<typeof Date>[0] = epoch) {
122
123
  callbacks = [];
123
124
  nowMs = new Date(time).getTime();
125
+ defaultToMacrotasks = false;
124
126
  MockTime.enable();
125
127
  },
126
128
 
@@ -133,6 +135,16 @@ export const MockTime = {
133
135
  }
134
136
  },
135
137
 
138
+ /**
139
+ * Enable macrotasks (true) or microtasks (false) for mock time incrementation.
140
+ *
141
+ * Microtasks are the default and are more efficient. Macrotasks are required for e.g. most of node's crypto.subtle
142
+ * methods to resolve.
143
+ */
144
+ set macrotasks(value: boolean) {
145
+ defaultToMacrotasks = value;
146
+ },
147
+
136
148
  atTime<T>(time: number | Date, actor: () => T): T {
137
149
  const revertTo = nowMs;
138
150
  let isAsync = false;
@@ -196,7 +208,7 @@ export const MockTime = {
196
208
  // if you only yield via microtask. It seems to require yielding via macrotask. So we optionally use
197
209
  // setTimeout here. Probably related to entropy collection but I think it's safe to classify as a Node bug.
198
210
  // Tested on version 20.11.0
199
- if (macrotasks) {
211
+ if (macrotasks ?? defaultToMacrotasks) {
200
212
  await new Promise<void>(resolve => setTimeout(() => resolve(), 0));
201
213
  } else {
202
214
  await MockTime.yield();
@@ -215,11 +227,13 @@ export const MockTime = {
215
227
 
216
228
  if (stepMs) {
217
229
  await this.advance(stepMs);
230
+ timeAdvanced += stepMs;
218
231
  } else {
219
232
  // Advance time exponentially, trying for granularity but also OK performance. Note that we are not only
220
233
  // advancing time but also yielding event loop. So it's possible if we run out of time it's just because
221
234
  // there were too few yields in one virtual hour. As designed currently it's 360 macrotasks and 360
222
235
  // microtasks (360 loops w/ 1 macro- and 1 micro-yield)
236
+ // TODO - this isn't exponential, fix comment or fix code
223
237
  await this.advance(1000);
224
238
  timeAdvanced += 1000;
225
239
  }
package/src/runner.ts CHANGED
@@ -17,6 +17,8 @@ import { Reporter } from "./reporter.js";
17
17
  import { listSupportFiles } from "./util/files.js";
18
18
  import { testWeb } from "./web.js";
19
19
 
20
+ const HARNESS_CONFIG_FILE = "build/esm/test/test.harness.js";
21
+
20
22
  export class TestRunner {
21
23
  static #current?: TestRunner;
22
24
 
@@ -29,7 +31,14 @@ export class TestRunner {
29
31
  }
30
32
 
31
33
  readonly reporter: Reporter;
32
- private spec = Array<string>();
34
+ #spec = Array<string>();
35
+ #configured = false;
36
+
37
+ /**
38
+ * If present the web runner will run this preprocessor on its entrypoint file. You can modify {@link lines} to
39
+ * add or change entrypoint logic.
40
+ */
41
+ entrypointPreprocessor?: (this: unknown, lines: string[]) => void;
33
42
 
34
43
  constructor(
35
44
  readonly pkg: Package,
@@ -52,11 +61,11 @@ export class TestRunner {
52
61
  })();
53
62
 
54
63
  if (options.spec === undefined) {
55
- this.spec = ["test/**/*Test.ts"];
64
+ this.#spec = ["test/**/*Test.ts"];
56
65
  } else if (Array.isArray(options.spec)) {
57
- this.spec = options.spec;
66
+ this.#spec = options.spec;
58
67
  } else {
59
- this.spec = [options.spec];
68
+ this.#spec = [options.spec];
60
69
  }
61
70
 
62
71
  if (options.debug) {
@@ -65,16 +74,32 @@ export class TestRunner {
65
74
  }
66
75
 
67
76
  async runNode(format: "esm" | "cjs" = "esm") {
77
+ await this.#configure();
78
+
68
79
  return await this.#run(this.progress, () => testNodejs(this, format));
69
80
  }
70
81
 
71
82
  async runWeb(manual = false) {
83
+ await this.#configure();
84
+
72
85
  await this.#run(this.progress, () => testWeb(this, manual));
73
86
  }
74
87
 
88
+ async #configure() {
89
+ if (this.#configured) {
90
+ return;
91
+ }
92
+
93
+ if (this.pkg.hasFile(HARNESS_CONFIG_FILE)) {
94
+ await import(this.pkg.resolve(HARNESS_CONFIG_FILE));
95
+ }
96
+
97
+ this.#configured = true;
98
+ }
99
+
75
100
  async loadFiles(format: "esm" | "cjs") {
76
101
  const tests = Array<string>();
77
- for (let spec of this.spec) {
102
+ for (let spec of this.#spec) {
78
103
  spec = spec.replace(/\.ts$/, ".js");
79
104
  spec = relative(this.pkg.path, spec);
80
105
  if (!spec.startsWith(".") && !spec.startsWith("build/") && !spec.startsWith("dist/")) {
@@ -94,7 +119,7 @@ export class TestRunner {
94
119
  }
95
120
 
96
121
  if (!tests.length) {
97
- fatal(`No files match ${this.spec.join(", ")}`);
122
+ fatal(`No files match ${this.#spec.join(", ")}`);
98
123
  }
99
124
 
100
125
  return [...listSupportFiles(format), ...tests];
package/src/util/files.ts CHANGED
@@ -13,6 +13,7 @@ export function listSupportFiles(format = "cjs") {
13
13
  // Always load tooling code in ESM format as tooling globals load as ESM
14
14
  const testing = Package.tools.findPackage("@matter/testing");
15
15
  files.push(testing.resolve("dist/esm/global-definitions.js"));
16
+ files.push(testing.resolve("dist/esm/chai.js"));
16
17
  files.push(testing.resolve("dist/esm/mocks/index.js"));
17
18
 
18
19
  // Package code should load in the format being tested
package/src/web.ts CHANGED
@@ -19,7 +19,7 @@ import { WebReporter } from "./web-reporter.js";
19
19
 
20
20
  export async function testWeb(runner: TestRunner, manual: boolean) {
21
21
  const files = await runner.loadFiles("esm");
22
- const bundlePath = await bundle(files, runner.pkg);
22
+ const bundlePath = await bundle(files, runner);
23
23
 
24
24
  const server = await new Promise<http.Server>((resolve, reject) => {
25
25
  try {
@@ -63,6 +63,13 @@ export async function testWeb(runner: TestRunner, manual: boolean) {
63
63
  });
64
64
  }
65
65
 
66
+ /**
67
+ * You can set this to modify the web entrypoint in your testing configuration.
68
+ *
69
+ * Input is the lines of the entrypoint file. You can modify these lines to add or modify generated code.
70
+ */
71
+ testWeb.entrypointPreprocessor = undefined as undefined | ((lines: string[]) => void);
72
+
66
73
  async function testInBrowser(url: string, reporter: Reporter, options: TestOptions) {
67
74
  async function setup() {
68
75
  const browser = await chromium.launch();
@@ -138,23 +145,23 @@ function buildIndex(bundlePath: string) {
138
145
  </html>`;
139
146
  }
140
147
 
141
- async function bundle(files: string[], pkg: Package) {
148
+ async function bundle(files: string[], { pkg, entrypointPreprocessor }: TestRunner) {
142
149
  const entrypointPath = pkg.resolve("build/esm/test-entrypoint.js");
143
150
  const bundlePath = pkg.resolve("build/cjs/test-bundle.js");
144
151
 
145
- const entrypoint = files
146
- .map(path => {
147
- path = relative(pkg.resolve("build/esm"), path).replace(/\\/g, "/");
148
- if (!path.startsWith(".")) {
149
- path = `./${path}`;
150
- }
151
- return `import ${JSON.stringify(path)}`;
152
- })
153
- .join("\n");
152
+ const entrypoint = files.map(path => {
153
+ path = relative(pkg.resolve("build/esm"), path).replace(/\\/g, "/");
154
+ if (!path.startsWith(".")) {
155
+ path = `./${path}`;
156
+ }
157
+ return `import ${JSON.stringify(path)}`;
158
+ });
159
+
160
+ entrypointPreprocessor?.(entrypoint);
154
161
 
155
162
  // I was unable to get esbuild to resolve the entrypoint using the "stdin" and "absWorkingDir" options. So we just
156
163
  // write to disk
157
- await writeFile(pkg.resolve("build/esm/test-entrypoint.js"), entrypoint);
164
+ await writeFile(pkg.resolve("build/esm/test-entrypoint.js"), entrypoint.join("\n"));
158
165
 
159
166
  await build({
160
167
  entryPoints: [entrypointPath],
@@ -163,6 +170,7 @@ async function bundle(files: string[], pkg: Package) {
163
170
  outfile: bundlePath,
164
171
  external: ["wtfnode"],
165
172
  keepNames: true,
173
+ conditions: ["static-load"],
166
174
 
167
175
  // This doesn't work...
168
176
  // logOverride: {