@@ -361,6 +361,76 @@ const isLastSuite = (suite, tests) => {
361
361
. value ( ) === suite
362
362
}
363
363
364
+ export function flattenTestsFromSuites ( data ) {
365
+ let allTests = [ ]
366
+
367
+ function extractTests ( obj ) {
368
+ if ( obj . tests ) {
369
+ allTests = allTests . concat ( obj . tests )
370
+ }
371
+
372
+ if ( obj . suites ) {
373
+ obj . suites . forEach ( ( suite ) => extractTests ( suite ) )
374
+ }
375
+ }
376
+
377
+ extractTests ( data )
378
+
379
+ return allTests
380
+ }
381
+
382
+ // retrieve data from the last run to enable skipping
383
+ export function loadPassedTests ( testLocation ) {
384
+ if ( ! window . passedTestsInfo ) {
385
+ window . passedTestsInfo = { }
386
+ }
387
+
388
+ //TODO should be from a file and not from window
389
+ return window . passedTestsInfo [ testLocation ] ? window . passedTestsInfo [ testLocation ] : [ ]
390
+ //return $utils.loadLastRunInfoFromFile(specsPath)
391
+ }
392
+
393
+ // this allows saving the info from the last run to enable skipping
394
+ export function savePassedTests ( suite , savedInfo , testLocation ) {
395
+ //if the tests finished running the info is suite.suites[0]
396
+ //if the tests were stopped during execution the info is still on suite
397
+ let currentTests = flattenTestsFromSuites ( suite )
398
+
399
+ function saveTest ( test ) {
400
+ if ( ! test ) {
401
+ return
402
+ }
403
+
404
+ if ( test . state === 'passed' ) {
405
+ if ( ! savedInfo . some ( ( savedTest ) => savedTest . id === test . id ) ) {
406
+ savedInfo . push ( { 'id' : test . id , 'body' : test . body } )
407
+ }
408
+ } else if ( test . state === 'failed' ) {
409
+ if ( savedInfo . some ( ( savedTest ) => savedTest . id === test . id ) ) {
410
+ savedInfo = savedInfo . filter ( ( savedTest ) => savedTest . id !== test . id )
411
+ }
412
+ }
413
+ }
414
+
415
+ currentTests . forEach ( saveTest . bind ( this ) )
416
+
417
+ //TODO should be from a file and not from window
418
+ window . passedTestsInfo [ testLocation ] = savedInfo
419
+ //$utils.saveLastRunInfoToFile(specsPath, savedInfo)
420
+ }
421
+
422
+ export function setSkipOnPassedTests ( suite , savedInfo ) {
423
+ let currentTests = flattenTestsFromSuites ( suite )
424
+
425
+ function skipTest ( test ) {
426
+ if ( savedInfo . some ( ( savedTest ) => savedTest . body === test . body ) ) {
427
+ test . pending = 'true'
428
+ }
429
+ }
430
+
431
+ currentTests . forEach ( skipTest . bind ( this ) )
432
+ }
433
+
364
434
// we are the last test that will run in the suite
365
435
// if we're the last test in the tests array or
366
436
// if we failed from a hook and that hook was 'before'
@@ -1217,9 +1287,15 @@ export default {
1217
1287
let _uncaughtFn : ( ( ) => never ) | null = null
1218
1288
let _resumedAtTestIndex : number | null = null
1219
1289
let _skipCollectingLogs = true
1290
+ let _passedTests = [ ]
1291
+ let _shouldSkipPassedTests = false
1220
1292
const _runner = mocha . getRunner ( )
1221
1293
1294
+ _passedTests = loadPassedTests ( Cypress . spec . absolute )
1222
1295
_runner . suite = mocha . getRootSuite ( )
1296
+ if ( Cypress . spec . skipPassed ) {
1297
+ _shouldSkipPassedTests = true
1298
+ }
1223
1299
1224
1300
function isNotAlreadyRunTest ( test ) {
1225
1301
return _resumedAtTestIndex == null || getTestIndexFromId ( test . id ) >= _resumedAtTestIndex
@@ -1583,6 +1659,10 @@ export default {
1583
1659
mocha . createRootTest ( 'An uncaught error was detected outside of a test' , _uncaughtFn )
1584
1660
}
1585
1661
1662
+ if ( _shouldSkipPassedTests ) {
1663
+ setSkipOnPassedTests ( _runner . suite , _passedTests )
1664
+ }
1665
+
1586
1666
return normalizeAll (
1587
1667
_runner . suite ,
1588
1668
tests ,
@@ -1905,6 +1985,7 @@ export default {
1905
1985
} ,
1906
1986
1907
1987
stop ( ) {
1988
+ savePassedTests ( _runner . suite , _passedTests , Cypress . spec . absolute )
1908
1989
if ( _runner . stopped ) {
1909
1990
return
1910
1991
}
0 commit comments