@@ -19,7 +19,7 @@ import os from 'os';
19
19
import path from 'path' ;
20
20
import * as readline from 'readline' ;
21
21
22
- import { ManualPromise , removeFolders } from '../../utils' ;
22
+ import { ManualPromise } from '../../utils' ;
23
23
import { wrapInASCIIBox } from '../utils/ascii' ;
24
24
import { RecentLogsCollector } from '../utils/debugLogger' ;
25
25
import { eventsHelper } from '../utils/eventsHelper' ;
@@ -166,8 +166,6 @@ export class Electron extends SdkObject {
166
166
}
167
167
168
168
const artifactsDir = await progress . race ( fs . promises . mkdtemp ( ARTIFACTS_FOLDER ) ) ;
169
- progress . cleanupWhenAborted ( ( ) => removeFolders ( [ artifactsDir ] ) ) ;
170
-
171
169
const browserLogsCollector = new RecentLogsCollector ( ) ;
172
170
const env = options . env ? envArrayToObject ( options . env ) : process . env ;
173
171
@@ -243,76 +241,76 @@ export class Electron extends SdkObject {
243
241
const chromeMatchPromise = waitForLine ( progress , launchedProcess , / ^ D e v T o o l s l i s t e n i n g o n ( w s : \/ \/ .* ) $ / ) ;
244
242
const debuggerDisconnectPromise = waitForLine ( progress , launchedProcess , / W a i t i n g f o r t h e d e b u g g e r t o d i s c o n n e c t \. \. \. / ) ;
245
243
246
- const nodeMatch = await nodeMatchPromise ;
247
- const nodeTransport = await WebSocketTransport . connect ( progress , nodeMatch [ 1 ] ) ;
248
- progress . cleanupWhenAborted ( ( ) => nodeTransport . close ( ) ) ;
249
- const nodeConnection = new CRConnection ( this , nodeTransport , helper . debugProtocolLogger ( ) , browserLogsCollector ) ;
244
+ try {
245
+ const nodeMatch = await nodeMatchPromise ;
246
+ const nodeTransport = await WebSocketTransport . connect ( progress , nodeMatch [ 1 ] ) ;
247
+ const nodeConnection = new CRConnection ( this , nodeTransport , helper . debugProtocolLogger ( ) , browserLogsCollector ) ;
248
+ // Immediately release exiting process under debug.
249
+ debuggerDisconnectPromise . then ( ( ) => {
250
+ nodeTransport . close ( ) ;
251
+ } ) . catch ( ( ) => { } ) ;
250
252
251
- // Immediately release exiting process under debug.
252
- debuggerDisconnectPromise . then ( ( ) => {
253
- nodeTransport . close ( ) ;
254
- } ) . catch ( ( ) => { } ) ;
255
- const chromeMatch = await Promise . race ( [
256
- chromeMatchPromise ,
257
- waitForXserverError ,
258
- ] ) as RegExpMatchArray ;
259
- const chromeTransport = await WebSocketTransport . connect ( progress , chromeMatch [ 1 ] ) ;
260
- progress . cleanupWhenAborted ( ( ) => chromeTransport . close ( ) ) ;
261
- const browserProcess : BrowserProcess = {
262
- onclose : undefined ,
263
- process : launchedProcess ,
264
- close : gracefullyClose ,
265
- kill
266
- } ;
267
- const contextOptions : types . BrowserContextOptions = {
268
- ...options ,
269
- noDefaultViewport : true ,
270
- } ;
271
- const browserOptions : BrowserOptions = {
272
- name : 'electron' ,
273
- isChromium : true ,
274
- headful : true ,
275
- persistent : contextOptions ,
276
- browserProcess,
277
- protocolLogger : helper . debugProtocolLogger ( ) ,
278
- browserLogsCollector,
279
- artifactsDir,
280
- downloadsPath : artifactsDir ,
281
- tracesDir : options . tracesDir || artifactsDir ,
282
- originalLaunchOptions : { } ,
283
- } ;
284
- validateBrowserContextOptions ( contextOptions , browserOptions ) ;
285
- const browser = await progress . race ( CRBrowser . connect ( this . attribution . playwright , chromeTransport , browserOptions ) ) ;
286
- app = new ElectronApplication ( this , browser , nodeConnection , launchedProcess ) ;
287
- await progress . race ( app . initialize ( ) ) ;
288
- return app ;
253
+ const chromeMatch = await Promise . race ( [
254
+ chromeMatchPromise ,
255
+ waitForXserverError ,
256
+ ] ) ;
257
+ const chromeTransport = await WebSocketTransport . connect ( progress , chromeMatch [ 1 ] ) ;
258
+ const browserProcess : BrowserProcess = {
259
+ onclose : undefined ,
260
+ process : launchedProcess ,
261
+ close : gracefullyClose ,
262
+ kill
263
+ } ;
264
+ const contextOptions : types . BrowserContextOptions = {
265
+ ...options ,
266
+ noDefaultViewport : true ,
267
+ } ;
268
+ const browserOptions : BrowserOptions = {
269
+ name : 'electron' ,
270
+ isChromium : true ,
271
+ headful : true ,
272
+ persistent : contextOptions ,
273
+ browserProcess,
274
+ protocolLogger : helper . debugProtocolLogger ( ) ,
275
+ browserLogsCollector,
276
+ artifactsDir,
277
+ downloadsPath : artifactsDir ,
278
+ tracesDir : options . tracesDir || artifactsDir ,
279
+ originalLaunchOptions : { } ,
280
+ } ;
281
+ validateBrowserContextOptions ( contextOptions , browserOptions ) ;
282
+ const browser = await progress . race ( CRBrowser . connect ( this . attribution . playwright , chromeTransport , browserOptions ) ) ;
283
+ app = new ElectronApplication ( this , browser , nodeConnection , launchedProcess ) ;
284
+ await progress . race ( app . initialize ( ) ) ;
285
+ return app ;
286
+ } catch ( error ) {
287
+ await kill ( ) ;
288
+ throw error ;
289
+ }
289
290
}
290
291
}
291
292
292
- function waitForLine ( progress : Progress , process : childProcess . ChildProcess , regex : RegExp ) : Promise < RegExpMatchArray > {
293
- return progress . race ( new Promise ( ( resolve , reject ) => {
294
- const rl = readline . createInterface ( { input : process . stderr ! } ) ;
295
- const failError = new Error ( 'Process failed to launch!' ) ;
296
- const listeners = [
297
- eventsHelper . addEventListener ( rl , 'line' , onLine ) ,
298
- eventsHelper . addEventListener ( rl , 'close' , reject . bind ( null , failError ) ) ,
299
- eventsHelper . addEventListener ( process , 'exit' , reject . bind ( null , failError ) ) ,
300
- // It is Ok to remove error handler because we did not create process and there is another listener.
301
- eventsHelper . addEventListener ( process , 'error' , reject . bind ( null , failError ) )
302
- ] ;
293
+ async function waitForLine ( progress : Progress , process : childProcess . ChildProcess , regex : RegExp ) {
294
+ const promise = new ManualPromise < RegExpMatchArray > ( ) ;
295
+ const rl = readline . createInterface ( { input : process . stderr ! } ) ;
296
+ const failError = new Error ( 'Process failed to launch!' ) ;
297
+ const listeners = [
298
+ eventsHelper . addEventListener ( rl , 'line' , onLine ) ,
299
+ eventsHelper . addEventListener ( rl , 'close' , ( ) => promise . reject ( failError ) ) ,
300
+ eventsHelper . addEventListener ( process , 'exit' , ( ) => promise . reject ( failError ) ) ,
301
+ // It is Ok to remove error handler because we did not create process and there is another listener.
302
+ eventsHelper . addEventListener ( process , 'error' , ( ) => promise . reject ( failError ) ) ,
303
+ ] ;
303
304
304
- progress . cleanupWhenAborted ( cleanup ) ;
305
-
306
- function onLine ( line : string ) {
307
- const match = line . match ( regex ) ;
308
- if ( ! match )
309
- return ;
310
- cleanup ( ) ;
311
- resolve ( match ) ;
312
- }
305
+ function onLine ( line : string ) {
306
+ const match = line . match ( regex ) ;
307
+ if ( match )
308
+ promise . resolve ( match ) ;
309
+ }
313
310
314
- function cleanup ( ) {
315
- eventsHelper . removeEventListeners ( listeners ) ;
316
- }
317
- } ) ) ;
311
+ try {
312
+ return await progress . race ( promise ) ;
313
+ } finally {
314
+ eventsHelper . removeEventListeners ( listeners ) ;
315
+ }
318
316
}
0 commit comments