@@ -4823,142 +4823,133 @@ describe('rerun --wait — dashboardUrl on terminal output', () => {
48234823// ---------------------------------------------------------------------------
48244824// Batch --all --wait fan-out: RequestTimeoutError must not leave stdout empty
48254825// ---------------------------------------------------------------------------
4826- describe (
4827- '[finding-5] batch rerun --wait: RequestTimeoutError during fan-out poll writes JSON stdout + exit 7' ,
4828- ( ) => {
4829- it (
4830- 'stdout contains accepted[] with runIds when member polls throw RequestTimeoutError' ,
4831- async ( ) => {
4832- const creds = makeCreds ( ) ;
4833- const batchResp : BatchRerunResponse = {
4834- accepted : [
4835- { testId : 'test_1' , runId : 'run_b1' , enqueuedAt : '2026-06-03T10:00:00.000Z' } ,
4836- { testId : 'test_2' , runId : 'run_b2' , enqueuedAt : '2026-06-03T10:00:00.000Z' } ,
4837- ] ,
4838- deferred : [ ] ,
4839- conflicts : [ ] ,
4840- closure : { byProject : [ ] } ,
4841- } ;
4842-
4843- const fetchImpl = makeFetch ( ( url ) => {
4844- if ( url . includes ( '/tests/batch/rerun' ) ) {
4845- return { status : 202 , body : batchResp } ;
4846- }
4847- if ( url . includes ( '/runs/' ) ) {
4848- throw new RequestTimeoutError ( 120000 , 'req_timeout_batch_rerun' ) ;
4849- }
4850- return errorBody ( 'NOT_FOUND' ) ;
4851- } ) ;
4826+ describe ( '[finding-5] batch rerun --wait: RequestTimeoutError during fan-out poll writes JSON stdout + exit 7' , ( ) => {
4827+ it ( 'stdout contains accepted[] with runIds when member polls throw RequestTimeoutError' , async ( ) => {
4828+ const creds = makeCreds ( ) ;
4829+ const batchResp : BatchRerunResponse = {
4830+ accepted : [
4831+ { testId : 'test_1' , runId : 'run_b1' , enqueuedAt : '2026-06-03T10:00:00.000Z' } ,
4832+ { testId : 'test_2' , runId : 'run_b2' , enqueuedAt : '2026-06-03T10:00:00.000Z' } ,
4833+ ] ,
4834+ deferred : [ ] ,
4835+ conflicts : [ ] ,
4836+ closure : { byProject : [ ] } ,
4837+ } ;
48524838
4853- const stdoutLines : string [ ] = [ ] ;
4854- const err = await runTestRerun (
4855- {
4856- testIds : [ 'test_1' , 'test_2' ] ,
4857- all : false ,
4858- wait : true ,
4859- timeoutSeconds : 60 ,
4860- autoHeal : false ,
4861- autoHealExplicit : false ,
4862- skipDependencies : false ,
4863- maxConcurrency : 1 ,
4864- profile : 'default' ,
4865- output : 'json' ,
4866- debug : false ,
4867- } ,
4868- {
4869- ...creds ,
4870- sleep : instantSleep ,
4871- fetchImpl : fetchImpl as unknown as FetchImpl ,
4872- stdout : ( line ) => stdoutLines . push ( line ) ,
4873- stderr : ( ) => undefined ,
4874- } ,
4875- ) . catch ( ( e ) => e ) ;
4839+ const fetchImpl = makeFetch ( url => {
4840+ if ( url . includes ( '/tests/batch/rerun' ) ) {
4841+ return { status : 202 , body : batchResp } ;
4842+ }
4843+ if ( url . includes ( '/runs/' ) ) {
4844+ throw new RequestTimeoutError ( 120000 , 'req_timeout_batch_rerun' ) ;
4845+ }
4846+ return errorBody ( 'NOT_FOUND' ) ;
4847+ } ) ;
48764848
4877- expect ( err ) . toMatchObject ( { exitCode : 7 } ) ;
4878- const parsed = JSON . parse ( stdoutLines . join ( '\n' ) ) as {
4879- accepted : Array < { testId : string ; runId : string ; status : string } > ;
4880- } ;
4881- expect ( parsed . accepted ) . toHaveLength ( 2 ) ;
4882- expect ( parsed . accepted . map ( ( r ) => r . runId ) . sort ( ) ) . toEqual ( [ 'run_b1' , 'run_b2' ] ) ;
4883- expect ( parsed . accepted . every ( ( r ) => r . status === 'timeout' ) ) . toBe ( true ) ;
4849+ const stdoutLines : string [ ] = [ ] ;
4850+ const err = await runTestRerun (
4851+ {
4852+ testIds : [ 'test_1' , 'test_2' ] ,
4853+ all : false ,
4854+ wait : true ,
4855+ timeoutSeconds : 60 ,
4856+ autoHeal : false ,
4857+ autoHealExplicit : false ,
4858+ skipDependencies : false ,
4859+ maxConcurrency : 1 ,
4860+ profile : 'default' ,
4861+ output : 'json' ,
4862+ debug : false ,
48844863 } ,
4885- ) ;
4886- } ,
4887- ) ;
4864+ {
4865+ ...creds ,
4866+ sleep : instantSleep ,
4867+ fetchImpl : fetchImpl as unknown as FetchImpl ,
4868+ stdout : ( line ) => stdoutLines . push ( line ) ,
4869+ stderr : ( ) => undefined ,
4870+ } ,
4871+ ) . catch ( e => e ) ;
4872+
4873+ expect ( err ) . toMatchObject ( { exitCode : 7 } ) ;
4874+ const parsed = JSON . parse ( stdoutLines . join ( '\n' ) ) as {
4875+ accepted : Array < { testId : string ; runId : string ; status : string } > ;
4876+ } ;
4877+ expect ( parsed . accepted ) . toHaveLength ( 2 ) ;
4878+ expect ( parsed . accepted . map ( r => r . runId ) . sort ( ) ) . toEqual ( [ 'run_b1' , 'run_b2' ] ) ;
4879+ expect ( parsed . accepted . every ( r => r . status === 'timeout' ) ) . toBe ( true ) ;
4880+ } ) ;
4881+ } ) ;
48884882
48894883// ---------------------------------------------------------------------------
48904884// TimeoutError on single FE rerun --wait: partial stdout + exit 7
48914885// ---------------------------------------------------------------------------
48924886describe ( '[finding-4] single FE rerun --wait: TimeoutError writes partial JSON to stdout' , ( ) => {
4893- it (
4894- 'exit 7 AND stdout contains {runId, status:"running"} when --timeout polling deadline is exceeded' ,
4895- async ( ) => {
4896- const creds = makeCreds ( ) ;
4897- const rerunResp = makeFeRerunResp ( ) ;
4898-
4899- let fetchCallCount = 0 ;
4900- const fetchImpl : typeof globalThis . fetch = async ( input , _init ) => {
4901- const url =
4902- typeof input === 'string'
4903- ? input
4904- : input instanceof URL
4887+ it ( 'exit 7 AND stdout contains {runId, status:"running"} when --timeout polling deadline is exceeded' , async ( ) => {
4888+ const creds = makeCreds ( ) ;
4889+ const rerunResp = makeFeRerunResp ( ) ;
4890+
4891+ let fetchCallCount = 0 ;
4892+ const fetchImpl : typeof globalThis . fetch = async ( input , _init ) => {
4893+ const url =
4894+ typeof input === 'string'
4895+ ? input
4896+ : input instanceof URL
49054897 ? input . toString ( )
49064898 : ( input as { url : string } ) . url ;
4907- fetchCallCount ++ ;
4908- if ( url . includes ( '/tests/test_fe_01/runs/rerun' ) ) {
4909- return new Response ( JSON . stringify ( rerunResp ) , {
4910- status : 202 ,
4911- headers : { 'content-type' : 'application/json' } ,
4912- } ) ;
4913- }
4914- if ( url . includes ( '/runs/' ) ) {
4915- const runningRun : RunResponse = {
4916- ...makeTerminalRun ( rerunResp . runId , 'passed' ) ,
4917- status : 'running' ,
4918- finishedAt : null ,
4919- } ;
4920- return new Response ( JSON . stringify ( runningRun ) , {
4921- status : 200 ,
4922- headers : { 'content-type' : 'application/json' } ,
4923- } ) ;
4924- }
4925- return new Response ( JSON . stringify ( { error : { code : 'NOT_FOUND' } } ) , { status : 404 } ) ;
4926- } ;
4899+ fetchCallCount ++ ;
4900+ if ( url . includes ( '/tests/test_fe_01/runs/rerun' ) ) {
4901+ return new Response ( JSON . stringify ( rerunResp ) , {
4902+ status : 202 ,
4903+ headers : { 'content-type' : 'application/json' } ,
4904+ } ) ;
4905+ }
4906+ if ( url . includes ( '/runs/' ) ) {
4907+ const runningRun : RunResponse = {
4908+ ...makeTerminalRun ( rerunResp . runId , 'passed' ) ,
4909+ status : 'running' ,
4910+ finishedAt : null ,
4911+ } ;
4912+ return new Response ( JSON . stringify ( runningRun ) , {
4913+ status : 200 ,
4914+ headers : { 'content-type' : 'application/json' } ,
4915+ } ) ;
4916+ }
4917+ return new Response ( JSON . stringify ( { error : { code : 'NOT_FOUND' } } ) , { status : 404 } ) ;
4918+ } ;
49274919
4928- const stdoutLines : string [ ] = [ ] ;
4920+ const stdoutLines : string [ ] = [ ] ;
49294921
4930- const err = await runTestRerun (
4931- {
4932- testIds : [ 'test_fe_01' ] ,
4933- all : false ,
4934- wait : true ,
4935- timeoutSeconds : 0 ,
4936- autoHeal : false ,
4937- autoHealExplicit : false ,
4938- skipDependencies : false ,
4939- maxConcurrency : 10 ,
4940- output : 'json' ,
4941- profile : 'default' ,
4942- dryRun : false ,
4943- debug : false ,
4944- verbose : false ,
4945- } ,
4946- {
4947- ...creds ,
4948- sleep : instantSleep ,
4949- fetchImpl : fetchImpl as unknown as FetchImpl ,
4950- stdout : ( line ) => stdoutLines . push ( line ) ,
4951- stderr : ( ) => undefined ,
4952- } ,
4953- ) . catch ( ( e ) => e ) ;
4922+ const err = await runTestRerun (
4923+ {
4924+ testIds : [ 'test_fe_01' ] ,
4925+ all : false ,
4926+ wait : true ,
4927+ timeoutSeconds : 0 ,
4928+ autoHeal : false ,
4929+ autoHealExplicit : false ,
4930+ skipDependencies : false ,
4931+ maxConcurrency : 10 ,
4932+ output : 'json' ,
4933+ profile : 'default' ,
4934+ dryRun : false ,
4935+ debug : false ,
4936+ verbose : false ,
4937+ } ,
4938+ {
4939+ ...creds ,
4940+ sleep : instantSleep ,
4941+ fetchImpl : fetchImpl as unknown as FetchImpl ,
4942+ stdout : line => stdoutLines . push ( line ) ,
4943+ stderr : ( ) => undefined ,
4944+ } ,
4945+ ) . catch ( e => e ) ;
49544946
4955- expect ( err ) . toMatchObject ( { exitCode : 7 } ) ;
4956- expect ( stdoutLines . length ) . toBeGreaterThan ( 0 ) ;
4957- const parsed = JSON . parse ( stdoutLines . join ( '\n' ) ) as { runId : string ; status : string } ;
4958- expect ( parsed . runId ) . toBe ( rerunResp . runId ) ;
4959- expect ( parsed . status ) . toBe ( 'running' ) ;
4947+ expect ( err ) . toMatchObject ( { exitCode : 7 } ) ;
4948+ expect ( stdoutLines . length ) . toBeGreaterThan ( 0 ) ;
4949+ const parsed = JSON . parse ( stdoutLines . join ( '\n' ) ) as { runId : string ; status : string } ;
4950+ expect ( parsed . runId ) . toBe ( rerunResp . runId ) ;
4951+ expect ( parsed . status ) . toBe ( 'running' ) ;
49604952
4961- void fetchCallCount ;
4962- } ,
4963- ) ;
4964- } ) ;
4953+ void fetchCallCount ;
4954+ } ) ;
4955+ } ) ;
0 commit comments