@@ -18,6 +18,7 @@ import { runFlaky } from './test.js';
1818
1919type FetchInput = Parameters < typeof globalThis . fetch > [ 0 ] ;
2020type RunStatus = 'passed' | 'failed' | 'blocked' | 'cancelled' ;
21+ type TriggerAuthErrorCode = 'AUTH_REQUIRED' | 'AUTH_INVALID' | 'AUTH_FORBIDDEN' ;
2122
2223function urlOf ( input : FetchInput ) : string {
2324 return typeof input === 'string'
@@ -46,6 +47,7 @@ function makeFlakyFetch(opts: {
4647 statuses : RunStatus [ ] ;
4748 testType ?: 'frontend' | 'backend' ;
4849 notFoundOnTrigger ?: boolean ;
50+ triggerAuthError ?: TriggerAuthErrorCode ;
4951} ) : { fetchImpl : FetchImpl ; triggerCount : ( ) => number } {
5052 let triggers = 0 ;
5153 const testType = opts . testType ?? 'frontend' ;
@@ -67,6 +69,17 @@ function makeFlakyFetch(opts: {
6769 }
6870
6971 if ( method === 'POST' && url . includes ( '/runs/rerun' ) ) {
72+ if ( opts . triggerAuthError ) {
73+ return jsonResponse ( opts . triggerAuthError === 'AUTH_FORBIDDEN' ? 403 : 401 , {
74+ error : {
75+ code : opts . triggerAuthError ,
76+ message : 'auth failed' ,
77+ nextAction : 'run setup' ,
78+ requestId : 'req_auth' ,
79+ details : { } ,
80+ } ,
81+ } ) ;
82+ }
7083 if ( opts . notFoundOnTrigger ) {
7184 return jsonResponse ( 404 , {
7285 error : {
@@ -345,6 +358,35 @@ describe('runFlaky', () => {
345358 expect ( ( err as ApiError ) . code ) . toBe ( 'NOT_FOUND' ) ;
346359 } ) ;
347360
361+ it . each ( [ 'AUTH_REQUIRED' , 'AUTH_INVALID' , 'AUTH_FORBIDDEN' ] as const ) (
362+ 'propagates %s during trigger instead of scoring an error attempt' ,
363+ async code => {
364+ const { fetchImpl, triggerCount } = makeFlakyFetch ( {
365+ statuses : [ ] ,
366+ triggerAuthError : code ,
367+ } ) ;
368+ const { deps, stdout } = makeDeps ( fetchImpl ) ;
369+ const err = await runFlaky (
370+ {
371+ profile : 'default' ,
372+ output : 'json' ,
373+ dryRun : false ,
374+ debug : false ,
375+ verbose : false ,
376+ testId : 'test_x' ,
377+ runs : 3 ,
378+ untilFail : false ,
379+ timeoutSeconds : 600 ,
380+ } ,
381+ deps ,
382+ ) . catch ( ( e : unknown ) => e ) ;
383+ expect ( err ) . toBeInstanceOf ( ApiError ) ;
384+ expect ( err ) . toMatchObject ( { code, exitCode : 3 } ) ;
385+ expect ( stdout ) . toEqual ( [ ] ) ;
386+ expect ( triggerCount ( ) ) . toBe ( 0 ) ;
387+ } ,
388+ ) ;
389+
348390 it ( 'rejects --runs below the range (0) with a validation error (exit 5)' , async ( ) => {
349391 const { fetchImpl } = makeFlakyFetch ( { statuses : [ ] } ) ;
350392 const { deps } = makeDeps ( fetchImpl ) ;
0 commit comments