ui5-test-runner 1.1.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +32 -188
  2. package/index.js +47 -16
  3. package/package.json +28 -10
  4. package/src/add-test-pages.js +35 -0
  5. package/src/add-test-pages.spec.js +95 -0
  6. package/src/browser.spec.js +724 -0
  7. package/src/browsers.js +220 -59
  8. package/src/capabilities/index.js +194 -0
  9. package/src/capabilities/tests/basic/iframe.html +8 -0
  10. package/src/capabilities/tests/basic/index.html +12 -0
  11. package/src/capabilities/tests/basic/index.js +20 -0
  12. package/src/capabilities/tests/basic/ui5.html +24 -0
  13. package/src/capabilities/tests/dynamic-include/index.js +21 -0
  14. package/src/capabilities/tests/dynamic-include/mix.html +11 -0
  15. package/src/capabilities/tests/dynamic-include/one.html +11 -0
  16. package/src/capabilities/tests/dynamic-include/post.js +3 -0
  17. package/src/capabilities/tests/dynamic-include/test.js +1 -0
  18. package/src/capabilities/tests/dynamic-include/two.html +11 -0
  19. package/src/capabilities/tests/index.js +16 -0
  20. package/src/capabilities/tests/local-storage/index.html +16 -0
  21. package/src/capabilities/tests/local-storage/index.js +21 -0
  22. package/src/capabilities/tests/screenshot/index.html +13 -0
  23. package/src/capabilities/tests/screenshot/index.js +18 -0
  24. package/src/capabilities/tests/scripts/index.js +50 -0
  25. package/src/capabilities/tests/scripts/qunit.html +22 -0
  26. package/src/capabilities/tests/scripts/testsuite.html +10 -0
  27. package/src/capabilities/tests/scripts/testsuite.js +8 -0
  28. package/src/capabilities/tests/timeout/index.html +21 -0
  29. package/src/capabilities/tests/timeout/index.js +19 -0
  30. package/src/capabilities/tests/traces/index.html +18 -0
  31. package/src/capabilities/tests/traces/index.js +81 -0
  32. package/src/cors.js +1 -1
  33. package/src/cors.spec.js +41 -0
  34. package/src/coverage.js +30 -18
  35. package/src/coverage.spec.js +79 -0
  36. package/src/csv-reader.js +36 -0
  37. package/src/csv-reader.spec.js +42 -0
  38. package/src/csv-writer.js +52 -0
  39. package/src/csv-writer.spec.js +77 -0
  40. package/src/defaults/browser.js +144 -0
  41. package/src/defaults/jsdom/compatibility.js +95 -0
  42. package/src/defaults/jsdom/debug.js +23 -0
  43. package/src/defaults/jsdom/resource-loader.js +43 -0
  44. package/src/defaults/jsdom/sap.ui.test.matchers.visible.js +39 -0
  45. package/src/defaults/jsdom.js +64 -0
  46. package/src/defaults/junit-xml-report.js +64 -0
  47. package/src/defaults/puppeteer.js +111 -0
  48. package/src/defaults/report/common.js +38 -0
  49. package/src/defaults/report/default.html +84 -0
  50. package/src/defaults/report/main.js +44 -0
  51. package/src/defaults/report/progress.js +49 -0
  52. package/src/defaults/report/styles.css +66 -0
  53. package/src/defaults/report.js +69 -0
  54. package/src/defaults/selenium-webdriver/chrome.js +38 -0
  55. package/src/defaults/selenium-webdriver/edge.js +25 -0
  56. package/src/defaults/selenium-webdriver/firefox.js +31 -0
  57. package/src/defaults/selenium-webdriver.js +138 -0
  58. package/src/endpoints.js +70 -124
  59. package/src/error.js +52 -0
  60. package/src/error.spec.js +17 -0
  61. package/src/get-job-progress.js +69 -0
  62. package/src/get-job-progress.spec.js +175 -0
  63. package/src/inject/post.js +96 -0
  64. package/src/inject/post.spec.js +147 -0
  65. package/src/inject/qunit-hooks.js +6 -21
  66. package/src/inject/qunit-intercept.js +30 -0
  67. package/src/inject/qunit-redirect.js +15 -7
  68. package/src/job-mode.js +45 -0
  69. package/src/job.js +254 -108
  70. package/src/job.spec.js +413 -0
  71. package/src/npm.js +73 -0
  72. package/src/npm.spec.js +98 -0
  73. package/src/options.js +73 -0
  74. package/src/options.spec.js +125 -0
  75. package/src/output.js +450 -131
  76. package/src/qunit-hooks.js +116 -0
  77. package/src/qunit-hooks.spec.js +687 -0
  78. package/src/report.js +47 -0
  79. package/src/reserve.js +3 -4
  80. package/src/simulate.spec.js +466 -0
  81. package/src/symbols.js +8 -0
  82. package/src/tests.js +127 -84
  83. package/src/timeout.spec.js +39 -0
  84. package/src/tools.js +111 -4
  85. package/src/tools.spec.js +90 -0
  86. package/src/ui5.js +3 -3
  87. package/src/unhandled.js +6 -6
  88. package/src/unhandled.spec.js +63 -0
  89. package/defaults/chromium.js +0 -62
  90. package/src/progress.html +0 -71
  91. package/src/proxies.js +0 -8
  92. package/src/report.html +0 -202
  93. /package/{defaults → src/defaults}/nyc.json +0 -0
@@ -0,0 +1,687 @@
1
+ jest.mock('./browsers.js', () => ({
2
+ screenshot: jest.fn(),
3
+ stop: jest.fn()
4
+ }))
5
+ const { screenshot, stop } = require('./browsers')
6
+
7
+ jest.mock('./coverage.js', () => ({
8
+ collect: jest.fn()
9
+ }))
10
+ const { collect } = require('./coverage')
11
+
12
+ const mockGenericError = jest.fn()
13
+
14
+ jest.mock('./output.js', () => ({
15
+ getOutput: () => ({
16
+ genericError: mockGenericError
17
+ })
18
+ }))
19
+
20
+ const {
21
+ get,
22
+ begin,
23
+ testStart,
24
+ log,
25
+ testDone,
26
+ done
27
+ } = require('./qunit-hooks.js')
28
+ const { UTRError } = require('./error')
29
+
30
+ describe('src/qunit-hooks', () => {
31
+ const url = 'http://localhost:80/page1.html'
32
+ let job
33
+
34
+ beforeEach(() => {
35
+ screenshot.mockReset()
36
+ stop.mockClear()
37
+ mockGenericError.mockClear()
38
+ job = {
39
+ screenshot: true,
40
+ browserCapabilities: {
41
+ screenshot: false
42
+ }
43
+ }
44
+ })
45
+
46
+ const getModules = () => [{
47
+ name: 'module 1',
48
+ tests: [{
49
+ name: 'test 1a',
50
+ testId: '1a'
51
+ }, {
52
+ name: 'test 1b',
53
+ testId: '1b'
54
+ }]
55
+ }, {
56
+ name: 'module 2',
57
+ tests: [{
58
+ name: 'test 2c',
59
+ testId: '2c'
60
+ }, {
61
+ name: 'test 2d',
62
+ testId: '2d'
63
+ }]
64
+ }]
65
+ const getBeginInfo = () => ({
66
+ totalTests: 4,
67
+ modules: getModules()
68
+ })
69
+
70
+ describe('begin', () => {
71
+ it('allocates a placeholder page', async () => {
72
+ await begin(job, url, getBeginInfo())
73
+ const { page } = get(job, url)
74
+ expect(page).not.toBeUndefined()
75
+ })
76
+
77
+ it('allocates an id for the page', async () => {
78
+ await begin(job, url, getBeginInfo())
79
+ const { page } = get(job, url)
80
+ expect(page.id).not.toBeUndefined()
81
+ })
82
+
83
+ it('stores test information and keeps track of when it starts', async () => {
84
+ await begin(job, url, getBeginInfo())
85
+ const { page } = get(job, url)
86
+ const { start, id, ...pageWithoutVariableInfos } = page
87
+ expect(pageWithoutVariableInfos).toStrictEqual({
88
+ isOpa: false,
89
+ failed: 0,
90
+ passed: 0,
91
+ count: 4,
92
+ modules: getModules()
93
+ })
94
+ expect(start).toBeInstanceOf(Date)
95
+ expect(id).not.toBeUndefined()
96
+ })
97
+
98
+ it('resets the existing structure on retry', async () => {
99
+ job.qunitPages = {
100
+ [url]: {
101
+ isOpa: true,
102
+ failed: 2,
103
+ passed: 1,
104
+ count: 4,
105
+ modules: [{
106
+ name: 'module 1',
107
+ tests: [{
108
+ name: 'test 1a',
109
+ testId: '1a',
110
+ logs: []
111
+ }, {
112
+ name: 'test 1b',
113
+ testId: '1b',
114
+ anything: true
115
+ }]
116
+ }, {
117
+ name: 'module 2',
118
+ tests: [{
119
+ name: 'test 2c',
120
+ testId: '2c',
121
+ failed: 1
122
+ }, {
123
+ name: 'test 2d',
124
+ testId: '2d',
125
+ whatever: {
126
+ }
127
+ }]
128
+ }],
129
+ start: 'Not a date',
130
+ end: 'Not a date'
131
+ }
132
+ }
133
+ await begin(job, url, {
134
+ isOpa: true,
135
+ ...getBeginInfo()
136
+ })
137
+ const { page } = get(job, url)
138
+ const { start, id, ...pageWithoutVariableInfos } = page
139
+ expect(pageWithoutVariableInfos).toStrictEqual({
140
+ isOpa: true,
141
+ failed: 0,
142
+ passed: 0,
143
+ count: 4,
144
+ modules: getModules()
145
+ })
146
+ expect(start).toBeInstanceOf(Date)
147
+ expect(id).not.toBeUndefined()
148
+ })
149
+
150
+ describe('ignoring hash variation', () => {
151
+ it('starts empty, receives #any_hash', async () => {
152
+ await begin(job, url, getBeginInfo())
153
+ const { page } = get(job, url + '#any_hash')
154
+ expect(page).not.toBeUndefined()
155
+ })
156
+
157
+ it('starts with #any_hash, receives #any_hash', async () => {
158
+ await begin(job, url, getBeginInfo())
159
+ const { page } = get(job, url + '#any_hash')
160
+ expect(page).not.toBeUndefined()
161
+ })
162
+
163
+ it('starts with #any_hash, receives #another_hash', async () => {
164
+ await begin(job, url, getBeginInfo())
165
+ const { page } = get(job, url + '#another_hash')
166
+ expect(page).not.toBeUndefined()
167
+ })
168
+
169
+ it('starts with #any_hash, receives empty', async () => {
170
+ await begin(job, url, getBeginInfo())
171
+ const { page } = get(job, url)
172
+ expect(page).not.toBeUndefined()
173
+ })
174
+ })
175
+
176
+ describe('validation', () => {
177
+ afterEach(() => {
178
+ expect(stop).toHaveBeenCalledWith(job, url)
179
+ expect(job.failed).toStrictEqual(true)
180
+ })
181
+
182
+ it('requires totalTests', async () => {
183
+ await expect(begin(job, url, {
184
+ isOpa: false,
185
+ modules: getModules()
186
+ })).rejects.toThrow(UTRError.QUNIT_ERROR('Invalid begin hook details'))
187
+ })
188
+
189
+ it('requires modules', async () => {
190
+ await expect(begin(job, url, {
191
+ isOpa: false,
192
+ totalTests: 1
193
+ })).rejects.toThrow(UTRError.QUNIT_ERROR('Invalid begin hook details'))
194
+ })
195
+ })
196
+ })
197
+
198
+ describe('testStart', () => {
199
+ beforeEach(async () => {
200
+ await begin(job, url, {
201
+ isOpa: false,
202
+ ...getBeginInfo()
203
+ })
204
+ })
205
+
206
+ it('signals test start', async () => {
207
+ await testStart(job, url, {
208
+ module: 'module 1',
209
+ name: 'test 1a',
210
+ testId: '1a'
211
+ })
212
+
213
+ const { test } = get(job, url, '1a')
214
+ expect(test.start).toBeInstanceOf(Date)
215
+ })
216
+ })
217
+
218
+ describe('log', () => {
219
+ const getLogFor1a = () => ({
220
+ module: 'module 1',
221
+ name: 'test 1a',
222
+ result: true,
223
+ message: 'message',
224
+ actual: true,
225
+ expected: true,
226
+ testId: '1a',
227
+ runtime: 1419
228
+ })
229
+
230
+ it('keeps track of logs', async () => {
231
+ await begin(job, url, {
232
+ isOpa: false,
233
+ ...getBeginInfo()
234
+ })
235
+ await log(job, url, getLogFor1a())
236
+ const { test } = get(job, url, '1a')
237
+ expect(test.logs).toBeInstanceOf(Array)
238
+ expect(test.logs.length).toStrictEqual(1)
239
+ expect(test.logs[0]).toStrictEqual({
240
+ result: true,
241
+ actual: true,
242
+ expected: true,
243
+ message: 'message',
244
+ runtime: 1419
245
+ })
246
+ })
247
+
248
+ it('keeps track of logs (multiple)', async () => {
249
+ await begin(job, url, {
250
+ isOpa: false,
251
+ ...getBeginInfo()
252
+ })
253
+ await log(job, url, getLogFor1a())
254
+ await log(job, url, {
255
+ ...getLogFor1a(),
256
+ result: false,
257
+ message: 'an error occurred',
258
+ actual: undefined,
259
+ expected: {},
260
+ runtime: 1506
261
+ })
262
+ const { test } = get(job, url, '1a')
263
+ expect(test.logs.length).toStrictEqual(2)
264
+ expect(test.logs).toStrictEqual([{
265
+ result: true,
266
+ actual: true,
267
+ expected: true,
268
+ message: 'message',
269
+ runtime: 1419
270
+ }, {
271
+ result: false,
272
+ actual: undefined,
273
+ expected: {},
274
+ message: 'an error occurred',
275
+ runtime: 1506
276
+ }])
277
+ })
278
+
279
+ it('does not take a screenshot if not OPA', async () => {
280
+ job.browserCapabilities.screenshot = '.png'
281
+ await begin(job, url, {
282
+ isOpa: false,
283
+ ...getBeginInfo()
284
+ })
285
+ await log(job, url, getLogFor1a())
286
+ expect(screenshot).not.toHaveBeenCalled()
287
+ })
288
+
289
+ it('does not take a screenshot if not available', async () => {
290
+ await begin(job, url, {
291
+ isOpa: true,
292
+ ...getBeginInfo()
293
+ })
294
+ await log(job, url, getLogFor1a())
295
+ expect(screenshot).not.toHaveBeenCalled()
296
+ })
297
+
298
+ it('does not take a screenshot if not disabled', async () => {
299
+ job.browserCapabilities.screenshot = '.png'
300
+ job.screenshot = false
301
+ await begin(job, url, {
302
+ isOpa: true,
303
+ ...getBeginInfo()
304
+ })
305
+ await log(job, url, getLogFor1a())
306
+ expect(screenshot).not.toHaveBeenCalled()
307
+ })
308
+
309
+ it('takes a screenshot for OPA tests', async () => {
310
+ job.browserCapabilities.screenshot = '.png'
311
+ await begin(job, url, {
312
+ isOpa: true,
313
+ ...getBeginInfo()
314
+ })
315
+ screenshot.mockImplementation(() => '1a-1419.png')
316
+ await log(job, url, getLogFor1a())
317
+ expect(screenshot).toHaveBeenCalledWith(job, url, '1a-1419')
318
+ const { test } = get(job, url, '1a')
319
+ expect(test.logs[0]).toStrictEqual({
320
+ result: true,
321
+ actual: true,
322
+ expected: true,
323
+ message: 'message',
324
+ runtime: 1419,
325
+ screenshot: '1a-1419.png'
326
+ })
327
+ })
328
+
329
+ it('takes a screenshot for OPA tests (hash changing)', async () => {
330
+ job.browserCapabilities.screenshot = '.png'
331
+ await begin(job, url, {
332
+ isOpa: true,
333
+ ...getBeginInfo()
334
+ })
335
+ await log(job, url + '#any_hash', getLogFor1a())
336
+ expect(screenshot).toHaveBeenCalledWith(job, url, '1a-1419')
337
+ })
338
+
339
+ it('does not fail if screenshot failed', async () => {
340
+ job.browserCapabilities.screenshot = '.png'
341
+ await begin(job, url, {
342
+ isOpa: true,
343
+ ...getBeginInfo()
344
+ })
345
+ screenshot.mockImplementation(() => Promise.reject(new Error()))
346
+ await log(job, url, getLogFor1a())
347
+ expect(mockGenericError).toHaveBeenCalled()
348
+ expect(job.failed).not.toStrictEqual(true)
349
+ const { page, test } = get(job, url, '1a')
350
+ expect(page).toMatchObject({
351
+ isOpa: true,
352
+ failed: 0,
353
+ passed: 0
354
+ })
355
+ expect(test.logs[0]).toStrictEqual({
356
+ result: true,
357
+ actual: true,
358
+ expected: true,
359
+ message: 'message',
360
+ runtime: 1419
361
+ })
362
+ })
363
+
364
+ it('fails on invalid test', async () => {
365
+ await begin(job, url, {
366
+ isOpa: true,
367
+ ...getBeginInfo()
368
+ })
369
+ await expect(log(job, url, {
370
+ module: 'module 1',
371
+ name: 'unknown',
372
+ result: true,
373
+ message: 'message',
374
+ actual: true,
375
+ expected: true,
376
+ testId: 'unk',
377
+ runtime: 1000
378
+ })).rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit unit test found with id unk'))
379
+ expect(stop).toHaveBeenCalledWith(job, url)
380
+ expect(job.failed).toStrictEqual(true)
381
+ })
382
+ })
383
+
384
+ describe('testDone', () => {
385
+ const getTestDoneFor1a = () => ({
386
+ name: 'test 1a',
387
+ module: 'module 1',
388
+ skipped: false,
389
+ failed: 0,
390
+ passed: 1,
391
+ total: 1,
392
+ runtime: 1515,
393
+ assertions: [{
394
+ result: true,
395
+ message: 'message'
396
+ }],
397
+ testId: '1a',
398
+ duration: 1515
399
+ })
400
+
401
+ beforeEach(async () => {
402
+ await begin(job, url, {
403
+ isOpa: false,
404
+ ...getBeginInfo()
405
+ })
406
+ })
407
+
408
+ describe('test success (no screenshot, page.passed += 1)', () => {
409
+ afterEach(() => {
410
+ expect(screenshot).not.toHaveBeenCalled()
411
+ const { page, test } = get(job, url, '1a')
412
+ expect(page).toMatchObject({
413
+ isOpa: false,
414
+ failed: 0,
415
+ passed: 1
416
+ })
417
+ expect(test).toMatchObject({
418
+ report: {
419
+ skipped: false,
420
+ failed: 0,
421
+ runtime: 1515,
422
+ duration: 1515
423
+ }
424
+ })
425
+ expect(test.end).toBeInstanceOf(Date)
426
+ })
427
+
428
+ it('store reports', async () => {
429
+ await testDone(job, url, getTestDoneFor1a())
430
+ const { test } = get(job, url, '1a')
431
+ expect(test).toMatchObject({
432
+ report: {
433
+ passed: 1,
434
+ total: 1
435
+ }
436
+ })
437
+ })
438
+
439
+ it('supports more than one assertion in the test', async () => {
440
+ await testDone(job, url, {
441
+ ...getTestDoneFor1a(),
442
+ passed: 2,
443
+ total: 2
444
+ })
445
+ const { test } = get(job, url, '1a')
446
+ expect(test).toMatchObject({
447
+ report: {
448
+ passed: 2,
449
+ total: 2
450
+ }
451
+ })
452
+ })
453
+ })
454
+
455
+ describe('test failure (page.failed += 1)', () => {
456
+ afterEach(() => {
457
+ const { page, test } = get(job, url, '1a')
458
+ expect(page).toMatchObject({
459
+ isOpa: false,
460
+ failed: 1,
461
+ passed: 0
462
+ })
463
+ expect(test).toMatchObject({
464
+ report: {
465
+ skipped: false,
466
+ runtime: 1515,
467
+ duration: 1515
468
+ }
469
+ })
470
+ expect(test.end).toBeInstanceOf(Date)
471
+ expect(job.failed).toStrictEqual(true)
472
+ })
473
+
474
+ describe('screenshot not supported', () => {
475
+ it('increases failed count only', async () => {
476
+ await testDone(job, url, {
477
+ ...getTestDoneFor1a(),
478
+ passed: 0,
479
+ failed: 1,
480
+ total: 1
481
+ })
482
+ expect(screenshot).not.toHaveBeenCalled()
483
+ const { test } = get(job, url, '1a')
484
+ expect(test).toMatchObject({
485
+ report: {
486
+ passed: 0,
487
+ failed: 1,
488
+ total: 1
489
+ }
490
+ })
491
+ })
492
+
493
+ it('supports more than one failed assertion in the test', async () => {
494
+ await testDone(job, url, {
495
+ ...getTestDoneFor1a(),
496
+ passed: 0,
497
+ failed: 2,
498
+ total: 2
499
+ })
500
+ const { test } = get(job, url, '1a')
501
+ expect(test).toMatchObject({
502
+ report: {
503
+ passed: 0,
504
+ failed: 2,
505
+ total: 2
506
+ }
507
+ })
508
+ })
509
+
510
+ it('supports failed and succeeded assertions in the test', async () => {
511
+ await testDone(job, url, {
512
+ ...getTestDoneFor1a(),
513
+ passed: 1,
514
+ failed: 1,
515
+ total: 2
516
+ })
517
+ const { test } = get(job, url, '1a')
518
+ expect(test).toMatchObject({
519
+ report: {
520
+ passed: 1,
521
+ failed: 1,
522
+ total: 2
523
+ }
524
+ })
525
+ })
526
+ })
527
+
528
+ describe('screenshot supported', () => {
529
+ beforeEach(() => {
530
+ job.browserCapabilities.screenshot = '.png'
531
+ })
532
+
533
+ it('takes a screenshot', async () => {
534
+ await testDone(job, url, {
535
+ ...getTestDoneFor1a(),
536
+ passed: 0,
537
+ failed: 1,
538
+ total: 1
539
+ })
540
+ expect(screenshot).toHaveBeenCalledWith(job, url, '1a')
541
+ })
542
+
543
+ it('takes a screenshot (even if disabled)', async () => {
544
+ job.screenshot = false
545
+ await testDone(job, url, {
546
+ ...getTestDoneFor1a(),
547
+ passed: 0,
548
+ failed: 1,
549
+ total: 1
550
+ })
551
+ expect(screenshot).toHaveBeenCalledWith(job, url, '1a')
552
+ })
553
+
554
+ it('takes a screenshot (hash changing)', async () => {
555
+ await testDone(job, url + '#any_hash', {
556
+ ...getTestDoneFor1a(),
557
+ passed: 0,
558
+ failed: 1,
559
+ total: 1
560
+ })
561
+ expect(screenshot).toHaveBeenCalledWith(job, url, '1a')
562
+ })
563
+
564
+ it('does not stop if screenshot failed', async () => {
565
+ screenshot.mockImplementation(() => Promise.reject(new Error()))
566
+ await testDone(job, url, {
567
+ ...getTestDoneFor1a(),
568
+ passed: 0,
569
+ failed: 1,
570
+ total: 1
571
+ })
572
+ expect(mockGenericError).toHaveBeenCalled()
573
+ expect(stop).not.toHaveBeenCalled()
574
+ })
575
+ })
576
+ })
577
+
578
+ it('fails if tests not started', async () => {
579
+ delete job.qunitPages
580
+ await expect(testDone(job, url, getTestDoneFor1a()))
581
+ .rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit page found for http://localhost:80/page1.html'))
582
+ expect(stop).toHaveBeenCalledWith(job, url)
583
+ expect(job.failed).toStrictEqual(true)
584
+ })
585
+
586
+ it('fails if URL does not exist', async () => {
587
+ job.qunitPages = {}
588
+ await expect(testDone(job, url, getTestDoneFor1a()))
589
+ .rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit page found for http://localhost:80/page1.html'))
590
+ expect(stop).toHaveBeenCalledWith(job, url)
591
+ expect(job.failed).toStrictEqual(true)
592
+ })
593
+
594
+ it('fails on invalid test id', async () => {
595
+ await expect(testDone(job, url, {
596
+ ...getTestDoneFor1a(),
597
+ testId: '1c'
598
+ }))
599
+ .rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit unit test found with id 1c'))
600
+ expect(stop).toHaveBeenCalledWith(job, url)
601
+ expect(job.failed).toStrictEqual(true)
602
+ })
603
+ })
604
+
605
+ describe('done', () => {
606
+ const getDoneInfo = () => ({
607
+ failed: 0,
608
+ passed: 4,
609
+ total: 4,
610
+ runtime: 2853
611
+ })
612
+
613
+ beforeEach(async () => {
614
+ await begin(job, url, {
615
+ isOpa: false,
616
+ ...getBeginInfo()
617
+ })
618
+ })
619
+
620
+ it('stops the browser', async () => {
621
+ await done(job, url, getDoneInfo())
622
+ expect(stop).toHaveBeenCalledWith(job, url)
623
+ })
624
+
625
+ it('takes a screenshot if enabled', async () => {
626
+ job.browserCapabilities.screenshot = '.png'
627
+ await done(job, url, getDoneInfo())
628
+ expect(screenshot).toHaveBeenCalledWith(job, url, 'done')
629
+ })
630
+
631
+ it('takes a screenshot if enabled (hash changing)', async () => {
632
+ job.browserCapabilities.screenshot = '.png'
633
+ await done(job, url + '#any_hash', getDoneInfo())
634
+ expect(screenshot).toHaveBeenCalledWith(job, url, 'done')
635
+ })
636
+
637
+ it('fails properly if screenshot failed', async () => {
638
+ job.browserCapabilities.screenshot = '.png'
639
+ screenshot.mockImplementation(() => Promise.reject(new Error()))
640
+ await done(job, url, getDoneInfo())
641
+ expect(mockGenericError).toHaveBeenCalled()
642
+ expect(stop).toHaveBeenCalledWith(job, url)
643
+ expect(job.failed).not.toStrictEqual(true)
644
+ })
645
+
646
+ it('takes no screenshot if disabled', async () => {
647
+ await done(job, url, getDoneInfo())
648
+ expect(screenshot).not.toHaveBeenCalled()
649
+ })
650
+
651
+ it('associates the report to the qunitPage', async () => {
652
+ await done(job, url, getDoneInfo())
653
+ const { page } = get(job, url)
654
+ expect(page.report).toStrictEqual(getDoneInfo())
655
+ })
656
+
657
+ it('collects and strips coverage information', async () => {
658
+ const report = getDoneInfo()
659
+ const coverage = {}
660
+ report.__coverage__ = coverage
661
+ await done(job, url, report)
662
+ expect(collect).toHaveBeenCalledWith(job, url, coverage)
663
+ const { page } = get(job, url)
664
+ expect(page.report).toStrictEqual(getDoneInfo())
665
+ })
666
+
667
+ it('documents when the page ended', async () => {
668
+ await done(job, url, getDoneInfo())
669
+ const { page } = get(job, url)
670
+ expect(page.end).toBeInstanceOf(Date)
671
+ })
672
+
673
+ it('fails if tests not started', async () => {
674
+ delete job.qunitPages
675
+ await expect(done(job, url, getDoneInfo())).rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit page found for http://localhost:80/page1.html'))
676
+ expect(stop).toHaveBeenCalledWith(job, url)
677
+ expect(job.failed).toStrictEqual(true)
678
+ })
679
+
680
+ it('fails if URL does not exist', async () => {
681
+ job.qunitPages = {}
682
+ await expect(done(job, url, {})).rejects.toThrow(UTRError.QUNIT_ERROR('No QUnit page found for http://localhost:80/page1.html'))
683
+ expect(stop).toHaveBeenCalledWith(job, url)
684
+ expect(job.failed).toStrictEqual(true)
685
+ })
686
+ })
687
+ })