@@ -43,10 +43,24 @@ function makeTargetFilter(enableExtensions = false) {
4343 } ;
4444}
4545
46+ function toPuppeteerChannel ( channel : Channel ) : ChromeReleaseChannel {
47+ switch ( channel ) {
48+ case 'canary' :
49+ return 'chrome-canary' ;
50+ case 'dev' :
51+ return 'chrome-dev' ;
52+ case 'beta' :
53+ return 'chrome-beta' ;
54+ case 'stable' :
55+ return 'chrome' ;
56+ }
57+ }
58+
4659export async function ensureBrowserConnected ( options : {
4760 browserURL ?: string ;
4861 wsEndpoint ?: string ;
4962 wsHeaders ?: Record < string , string > ;
63+ autoConnect ?: boolean ;
5064 devtools : boolean ;
5165 channel ?: Channel ;
5266 userDataDir ?: string ;
@@ -57,24 +71,62 @@ export async function ensureBrowserConnected(options: {
5771 return browser ;
5872 }
5973
60- const connectOptions : Parameters < typeof puppeteer . connect > [ 0 ] = {
61- targetFilter : makeTargetFilter ( enableExtensions ) ,
62- defaultViewport : null ,
63- handleDevToolsAsPage : true ,
74+ const createConnectOptions = ( ) : Parameters < typeof puppeteer . connect > [ 0 ] => {
75+ return {
76+ targetFilter : makeTargetFilter ( enableExtensions ) ,
77+ defaultViewport : null ,
78+ handleDevToolsAsPage : true ,
79+ } ;
80+ } ;
81+
82+ const connect = async (
83+ connectOptions : Parameters < typeof puppeteer . connect > [ 0 ] ,
84+ ) : Promise < Browser > => {
85+ logger ( 'Connecting Puppeteer to ' , JSON . stringify ( connectOptions ) ) ;
86+ const connectedBrowser = await puppeteer . connect ( connectOptions ) ;
87+ logger ( 'Connected Puppeteer' ) ;
88+ return connectedBrowser ;
6489 } ;
6590
66- let autoConnect = false ;
67- if ( options . wsEndpoint ) {
68- connectOptions . browserWSEndpoint = options . wsEndpoint ;
69- if ( options . wsHeaders ) {
70- connectOptions . headers = options . wsHeaders ;
91+ const connectionError = ( autoConnect : boolean , cause : unknown ) : Error => {
92+ return new Error (
93+ `Could not connect to Chrome. ${ autoConnect ? `Check if Chrome is running and remote debugging is enabled by going to chrome://inspect/#remote-debugging.` : `Check if Chrome is running.` } ` ,
94+ {
95+ cause,
96+ } ,
97+ ) ;
98+ } ;
99+
100+ if ( options . wsEndpoint || options . browserURL ) {
101+ const connectOptions = createConnectOptions ( ) ;
102+ if ( options . wsEndpoint ) {
103+ connectOptions . browserWSEndpoint = options . wsEndpoint ;
104+ if ( options . wsHeaders ) {
105+ connectOptions . headers = options . wsHeaders ;
106+ }
107+ } else {
108+ connectOptions . browserURL = options . browserURL ;
71109 }
72- } else if ( options . browserURL ) {
73- connectOptions . browserURL = options . browserURL ;
74- } else if ( channel || options . userDataDir ) {
110+ try {
111+ browser = await connect ( connectOptions ) ;
112+ return browser ;
113+ } catch ( error ) {
114+ if ( ! options . autoConnect ) {
115+ throw connectionError ( false , error ) ;
116+ }
117+ logger (
118+ 'Direct browser connection failed; falling back to auto-connect' ,
119+ error ,
120+ ) ;
121+ }
122+ }
123+
124+ const connectOptions = createConnectOptions ( ) ;
125+ let autoConnect = false ;
126+ if ( channel || options . userDataDir || options . autoConnect ) {
75127 const userDataDir = options . userDataDir ;
128+ autoConnect = true ;
76129 if ( userDataDir ) {
77- autoConnect = true ;
78130 // TODO: re-expose this logic via Puppeteer.
79131 const portPath = path . join ( userDataDir , 'DevToolsActivePort' ) ;
80132 try {
@@ -105,31 +157,19 @@ export async function ensureBrowserConnected(options: {
105157 ) ;
106158 }
107159 } else {
108- if ( ! channel ) {
109- throw new Error ( 'Channel must be provided if userDataDir is missing' ) ;
110- }
111- connectOptions . channel = (
112- channel === 'stable' ? 'chrome' : `chrome-${ channel } `
113- ) as ChromeReleaseChannel ;
160+ connectOptions . channel = toPuppeteerChannel ( channel ?? 'stable' ) ;
114161 }
115162 } else {
116163 throw new Error (
117164 'Either browserURL, wsEndpoint, channel or userDataDir must be provided' ,
118165 ) ;
119166 }
120167
121- logger ( 'Connecting Puppeteer to ' , JSON . stringify ( connectOptions ) ) ;
122168 try {
123- browser = await puppeteer . connect ( connectOptions ) ;
169+ browser = await connect ( connectOptions ) ;
124170 } catch ( err ) {
125- throw new Error (
126- `Could not connect to Chrome. ${ autoConnect ? `Check if Chrome is running and remote debugging is enabled by going to chrome://inspect/#remote-debugging.` : `Check if Chrome is running.` } ` ,
127- {
128- cause : err ,
129- } ,
130- ) ;
171+ throw connectionError ( autoConnect , err ) ;
131172 }
132- logger ( 'Connected Puppeteer' ) ;
133173 return browser ;
134174}
135175
0 commit comments