@seleniumhq/side-runtime 4.0.0-alpha.4 → 4.0.0-alpha.40

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 (96) hide show
  1. package/dist/__tests__/callstack.spec.d.ts +2 -0
  2. package/dist/__tests__/callstack.spec.d.ts.map +1 -0
  3. package/dist/__tests__/callstack.spec.js +63 -0
  4. package/dist/__tests__/callstack.spec.js.map +1 -0
  5. package/dist/__tests__/integration/playback-webdriver.spec.d.ts +2 -0
  6. package/dist/__tests__/integration/playback-webdriver.spec.d.ts.map +1 -0
  7. package/dist/__tests__/integration/playback-webdriver.spec.js +249 -0
  8. package/dist/__tests__/integration/playback-webdriver.spec.js.map +1 -0
  9. package/dist/__tests__/playback-tree/command-leveler.spec.d.ts +2 -0
  10. package/dist/__tests__/playback-tree/command-leveler.spec.d.ts.map +1 -0
  11. package/dist/__tests__/playback-tree/command-leveler.spec.js +69 -0
  12. package/dist/__tests__/playback-tree/command-leveler.spec.js.map +1 -0
  13. package/dist/__tests__/playback-tree/command-node.spec.d.ts +2 -0
  14. package/dist/__tests__/playback-tree/command-node.spec.d.ts.map +1 -0
  15. package/dist/__tests__/playback-tree/command-node.spec.js +232 -0
  16. package/dist/__tests__/playback-tree/command-node.spec.js.map +1 -0
  17. package/dist/__tests__/playback-tree/playback-tree.spec.d.ts +2 -0
  18. package/dist/__tests__/playback-tree/playback-tree.spec.d.ts.map +1 -0
  19. package/dist/__tests__/playback-tree/playback-tree.spec.js +463 -0
  20. package/dist/__tests__/playback-tree/playback-tree.spec.js.map +1 -0
  21. package/dist/__tests__/playback-tree/syntax-validation.spec.d.ts +2 -0
  22. package/dist/__tests__/playback-tree/syntax-validation.spec.d.ts.map +1 -0
  23. package/dist/__tests__/playback-tree/syntax-validation.spec.js +224 -0
  24. package/dist/__tests__/playback-tree/syntax-validation.spec.js.map +1 -0
  25. package/dist/__tests__/playback.spec.d.ts +2 -0
  26. package/dist/__tests__/playback.spec.d.ts.map +1 -0
  27. package/dist/__tests__/playback.spec.js +2161 -0
  28. package/dist/__tests__/playback.spec.js.map +1 -0
  29. package/dist/__tests__/preprocessors.spec.d.ts +2 -0
  30. package/dist/__tests__/preprocessors.spec.d.ts.map +1 -0
  31. package/dist/__tests__/preprocessors.spec.js +141 -0
  32. package/dist/__tests__/preprocessors.spec.js.map +1 -0
  33. package/dist/__tests__/util/FakeExecutor.d.ts +32 -0
  34. package/dist/__tests__/util/FakeExecutor.d.ts.map +1 -0
  35. package/dist/__tests__/util/FakeExecutor.js +81 -0
  36. package/dist/__tests__/util/FakeExecutor.js.map +1 -0
  37. package/dist/__tests__/util/JestFakeExecutor.d.ts +32 -0
  38. package/dist/__tests__/util/JestFakeExecutor.d.ts.map +1 -0
  39. package/dist/__tests__/util/JestFakeExecutor.js +79 -0
  40. package/dist/__tests__/util/JestFakeExecutor.js.map +1 -0
  41. package/dist/__tests__/utils.spec.d.ts +2 -0
  42. package/dist/__tests__/utils.spec.d.ts.map +1 -0
  43. package/dist/__tests__/utils.spec.js +40 -0
  44. package/dist/__tests__/utils.spec.js.map +1 -0
  45. package/dist/__tests__/webdriver.spec.d.ts +2 -0
  46. package/dist/__tests__/webdriver.spec.d.ts.map +1 -0
  47. package/dist/__tests__/webdriver.spec.js +522 -0
  48. package/dist/__tests__/webdriver.spec.js.map +1 -0
  49. package/dist/callstack.d.ts +1 -1
  50. package/dist/callstack.d.ts.map +1 -1
  51. package/dist/playback-tree/command-leveler.d.ts +2 -2
  52. package/dist/playback-tree/command-leveler.d.ts.map +1 -1
  53. package/dist/playback-tree/command-leveler.js +4 -2
  54. package/dist/playback-tree/command-leveler.js.map +1 -1
  55. package/dist/playback-tree/command-node.d.ts +4 -4
  56. package/dist/playback-tree/command-node.d.ts.map +1 -1
  57. package/dist/playback-tree/command-node.js +70 -39
  58. package/dist/playback-tree/command-node.js.map +1 -1
  59. package/dist/playback-tree/commands.d.ts +12 -9
  60. package/dist/playback-tree/commands.d.ts.map +1 -1
  61. package/dist/playback-tree/commands.js +22 -14
  62. package/dist/playback-tree/commands.js.map +1 -1
  63. package/dist/playback-tree/index.d.ts +1 -1
  64. package/dist/playback-tree/index.d.ts.map +1 -1
  65. package/dist/playback-tree/index.js +5 -2
  66. package/dist/playback-tree/index.js.map +1 -1
  67. package/dist/playback-tree/syntax-validation.d.ts.map +1 -1
  68. package/dist/playback-tree/syntax-validation.js +4 -2
  69. package/dist/playback-tree/syntax-validation.js.map +1 -1
  70. package/dist/playback.d.ts +14 -12
  71. package/dist/playback.d.ts.map +1 -1
  72. package/dist/playback.js +59 -29
  73. package/dist/playback.js.map +1 -1
  74. package/dist/plugins.d.ts +4 -3
  75. package/dist/plugins.d.ts.map +1 -1
  76. package/dist/plugins.js +28 -9
  77. package/dist/plugins.js.map +1 -1
  78. package/dist/preprocessors.d.ts +2 -2
  79. package/dist/preprocessors.d.ts.map +1 -1
  80. package/dist/preprocessors.js +12 -28
  81. package/dist/preprocessors.js.map +1 -1
  82. package/dist/recording-syncronizer-webdriver.d.ts +3 -3
  83. package/dist/recording-syncronizer.d.ts +4 -3
  84. package/dist/recording-syncronizer.d.ts.map +1 -1
  85. package/dist/recording-syncronizer.js +1 -1
  86. package/dist/recording-syncronizer.js.map +1 -1
  87. package/dist/types.d.ts +25 -27
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/variables.d.ts.map +1 -1
  90. package/dist/variables.js +6 -0
  91. package/dist/variables.js.map +1 -1
  92. package/dist/webdriver.d.ts +36 -44
  93. package/dist/webdriver.d.ts.map +1 -1
  94. package/dist/webdriver.js +264 -218
  95. package/dist/webdriver.js.map +1 -1
  96. package/package.json +16 -14
@@ -0,0 +1,2161 @@
1
+ "use strict";
2
+ // Licensed to the Software Freedom Conservancy (SFC) under one
3
+ // or more contributor license agreements. See the NOTICE file
4
+ // distributed with this work for additional information
5
+ // regarding copyright ownership. The SFC licenses this file
6
+ // to you under the Apache License, Version 2.0 (the
7
+ // "License"); you may not use this file except in compliance
8
+ // with the License. You may obtain a copy of the License at
9
+ //
10
+ // http://www.apache.org/licenses/LICENSE-2.0
11
+ //
12
+ // Unless required by applicable law or agreed to in writing,
13
+ // software distributed under the License is distributed on an
14
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ // KIND, either express or implied. See the License for the
16
+ // specific language governing permissions and limitations
17
+ // under the License.
18
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ var desc = Object.getOwnPropertyDescriptor(m, k);
21
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
+ desc = { enumerable: true, get: function() { return m[k]; } };
23
+ }
24
+ Object.defineProperty(o, k2, desc);
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ var __importDefault = (this && this.__importDefault) || function (mod) {
42
+ return (mod && mod.__esModule) ? mod : { "default": mod };
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ const playback_1 = __importStar(require("../playback"));
46
+ const errors_1 = require("../errors");
47
+ const variables_1 = __importDefault(require("../variables"));
48
+ const JestFakeExecutor_1 = __importDefault(require("./util/JestFakeExecutor"));
49
+ describe('Playback', () => {
50
+ describe('Event emitting', () => {
51
+ describe('Control Flow', () => {
52
+ it('forEach', async () => {
53
+ const test = {
54
+ id: '1',
55
+ name: 'Test',
56
+ commands: [
57
+ {
58
+ id: 'asdf0',
59
+ command: 'forEach',
60
+ target: 'collectionVarName',
61
+ value: 'iteratorVarName',
62
+ },
63
+ {
64
+ id: 'asdf1',
65
+ command: 'open',
66
+ target: '',
67
+ value: '',
68
+ },
69
+ {
70
+ id: 'asdf2',
71
+ command: 'end',
72
+ target: '',
73
+ value: '',
74
+ },
75
+ ],
76
+ };
77
+ const executor = new JestFakeExecutor_1.default();
78
+ const variables = new variables_1.default();
79
+ variables.set('collectionVarName', ['a', 'b', 'c']);
80
+ const playback = new playback_1.default({
81
+ baseUrl: '',
82
+ executor: executor,
83
+ getTestByName: (_name = '') => ({}),
84
+ logger: console,
85
+ variables,
86
+ });
87
+ const cb = jest.fn();
88
+ playback['event-emitter'].on(playback_1.PlaybackEvents.CONTROL_FLOW_CHANGED, cb);
89
+ await (await playback.play(test))();
90
+ const results = flat(cb.mock.calls);
91
+ expect(results).toMatchSnapshot();
92
+ });
93
+ });
94
+ });
95
+ describe('Playback test queue', () => {
96
+ it('should play a test', async () => {
97
+ const test = {
98
+ id: '1',
99
+ name: 'Test',
100
+ commands: [
101
+ {
102
+ id: 'a',
103
+ command: 'open',
104
+ target: '',
105
+ value: '',
106
+ },
107
+ {
108
+ id: 'b',
109
+ command: 'open',
110
+ target: '',
111
+ value: '',
112
+ },
113
+ {
114
+ id: 'c',
115
+ command: 'open',
116
+ target: '',
117
+ value: '',
118
+ },
119
+ ],
120
+ };
121
+ const executor = new JestFakeExecutor_1.default();
122
+ executor.doOpen.mockImplementation(async () => { });
123
+ const playback = new playback_1.default({
124
+ executor,
125
+ });
126
+ await (await playback.play(test))();
127
+ expect(executor.doOpen).toHaveBeenCalledTimes(3);
128
+ });
129
+ it('should play a test twice', async () => {
130
+ const test = {
131
+ id: '1',
132
+ name: 'Test',
133
+ commands: [
134
+ {
135
+ id: 'a',
136
+ command: 'open',
137
+ target: '',
138
+ value: '',
139
+ },
140
+ {
141
+ id: 'b',
142
+ command: 'open',
143
+ target: '',
144
+ value: '',
145
+ },
146
+ {
147
+ id: 'c',
148
+ command: 'open',
149
+ target: '',
150
+ value: '',
151
+ },
152
+ ],
153
+ };
154
+ const executor = new JestFakeExecutor_1.default();
155
+ executor.doOpen.mockImplementation(async () => { });
156
+ const playback = new playback_1.default({
157
+ executor,
158
+ });
159
+ await (await playback.play(test))();
160
+ await (await playback.play(test))();
161
+ expect(executor.doOpen).toHaveBeenCalledTimes(6);
162
+ });
163
+ it("should init the executor if it hasn't been initialized", async () => {
164
+ const test = {
165
+ id: '1',
166
+ name: 'Test',
167
+ commands: [
168
+ {
169
+ id: 'a',
170
+ command: 'open',
171
+ target: '',
172
+ value: '',
173
+ },
174
+ {
175
+ id: 'b',
176
+ command: 'open',
177
+ target: '',
178
+ value: '',
179
+ },
180
+ {
181
+ id: 'c',
182
+ command: 'open',
183
+ target: '',
184
+ value: '',
185
+ },
186
+ ],
187
+ };
188
+ const executor = new JestFakeExecutor_1.default();
189
+ executor.doOpen.mockImplementation(async () => { });
190
+ const playback = new playback_1.default({
191
+ executor,
192
+ });
193
+ await (await playback.play(test))();
194
+ expect(executor.init).toHaveBeenCalled();
195
+ executor.cleanup();
196
+ try {
197
+ await (await playback.play(test))();
198
+ }
199
+ catch (err) {
200
+ expect(err.message).toBe('executor is dead');
201
+ }
202
+ });
203
+ it('should throw if trying to play while a test is running', async () => {
204
+ const test = {
205
+ id: '1',
206
+ name: 'Test',
207
+ commands: [
208
+ {
209
+ id: 'a',
210
+ command: 'open',
211
+ target: '',
212
+ value: '',
213
+ },
214
+ {
215
+ id: 'b',
216
+ command: 'open',
217
+ target: '',
218
+ value: '',
219
+ },
220
+ {
221
+ id: 'c',
222
+ command: 'open',
223
+ target: '',
224
+ value: '',
225
+ },
226
+ ],
227
+ };
228
+ const executor = new JestFakeExecutor_1.default({});
229
+ executor.doOpen.mockImplementation(async () => { });
230
+ const playback = new playback_1.default({
231
+ executor,
232
+ });
233
+ await playback.play(test);
234
+ expect.assertions(1);
235
+ try {
236
+ await (await playback.play(test))();
237
+ }
238
+ catch (err) {
239
+ expect(err.message).toBe("Can't start playback while a different playback is running");
240
+ }
241
+ });
242
+ it("should not throw an uncought error if finish wasn't called", () => {
243
+ const test = {
244
+ id: '1',
245
+ name: 'Test',
246
+ commands: [
247
+ {
248
+ id: 'a',
249
+ command: 'open',
250
+ target: '',
251
+ value: '',
252
+ },
253
+ {
254
+ id: 'b',
255
+ command: 'error',
256
+ target: '',
257
+ value: '',
258
+ },
259
+ {
260
+ id: 'c',
261
+ command: 'open',
262
+ target: '',
263
+ value: '',
264
+ },
265
+ ],
266
+ };
267
+ const executor = new JestFakeExecutor_1.default({});
268
+ executor.doOpen.mockImplementation(async () => { });
269
+ const playback = new playback_1.default({
270
+ executor,
271
+ });
272
+ playback.play(test);
273
+ return psetTimeout(2);
274
+ });
275
+ it('should fail to play a test with an unknown command', async () => {
276
+ const test = {
277
+ id: '1',
278
+ name: 'Test',
279
+ commands: [
280
+ {
281
+ id: 'a',
282
+ command: 'fail',
283
+ target: '',
284
+ value: '',
285
+ },
286
+ ],
287
+ };
288
+ const executor = new JestFakeExecutor_1.default({});
289
+ const playback = new playback_1.default({
290
+ executor,
291
+ });
292
+ expect.assertions(1);
293
+ try {
294
+ await (await playback.play(test))();
295
+ }
296
+ catch (err) {
297
+ expect(err.message).toBe('Unknown command fail');
298
+ }
299
+ });
300
+ it('should pass a test with a failing verify', async () => {
301
+ const test = {
302
+ id: '1',
303
+ name: 'Test',
304
+ commands: [
305
+ {
306
+ id: 'a',
307
+ command: 'verifyText',
308
+ target: '',
309
+ value: '',
310
+ },
311
+ ],
312
+ };
313
+ const executor = new JestFakeExecutor_1.default({});
314
+ executor.doVerifyText.mockImplementation(async () => {
315
+ throw new errors_1.VerificationError('failed to verify');
316
+ });
317
+ const playback = new playback_1.default({
318
+ executor,
319
+ });
320
+ expect(async () => await (await playback.play(test))()).not.toThrow();
321
+ });
322
+ it('should play a single command', async () => {
323
+ const command = {
324
+ id: 'a',
325
+ command: 'open',
326
+ target: '',
327
+ value: '',
328
+ };
329
+ const executor = new JestFakeExecutor_1.default({});
330
+ executor.doOpen.mockImplementation(async () => { });
331
+ const playback = new playback_1.default({
332
+ executor,
333
+ });
334
+ await playback.playSingleCommand(command);
335
+ expect(executor.doOpen).toHaveBeenCalledTimes(1);
336
+ });
337
+ it('should play a single command twice', async () => {
338
+ const command = {
339
+ id: 'a',
340
+ command: 'open',
341
+ target: '',
342
+ value: '',
343
+ };
344
+ const executor = new JestFakeExecutor_1.default({});
345
+ executor.doOpen.mockImplementation(async () => { });
346
+ const playback = new playback_1.default({
347
+ executor,
348
+ });
349
+ await playback.playSingleCommand(command);
350
+ await playback.playSingleCommand(command);
351
+ expect(executor.doOpen).toHaveBeenCalledTimes(2);
352
+ });
353
+ it('should not be able to play a single command twice at the same time', async () => {
354
+ const command = {
355
+ id: 'a',
356
+ command: 'open',
357
+ target: '',
358
+ value: '',
359
+ };
360
+ const executor = new JestFakeExecutor_1.default({});
361
+ executor.doOpen.mockImplementation(async (_url) => {
362
+ await psetTimeout(1);
363
+ return;
364
+ });
365
+ const playback = new playback_1.default({
366
+ executor,
367
+ });
368
+ playback.playSingleCommand(command);
369
+ try {
370
+ await playback.playSingleCommand(command);
371
+ }
372
+ catch (err) {
373
+ expect(err.message).toBe("Can't play a command while playback is running");
374
+ }
375
+ });
376
+ it('should play a single command while a test case is paused and then continue', async () => {
377
+ const test = {
378
+ id: '1',
379
+ name: 'Test',
380
+ commands: [
381
+ {
382
+ id: 'a',
383
+ command: 'open',
384
+ target: '1',
385
+ value: '',
386
+ },
387
+ {
388
+ id: 'b',
389
+ command: 'open',
390
+ target: '2',
391
+ value: '',
392
+ },
393
+ {
394
+ id: 'c',
395
+ command: 'open',
396
+ target: '3',
397
+ value: '',
398
+ },
399
+ ],
400
+ };
401
+ const executor = new JestFakeExecutor_1.default({});
402
+ executor.doOpen.mockImplementation(async (_url) => {
403
+ await psetTimeout(10);
404
+ });
405
+ const playback = new playback_1.default({
406
+ executor,
407
+ });
408
+ await playback.play(test);
409
+ await psetTimeout(15);
410
+ await playback.pause();
411
+ await playback.playSingleCommand({
412
+ id: 'a',
413
+ command: 'open',
414
+ target: '4',
415
+ value: '',
416
+ });
417
+ await playback.resume();
418
+ await psetTimeout(50);
419
+ expect(executor.doOpen).toHaveBeenCalledTimes(4);
420
+ }, 10000);
421
+ it('should not be able to play a single command while a test case is playing', async () => {
422
+ const test = {
423
+ id: '1',
424
+ name: 'Test',
425
+ commands: [
426
+ {
427
+ id: 'a',
428
+ command: 'open',
429
+ target: '',
430
+ value: '',
431
+ },
432
+ {
433
+ id: 'b',
434
+ command: 'open',
435
+ target: '',
436
+ value: '',
437
+ },
438
+ {
439
+ id: 'c',
440
+ command: 'open',
441
+ target: '',
442
+ value: '',
443
+ },
444
+ ],
445
+ };
446
+ const executor = new JestFakeExecutor_1.default({});
447
+ executor.doOpen.mockImplementation(async (_url) => {
448
+ await psetTimeout(1);
449
+ return;
450
+ });
451
+ const playback = new playback_1.default({
452
+ executor,
453
+ });
454
+ expect.assertions(1);
455
+ await playback.play(test);
456
+ try {
457
+ await playback.playSingleCommand({
458
+ id: 'a',
459
+ command: 'open',
460
+ target: '',
461
+ value: '',
462
+ });
463
+ }
464
+ catch (err) {
465
+ expect(err.message).toBe("Can't play a command while playback is running");
466
+ }
467
+ });
468
+ it('should play a nested test case', async () => {
469
+ const test = {
470
+ id: '1',
471
+ name: 'Test',
472
+ commands: [
473
+ {
474
+ id: '1',
475
+ command: 'open',
476
+ target: '',
477
+ value: '',
478
+ },
479
+ {
480
+ id: '2',
481
+ command: 'run',
482
+ target: 'test2',
483
+ value: '',
484
+ },
485
+ {
486
+ id: '3',
487
+ command: 'open',
488
+ target: '',
489
+ value: '',
490
+ },
491
+ ],
492
+ };
493
+ const test2 = {
494
+ id: '2',
495
+ name: 'Test2',
496
+ commands: [
497
+ {
498
+ id: '4',
499
+ command: 'open',
500
+ target: '',
501
+ value: '',
502
+ },
503
+ {
504
+ id: '5',
505
+ command: 'open',
506
+ target: '',
507
+ value: '',
508
+ },
509
+ {
510
+ id: '6',
511
+ command: 'open',
512
+ target: '',
513
+ value: '',
514
+ },
515
+ ],
516
+ };
517
+ const executor = new JestFakeExecutor_1.default({});
518
+ executor.doOpen.mockImplementation(async () => {
519
+ await psetTimeout(0);
520
+ return;
521
+ });
522
+ const playback = new playback_1.default({
523
+ executor,
524
+ getTestByName: () => test2,
525
+ });
526
+ const cb = jest.fn();
527
+ playback['event-emitter'].on(playback_1.PlaybackEvents.CALL_STACK_CHANGED, cb);
528
+ const commandResults = [];
529
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
530
+ await (await playback.play(test))();
531
+ const results = flat(cb.mock.calls);
532
+ expect(results.length).toBe(2);
533
+ expect(results[0].change).toBe(playback_1.CallstackChange.CALLED);
534
+ expect(results[1].change).toBe(playback_1.CallstackChange.UNWINDED);
535
+ expect(commandResults).toMatchSnapshot();
536
+ });
537
+ it("should fail to execute a nested test without providing 'getTestByName'", async () => {
538
+ const test = {
539
+ id: '1',
540
+ name: 'Test',
541
+ commands: [
542
+ {
543
+ id: '1',
544
+ command: 'open',
545
+ target: '',
546
+ value: '',
547
+ },
548
+ {
549
+ id: '2',
550
+ command: 'run',
551
+ target: 'test2',
552
+ value: '',
553
+ },
554
+ {
555
+ id: '3',
556
+ command: 'open',
557
+ target: '',
558
+ value: '',
559
+ },
560
+ ],
561
+ };
562
+ const executor = new JestFakeExecutor_1.default({});
563
+ executor.doOpen.mockImplementation(async () => {
564
+ await psetTimeout(0);
565
+ return;
566
+ });
567
+ const playback = new playback_1.default({
568
+ executor,
569
+ });
570
+ expect.assertions(1);
571
+ try {
572
+ await (await playback.play(test))();
573
+ }
574
+ catch (err) {
575
+ expect(err.message).toBe("'run' command is not supported");
576
+ }
577
+ });
578
+ it("should fail to execute a nested test if the test doesn't exist", async () => {
579
+ const test = {
580
+ id: '1',
581
+ name: 'Test',
582
+ commands: [
583
+ {
584
+ id: '1',
585
+ command: 'open',
586
+ target: '',
587
+ value: '',
588
+ },
589
+ {
590
+ id: '2',
591
+ command: 'run',
592
+ target: 'test2',
593
+ value: '',
594
+ },
595
+ {
596
+ id: '3',
597
+ command: 'open',
598
+ target: '',
599
+ value: '',
600
+ },
601
+ ],
602
+ };
603
+ const executor = new JestFakeExecutor_1.default({});
604
+ executor.doOpen.mockImplementation(async () => {
605
+ await psetTimeout(0);
606
+ return;
607
+ });
608
+ const playback = new playback_1.default({
609
+ executor,
610
+ getTestByName: () => undefined,
611
+ });
612
+ expect.assertions(1);
613
+ try {
614
+ await (await playback.play(test))();
615
+ }
616
+ catch (err) {
617
+ expect(err.message).toBe("Can't run unknown test: test2");
618
+ }
619
+ });
620
+ it('should play a test step by step', async () => {
621
+ const test = {
622
+ id: '1',
623
+ name: 'Test',
624
+ commands: [
625
+ {
626
+ id: 'a',
627
+ command: 'open',
628
+ target: '',
629
+ value: '',
630
+ },
631
+ {
632
+ id: 'b',
633
+ command: 'open',
634
+ target: '',
635
+ value: '',
636
+ },
637
+ {
638
+ id: 'c',
639
+ command: 'open',
640
+ target: '',
641
+ value: '',
642
+ },
643
+ ],
644
+ };
645
+ const executor = new JestFakeExecutor_1.default({});
646
+ executor.doOpen.mockImplementation(async () => {
647
+ await psetTimeout(0);
648
+ return;
649
+ });
650
+ const playback = new playback_1.default({
651
+ executor,
652
+ });
653
+ const playPromise = await playback.play(test, { pauseImmediately: true });
654
+ expect(executor.doOpen).toHaveBeenCalledTimes(0);
655
+ await psetTimeout(1);
656
+ await playback.step();
657
+ expect(executor.doOpen).toHaveBeenCalledTimes(1);
658
+ await playback.step(2);
659
+ expect(executor.doOpen).toHaveBeenCalledTimes(3);
660
+ await playback.resume();
661
+ await playPromise();
662
+ expect(executor.doOpen).toHaveBeenCalledTimes(3);
663
+ });
664
+ it('should reject step if one of the steps failed', async () => {
665
+ const test = {
666
+ id: '1',
667
+ name: 'Test',
668
+ commands: [
669
+ {
670
+ id: 'a',
671
+ command: 'open',
672
+ target: '',
673
+ value: '',
674
+ },
675
+ {
676
+ id: 'b',
677
+ command: 'fail',
678
+ target: '',
679
+ value: '',
680
+ },
681
+ {
682
+ id: 'c',
683
+ command: 'open',
684
+ target: '',
685
+ value: '',
686
+ },
687
+ ],
688
+ };
689
+ const executor = new JestFakeExecutor_1.default({});
690
+ executor.doOpen.mockImplementation(async () => {
691
+ await psetTimeout(0);
692
+ return;
693
+ });
694
+ const playback = new playback_1.default({
695
+ executor,
696
+ });
697
+ const playPromise = await playback.play(test, { pauseImmediately: true });
698
+ playPromise().catch(() => { });
699
+ await psetTimeout(1);
700
+ await playback.step();
701
+ expect.assertions(2);
702
+ expect(executor.doOpen).toHaveBeenCalledTimes(1);
703
+ try {
704
+ await playback.step(2);
705
+ }
706
+ catch (err) {
707
+ expect(err.message).toBe('Playback stopped prematurely');
708
+ }
709
+ await playPromise();
710
+ });
711
+ });
712
+ describe('play to and from', () => {
713
+ it('should play to a point and continue to the end', async () => {
714
+ const test = {
715
+ id: '1',
716
+ name: 'Test',
717
+ commands: [
718
+ {
719
+ id: 'a',
720
+ command: 'open',
721
+ target: '',
722
+ value: '',
723
+ },
724
+ {
725
+ id: 'b',
726
+ command: 'open',
727
+ target: '',
728
+ value: '',
729
+ },
730
+ {
731
+ id: 'c',
732
+ command: 'open',
733
+ target: '',
734
+ value: '',
735
+ },
736
+ ],
737
+ };
738
+ const executor = new JestFakeExecutor_1.default({});
739
+ executor.doOpen.mockImplementation(async () => { });
740
+ const playback = new playback_1.default({
741
+ executor,
742
+ });
743
+ const playPromise = await playback.playTo(test, 2, 0);
744
+ expect(executor.doOpen).toHaveBeenCalledTimes(2);
745
+ await playback.resume();
746
+ await playPromise();
747
+ expect(executor.doOpen).toHaveBeenCalledTimes(3);
748
+ });
749
+ it('should fail to play to a point that does not exist in the test', async () => {
750
+ const test = {
751
+ id: '1',
752
+ name: 'Test',
753
+ commands: [
754
+ {
755
+ id: 'a',
756
+ command: 'open',
757
+ target: '',
758
+ value: '',
759
+ },
760
+ ],
761
+ };
762
+ const executor = new JestFakeExecutor_1.default({});
763
+ const playback = new playback_1.default({
764
+ executor,
765
+ });
766
+ expect.assertions(1);
767
+ try {
768
+ await playback.playTo(test, 5, 0);
769
+ }
770
+ catch (err) {
771
+ expect(err.message).toBe('Command not found in test');
772
+ }
773
+ });
774
+ it('should replay a command when in a control flow loop', async () => {
775
+ const test = {
776
+ id: '1',
777
+ name: 'Test',
778
+ commands: [
779
+ {
780
+ id: 'a',
781
+ command: 'forEach',
782
+ target: 'collectionVarName',
783
+ value: 'iteratorVarName',
784
+ },
785
+ {
786
+ id: 'b',
787
+ command: 'open',
788
+ target: '',
789
+ value: '',
790
+ },
791
+ {
792
+ id: 'c',
793
+ command: 'end',
794
+ target: '',
795
+ value: '',
796
+ },
797
+ ],
798
+ };
799
+ const executor = new JestFakeExecutor_1.default({});
800
+ executor.doOpen.mockImplementation(async () => { });
801
+ const variables = new variables_1.default();
802
+ variables.set('collectionVarName', [0, 1, 2]);
803
+ const playback = new playback_1.default({
804
+ executor,
805
+ variables,
806
+ });
807
+ const playPromise = await playback.playFrom(test, test.commands[0]);
808
+ await playPromise();
809
+ expect(executor.doOpen).toHaveBeenCalledTimes(3);
810
+ });
811
+ it('should fail to play to an unreachable point', async () => {
812
+ const test = {
813
+ id: '1',
814
+ name: 'Test',
815
+ commands: [
816
+ {
817
+ id: 'a',
818
+ command: 'open',
819
+ target: '',
820
+ value: '',
821
+ },
822
+ {
823
+ id: 'b',
824
+ command: 'if',
825
+ target: '',
826
+ value: '',
827
+ },
828
+ {
829
+ id: 'c',
830
+ command: 'open',
831
+ target: '',
832
+ value: '',
833
+ },
834
+ {
835
+ id: 'd',
836
+ command: 'end',
837
+ target: '',
838
+ value: '',
839
+ },
840
+ ],
841
+ };
842
+ const executor = new JestFakeExecutor_1.default({});
843
+ executor.doOpen.mockImplementation(async () => { });
844
+ executor.evaluateConditional.mockImplementation(async () => false);
845
+ const playback = new playback_1.default({
846
+ executor,
847
+ });
848
+ expect.assertions(1);
849
+ try {
850
+ await playback.playTo(test, 2, 0);
851
+ }
852
+ catch (err) {
853
+ expect(err.message).toBe("Playback finished before reaching the requested command, check to make sure control flow isn't preventing this");
854
+ }
855
+ });
856
+ it('should play from a point', async () => {
857
+ const test = {
858
+ id: '1',
859
+ name: 'Test',
860
+ commands: [
861
+ {
862
+ id: 'a',
863
+ command: 'open',
864
+ target: '',
865
+ value: '',
866
+ },
867
+ {
868
+ id: 'b',
869
+ command: 'open',
870
+ target: '',
871
+ value: '',
872
+ },
873
+ {
874
+ id: 'c',
875
+ command: 'open',
876
+ target: '',
877
+ value: '',
878
+ },
879
+ ],
880
+ };
881
+ const executor = new JestFakeExecutor_1.default({});
882
+ executor.doOpen.mockImplementation(async () => { });
883
+ const playback = new playback_1.default({
884
+ executor,
885
+ });
886
+ const playPromise = await playback.playFrom(test, test.commands[1]);
887
+ await playPromise();
888
+ expect(executor.doOpen).toHaveBeenCalledTimes(2);
889
+ });
890
+ it('should play to a command from a command', async () => {
891
+ const test = {
892
+ id: '1',
893
+ name: 'Test',
894
+ commands: [
895
+ {
896
+ id: 'a',
897
+ command: 'open',
898
+ target: 't1',
899
+ value: '',
900
+ },
901
+ {
902
+ id: 'b',
903
+ command: 'open',
904
+ target: 't2',
905
+ value: '',
906
+ },
907
+ {
908
+ id: 'c',
909
+ command: 'open',
910
+ target: 't3',
911
+ value: '',
912
+ },
913
+ {
914
+ id: 'd',
915
+ command: 'open',
916
+ target: 't4',
917
+ value: '',
918
+ },
919
+ ],
920
+ };
921
+ const executor = new JestFakeExecutor_1.default({});
922
+ executor.doOpen.mockImplementation(async () => { });
923
+ const playback = new playback_1.default({
924
+ executor,
925
+ });
926
+ await playback.playTo(test, 2, 1);
927
+ expect(executor.doOpen).toHaveBeenCalledTimes(1);
928
+ expect(executor.doOpen).toHaveBeenCalledWith('t2', '', test.commands[1]);
929
+ });
930
+ it('should fail to play to a point that exists, from a point that does not exist in the test', async () => {
931
+ const test = {
932
+ id: '1',
933
+ name: 'Test',
934
+ commands: [
935
+ {
936
+ id: 'a',
937
+ command: 'open',
938
+ target: '',
939
+ value: '',
940
+ },
941
+ ],
942
+ };
943
+ const executor = new JestFakeExecutor_1.default({});
944
+ const playback = new playback_1.default({
945
+ executor,
946
+ });
947
+ expect.assertions(1);
948
+ try {
949
+ await playback.playTo(test, 0, 5);
950
+ }
951
+ catch (err) {
952
+ expect(err.message).toBe('Command to start from not found in test');
953
+ }
954
+ });
955
+ });
956
+ describe('resume', () => {
957
+ it('should resume a paused test', async () => {
958
+ const test = {
959
+ id: '1',
960
+ name: 'Test',
961
+ commands: [
962
+ {
963
+ id: '1',
964
+ command: 'open',
965
+ target: '',
966
+ value: '',
967
+ },
968
+ {
969
+ id: '2',
970
+ command: 'open',
971
+ target: '',
972
+ value: '',
973
+ },
974
+ {
975
+ id: '3',
976
+ command: 'open',
977
+ target: '',
978
+ value: '',
979
+ },
980
+ ],
981
+ };
982
+ const executor = new JestFakeExecutor_1.default({});
983
+ executor.doOpen.mockImplementation(async () => {
984
+ await psetTimeout(10);
985
+ return;
986
+ });
987
+ const playback = new playback_1.default({
988
+ executor,
989
+ });
990
+ const cb = jest.fn();
991
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
992
+ const commandResults = [];
993
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
994
+ const playbackPromise = await playback.play(test);
995
+ await psetTimeout(15);
996
+ await playback.pause();
997
+ await psetTimeout(15);
998
+ await playback.resume();
999
+ await playbackPromise();
1000
+ const results = flat(cb.mock.calls);
1001
+ expect(results.length).toBe(5);
1002
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1003
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1004
+ expect(results[2].state).toBe(playback_1.PlaybackStates.PAUSED);
1005
+ expect(results[3].state).toBe(playback_1.PlaybackStates.PLAYING);
1006
+ expect(results[4].state).toBe(playback_1.PlaybackStates.FINISHED);
1007
+ expect(commandResults).toMatchSnapshot();
1008
+ });
1009
+ it("resume is a no-op if test isn't paused", async () => {
1010
+ const test = {
1011
+ id: '1',
1012
+ name: 'Test',
1013
+ commands: [
1014
+ {
1015
+ id: '1',
1016
+ command: 'open',
1017
+ target: '',
1018
+ value: '',
1019
+ },
1020
+ {
1021
+ id: '2',
1022
+ command: 'open',
1023
+ target: '',
1024
+ value: '',
1025
+ },
1026
+ {
1027
+ id: '3',
1028
+ command: 'open',
1029
+ target: '',
1030
+ value: '',
1031
+ },
1032
+ ],
1033
+ };
1034
+ const executor = new JestFakeExecutor_1.default({});
1035
+ executor.doOpen.mockImplementation(async () => {
1036
+ await psetTimeout(0);
1037
+ return;
1038
+ });
1039
+ const playback = new playback_1.default({
1040
+ executor,
1041
+ });
1042
+ const playbackPromise = await playback.play(test);
1043
+ expect(() => playback.resume()).not.toThrow();
1044
+ await playbackPromise().catch(() => { });
1045
+ });
1046
+ it('resume after hitting a breakpoint', async () => {
1047
+ const test = {
1048
+ id: '1',
1049
+ name: 'Test',
1050
+ commands: [
1051
+ {
1052
+ id: '1',
1053
+ command: 'open',
1054
+ target: '',
1055
+ value: '',
1056
+ },
1057
+ {
1058
+ id: '2',
1059
+ command: 'open',
1060
+ target: '',
1061
+ value: '',
1062
+ isBreakpoint: true,
1063
+ },
1064
+ {
1065
+ id: '3',
1066
+ command: 'open',
1067
+ target: '',
1068
+ value: '',
1069
+ },
1070
+ ],
1071
+ };
1072
+ const executor = new JestFakeExecutor_1.default({});
1073
+ executor.doOpen.mockImplementation(async () => {
1074
+ await psetTimeout(10);
1075
+ return;
1076
+ });
1077
+ const playback = new playback_1.default({
1078
+ executor,
1079
+ });
1080
+ const cb = jest.fn();
1081
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1082
+ const commandResults = [];
1083
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1084
+ const playbackPromise = await playback.play(test);
1085
+ await psetTimeout(15);
1086
+ await playback.resume();
1087
+ await playbackPromise();
1088
+ const results = flat(cb.mock.calls);
1089
+ expect(results.length).toBe(5);
1090
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1091
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1092
+ expect(results[2].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1093
+ expect(results[3].state).toBe(playback_1.PlaybackStates.PLAYING);
1094
+ expect(results[4].state).toBe(playback_1.PlaybackStates.FINISHED);
1095
+ expect(commandResults).toMatchSnapshot();
1096
+ });
1097
+ });
1098
+ describe('stop', () => {
1099
+ it('should stop a test', async () => {
1100
+ const test = {
1101
+ id: '1',
1102
+ name: 'Test',
1103
+ commands: [
1104
+ {
1105
+ id: '1',
1106
+ command: 'open',
1107
+ target: '',
1108
+ value: '',
1109
+ },
1110
+ {
1111
+ id: '2',
1112
+ command: 'open',
1113
+ target: '',
1114
+ value: '',
1115
+ },
1116
+ {
1117
+ id: '3',
1118
+ command: 'open',
1119
+ target: '',
1120
+ value: '',
1121
+ },
1122
+ ],
1123
+ };
1124
+ const executor = new JestFakeExecutor_1.default({});
1125
+ executor.doOpen.mockImplementation(async () => {
1126
+ await psetTimeout(10);
1127
+ return;
1128
+ });
1129
+ const playback = new playback_1.default({
1130
+ executor,
1131
+ });
1132
+ const cb = jest.fn();
1133
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1134
+ const commandResults = [];
1135
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1136
+ const playbackPromise = await playback.play(test);
1137
+ await psetTimeout(15);
1138
+ await playback.stop();
1139
+ await playbackPromise();
1140
+ const results = flat(cb.mock.calls);
1141
+ expect(results.length).toBe(3);
1142
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1143
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1144
+ expect(results[2].state).toBe(playback_1.PlaybackStates.STOPPED);
1145
+ expect(commandResults).toMatchSnapshot();
1146
+ });
1147
+ it('should stop a paused test', async () => {
1148
+ const test = {
1149
+ id: '1',
1150
+ name: 'Test',
1151
+ commands: [
1152
+ {
1153
+ id: '1',
1154
+ command: 'open',
1155
+ target: '',
1156
+ value: '',
1157
+ },
1158
+ {
1159
+ id: '2',
1160
+ command: 'open',
1161
+ target: '',
1162
+ value: '',
1163
+ },
1164
+ {
1165
+ id: '3',
1166
+ command: 'open',
1167
+ target: '',
1168
+ value: '',
1169
+ },
1170
+ ],
1171
+ };
1172
+ const executor = new JestFakeExecutor_1.default({});
1173
+ executor.doOpen.mockImplementation(async () => {
1174
+ await psetTimeout(10);
1175
+ return;
1176
+ });
1177
+ const playback = new playback_1.default({
1178
+ executor,
1179
+ });
1180
+ const cb = jest.fn();
1181
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1182
+ const commandResults = [];
1183
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1184
+ const playbackPromise = await playback.play(test);
1185
+ await psetTimeout(15);
1186
+ await playback.pause();
1187
+ await psetTimeout(15);
1188
+ await playback.stop();
1189
+ await playbackPromise();
1190
+ const results = flat(cb.mock.calls);
1191
+ expect(results.length).toBe(4);
1192
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1193
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1194
+ expect(results[2].state).toBe(playback_1.PlaybackStates.PAUSED);
1195
+ expect(results[3].state).toBe(playback_1.PlaybackStates.STOPPED);
1196
+ expect(commandResults).toMatchSnapshot();
1197
+ });
1198
+ });
1199
+ describe('abort', () => {
1200
+ it('should abort a test', async () => {
1201
+ const test = {
1202
+ id: '1',
1203
+ name: 'Test',
1204
+ commands: [
1205
+ {
1206
+ id: '1',
1207
+ command: 'open',
1208
+ target: '',
1209
+ value: '',
1210
+ },
1211
+ {
1212
+ id: '2',
1213
+ command: 'open',
1214
+ target: '',
1215
+ value: '',
1216
+ },
1217
+ {
1218
+ id: '3',
1219
+ command: 'open',
1220
+ target: '',
1221
+ value: '',
1222
+ },
1223
+ ],
1224
+ };
1225
+ const executor = new JestFakeExecutor_1.default({});
1226
+ executor.doOpen.mockImplementation(async () => {
1227
+ await psetTimeout(10);
1228
+ return;
1229
+ });
1230
+ const playback = new playback_1.default({
1231
+ executor,
1232
+ });
1233
+ const cb = jest.fn();
1234
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1235
+ const commandResults = [];
1236
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1237
+ const playbackPromise = await playback.play(test);
1238
+ await psetTimeout(15);
1239
+ await playback.abort();
1240
+ await playbackPromise();
1241
+ await psetTimeout(2);
1242
+ const results = flat(cb.mock.calls);
1243
+ expect(results.length).toBe(3);
1244
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1245
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1246
+ expect(results[2].state).toBe(playback_1.PlaybackStates.ABORTED);
1247
+ expect(commandResults).toMatchSnapshot();
1248
+ });
1249
+ it('should abort a test after attempting to stop', async () => {
1250
+ const test = {
1251
+ id: '1',
1252
+ name: 'Test',
1253
+ commands: [
1254
+ {
1255
+ id: '1',
1256
+ command: 'open',
1257
+ target: '',
1258
+ value: '',
1259
+ },
1260
+ {
1261
+ id: '2',
1262
+ command: 'open',
1263
+ target: '',
1264
+ value: '',
1265
+ },
1266
+ {
1267
+ id: '3',
1268
+ command: 'open',
1269
+ target: '',
1270
+ value: '',
1271
+ },
1272
+ ],
1273
+ };
1274
+ const executor = new JestFakeExecutor_1.default({});
1275
+ executor.doOpen.mockImplementation(async () => {
1276
+ await psetTimeout(10);
1277
+ return;
1278
+ });
1279
+ const playback = new playback_1.default({
1280
+ executor,
1281
+ });
1282
+ const cb = jest.fn();
1283
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1284
+ const commandResults = [];
1285
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1286
+ const playbackPromise = await playback.play(test);
1287
+ playbackPromise().catch((err) => {
1288
+ expect(err.message).toBe('playback is dead');
1289
+ });
1290
+ await psetTimeout(15);
1291
+ playback.stop();
1292
+ await psetTimeout(2);
1293
+ await playback.abort();
1294
+ await playbackPromise();
1295
+ await psetTimeout(2);
1296
+ const results = flat(cb.mock.calls);
1297
+ expect(results.length).toBe(3);
1298
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1299
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1300
+ expect(results[2].state).toBe(playback_1.PlaybackStates.ABORTED);
1301
+ expect(commandResults).toMatchSnapshot();
1302
+ });
1303
+ it('should abort a paused test', async () => {
1304
+ const test = {
1305
+ id: '1',
1306
+ name: 'Test',
1307
+ commands: [
1308
+ {
1309
+ id: '1',
1310
+ command: 'open',
1311
+ target: '',
1312
+ value: '',
1313
+ },
1314
+ {
1315
+ id: '2',
1316
+ command: 'open',
1317
+ target: '',
1318
+ value: '',
1319
+ },
1320
+ {
1321
+ id: '3',
1322
+ command: 'open',
1323
+ target: '',
1324
+ value: '',
1325
+ },
1326
+ ],
1327
+ };
1328
+ const executor = new JestFakeExecutor_1.default({});
1329
+ executor.doOpen.mockImplementation(async () => {
1330
+ await psetTimeout(10);
1331
+ return;
1332
+ });
1333
+ const playback = new playback_1.default({
1334
+ executor,
1335
+ });
1336
+ const cb = jest.fn();
1337
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1338
+ const commandResults = [];
1339
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1340
+ const playbackPromise = await playback.play(test);
1341
+ playbackPromise().catch((err) => {
1342
+ expect(err.message).toBe('playback is dead');
1343
+ });
1344
+ await psetTimeout(15);
1345
+ await playback.pause();
1346
+ await psetTimeout(15);
1347
+ await playback.abort();
1348
+ await playbackPromise();
1349
+ const results = flat(cb.mock.calls);
1350
+ expect(results.length).toBe(4);
1351
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1352
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1353
+ expect(results[2].state).toBe(playback_1.PlaybackStates.PAUSED);
1354
+ expect(results[3].state).toBe(playback_1.PlaybackStates.ABORTED);
1355
+ expect(commandResults).toMatchSnapshot();
1356
+ });
1357
+ });
1358
+ describe('pause on exceptions', () => {
1359
+ it('should pause until the command is fixed', async () => {
1360
+ const test = {
1361
+ id: '1',
1362
+ name: 'Test',
1363
+ commands: [
1364
+ {
1365
+ id: '1',
1366
+ command: 'open',
1367
+ target: '',
1368
+ value: '',
1369
+ },
1370
+ ],
1371
+ };
1372
+ const executor = new JestFakeExecutor_1.default({});
1373
+ executor.doOpen.mockImplementation(async () => {
1374
+ throw new Error('Mock open error');
1375
+ });
1376
+ const playback = new playback_1.default({
1377
+ executor,
1378
+ options: {
1379
+ pauseOnExceptions: true,
1380
+ },
1381
+ });
1382
+ const cb = jest.fn();
1383
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1384
+ const commandResults = [];
1385
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1386
+ await playback.play(test);
1387
+ await psetTimeout(5);
1388
+ await playback.resume();
1389
+ await psetTimeout(5);
1390
+ await playback.resume();
1391
+ await psetTimeout(5);
1392
+ executor.doOpen.mockImplementation(async () => { });
1393
+ await playback.resume();
1394
+ await psetTimeout(10);
1395
+ const results = flat(cb.mock.calls);
1396
+ expect(results.length).toBe(9);
1397
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1398
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1399
+ expect(results[2].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1400
+ expect(results[3].state).toBe(playback_1.PlaybackStates.PLAYING);
1401
+ expect(results[4].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1402
+ expect(results[5].state).toBe(playback_1.PlaybackStates.PLAYING);
1403
+ expect(results[6].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1404
+ expect(results[7].state).toBe(playback_1.PlaybackStates.PLAYING);
1405
+ expect(results[8].state).toBe(playback_1.PlaybackStates.FINISHED);
1406
+ expect(commandResults).toMatchSnapshot();
1407
+ });
1408
+ it('should pause for every type of error', async () => {
1409
+ const test = {
1410
+ id: '1',
1411
+ name: 'Test',
1412
+ commands: [
1413
+ {
1414
+ id: '1',
1415
+ command: 'open',
1416
+ target: '',
1417
+ value: '',
1418
+ },
1419
+ {
1420
+ id: '2',
1421
+ command: 'verify',
1422
+ target: '',
1423
+ value: '',
1424
+ },
1425
+ {
1426
+ id: '3',
1427
+ command: 'assert',
1428
+ target: '',
1429
+ value: '',
1430
+ },
1431
+ ],
1432
+ };
1433
+ const executor = new JestFakeExecutor_1.default({});
1434
+ executor.doOpen.mockImplementation(async () => {
1435
+ throw new Error('Mock error in open');
1436
+ });
1437
+ executor.doVerify.mockImplementation(async () => {
1438
+ throw new errors_1.VerificationError('Mock error in verify');
1439
+ });
1440
+ executor.doAssert.mockImplementation(async () => {
1441
+ throw new errors_1.AssertionError('Mock error in assert');
1442
+ });
1443
+ const playback = new playback_1.default({
1444
+ executor,
1445
+ options: {
1446
+ pauseOnExceptions: true,
1447
+ },
1448
+ });
1449
+ const cb = jest.fn();
1450
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1451
+ const commandResults = [];
1452
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1453
+ await playback.play(test);
1454
+ await psetTimeout(5);
1455
+ executor.doOpen.mockImplementation(async () => { });
1456
+ await playback.resume();
1457
+ await psetTimeout(5);
1458
+ executor.doVerify.mockImplementation(async () => { });
1459
+ await playback.resume();
1460
+ await psetTimeout(5);
1461
+ executor.doAssert.mockImplementation(async () => { });
1462
+ await psetTimeout(5);
1463
+ await playback.resume();
1464
+ await psetTimeout(10);
1465
+ const results = flat(cb.mock.calls);
1466
+ expect(results.length).toBe(9);
1467
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1468
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1469
+ expect(results[2].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1470
+ expect(results[3].state).toBe(playback_1.PlaybackStates.PLAYING);
1471
+ expect(results[4].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1472
+ expect(results[5].state).toBe(playback_1.PlaybackStates.PLAYING);
1473
+ expect(results[6].state).toBe(playback_1.PlaybackStates.BREAKPOINT);
1474
+ expect(results[7].state).toBe(playback_1.PlaybackStates.PLAYING);
1475
+ expect(results[8].state).toBe(playback_1.PlaybackStates.FINISHED);
1476
+ expect(commandResults).toMatchSnapshot();
1477
+ });
1478
+ });
1479
+ describe('ignore breakpoints', () => {
1480
+ it('should ignore breakpoints', async () => {
1481
+ const test = {
1482
+ id: '1',
1483
+ name: 'Test',
1484
+ commands: [
1485
+ {
1486
+ id: '1',
1487
+ command: 'open',
1488
+ target: '',
1489
+ value: '',
1490
+ },
1491
+ {
1492
+ id: '2',
1493
+ command: 'open',
1494
+ target: '',
1495
+ value: '',
1496
+ isBreakpoint: true,
1497
+ },
1498
+ {
1499
+ id: '3',
1500
+ command: 'open',
1501
+ target: '',
1502
+ value: '',
1503
+ },
1504
+ ],
1505
+ };
1506
+ const executor = new JestFakeExecutor_1.default({});
1507
+ executor.doOpen.mockImplementation(async () => {
1508
+ await psetTimeout(1);
1509
+ return;
1510
+ });
1511
+ const playback = new playback_1.default({
1512
+ executor,
1513
+ options: {
1514
+ ignoreBreakpoints: true,
1515
+ },
1516
+ });
1517
+ const cb = jest.fn();
1518
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
1519
+ const commandResults = [];
1520
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1521
+ const playbackPromise = await playback.play(test);
1522
+ await playbackPromise();
1523
+ const results = flat(cb.mock.calls);
1524
+ expect(results.length).toBe(3);
1525
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
1526
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
1527
+ expect(results[2].state).toBe(playback_1.PlaybackStates.FINISHED);
1528
+ expect(commandResults).toMatchSnapshot();
1529
+ });
1530
+ });
1531
+ describe('delay between commands', () => {
1532
+ it('should delay between commands', async () => {
1533
+ const test = {
1534
+ id: '1',
1535
+ name: 'Test',
1536
+ commands: [
1537
+ {
1538
+ id: 'a',
1539
+ command: 'open',
1540
+ target: '',
1541
+ value: '',
1542
+ },
1543
+ {
1544
+ id: 'b',
1545
+ command: 'open',
1546
+ target: '',
1547
+ value: '',
1548
+ },
1549
+ {
1550
+ id: 'c',
1551
+ command: 'open',
1552
+ target: '',
1553
+ value: '',
1554
+ },
1555
+ ],
1556
+ };
1557
+ const executor = new JestFakeExecutor_1.default({});
1558
+ executor.doOpen.mockImplementation(async () => { });
1559
+ const playback = new playback_1.default({
1560
+ executor,
1561
+ options: {
1562
+ delay: 5,
1563
+ },
1564
+ });
1565
+ const d = Date.now();
1566
+ const playbackPromise = await playback.play(test);
1567
+ await playbackPromise();
1568
+ expect(Date.now() - d).toBeGreaterThan(10);
1569
+ });
1570
+ it('should be able to pause mid-delay', async () => {
1571
+ const test = {
1572
+ id: '1',
1573
+ name: 'Test',
1574
+ commands: [
1575
+ {
1576
+ id: 'a',
1577
+ command: 'open',
1578
+ target: '',
1579
+ value: '',
1580
+ },
1581
+ ],
1582
+ };
1583
+ const executor = new JestFakeExecutor_1.default({});
1584
+ executor.doOpen.mockImplementation(async () => { });
1585
+ const playback = new playback_1.default({
1586
+ executor,
1587
+ options: {
1588
+ delay: 500,
1589
+ },
1590
+ });
1591
+ const d = Date.now();
1592
+ await playback.play(test);
1593
+ await psetTimeout(2);
1594
+ await playback.pause();
1595
+ expect(Date.now() - d).toBeLessThan(200);
1596
+ });
1597
+ it('should be able to stop mid-delay', async () => {
1598
+ const test = {
1599
+ id: '1',
1600
+ name: 'Test',
1601
+ commands: [
1602
+ {
1603
+ id: 'a',
1604
+ command: 'open',
1605
+ target: '',
1606
+ value: '',
1607
+ },
1608
+ ],
1609
+ };
1610
+ const executor = new JestFakeExecutor_1.default({});
1611
+ executor.doOpen.mockImplementation(async () => { });
1612
+ const playback = new playback_1.default({
1613
+ executor,
1614
+ options: {
1615
+ delay: 500,
1616
+ },
1617
+ });
1618
+ const d = Date.now();
1619
+ await playback.play(test);
1620
+ await psetTimeout(2);
1621
+ await playback.stop();
1622
+ expect(Date.now() - d).toBeLessThan(200);
1623
+ });
1624
+ it('should be able to abort mid-delay', async () => {
1625
+ const test = {
1626
+ id: '1',
1627
+ name: 'Test',
1628
+ commands: [
1629
+ {
1630
+ id: 'a',
1631
+ command: 'open',
1632
+ target: '',
1633
+ value: '',
1634
+ },
1635
+ ],
1636
+ };
1637
+ const executor = new JestFakeExecutor_1.default({});
1638
+ executor.doOpen.mockImplementation(async () => { });
1639
+ const playback = new playback_1.default({
1640
+ executor,
1641
+ options: {
1642
+ delay: 500,
1643
+ },
1644
+ });
1645
+ const d = Date.now();
1646
+ const playbackPromise = await playback.play(test);
1647
+ playbackPromise().catch((err) => {
1648
+ expect(err.message).toBe('playback is dead');
1649
+ });
1650
+ await psetTimeout(2);
1651
+ await playback.abort();
1652
+ expect(Date.now() - d).toBeLessThan(200);
1653
+ });
1654
+ });
1655
+ describe('skip', () => {
1656
+ it('should skip a command', async () => {
1657
+ const test = {
1658
+ id: '1',
1659
+ name: 'Test',
1660
+ commands: [
1661
+ {
1662
+ id: 'a',
1663
+ command: 'open',
1664
+ target: '',
1665
+ value: '',
1666
+ },
1667
+ {
1668
+ id: 'b',
1669
+ command: 'open',
1670
+ target: '',
1671
+ value: '',
1672
+ skip: true,
1673
+ },
1674
+ {
1675
+ id: 'c',
1676
+ command: 'open',
1677
+ target: '',
1678
+ value: '',
1679
+ },
1680
+ ],
1681
+ };
1682
+ const executor = new JestFakeExecutor_1.default({});
1683
+ executor.doOpen.mockImplementation(async () => { });
1684
+ const playback = new playback_1.default({
1685
+ executor,
1686
+ });
1687
+ await (await playback.play(test))();
1688
+ expect(executor.doOpen).toHaveBeenCalledTimes(2);
1689
+ });
1690
+ it('should send a skipped status for skipped commands', async () => {
1691
+ const test = {
1692
+ id: '1',
1693
+ name: 'Test',
1694
+ commands: [
1695
+ {
1696
+ id: '1',
1697
+ command: 'open',
1698
+ target: '',
1699
+ value: '',
1700
+ },
1701
+ {
1702
+ id: '2',
1703
+ command: 'open',
1704
+ target: '',
1705
+ value: '',
1706
+ skip: true,
1707
+ },
1708
+ {
1709
+ id: '3',
1710
+ command: 'open',
1711
+ target: '',
1712
+ value: '',
1713
+ },
1714
+ ],
1715
+ };
1716
+ const executor = new JestFakeExecutor_1.default({});
1717
+ executor.doOpen.mockImplementation(async () => {
1718
+ await psetTimeout(10);
1719
+ return;
1720
+ });
1721
+ const playback = new playback_1.default({
1722
+ executor,
1723
+ });
1724
+ const commandResults = [];
1725
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1726
+ await (await playback.play(test))();
1727
+ expect(commandResults[3].state).toBe(playback_1.CommandStates.SKIPPED);
1728
+ });
1729
+ it('should skip when playing single command', async () => {
1730
+ const command = {
1731
+ id: '1',
1732
+ command: 'open',
1733
+ target: '',
1734
+ value: '',
1735
+ skip: true,
1736
+ };
1737
+ const executor = new JestFakeExecutor_1.default({});
1738
+ executor.doOpen.mockImplementation(async () => { });
1739
+ const playback = new playback_1.default({
1740
+ executor,
1741
+ });
1742
+ const commandResults = [];
1743
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1744
+ await playback.playSingleCommand(command);
1745
+ expect(executor.doOpen).toHaveBeenCalledTimes(0);
1746
+ expect(commandResults[1].state).toBe(playback_1.CommandStates.SKIPPED);
1747
+ });
1748
+ it('should skip control flow commands', async () => {
1749
+ const test = {
1750
+ id: '1',
1751
+ name: 'Test',
1752
+ commands: [
1753
+ {
1754
+ id: '1',
1755
+ command: 'if',
1756
+ target: '',
1757
+ value: '',
1758
+ skip: true,
1759
+ },
1760
+ {
1761
+ id: '2',
1762
+ command: 'open',
1763
+ target: '',
1764
+ value: '',
1765
+ },
1766
+ {
1767
+ id: '3',
1768
+ command: 'end',
1769
+ target: '',
1770
+ value: '',
1771
+ skip: true,
1772
+ },
1773
+ ],
1774
+ };
1775
+ const executor = new JestFakeExecutor_1.default({});
1776
+ executor.doOpen.mockImplementation(async () => {
1777
+ await psetTimeout(10);
1778
+ return;
1779
+ });
1780
+ const playback = new playback_1.default({
1781
+ executor,
1782
+ });
1783
+ const commandResults = [];
1784
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1785
+ await (await playback.play(test))();
1786
+ expect(executor.doOpen).toHaveBeenCalledTimes(1);
1787
+ expect(commandResults[1].state).toBe(playback_1.CommandStates.SKIPPED);
1788
+ expect(commandResults[5].state).toBe(playback_1.CommandStates.SKIPPED);
1789
+ });
1790
+ it('should fail to play a test with invalid control flow structure due to skipping commands', async () => {
1791
+ const test = {
1792
+ id: '1',
1793
+ name: 'Test',
1794
+ commands: [
1795
+ {
1796
+ id: '1',
1797
+ command: 'if',
1798
+ target: '',
1799
+ value: '',
1800
+ skip: true,
1801
+ },
1802
+ {
1803
+ id: '2',
1804
+ command: 'open',
1805
+ target: '',
1806
+ value: '',
1807
+ },
1808
+ {
1809
+ id: '3',
1810
+ command: 'end',
1811
+ target: '',
1812
+ value: '',
1813
+ },
1814
+ ],
1815
+ };
1816
+ const executor = new JestFakeExecutor_1.default({});
1817
+ executor.doOpen.mockImplementation(async () => {
1818
+ await psetTimeout(10);
1819
+ return;
1820
+ });
1821
+ const playback = new playback_1.default({
1822
+ executor,
1823
+ });
1824
+ const commandResults = [];
1825
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1826
+ expect.assertions(1);
1827
+ try {
1828
+ await playback.play(test);
1829
+ }
1830
+ catch (err) {
1831
+ expect(err.message).toBe('Use of end without an opening keyword');
1832
+ }
1833
+ });
1834
+ it('should fail to play a test with undetermined control flow structure due to skipping commands', async () => {
1835
+ const test = {
1836
+ id: '1',
1837
+ name: 'Test',
1838
+ commands: [
1839
+ {
1840
+ id: '1',
1841
+ command: 'if',
1842
+ target: '',
1843
+ value: '',
1844
+ },
1845
+ {
1846
+ id: '2',
1847
+ command: 'open',
1848
+ target: '',
1849
+ value: '',
1850
+ },
1851
+ {
1852
+ id: '3',
1853
+ command: 'end',
1854
+ target: '',
1855
+ value: '',
1856
+ skip: true,
1857
+ },
1858
+ ],
1859
+ };
1860
+ const executor = new JestFakeExecutor_1.default({});
1861
+ executor.doOpen.mockImplementation(async () => {
1862
+ await psetTimeout(10);
1863
+ return;
1864
+ });
1865
+ const playback = new playback_1.default({
1866
+ executor,
1867
+ });
1868
+ const commandResults = [];
1869
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1870
+ expect.assertions(1);
1871
+ try {
1872
+ await playback.play(test);
1873
+ }
1874
+ catch (err) {
1875
+ expect(err.message).toBe('Incomplete block at if');
1876
+ }
1877
+ });
1878
+ it('should support skipping `run` command', async () => {
1879
+ const test = {
1880
+ id: '1',
1881
+ name: 'Test',
1882
+ commands: [
1883
+ {
1884
+ id: '1',
1885
+ command: 'open',
1886
+ target: '',
1887
+ value: '',
1888
+ },
1889
+ {
1890
+ id: '2',
1891
+ command: 'run',
1892
+ target: 'test',
1893
+ value: '',
1894
+ skip: true,
1895
+ },
1896
+ {
1897
+ id: '3',
1898
+ command: 'open',
1899
+ target: '',
1900
+ value: '',
1901
+ },
1902
+ ],
1903
+ };
1904
+ const executor = new JestFakeExecutor_1.default({});
1905
+ executor.doOpen.mockImplementation(async () => {
1906
+ await psetTimeout(10);
1907
+ return;
1908
+ });
1909
+ const playback = new playback_1.default({
1910
+ executor,
1911
+ });
1912
+ const commandResults = [];
1913
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, (r) => commandResults.push(r));
1914
+ await (await playback.play(test))();
1915
+ expect(commandResults[3].state).toBe(playback_1.CommandStates.SKIPPED);
1916
+ });
1917
+ });
1918
+ describe('Events', () => {
1919
+ describe("'command-state-changed'", () => {
1920
+ it('should listen to pending and pass changes', async () => {
1921
+ const test = {
1922
+ id: '1',
1923
+ name: 'Test',
1924
+ commands: [
1925
+ {
1926
+ id: '1',
1927
+ command: 'open',
1928
+ target: '',
1929
+ value: '',
1930
+ },
1931
+ ],
1932
+ };
1933
+ const executor = new JestFakeExecutor_1.default({});
1934
+ executor.doOpen.mockImplementation(async () => { });
1935
+ const playback = new playback_1.default({
1936
+ executor,
1937
+ });
1938
+ const cb = jest.fn();
1939
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, cb);
1940
+ await (await playback.play(test))();
1941
+ const results = flat(cb.mock.calls);
1942
+ expect(results.length).toBe(2);
1943
+ expect(results[0].state).toBe(playback_1.CommandStates.EXECUTING);
1944
+ expect(results[1].state).toBe(playback_1.CommandStates.PASSED);
1945
+ });
1946
+ it('should listen to fail changes', async () => {
1947
+ const test = {
1948
+ id: '1',
1949
+ name: 'Test',
1950
+ commands: [
1951
+ {
1952
+ id: '1',
1953
+ command: 'verifyText',
1954
+ target: '',
1955
+ value: '',
1956
+ },
1957
+ ],
1958
+ };
1959
+ const executor = new JestFakeExecutor_1.default({});
1960
+ executor.doVerifyText.mockImplementation(async () => {
1961
+ throw new errors_1.VerificationError('failed to verify');
1962
+ });
1963
+ const playback = new playback_1.default({
1964
+ executor,
1965
+ });
1966
+ const cb = jest.fn();
1967
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, cb);
1968
+ await (await playback.play(test))().catch(() => { });
1969
+ const results = flat(cb.mock.calls);
1970
+ expect(results.length).toBe(2);
1971
+ expect(results[0].state).toBe(playback_1.CommandStates.EXECUTING);
1972
+ expect(results[1].state).toBe(playback_1.CommandStates.FAILED);
1973
+ });
1974
+ it('should listen to error changes', async () => {
1975
+ const test = {
1976
+ id: '1',
1977
+ name: 'Test',
1978
+ commands: [
1979
+ {
1980
+ id: '1',
1981
+ command: 'fatal',
1982
+ target: '',
1983
+ value: '',
1984
+ },
1985
+ ],
1986
+ };
1987
+ const executor = new JestFakeExecutor_1.default({});
1988
+ const playback = new playback_1.default({
1989
+ executor,
1990
+ });
1991
+ const cb = jest.fn();
1992
+ playback['event-emitter'].on(playback_1.PlaybackEvents.COMMAND_STATE_CHANGED, cb);
1993
+ await (await playback.play(test))().catch(() => { });
1994
+ const results = flat(cb.mock.calls);
1995
+ expect(results.length).toBe(2);
1996
+ expect(results[0].state).toBe(playback_1.CommandStates.EXECUTING);
1997
+ expect(results[1].state).toBe(playback_1.CommandStates.ERRORED);
1998
+ });
1999
+ });
2000
+ describe("'playback-state-changed'", () => {
2001
+ it('should finish test successfully', async () => {
2002
+ const test = {
2003
+ id: '1',
2004
+ name: 'Test',
2005
+ commands: [
2006
+ {
2007
+ id: '1',
2008
+ command: 'open',
2009
+ target: '',
2010
+ value: '',
2011
+ },
2012
+ ],
2013
+ };
2014
+ const executor = new JestFakeExecutor_1.default({});
2015
+ executor.doOpen.mockImplementation(async () => { });
2016
+ const playback = new playback_1.default({
2017
+ executor,
2018
+ });
2019
+ const cb = jest.fn();
2020
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
2021
+ await (await playback.play(test))();
2022
+ const results = flat(cb.mock.calls);
2023
+ expect(results.length).toBe(3);
2024
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
2025
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
2026
+ expect(results[2].state).toBe(playback_1.PlaybackStates.FINISHED);
2027
+ });
2028
+ it('should fail due to verify', async () => {
2029
+ const test = {
2030
+ id: '1',
2031
+ name: 'Test',
2032
+ commands: [
2033
+ {
2034
+ id: '1',
2035
+ command: 'open',
2036
+ target: '',
2037
+ value: '',
2038
+ },
2039
+ {
2040
+ id: '2',
2041
+ command: 'verifyText',
2042
+ target: '',
2043
+ value: '',
2044
+ },
2045
+ {
2046
+ id: '3',
2047
+ command: 'open',
2048
+ target: '',
2049
+ value: '',
2050
+ },
2051
+ ],
2052
+ };
2053
+ const executor = new JestFakeExecutor_1.default({});
2054
+ executor.doOpen.mockImplementation(async () => { });
2055
+ executor.doVerifyText.mockImplementation(async () => {
2056
+ throw new errors_1.VerificationError('failed to verify');
2057
+ });
2058
+ const playback = new playback_1.default({
2059
+ executor,
2060
+ });
2061
+ const cb = jest.fn();
2062
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
2063
+ await (await playback.play(test))();
2064
+ const results = flat(cb.mock.calls);
2065
+ expect(results.length).toBe(3);
2066
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
2067
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
2068
+ expect(results[2].state).toBe(playback_1.PlaybackStates.FAILED);
2069
+ });
2070
+ it('should fail due to assertion', async () => {
2071
+ const test = {
2072
+ id: '1',
2073
+ name: 'Test',
2074
+ commands: [
2075
+ {
2076
+ id: '1',
2077
+ command: 'open',
2078
+ target: '',
2079
+ value: '',
2080
+ },
2081
+ {
2082
+ id: '2',
2083
+ command: 'assertText',
2084
+ target: '',
2085
+ value: '',
2086
+ },
2087
+ {
2088
+ id: '3',
2089
+ command: 'open',
2090
+ target: '',
2091
+ value: '',
2092
+ },
2093
+ ],
2094
+ };
2095
+ const executor = new JestFakeExecutor_1.default({});
2096
+ executor.doOpen.mockImplementation(async () => { });
2097
+ executor.doAssertText.mockImplementation(async () => {
2098
+ throw new errors_1.AssertionError('failed to assert');
2099
+ });
2100
+ const playback = new playback_1.default({
2101
+ executor,
2102
+ });
2103
+ const cb = jest.fn();
2104
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
2105
+ await (await playback.play(test))().catch(() => { });
2106
+ const results = flat(cb.mock.calls);
2107
+ expect(results.length).toBe(3);
2108
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
2109
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
2110
+ expect(results[2].state).toBe(playback_1.PlaybackStates.FAILED);
2111
+ });
2112
+ it('should fail due to error', async () => {
2113
+ const test = {
2114
+ id: '1',
2115
+ name: 'Test',
2116
+ commands: [
2117
+ {
2118
+ id: '1',
2119
+ command: 'open',
2120
+ target: '',
2121
+ value: '',
2122
+ },
2123
+ {
2124
+ id: '2',
2125
+ command: 'assertText',
2126
+ target: '',
2127
+ value: '',
2128
+ },
2129
+ {
2130
+ id: '3',
2131
+ command: 'open',
2132
+ target: '',
2133
+ value: '',
2134
+ },
2135
+ ],
2136
+ };
2137
+ const executor = new JestFakeExecutor_1.default({});
2138
+ executor.doOpen.mockImplementation(async () => { });
2139
+ executor.doAssertText.mockImplementation(async () => {
2140
+ throw new Error('error in command');
2141
+ });
2142
+ const playback = new playback_1.default({
2143
+ executor,
2144
+ });
2145
+ const cb = jest.fn();
2146
+ playback['event-emitter'].on(playback_1.PlaybackEvents.PLAYBACK_STATE_CHANGED, cb);
2147
+ await (await playback.play(test))().catch(() => { });
2148
+ const results = flat(cb.mock.calls);
2149
+ expect(results.length).toBe(3);
2150
+ expect(results[0].state).toBe(playback_1.PlaybackStates.PREPARATION);
2151
+ expect(results[1].state).toBe(playback_1.PlaybackStates.PLAYING);
2152
+ expect(results[2].state).toBe(playback_1.PlaybackStates.ERRORED);
2153
+ });
2154
+ });
2155
+ });
2156
+ });
2157
+ const psetTimeout = (timeout) => new Promise((res) => {
2158
+ setTimeout(res, timeout);
2159
+ });
2160
+ const flat = (arr) => arr.reduce((f, a) => [...f, ...a], []);
2161
+ //# sourceMappingURL=playback.spec.js.map