@@ -39,8 +39,10 @@ const getReportWithRunsAndMatches = async (id, { transaction }) =>
39
39
id
40
40
testResults {
41
41
id
42
+ test { id rowNumber }
42
43
scenarioResults {
43
44
id
45
+ scenario { id }
44
46
output
45
47
match {
46
48
type
@@ -447,4 +449,122 @@ describe('Verdict service', () => {
447
449
expect ( sawMatch ) . toBe ( true ) ;
448
450
} ) ;
449
451
} ) ;
452
+
453
+ it ( 'annotates CROSS_SCENARIO for a specific scenario when outputs are swapped between two scenarios' , async ( ) => {
454
+ await apiServer . sessionAgentDbCleaner ( async transaction => {
455
+ // Use historical finalized report id 25; seeded via run 26 with distinct per-scenario outputs
456
+ const { testPlanReport : historicalReport } = await getTestPlanReport (
457
+ '25' ,
458
+ {
459
+ transaction
460
+ }
461
+ ) ;
462
+
463
+ // Choose a historical test with at least 2 scenarios, different outputs, and identical assertion id sets
464
+ const targetHistorical = (
465
+ historicalReport . finalizedTestResults || [ ]
466
+ ) . find ( tr => {
467
+ if ( ! tr . scenarioResults || tr . scenarioResults . length < 2 ) return false ;
468
+ const [ sr0 , sr1 ] = tr . scenarioResults ;
469
+ if ( sr0 . output === sr1 . output ) return false ;
470
+ const setFrom = srs =>
471
+ new Set (
472
+ ( srs . assertionResults || [ ] ) . map ( a => String ( a . assertion . id ) )
473
+ ) ;
474
+ const s0 = setFrom ( sr0 ) ;
475
+ const s1 = setFrom ( sr1 ) ;
476
+ if ( s0 . size !== s1 . size ) return false ;
477
+ for ( const id of s0 ) if ( ! s1 . has ( id ) ) return false ;
478
+ return true ;
479
+ } ) ;
480
+
481
+ expect ( targetHistorical ) . toBeDefined ( ) ;
482
+ const [ hSr0 , hSr1 ] = targetHistorical . scenarioResults ;
483
+ const sId0 = hSr0 . scenario . id ;
484
+ const sId1 = hSr1 . scenario . id ;
485
+ const out1 = hSr1 . output ;
486
+
487
+ const currentAtVersion = await getAtVersionByQuery ( {
488
+ where : { atId : 3 , name : '14.0' } ,
489
+ transaction
490
+ } ) ;
491
+
492
+ const createResponse =
493
+ await createCollectionJobsFromPreviousVersionMutation (
494
+ currentAtVersion . id ,
495
+ { transaction }
496
+ ) ;
497
+ const result = createResponse . createCollectionJobsFromPreviousAtVersion ;
498
+ const { collectionJob : newJob } = await getTestCollectionJob (
499
+ result . collectionJobs [ 0 ] . id ,
500
+ { transaction }
501
+ ) ;
502
+
503
+ const secret = await getJobSecret ( newJob . id , { transaction } ) ;
504
+ let updateResponse = await sessionAgent
505
+ . post ( `/api/jobs/${ newJob . id } ` )
506
+ . send ( { status : 'RUNNING' } )
507
+ . set ( 'x-automation-secret' , secret )
508
+ . set ( 'x-transaction-id' , transaction . id ) ;
509
+ expect ( updateResponse . statusCode ) . toBe ( 200 ) ;
510
+
511
+ // Post responses; for the chosen test, swap the first two scenario outputs to induce CROSS_SCENARIO
512
+ for ( const historicalResult of historicalReport . finalizedTestResults ) {
513
+ const testRowNumber = historicalResult . test . rowNumber ;
514
+ const responses = historicalResult . scenarioResults . map ( sr => sr . output ) ;
515
+ if (
516
+ historicalResult . test . id === targetHistorical . test . id &&
517
+ responses . length >= 2
518
+ ) {
519
+ if ( responses [ 0 ] !== responses [ 1 ] ) {
520
+ const tmp = responses [ 0 ] ;
521
+ responses [ 0 ] = responses [ 1 ] ;
522
+ responses [ 1 ] = tmp ;
523
+ }
524
+ }
525
+ const updateRes = await sessionAgent
526
+ . post ( `/api/jobs/${ newJob . id } /test/${ testRowNumber } ` )
527
+ . send ( {
528
+ responses,
529
+ capabilities : {
530
+ atName : historicalReport . at . name ,
531
+ atVersion : newJob . testPlanRun . testPlanReport . exactAtVersion . name ,
532
+ browserName : historicalReport . browser . name ,
533
+ browserVersion : historicalResult . browserVersion . name
534
+ }
535
+ } )
536
+ . set ( 'x-automation-secret' , secret )
537
+ . set ( 'x-transaction-id' , transaction . id ) ;
538
+ expect ( updateRes . statusCode ) . toBe ( 200 ) ;
539
+ }
540
+
541
+ const { testPlanReport : updated } = await getReportWithRunsAndMatches (
542
+ newJob . testPlanRun . testPlanReport . id ,
543
+ { transaction }
544
+ ) ;
545
+
546
+ expect ( updated . isRerun ) . toBe ( true ) ;
547
+ const updatedTestResult = ( updated . draftTestPlanRuns || [ ] )
548
+ . flatMap ( run => run . testResults || [ ] )
549
+ . find ( tr => tr . test && tr . test . id === targetHistorical . test . id ) ;
550
+ expect ( updatedTestResult ) . toBeDefined ( ) ;
551
+
552
+ const updatedSr0 = ( updatedTestResult . scenarioResults || [ ] ) . find (
553
+ sr => sr . scenario && sr . scenario . id === sId0
554
+ ) ;
555
+ const updatedSr1 = ( updatedTestResult . scenarioResults || [ ] ) . find (
556
+ sr => sr . scenario && sr . scenario . id === sId1
557
+ ) ;
558
+ expect ( updatedSr0 ) . toBeDefined ( ) ;
559
+ expect ( updatedSr1 ) . toBeDefined ( ) ;
560
+
561
+ // After swap: scenario sId0 now has output out1 and should be CROSS_SCENARIO sourcing scenario sId1
562
+ expect ( updatedSr0 . output ) . toBe ( out1 ) ;
563
+ expect ( updatedSr0 . match ) . toBeDefined ( ) ;
564
+ expect ( updatedSr0 . match . type ) . toBe ( 'CROSS_SCENARIO' ) ;
565
+ expect ( updatedSr0 . match . source ) . toBeDefined ( ) ;
566
+ expect ( updatedSr0 . match . source . scenarioId ) . toBe ( sId1 ) ;
567
+ expect ( updatedSr0 . match . source . output ) . toBe ( out1 ) ;
568
+ } ) ;
569
+ } ) ;
450
570
} ) ;
0 commit comments