@@ -346,6 +346,93 @@ describe('tdd/tdd-service', () => {
346346 } ) ;
347347 } ) ;
348348
349+ describe ( '_upsertComparison' , ( ) => {
350+ it ( 'replaces existing comparison when ID matches' , ( ) => {
351+ let mockDeps = createMockDeps ( ) ;
352+ let service = new TddService ( { } , '/test' , false , null , mockDeps ) ;
353+
354+ // Add initial comparison
355+ service . comparisons = [
356+ { id : 'comp-1' , name : 'homepage' , status : 'failed' , diffPercentage : 5.0 } ,
357+ { id : 'comp-2' , name : 'button' , status : 'passed' } ,
358+ ] ;
359+
360+ // Upsert with same ID but different status
361+ service . _upsertComparison ( {
362+ id : 'comp-1' ,
363+ name : 'homepage' ,
364+ status : 'passed' ,
365+ diffPercentage : 0 ,
366+ } ) ;
367+
368+ assert . strictEqual ( service . comparisons . length , 2 ) ;
369+ assert . strictEqual ( service . comparisons [ 0 ] . status , 'passed' ) ;
370+ assert . strictEqual ( service . comparisons [ 0 ] . diffPercentage , 0 ) ;
371+ } ) ;
372+
373+ it ( 'appends new comparison when ID does not exist' , ( ) => {
374+ let mockDeps = createMockDeps ( ) ;
375+ let service = new TddService ( { } , '/test' , false , null , mockDeps ) ;
376+
377+ service . comparisons = [
378+ { id : 'comp-1' , name : 'homepage' , status : 'passed' } ,
379+ ] ;
380+
381+ service . _upsertComparison ( {
382+ id : 'comp-2' ,
383+ name : 'button' ,
384+ status : 'new' ,
385+ } ) ;
386+
387+ assert . strictEqual ( service . comparisons . length , 2 ) ;
388+ assert . strictEqual ( service . comparisons [ 1 ] . id , 'comp-2' ) ;
389+ } ) ;
390+
391+ it ( 'prevents stale results from accumulating in daemon mode' , async ( ) => {
392+ // This test verifies the fix for issue #158
393+ // In daemon mode, re-running tests should replace old results, not accumulate them
394+ let mockDeps = createMockDeps ( {
395+ baseline : { baselineExists : ( ) => true } ,
396+ comparison : {
397+ compareImages : async ( ) => ( {
398+ isDifferent : true ,
399+ diffPercentage : 5.5 ,
400+ diffPixels : 1000 ,
401+ diffClusters : [ ] ,
402+ } ) ,
403+ buildFailedComparison : params => ( {
404+ id : params . signature ? `comp-${ params . signature } ` : 'test-id' ,
405+ status : 'failed' ,
406+ ...params ,
407+ } ) ,
408+ } ,
409+ signature : {
410+ generateScreenshotSignature : ( ) => 'homepage|1920|chrome' ,
411+ generateBaselineFilename : ( ) => 'homepage_hash.png' ,
412+ generateComparisonId : sig => `comp-${ sig } ` ,
413+ sanitizeScreenshotName : name => name ,
414+ validateScreenshotProperties : props => props ,
415+ safePath : ( ...parts ) => parts . join ( '/' ) ,
416+ } ,
417+ } ) ;
418+ let service = new TddService ( { } , '/test' , false , null , mockDeps ) ;
419+
420+ // First run - screenshot fails
421+ await service . compareScreenshot ( 'homepage' , Buffer . from ( 'test1' ) , { } ) ;
422+ assert . strictEqual ( service . comparisons . length , 1 ) ;
423+ assert . strictEqual ( service . comparisons [ 0 ] . status , 'failed' ) ;
424+
425+ // Second run - same screenshot, still fails (simulating daemon mode re-run)
426+ // Without the fix, this would add a second comparison
427+ await service . compareScreenshot ( 'homepage' , Buffer . from ( 'test2' ) , { } ) ;
428+ assert . strictEqual (
429+ service . comparisons . length ,
430+ 1 ,
431+ 'Should still have only 1 comparison, not 2'
432+ ) ;
433+ } ) ;
434+ } ) ;
435+
349436 describe ( 'compareScreenshot' , ( ) => {
350437 it ( 'creates new baseline when none exists' , async ( ) => {
351438 let savedBaseline = null ;
0 commit comments