import { Workbench } from './workbench' ; import { Code , launch , LaunchOptions } from './code' ; import { Logger } from './logger' ; export const enum Quality { Dev , Insiders , Stable } export interface ApplicationOptions extends LaunchOptions { quality : Quality ; workspacePath : string ; waitTime : number ; } export class Application { private static INSTANCES = 0 ; constructor ( private options ) { Application . INSTANCES ++ ; this . _userDataPath = options . userDataDir ; this . _workspacePathOrFolder = options . workspacePath ; } private _code : Code | undefined ; get code ( ) : Code { return this . _code ! ; } private _workbench : Workbench | undefined ; get workbench ( ) : Workbench { return this . _workbench ! ; } get quality ( ) : Quality { return this . options . quality ; } get logger ( ) : Logger { return this . options . logger ; } get remote ( ) : boolean { return ! ! this . options . remote ; } get web ( ) : boolean { return ! ! this . options . web ; } private _workspacePathOrFolder : string ; get workspacePathOrFolder ( ) : string { return this . _workspacePathOrFolder ; } get extensionsPath ( ) : string { return this . options . extensionsPath ; } private _userDataPath : string ; get userDataPath ( ) : string { return this . _userDataPath ; } async start ( ) { await this . _start ( ) ; await this . code . waitForElement ( '.explorer-folders-view' ) ; } async restart ( options ? ) { await this . stop ( ) ; await this . _start ( options ?. workspaceOrFolder , options ?. extraArgs ) ; } private async _start ( workspaceOrFolder = this . workspacePathOrFolder , extraArgs = [ ] ) { this . _workspacePathOrFolder = workspaceOrFolder ; const code = await this . startApplication ( extraArgs ) ; const windowReady = this . checkWindowReady ( code ) ; const timeoutHandle = setTimeout ( ( ) => this . takeScreenshot ( `checkWindowReady_instance_${ Application . INSTANCES }` ) , 20000 ) ; try { await windowReady ; } finally { clearTimeout ( timeoutHandle ) ; } } async stop ( ) { if ( this . _code ) { try { await this . _code . exit ( ) ; } finally { this . _code = undefined ; } } } async startTracing ( name ) { await this . _code ?. startTracing ( name ) ; } async stopTracing ( name , persist ) { await this . _code ?. stopTracing ( name , persist ) ; } private async takeScreenshot ( name ) { if ( this . web ) { return ; } return this . _code ?. stopTracing ( name , true ) ; } private async startApplication ( extraArgs = [ ] ) { const code = this . _code = await launch ( { ... this . options , extraArgs : [ ... ( this . options . extraArgs || [ ] ) , ... extraArgs ] , } ) ; this . _workbench = new Workbench ( this . _code , this . userDataPath ) ; return code ; } private async checkWindowReady ( code ) { this . logger . log ( 'checkWindowReady: begin' ) ; await code . waitForWindowIds ( ids => ids . length > 0 ) ; await code . waitForElement ( '.monaco-workbench' ) ; if ( this . remote || this . web ) { await code . waitForTextContent ( '.monaco-workbench .statusbar-item[id="status.host"]' , undefined , s => { this . logger . log ( `checkWindowReady: remote indicator text is ${ s }` ) ; return ! s . includes ( 'Opening Remote' ) ; } , 300 ) ; } this . logger . log ( 'checkWindowReady: end' ) ; } }