@@ -25,11 +25,13 @@ import { debugLogger, isUnderTest } from '../utils';
2525import  {  serverSideCallMetadata  }  from  '../server' ; 
2626import  {  SocksProxy  }  from  '../server/utils/socksProxy' ; 
2727import  {  Browser  }  from  '../server/browser' ; 
28+ import  {  ProgressController  }  from  '../server/progress' ; 
2829
2930import  type  {  AndroidDevice  }  from  '../server/android/android' ; 
3031import  type  {  Playwright  }  from  '../server/playwright' ; 
31- import  type    {  LaunchOptions  }  from  '../server/types' ; 
32+ import  type  {  LaunchOptions   as   LaunchOptionsWithoutTimeout  }  from  '../server/types' ; 
3233
34+ type  LaunchOptionsWithTimeout  =  LaunchOptionsWithoutTimeout  &  {  timeout : number  } ; 
3335
3436type  ServerOptions  =  { 
3537  path : string ; 
@@ -93,9 +95,11 @@ export class PlaywrightServer {
9395        const  launchOptionsHeader  =  request . headers [ 'x-playwright-launch-options' ]  ||  '' ; 
9496        const  launchOptionsHeaderValue  =  Array . isArray ( launchOptionsHeader )  ? launchOptionsHeader [ 0 ]  : launchOptionsHeader ; 
9597        const  launchOptionsParam  =  url . searchParams . get ( 'launch-options' ) ; 
96-         let  launchOptions : LaunchOptions  =  {  timeout : DEFAULT_PLAYWRIGHT_LAUNCH_TIMEOUT  } ; 
98+         let  launchOptions : LaunchOptionsWithTimeout  =  {  timeout : DEFAULT_PLAYWRIGHT_LAUNCH_TIMEOUT  } ; 
9799        try  { 
98100          launchOptions  =  JSON . parse ( launchOptionsParam  ||  launchOptionsHeaderValue ) ; 
101+           if  ( ! launchOptions . timeout ) 
102+             launchOptions . timeout  =  DEFAULT_PLAYWRIGHT_LAUNCH_TIMEOUT ; 
99103        }  catch  ( e )  { 
100104        } 
101105
@@ -172,7 +176,7 @@ export class PlaywrightServer {
172176    } ) ; 
173177  } 
174178
175-   private  async  _initReuseBrowsersMode ( browserName : string  |  null ,  launchOptions : LaunchOptions ,  id : string ) : Promise < PlaywrightInitializeResult >  { 
179+   private  async  _initReuseBrowsersMode ( browserName : string  |  null ,  launchOptions : LaunchOptionsWithTimeout ,  id : string ) : Promise < PlaywrightInitializeResult >  { 
176180    // Note: reuse browser mode does not support socks proxy, because 
177181    // clients come and go, while the browser stays the same. 
178182
@@ -184,7 +188,7 @@ export class PlaywrightServer {
184188        return  false ; 
185189      if  ( this . _dontReuseBrowsers . has ( b ) ) 
186190        return  false ; 
187-       const  existingOptions  =  launchOptionsHash ( b . options . originalLaunchOptions ) ; 
191+       const  existingOptions  =  launchOptionsHash ( {  ... b . options . originalLaunchOptions ,   timeout :  DEFAULT_PLAYWRIGHT_LAUNCH_TIMEOUT   } ) ; 
188192      return  existingOptions  ===  requestedOptions ; 
189193    } ) ; 
190194
@@ -199,10 +203,12 @@ export class PlaywrightServer {
199203    } 
200204
201205    if  ( ! browser )  { 
202-       browser  =  await  this . _playwright [ ( browserName  ||  'chromium' )  as  'chromium' ] . launch ( serverSideCallMetadata ( ) ,  { 
206+       const  browserType  =  this . _playwright [ ( browserName  ||  'chromium' )  as  'chromium' ] ; 
207+       const  controller  =  new  ProgressController ( serverSideCallMetadata ( ) ,  browserType ) ; 
208+       browser  =  await  controller . run ( progress  =>  browserType . launch ( progress ,  { 
203209        ...launchOptions , 
204210        headless : ! ! process . env . PW_DEBUG_CONTROLLER_HEADLESS , 
205-       } ) ; 
211+       } ) ,   launchOptions . timeout ) ; 
206212    } 
207213
208214    return  { 
@@ -222,14 +228,16 @@ export class PlaywrightServer {
222228    } ; 
223229  } 
224230
225-   private  async  _initConnectMode ( id : string ,  filter : 'first' ,  browserName : string  |  null ,  launchOptions : LaunchOptions ) : Promise < PlaywrightInitializeResult >  { 
231+   private  async  _initConnectMode ( id : string ,  filter : 'first' ,  browserName : string  |  null ,  launchOptions : LaunchOptionsWithTimeout ) : Promise < PlaywrightInitializeResult >  { 
226232    browserName  ??=  'chromium' ; 
227233
228234    debugLogger . log ( 'server' ,  `[${ id }  ) ; 
229235
230236    let  browser  =  this . _playwright . allBrowsers ( ) . find ( b  =>  b . options . name  ===  browserName ) ; 
231237    if  ( ! browser )  { 
232-       browser  =  await  this . _playwright [ browserName  as  'chromium' ] . launch ( serverSideCallMetadata ( ) ,  launchOptions ) ; 
238+       const  browserType  =  this . _playwright [ browserName  as  'chromium' ] ; 
239+       const  controller  =  new  ProgressController ( serverSideCallMetadata ( ) ,  browserType ) ; 
240+       browser  =  await  controller . run ( progress  =>  browserType . launch ( progress ,  launchOptions ) ,  launchOptions . timeout ) ; 
233241      this . _dontReuse ( browser ) ; 
234242    } 
235243
@@ -268,7 +276,7 @@ export class PlaywrightServer {
268276    } ; 
269277  } 
270278
271-   private  async  _initLaunchBrowserMode ( browserName : string  |  null ,  proxyValue : string  |  undefined ,  launchOptions : LaunchOptions ,  id : string ) : Promise < PlaywrightInitializeResult >  { 
279+   private  async  _initLaunchBrowserMode ( browserName : string  |  null ,  proxyValue : string  |  undefined ,  launchOptions : LaunchOptionsWithTimeout ,  id : string ) : Promise < PlaywrightInitializeResult >  { 
272280    debugLogger . log ( 'server' ,  `[${ id } ${ browserName }  ) ; 
273281    let  socksProxy : SocksProxy  |  undefined ; 
274282    if  ( proxyValue )  { 
@@ -279,7 +287,9 @@ export class PlaywrightServer {
279287    }  else  { 
280288      launchOptions . socksProxyPort  =  undefined ; 
281289    } 
282-     const  browser  =  await  this . _playwright [ browserName  as  'chromium' ] . launch ( serverSideCallMetadata ( ) ,  launchOptions ) ; 
290+     const  browserType  =  this . _playwright [ browserName  as  'chromium' ] ; 
291+     const  controller  =  new  ProgressController ( serverSideCallMetadata ( ) ,  browserType ) ; 
292+     const  browser  =  await  controller . run ( progress  =>  browserType . launch ( progress ,  launchOptions ) ,  launchOptions . timeout ) ; 
283293    this . _dontReuseBrowsers . add ( browser ) ; 
284294    return  { 
285295      preLaunchedBrowser : browser , 
@@ -334,10 +344,10 @@ function userAgentVersionMatchesErrorMessage(userAgent: string) {
334344  } 
335345} 
336346
337- function  launchOptionsHash ( options : LaunchOptions )  { 
347+ function  launchOptionsHash ( options : LaunchOptionsWithTimeout )  { 
338348  const  copy  =  {  ...options  } ; 
339349  for  ( const  k  of  Object . keys ( copy ) )  { 
340-     const  key  =  k  as  keyof  LaunchOptions ; 
350+     const  key  =  k  as  keyof  LaunchOptionsWithTimeout ; 
341351    if  ( copy [ key ]  ===  defaultLaunchOptions [ key ] ) 
342352      delete  copy [ key ] ; 
343353  } 
@@ -346,7 +356,7 @@ function launchOptionsHash(options: LaunchOptions) {
346356  return  JSON . stringify ( copy ) ; 
347357} 
348358
349- function  filterLaunchOptions ( options : LaunchOptions ,  allowFSPaths : boolean ) : LaunchOptions  { 
359+ function  filterLaunchOptions ( options : LaunchOptionsWithTimeout ,  allowFSPaths : boolean ) : LaunchOptionsWithTimeout  { 
350360  return  { 
351361    channel : options . channel , 
352362    args : options . args , 
@@ -363,7 +373,7 @@ function filterLaunchOptions(options: LaunchOptions, allowFSPaths: boolean): Lau
363373  } ; 
364374} 
365375
366- const  defaultLaunchOptions : Partial < LaunchOptions >  =  { 
376+ const  defaultLaunchOptions : Partial < LaunchOptionsWithTimeout >  =  { 
367377  ignoreAllDefaultArgs : false , 
368378  handleSIGINT : false , 
369379  handleSIGTERM : false , 
@@ -372,7 +382,7 @@ const defaultLaunchOptions: Partial<LaunchOptions> = {
372382  devtools : false , 
373383} ; 
374384
375- const  optionsThatAllowBrowserReuse : ( keyof  LaunchOptions ) [ ]  =  [ 
385+ const  optionsThatAllowBrowserReuse : ( keyof  LaunchOptionsWithTimeout ) [ ]  =  [ 
376386  'headless' , 
377387  'timeout' , 
378388  'tracesDir' , 
0 commit comments