@@ -64,6 +64,7 @@ export class ProtocolService {
64
64
private parallelConnection ?: ProtocolClient . InspectorBackend . Connection ;
65
65
private lighthouseWorkerPromise ?: Promise < Worker > ;
66
66
private lighthouseMessageUpdateCallback ?: ( ( arg0 : string ) => void ) ;
67
+ private removeDialogHandler ?: ( ) => void ;
67
68
private configForTesting ?: Object ;
68
69
69
70
async attach ( ) : Promise < void > {
@@ -92,6 +93,23 @@ export class ProtocolService {
92
93
this . dispatchProtocolMessage ( message ) ;
93
94
} ) ;
94
95
96
+ // Lighthouse implements its own dialog handler like this, however its lifecycle ends when
97
+ // the internal Lighthouse session is disposed.
98
+ //
99
+ // If the page is reloaded near the end of the run (e.g. bfcache testing), the Lighthouse
100
+ // internal session can be disposed before a dialog message appears. This allows the dialog
101
+ // to block important Lighthouse teardown operations in LighthouseProtocolService.
102
+ //
103
+ // To ensure the teardown operations can proceed, we need a dialog handler which lasts until
104
+ // the LighthouseProtocolService detaches.
105
+ const dialogHandler = ( ) : void => {
106
+ void mainTarget . pageAgent ( ) . invoke_handleJavaScriptDialog ( { accept : true } ) ;
107
+ } ;
108
+
109
+ resourceTreeModel . addEventListener ( SDK . ResourceTreeModel . Events . JavaScriptDialogOpening , dialogHandler ) ;
110
+ this . removeDialogHandler = ( ) : void =>
111
+ resourceTreeModel . removeEventListener ( SDK . ResourceTreeModel . Events . JavaScriptDialogOpening , dialogHandler ) ;
112
+
95
113
this . parallelConnection = connection ;
96
114
this . targetInfos = childTargetManager . targetInfos ( ) ;
97
115
this . mainFrameId = mainFrame . id ;
@@ -163,6 +181,7 @@ export class ProtocolService {
163
181
await oldParallelConnection . disconnect ( ) ;
164
182
}
165
183
await SDK . TargetManager . TargetManager . instance ( ) . resumeAllTargets ( ) ;
184
+ this . removeDialogHandler ?.( ) ;
166
185
}
167
186
168
187
registerStatusCallback ( callback : ( arg0 : string ) => void ) : void {
0 commit comments