@@ -269,7 +269,7 @@ export class FrameManager {
269269 name : frame . _name ,
270270 newDocument : frame . pendingDocument ( ) ,
271271 error : new NavigationAbortedError ( documentId , errorText ) ,
272- isPublic : ! frame . _pendingNavigationRedirectAfterAbort
272+ isPublic : ! ( documentId && frame . _redirectedNavigations . has ( documentId ) ) ,
273273 } ;
274274 frame . setPendingDocument ( undefined ) ;
275275 frame . emit ( Frame . Events . InternalNavigation , navigationEvent ) ;
@@ -467,7 +467,7 @@ export class Frame extends SdkObject {
467467 readonly _detachedPromise : Promise < void > ;
468468 private _detachedCallback = ( ) => { } ;
469469 private _raceAgainstEvaluationStallingEventsPromises = new Set < ManualPromise < any > > ( ) ;
470- _pendingNavigationRedirectAfterAbort : { url : string , documentId : string } | undefined ;
470+ readonly _redirectedNavigations = new Map < string , { url : string , gotoPromise : Promise < network . Response | null > } > ( ) ; // documentId -> data
471471
472472 constructor ( page : Page , id : string , parentFrame : Frame | null ) {
473473 super ( page , 'frame' ) ;
@@ -604,21 +604,26 @@ export class Frame extends SdkObject {
604604 this . _page . _crashedPromise . then ( ( ) => { throw new Error ( 'Navigation failed because page crashed!' ) ; } ) ,
605605 this . _detachedPromise . then ( ( ) => { throw new Error ( 'Navigating frame was detached!' ) ; } ) ,
606606 action ( ) . catch ( e => {
607- if ( this . _pendingNavigationRedirectAfterAbort && e instanceof NavigationAbortedError ) {
608- const { url, documentId } = this . _pendingNavigationRedirectAfterAbort ;
609- this . _pendingNavigationRedirectAfterAbort = undefined ;
610- if ( e . documentId === documentId ) {
611- progress . log ( `redirecting navigation to "${ url } "` ) ;
612- return this . _gotoAction ( progress , url , options ) ;
607+ if ( e instanceof NavigationAbortedError && e . documentId ) {
608+ const data = this . _redirectedNavigations . get ( e . documentId ) ;
609+ if ( data ) {
610+ progress . log ( `waiting for redirected navigation to "${ data . url } "` ) ;
611+ return data . gotoPromise ;
613612 }
614613 }
615614 throw e ;
616615 } ) ,
617616 ] ) ;
618617 }
619618
620- redirectNavigationAfterAbort ( url : string , documentId : string ) {
621- this . _pendingNavigationRedirectAfterAbort = { url, documentId } ;
619+ redirectNavigation ( url : string , documentId : string , referer : string | undefined ) {
620+ const controller = new ProgressController ( serverSideCallMetadata ( ) , this ) ;
621+ const data = {
622+ url,
623+ gotoPromise : controller . run ( progress => this . _gotoAction ( progress , url , { referer } ) , 0 ) ,
624+ } ;
625+ this . _redirectedNavigations . set ( documentId , data ) ;
626+ data . gotoPromise . finally ( ( ) => this . _redirectedNavigations . delete ( documentId ) ) ;
622627 }
623628
624629 async goto ( metadata : CallMetadata , url : string , options : types . GotoOptions = { } ) : Promise < network . Response | null > {
@@ -659,7 +664,7 @@ export class Frame extends SdkObject {
659664 if ( event . newDocument ! . documentId !== navigateResult . newDocumentId ) {
660665 // This is just a sanity check. In practice, new navigation should
661666 // cancel the previous one and report "request cancelled"-like error.
662- throw new Error ( 'Navigation interrupted by another one' ) ;
667+ throw new NavigationAbortedError ( navigateResult . newDocumentId , 'Navigation interrupted by another one' ) ;
663668 }
664669 if ( event . error )
665670 throw event . error ;
0 commit comments