@@ -2155,6 +2155,62 @@ describe(`jest@${JEST_VERSION} commonJS`, () => {
21552155 ] )
21562156 } )
21572157
2158+ it ( 'preserves test errors when ATR retry suppression is active due to EFD' , async ( ) => {
2159+ receiver . setInfoResponse ( { endpoints : [ '/evp_proxy/v4' ] } )
2160+ // All tests are considered new, so EFD will be active
2161+ receiver . setKnownTests ( { jest : { } } )
2162+ const NUM_RETRIES_EFD = 2
2163+ receiver . setSettings ( {
2164+ early_flake_detection : {
2165+ enabled : true ,
2166+ slow_test_retries : {
2167+ '5s' : NUM_RETRIES_EFD ,
2168+ } ,
2169+ faulty_session_threshold : 100 ,
2170+ } ,
2171+ known_tests_enabled : true ,
2172+ flaky_test_retries_enabled : true ,
2173+ } )
2174+
2175+ const eventsPromise = receiver
2176+ . gatherPayloadsMaxTimeout ( ( { url } ) => url . endsWith ( '/api/v2/citestcycle' ) , ( payloads ) => {
2177+ const events = payloads . flatMap ( ( { payload } ) => payload . events )
2178+ const tests = events . filter ( event => event . type === 'test' ) . map ( event => event . content )
2179+ const failingTests = tests . filter ( test => test . meta [ TEST_STATUS ] === 'fail' )
2180+
2181+ // Verify that all failing tests have error messages preserved
2182+ // even though ATR retry suppression is active (due to EFD)
2183+ failingTests . forEach ( test => {
2184+ assert . ok (
2185+ ERROR_MESSAGE in test . meta ,
2186+ 'Test error message should be preserved when ATR retry suppression is active'
2187+ )
2188+ assert . ok ( test . meta [ ERROR_MESSAGE ] . length > 0 , 'Test error message should not be empty' )
2189+ // The error should contain information about the assertion failure
2190+ assert . match ( test . meta [ ERROR_MESSAGE ] , / d e e p S t r i c t E q u a l | E x p e c t e d | a c t u a l / i)
2191+ } )
2192+
2193+ // Verify EFD is active (ATR should be suppressed)
2194+ const efdRetries = tests . filter ( t => t . meta [ TEST_RETRY_REASON ] === TEST_RETRY_REASON_TYPES . efd )
2195+ const atrRetries = tests . filter ( t => t . meta [ TEST_RETRY_REASON ] === TEST_RETRY_REASON_TYPES . atr )
2196+ assert . strictEqual ( efdRetries . length , NUM_RETRIES_EFD )
2197+ assert . strictEqual ( atrRetries . length , 0 )
2198+ } )
2199+
2200+ childProcess = exec (
2201+ runTestsCommand ,
2202+ {
2203+ cwd,
2204+ env : { ...getCiVisAgentlessConfig ( receiver . port ) , TESTS_TO_RUN : 'jest-flaky/flaky-fails.js' } ,
2205+ }
2206+ )
2207+
2208+ await Promise . all ( [
2209+ once ( childProcess , 'exit' ) ,
2210+ eventsPromise ,
2211+ ] )
2212+ } )
2213+
21582214 it (
21592215 'sets final_status tag only on last ATR retry when EFD is enabled but not active and ATR is active' ,
21602216 async ( ) => {
@@ -4494,6 +4550,69 @@ describe(`jest@${JEST_VERSION} commonJS`, () => {
44944550 ] )
44954551 } )
44964552
4553+ it ( 'preserves test errors when ATR retry suppression is active due to attempt to fix' , async ( ) => {
4554+ receiver . setSettings ( {
4555+ test_management : { enabled : true , attempt_to_fix_retries : 2 } ,
4556+ flaky_test_retries_enabled : true ,
4557+ } )
4558+
4559+ receiver . setTestManagementTests ( {
4560+ jest : {
4561+ suites : {
4562+ 'ci-visibility/jest-flaky/flaky-fails.js' : {
4563+ tests : {
4564+ 'test-flaky-test-retries can retry failed tests' : {
4565+ properties : {
4566+ attempt_to_fix : true ,
4567+ } ,
4568+ } ,
4569+ } ,
4570+ } ,
4571+ } ,
4572+ } ,
4573+ } )
4574+ const eventsPromise = receiver
4575+ . gatherPayloadsMaxTimeout ( ( { url } ) => url . endsWith ( '/api/v2/citestcycle' ) , ( payloads ) => {
4576+ const events = payloads . flatMap ( ( { payload } ) => payload . events )
4577+ const tests = events . filter ( event => event . type === 'test' ) . map ( event => event . content )
4578+ const failingTests = tests . filter ( test => test . meta [ TEST_STATUS ] === 'fail' )
4579+
4580+ // Verify that all failing tests have error messages preserved
4581+ // even though ATR retry suppression is active (due to attempt to fix)
4582+ failingTests . forEach ( test => {
4583+ assert . ok (
4584+ ERROR_MESSAGE in test . meta ,
4585+ 'Test error message should be preserved when ATR retry suppression is active due to attempt to fix'
4586+ )
4587+ assert . ok ( test . meta [ ERROR_MESSAGE ] . length > 0 , 'Test error message should not be empty' )
4588+ // The error should contain information about the assertion failure
4589+ assert . match ( test . meta [ ERROR_MESSAGE ] , / d e e p S t r i c t E q u a l | E x p e c t e d | a c t u a l / i)
4590+ } )
4591+
4592+ // Verify attempt to fix is active (ATR should be suppressed)
4593+ const atfRetries = tests . filter ( t => t . meta [ TEST_RETRY_REASON ] === TEST_RETRY_REASON_TYPES . atf )
4594+ const atrRetries = tests . filter ( t => t . meta [ TEST_RETRY_REASON ] === TEST_RETRY_REASON_TYPES . atr )
4595+ assert . strictEqual ( atfRetries . length , 2 )
4596+ assert . strictEqual ( atrRetries . length , 0 )
4597+ } )
4598+
4599+ childProcess = exec (
4600+ runTestsCommand ,
4601+ {
4602+ cwd,
4603+ env : {
4604+ ...getCiVisAgentlessConfig ( receiver . port ) ,
4605+ TESTS_TO_RUN : 'jest-flaky/flaky-fails.js' ,
4606+ } ,
4607+ }
4608+ )
4609+
4610+ await Promise . all ( [
4611+ once ( childProcess , 'exit' ) ,
4612+ eventsPromise ,
4613+ ] )
4614+ } )
4615+
44974616 it ( 'attempt to fix takes precedence over EFD for new tests' , async ( ) => {
44984617 const NUM_RETRIES_EFD = 2
44994618 receiver . setKnownTests ( { jest : { } } )
0 commit comments