@deck.gl/test-utils 9.0.0-alpha.7 → 9.0.0-beta.10

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 (75) hide show
  1. package/dist/generate-layer-tests.d.ts +20 -0
  2. package/dist/generate-layer-tests.d.ts.map +1 -0
  3. package/dist/generate-layer-tests.js +209 -0
  4. package/dist/index.cjs +645 -0
  5. package/dist/index.cjs.map +7 -0
  6. package/dist/index.d.ts +11 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +11 -0
  9. package/dist/interaction-test-runner.d.ts +29 -0
  10. package/dist/interaction-test-runner.d.ts.map +1 -0
  11. package/dist/interaction-test-runner.js +57 -0
  12. package/dist/lifecycle-test.d.ts +119 -0
  13. package/dist/lifecycle-test.d.ts.map +1 -0
  14. package/dist/lifecycle-test.js +232 -0
  15. package/dist/snapshot-test-runner.d.ts +46 -0
  16. package/dist/snapshot-test-runner.d.ts.map +1 -0
  17. package/dist/snapshot-test-runner.js +101 -0
  18. package/dist/test-runner.d.ts +56 -0
  19. package/dist/test-runner.d.ts.map +1 -0
  20. package/dist/test-runner.js +143 -0
  21. package/dist/utils/dom.d.ts +7 -0
  22. package/dist/utils/dom.d.ts.map +1 -0
  23. package/dist/utils/dom.js +11 -0
  24. package/dist/utils/precision.d.ts +4 -0
  25. package/dist/utils/precision.d.ts.map +1 -0
  26. package/dist/utils/precision.js +19 -0
  27. package/dist/utils/setup-gl.d.ts +5 -0
  28. package/dist/utils/setup-gl.d.ts.map +1 -0
  29. package/dist/utils/setup-gl.js +15 -0
  30. package/package.json +17 -8
  31. package/src/generate-layer-tests.ts +55 -15
  32. package/src/index.ts +7 -3
  33. package/src/interaction-test-runner.ts +29 -13
  34. package/src/lifecycle-test.ts +214 -27
  35. package/src/snapshot-test-runner.ts +79 -47
  36. package/src/test-runner.ts +77 -59
  37. package/src/utils/dom.ts +6 -1
  38. package/src/utils/precision.ts +13 -6
  39. package/src/utils/setup-gl.ts +2 -2
  40. package/dist/es5/generate-layer-tests.js +0 -243
  41. package/dist/es5/generate-layer-tests.js.map +0 -1
  42. package/dist/es5/index.js +0 -88
  43. package/dist/es5/index.js.map +0 -1
  44. package/dist/es5/interaction-test-runner.js +0 -119
  45. package/dist/es5/interaction-test-runner.js.map +0 -1
  46. package/dist/es5/lifecycle-test.js +0 -456
  47. package/dist/es5/lifecycle-test.js.map +0 -1
  48. package/dist/es5/snapshot-test-runner.js +0 -145
  49. package/dist/es5/snapshot-test-runner.js.map +0 -1
  50. package/dist/es5/test-runner.js +0 -198
  51. package/dist/es5/test-runner.js.map +0 -1
  52. package/dist/es5/utils/dom.js +0 -17
  53. package/dist/es5/utils/dom.js.map +0 -1
  54. package/dist/es5/utils/precision.js +0 -33
  55. package/dist/es5/utils/precision.js.map +0 -1
  56. package/dist/es5/utils/setup-gl.js +0 -19
  57. package/dist/es5/utils/setup-gl.js.map +0 -1
  58. package/dist/esm/generate-layer-tests.js +0 -216
  59. package/dist/esm/generate-layer-tests.js.map +0 -1
  60. package/dist/esm/index.js +0 -8
  61. package/dist/esm/index.js.map +0 -1
  62. package/dist/esm/interaction-test-runner.js +0 -52
  63. package/dist/esm/interaction-test-runner.js.map +0 -1
  64. package/dist/esm/lifecycle-test.js +0 -282
  65. package/dist/esm/lifecycle-test.js.map +0 -1
  66. package/dist/esm/snapshot-test-runner.js +0 -94
  67. package/dist/esm/snapshot-test-runner.js.map +0 -1
  68. package/dist/esm/test-runner.js +0 -134
  69. package/dist/esm/test-runner.js.map +0 -1
  70. package/dist/esm/utils/dom.js +0 -10
  71. package/dist/esm/utils/dom.js.map +0 -1
  72. package/dist/esm/utils/precision.js +0 -18
  73. package/dist/esm/utils/precision.js.map +0 -1
  74. package/dist/esm/utils/setup-gl.js +0 -9
  75. package/dist/esm/utils/setup-gl.js.map +0 -1
package/dist/index.cjs ADDED
@@ -0,0 +1,645 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // dist/index.js
21
+ var dist_exports = {};
22
+ __export(dist_exports, {
23
+ InteractionTestRunner: () => InteractionTestRunner,
24
+ SnapshotTestRunner: () => SnapshotTestRunner,
25
+ TestRunner: () => TestRunner,
26
+ device: () => device,
27
+ generateLayerTests: () => generateLayerTests,
28
+ gl: () => gl,
29
+ testInitializeLayer: () => testInitializeLayer,
30
+ testInitializeLayerAsync: () => testInitializeLayerAsync,
31
+ testLayer: () => testLayer,
32
+ testLayerAsync: () => testLayerAsync,
33
+ toLowPrecision: () => toLowPrecision
34
+ });
35
+ module.exports = __toCommonJS(dist_exports);
36
+
37
+ // dist/utils/precision.js
38
+ function toLowPrecision(input, precision = 11) {
39
+ if (typeof input === "number") {
40
+ return Number(input.toPrecision(precision));
41
+ }
42
+ if (Array.isArray(input)) {
43
+ return input.map((item) => toLowPrecision(item, precision));
44
+ }
45
+ if (typeof input === "object") {
46
+ for (const key in input) {
47
+ input[key] = toLowPrecision(input[key], precision);
48
+ }
49
+ }
50
+ return input;
51
+ }
52
+
53
+ // dist/utils/setup-gl.js
54
+ var import_test_utils = require("@luma.gl/test-utils");
55
+ var device = import_test_utils.webglDevice;
56
+ var gl = (0, import_test_utils.createTestContext)({
57
+ width: 1,
58
+ height: 1,
59
+ debug: true
60
+ });
61
+ globalThis.glContext = globalThis.glContext || gl;
62
+
63
+ // dist/lifecycle-test.js
64
+ var import_core = require("@deck.gl/core");
65
+ var import_test_utils2 = require("@probe.gl/test-utils");
66
+ var testViewport = new import_core.MapView({}).makeViewport({
67
+ width: 100,
68
+ height: 100,
69
+ viewState: { longitude: 0, latitude: 0, zoom: 1 }
70
+ });
71
+ function defaultOnError(error, title) {
72
+ if (error) {
73
+ throw error;
74
+ }
75
+ }
76
+ function initializeLayerManager({ layer, viewport = testViewport, onError = defaultOnError }) {
77
+ const layerManager = new import_core.LayerManager(device, { viewport });
78
+ layerManager.setProps({
79
+ onError: (error) => onError(error, `initializing ${layer.id}`)
80
+ });
81
+ layerManager.setLayers([layer]);
82
+ return layerManager;
83
+ }
84
+ function testInitializeLayer(opts) {
85
+ const layerManager = initializeLayerManager(opts);
86
+ if (opts.finalize === false) {
87
+ return {
88
+ finalize: () => layerManager.finalize()
89
+ };
90
+ }
91
+ layerManager.finalize();
92
+ return null;
93
+ }
94
+ async function testInitializeLayerAsync(opts) {
95
+ const layerManager = initializeLayerManager(opts);
96
+ const deckRenderer = new import_core.DeckRenderer(device);
97
+ while (!opts.layer.isLoaded) {
98
+ await update({ layerManager, deckRenderer, oldResourceCounts: {} });
99
+ }
100
+ if (opts.finalize === false) {
101
+ return {
102
+ finalize: () => layerManager.finalize()
103
+ };
104
+ }
105
+ layerManager.finalize();
106
+ return null;
107
+ }
108
+ function testLayer(opts) {
109
+ const { Layer, testCases = [], spies = [], onError = defaultOnError } = opts;
110
+ const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);
111
+ let layer = new Layer();
112
+ for (const testCase of testCases) {
113
+ const oldState = { ...layer.state };
114
+ const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies);
115
+ runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
116
+ Object.keys(spyMap).forEach((k) => spyMap[k].reset());
117
+ layer = newLayer;
118
+ }
119
+ const error = cleanupAfterLayerTests(resources);
120
+ if (error) {
121
+ onError(error, `${Layer.layerName} should delete all resources`);
122
+ }
123
+ }
124
+ async function testLayerAsync(opts) {
125
+ const { Layer, testCases = [], spies = [], onError = defaultOnError } = opts;
126
+ const resources = setupLayerTests(`testing ${Layer.layerName}`, opts);
127
+ let layer = new Layer();
128
+ for (const testCase of testCases) {
129
+ const oldState = { ...layer.state };
130
+ const { layer: newLayer, spyMap } = runLayerTestUpdate(testCase, resources, layer, spies);
131
+ runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
132
+ while (!newLayer.isLoaded) {
133
+ await update(resources);
134
+ runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap);
135
+ }
136
+ Object.keys(spyMap).forEach((k) => spyMap[k].reset());
137
+ layer = newLayer;
138
+ }
139
+ const error = cleanupAfterLayerTests(resources);
140
+ if (error) {
141
+ onError(error, `${Layer.layerName} should delete all resources`);
142
+ }
143
+ }
144
+ function setupLayerTests(testTitle, { viewport = testViewport, timeline, onError = defaultOnError }) {
145
+ const oldResourceCounts = getResourceCounts();
146
+ const layerManager = new import_core.LayerManager(device, { viewport, timeline });
147
+ const deckRenderer = new import_core.DeckRenderer(device);
148
+ const props = {
149
+ layerFilter: null,
150
+ drawPickingColors: false,
151
+ onError: (error) => onError(error, testTitle)
152
+ };
153
+ layerManager.setProps(props);
154
+ deckRenderer.setProps(props);
155
+ return { layerManager, deckRenderer, oldResourceCounts };
156
+ }
157
+ function cleanupAfterLayerTests({ layerManager, deckRenderer, oldResourceCounts }) {
158
+ layerManager.setLayers([]);
159
+ layerManager.finalize();
160
+ deckRenderer.finalize();
161
+ const resourceCounts = getResourceCounts();
162
+ for (const resourceName in resourceCounts) {
163
+ if (resourceCounts[resourceName] !== oldResourceCounts[resourceName]) {
164
+ return new Error(`${resourceCounts[resourceName] - oldResourceCounts[resourceName]} ${resourceName}s`);
165
+ }
166
+ }
167
+ return null;
168
+ }
169
+ function getResourceCounts() {
170
+ const resourceStats = luma.stats.get("Resource Counts");
171
+ return {
172
+ Texture2D: resourceStats.get("Texture2Ds Active").count,
173
+ Buffer: resourceStats.get("Buffers Active").count
174
+ };
175
+ }
176
+ function injectSpies(layer, spies) {
177
+ const spyMap = {};
178
+ if (spies) {
179
+ for (const functionName of spies) {
180
+ spyMap[functionName] = (0, import_test_utils2.makeSpy)(Object.getPrototypeOf(layer), functionName);
181
+ }
182
+ }
183
+ return spyMap;
184
+ }
185
+ function runLayerTestPostUpdateCheck(testCase, newLayer, oldState, spyMap) {
186
+ if (testCase.onAfterUpdate) {
187
+ const subLayers = newLayer.isComposite ? newLayer.getSubLayers() : [];
188
+ const subLayer = subLayers.length ? subLayers[0] : null;
189
+ testCase.onAfterUpdate({
190
+ testCase,
191
+ layer: newLayer,
192
+ oldState,
193
+ subLayers,
194
+ subLayer,
195
+ spies: spyMap
196
+ });
197
+ }
198
+ }
199
+ function runLayerTestUpdate(testCase, { layerManager, deckRenderer }, layer, spies) {
200
+ const { props, updateProps, onBeforeUpdate, viewport = layerManager.context.viewport } = testCase;
201
+ if (onBeforeUpdate) {
202
+ onBeforeUpdate({ layer, testCase });
203
+ }
204
+ if (props) {
205
+ layer = new layer.constructor(props);
206
+ } else if (updateProps) {
207
+ layer = layer.clone(updateProps);
208
+ }
209
+ spies = testCase.spies || spies;
210
+ const spyMap = injectSpies(layer, spies);
211
+ const drawLayers = () => {
212
+ deckRenderer.renderLayers({
213
+ pass: "test",
214
+ views: {},
215
+ effects: [],
216
+ viewports: [viewport],
217
+ layers: layerManager.getLayers(),
218
+ onViewportActive: layerManager.activateViewport
219
+ });
220
+ };
221
+ layerManager.setLayers([layer]);
222
+ drawLayers();
223
+ if (layerManager.needsUpdate()) {
224
+ layerManager.updateLayers();
225
+ drawLayers();
226
+ }
227
+ return { layer, spyMap };
228
+ }
229
+ function update({ layerManager, deckRenderer }) {
230
+ return new Promise((resolve) => {
231
+ const onAnimationFrame = () => {
232
+ if (layerManager.needsUpdate()) {
233
+ layerManager.updateLayers();
234
+ deckRenderer.renderLayers({
235
+ pass: "test",
236
+ views: {},
237
+ effects: [],
238
+ viewports: [layerManager.context.viewport],
239
+ layers: layerManager.getLayers(),
240
+ onViewportActive: layerManager.activateViewport
241
+ });
242
+ resolve();
243
+ return;
244
+ }
245
+ setTimeout(onAnimationFrame, 50);
246
+ };
247
+ onAnimationFrame();
248
+ });
249
+ }
250
+
251
+ // dist/generate-layer-tests.js
252
+ var import_core2 = require("@deck.gl/core");
253
+ function noop() {
254
+ }
255
+ function defaultAssert(condition, comment) {
256
+ if (!condition) {
257
+ throw new Error(comment);
258
+ }
259
+ }
260
+ function generateLayerTests({ Layer, sampleProps = {}, assert = defaultAssert, onBeforeUpdate = noop, onAfterUpdate = noop, runDefaultAsserts = true }) {
261
+ assert(Layer.layerName, "Layer should have display name");
262
+ function wrapTestCaseTitle(title) {
263
+ return `${Layer.layerName}#${title}`;
264
+ }
265
+ const testCases = [
266
+ {
267
+ title: "Empty props",
268
+ props: {}
269
+ },
270
+ {
271
+ title: "Null data",
272
+ updateProps: { data: null }
273
+ },
274
+ {
275
+ title: "Sample data",
276
+ updateProps: sampleProps
277
+ }
278
+ ];
279
+ try {
280
+ new Layer({});
281
+ } catch (error) {
282
+ assert(false, `Construct ${Layer.layerName} throws: ${error.message}`);
283
+ }
284
+ const { _propTypes: propTypes, _mergedDefaultProps: defaultProps } = Layer;
285
+ testCases.push(...makeAltDataTestCases(sampleProps, propTypes));
286
+ for (const propName in Layer.defaultProps) {
287
+ if (!(propName in sampleProps)) {
288
+ const newTestCase = makeAltPropTestCase({ propName, propTypes, defaultProps, sampleProps, assert }) || [];
289
+ testCases.push(...newTestCase);
290
+ }
291
+ }
292
+ testCases.forEach((testCase) => {
293
+ testCase.title = wrapTestCaseTitle(testCase.title);
294
+ const beforeFunc = testCase.onBeforeUpdate || noop;
295
+ const afterFunc = testCase.onAfterUpdate || noop;
296
+ testCase.onBeforeUpdate = (params) => {
297
+ beforeFunc(params);
298
+ onBeforeUpdate(params);
299
+ };
300
+ testCase.onAfterUpdate = (params) => {
301
+ afterFunc(params);
302
+ onAfterUpdate(params);
303
+ if (runDefaultAsserts) {
304
+ if (params.layer.isComposite) {
305
+ const { data } = params.layer.props;
306
+ if (data && typeof data === "object" && (0, import_core2._count)(data)) {
307
+ assert(params.subLayers.length, "Layer should have sublayers");
308
+ }
309
+ } else {
310
+ assert(params.layer.getModels().length, "Layer should have models");
311
+ }
312
+ }
313
+ };
314
+ });
315
+ return testCases;
316
+ }
317
+ function makeAltPropTestCase({ propName, propTypes, defaultProps, sampleProps, assert }) {
318
+ const newProps = { ...sampleProps };
319
+ const propDef = propTypes[propName];
320
+ if (!propDef) {
321
+ return null;
322
+ }
323
+ switch (propDef.type) {
324
+ case "boolean":
325
+ newProps[propName] = !defaultProps[propName];
326
+ return [
327
+ {
328
+ title: `${propName}: ${String(newProps[propName])}`,
329
+ props: newProps
330
+ }
331
+ ];
332
+ case "number":
333
+ if ("max" in propDef) {
334
+ newProps[propName] = propDef.max;
335
+ } else if ("min" in propDef) {
336
+ newProps[propName] = propDef.min;
337
+ } else {
338
+ newProps[propName] = defaultProps[propName] + 1;
339
+ }
340
+ return [
341
+ {
342
+ title: `${propName}: ${String(newProps[propName])}`,
343
+ props: newProps
344
+ }
345
+ ];
346
+ case "accessor": {
347
+ if (typeof defaultProps[propName] === "function") {
348
+ return null;
349
+ }
350
+ let callCount = 0;
351
+ newProps[propName] = () => {
352
+ callCount++;
353
+ return defaultProps[propName];
354
+ };
355
+ newProps.updateTriggers = {
356
+ [propName]: "function"
357
+ };
358
+ const onBeforeUpdate = () => callCount = 0;
359
+ const onAfterUpdate = () => assert(callCount > 0, "accessor function is called");
360
+ return [
361
+ {
362
+ title: `${propName}: () => ${defaultProps[propName]}`,
363
+ props: newProps,
364
+ onBeforeUpdate,
365
+ onAfterUpdate
366
+ },
367
+ {
368
+ title: `${propName}: updateTrigger`,
369
+ updateProps: {
370
+ updateTriggers: {
371
+ [propName]: "function+trigger"
372
+ }
373
+ },
374
+ onBeforeUpdate,
375
+ onAfterUpdate
376
+ }
377
+ ];
378
+ }
379
+ default:
380
+ return null;
381
+ }
382
+ }
383
+ function makeAltDataTestCases(props, propTypes) {
384
+ const originalData = props.data;
385
+ if (!Array.isArray(originalData)) {
386
+ return [];
387
+ }
388
+ const partialUpdateProps = {
389
+ data: originalData.slice(),
390
+ _dataDiff: () => [{ startRow: 0, endRow: 2 }]
391
+ };
392
+ const genIterableProps = {
393
+ data: new Set(originalData),
394
+ _dataDiff: null
395
+ };
396
+ const nonIterableProps = {
397
+ data: {
398
+ length: originalData.length
399
+ }
400
+ };
401
+ for (const propName in props) {
402
+ if (propTypes[propName].type === "accessor") {
403
+ nonIterableProps[propName] = (_, info) => props[propName](originalData[info.index], info);
404
+ }
405
+ }
406
+ return [
407
+ {
408
+ title: "Partial update",
409
+ updateProps: partialUpdateProps
410
+ },
411
+ {
412
+ title: "Generic iterable data",
413
+ updateProps: genIterableProps
414
+ },
415
+ {
416
+ title: "non-iterable data",
417
+ updateProps: nonIterableProps
418
+ }
419
+ ];
420
+ }
421
+
422
+ // dist/test-runner.js
423
+ var import_core3 = require("@deck.gl/core");
424
+ var DEFAULT_DECK_PROPS = {
425
+ ...import_core3.Deck.defaultProps,
426
+ id: "deckgl-render-test",
427
+ width: 800,
428
+ height: 450,
429
+ style: { position: "absolute", left: "0px", top: "0px" },
430
+ views: [new import_core3.MapView({})],
431
+ useDevicePixels: false,
432
+ debug: true
433
+ };
434
+ var DEFAULT_TEST_OPTIONS = {
435
+ onTestStart: (testCase) => console.log(`# ${testCase.name}`),
436
+ onTestPass: (testCase) => console.log(`ok ${testCase.name} passed`),
437
+ onTestFail: (testCase) => console.log(`not ok ${testCase.name} failed`),
438
+ timeout: 2e3
439
+ };
440
+ var TestRunner = class {
441
+ constructor(props = {}, options) {
442
+ this.deck = null;
443
+ this.isRunning = false;
444
+ this._testCases = [];
445
+ this._currentTestCase = null;
446
+ this._testCaseData = null;
447
+ this.props = { ...DEFAULT_DECK_PROPS, ...props };
448
+ this.isHeadless = Boolean(window.browserTestDriver_isHeadless);
449
+ this.testOptions = { ...DEFAULT_TEST_OPTIONS, ...options };
450
+ }
451
+ get defaultTestCase() {
452
+ throw new Error("Not implemented");
453
+ }
454
+ add(testCases) {
455
+ if (!Array.isArray(testCases)) {
456
+ testCases = [testCases];
457
+ }
458
+ for (const testCase of testCases) {
459
+ this._testCases.push(testCase);
460
+ }
461
+ return this;
462
+ }
463
+ run(options = {}) {
464
+ Object.assign(this.testOptions, options);
465
+ return new Promise((resolve, reject) => {
466
+ this.deck = new import_core3.Deck({
467
+ ...this.props,
468
+ onDeviceInitialized: this._onDeviceInitialized.bind(this),
469
+ onLoad: resolve
470
+ });
471
+ this.isRunning = true;
472
+ this._currentTestCase = null;
473
+ }).then(() => {
474
+ let promise = Promise.resolve();
475
+ this._testCases.forEach((testCase) => {
476
+ promise = promise.then(() => this._runTest(testCase));
477
+ });
478
+ return promise;
479
+ }).catch((error) => {
480
+ this.fail({ error: error.message });
481
+ }).finally(() => {
482
+ this.deck.finalize();
483
+ this.deck = null;
484
+ });
485
+ }
486
+ initTestCase(testCase) {
487
+ for (const key in this.defaultTestCase) {
488
+ if (!(key in testCase)) {
489
+ testCase[key] = this.defaultTestCase[key];
490
+ }
491
+ }
492
+ this.testOptions.onTestStart(testCase);
493
+ }
494
+ pass(result) {
495
+ this.testOptions.onTestPass(this._currentTestCase, result);
496
+ }
497
+ fail(result) {
498
+ this.testOptions.onTestFail(this._currentTestCase, result);
499
+ }
500
+ _onDeviceInitialized(device2) {
501
+ this.gpuVendor = device2.info.vendor;
502
+ }
503
+ async _runTest(testCase) {
504
+ this._currentTestCase = testCase;
505
+ this.initTestCase(testCase);
506
+ const timeout = testCase.timeout || this.testOptions.timeout;
507
+ const task = this.runTestCase(testCase);
508
+ const timeoutTask = new Promise((_, reject) => {
509
+ setTimeout(() => {
510
+ reject("Timeout");
511
+ }, timeout);
512
+ });
513
+ try {
514
+ await Promise.race([task, timeoutTask]);
515
+ await this.assert(testCase);
516
+ } catch (err) {
517
+ if (err === "Timeout") {
518
+ this.fail({ error: "Timeout" });
519
+ }
520
+ }
521
+ }
522
+ };
523
+
524
+ // dist/utils/dom.js
525
+ function getBoundingBoxInPage(domElement) {
526
+ const bbox = domElement.getBoundingClientRect();
527
+ return {
528
+ x: window.scrollX + bbox.x,
529
+ y: window.scrollY + bbox.y,
530
+ width: bbox.width,
531
+ height: bbox.height
532
+ };
533
+ }
534
+
535
+ // dist/snapshot-test-runner.js
536
+ var DEFAULT_TEST_OPTIONS2 = {
537
+ imageDiffOptions: {}
538
+ };
539
+ var DEFAULT_TEST_CASE = {
540
+ name: "Unnamed snapshot test",
541
+ props: {},
542
+ onBeforeRender: ({ deck, layers }) => {
543
+ },
544
+ onAfterRender: ({ deck, layers, done }) => {
545
+ if (layers.every((layer) => layer.isLoaded)) {
546
+ done();
547
+ }
548
+ },
549
+ goldenImage: ""
550
+ };
551
+ var SnapshotTestRunner = class extends TestRunner {
552
+ constructor(props) {
553
+ super(props, DEFAULT_TEST_OPTIONS2);
554
+ this._isDiffing = false;
555
+ this._isDiffing = false;
556
+ }
557
+ get defaultTestCase() {
558
+ return DEFAULT_TEST_CASE;
559
+ }
560
+ initTestCase(testCase) {
561
+ super.initTestCase(testCase);
562
+ if (!testCase.goldenImage) {
563
+ throw new Error(`Test case ${testCase.name} does not have golden image`);
564
+ }
565
+ }
566
+ runTestCase(testCase) {
567
+ const deck = this.deck;
568
+ return new Promise((resolve) => {
569
+ deck.setProps({
570
+ ...this.props,
571
+ ...testCase,
572
+ onBeforeRender: () => {
573
+ testCase.onBeforeRender({
574
+ deck,
575
+ layers: this.deck.layerManager.getLayers()
576
+ });
577
+ },
578
+ onAfterRender: () => {
579
+ testCase.onAfterRender({
580
+ deck,
581
+ layers: this.deck.layerManager.getLayers(),
582
+ done: resolve
583
+ });
584
+ }
585
+ });
586
+ });
587
+ }
588
+ async assert(testCase) {
589
+ if (this._isDiffing) {
590
+ return;
591
+ }
592
+ this._isDiffing = true;
593
+ const diffOptions = {
594
+ ...this.testOptions.imageDiffOptions,
595
+ ...testCase.imageDiffOptions,
596
+ goldenImage: testCase.goldenImage,
597
+ region: getBoundingBoxInPage(this.deck.getCanvas())
598
+ };
599
+ const result = await window.browserTestDriver_captureAndDiffScreen(diffOptions);
600
+ if (result.success) {
601
+ this.pass(result);
602
+ } else {
603
+ this.fail(result);
604
+ }
605
+ this._isDiffing = false;
606
+ }
607
+ };
608
+
609
+ // dist/interaction-test-runner.js
610
+ var DEFAULT_TEST_CASE2 = {
611
+ name: "Unnamed interaction test",
612
+ events: [],
613
+ onBeforeEvents: ({ deck }) => {
614
+ },
615
+ onAfterEvents: ({ deck, layers, context }) => {
616
+ }
617
+ };
618
+ function sleep(timeout) {
619
+ return new Promise((resolve) => window.setTimeout(resolve, timeout));
620
+ }
621
+ var InteractionTestRunner = class extends TestRunner {
622
+ get defaultTestCase() {
623
+ return DEFAULT_TEST_CASE2;
624
+ }
625
+ async runTestCase(testCase) {
626
+ testCase.context = testCase.onBeforeEvents({
627
+ deck: this.deck
628
+ });
629
+ for (const event of testCase.events) {
630
+ if (event.wait) {
631
+ await sleep(event.wait);
632
+ } else {
633
+ await window.browserTestDriver_emulateInput(event);
634
+ }
635
+ }
636
+ }
637
+ async assert(testCase) {
638
+ testCase.onAfterEvents({
639
+ deck: this.deck,
640
+ layers: this.deck.layerManager.getLayers(),
641
+ context: testCase.context
642
+ });
643
+ }
644
+ };
645
+ //# sourceMappingURL=index.cjs.map