33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import * as puppeteer from 'puppeteer ' ;
6+ import * as playwright from 'playwright ' ;
77import { ChildProcess , spawn } from 'child_process' ;
88import { join } from 'path' ;
99import { mkdir } from 'fs' ;
1010import { promisify } from 'util' ;
1111import { IDriver , IDisposable } from './driver' ;
12+ import { URI } from 'vscode-uri' ;
1213
1314const width = 1200 ;
1415const height = 800 ;
1516
16- const vscodeToPuppeteerKey : { [ key : string ] : string } = {
17+ const vscodeToPlaywrightKey : { [ key : string ] : string } = {
1718 cmd : 'Meta' ,
1819 ctrl : 'Control' ,
1920 shift : 'Shift' ,
@@ -26,7 +27,7 @@ const vscodeToPuppeteerKey: { [key: string]: string } = {
2627 home : 'Home'
2728} ;
2829
29- function buildDriver ( browser : puppeteer . Browser , page : puppeteer . Page ) : IDriver {
30+ function buildDriver ( browser : playwright . Browser , page : playwright . Page ) : IDriver {
3031 const driver : IDriver = {
3132 _serviceBrand : undefined ,
3233 getWindowIds : ( ) => {
@@ -45,8 +46,8 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver
4546 const keys = chord . split ( '+' ) ;
4647 const keysDown : string [ ] = [ ] ;
4748 for ( let i = 0 ; i < keys . length ; i ++ ) {
48- if ( keys [ i ] in vscodeToPuppeteerKey ) {
49- keys [ i ] = vscodeToPuppeteerKey [ keys [ i ] ] ;
49+ if ( keys [ i ] in vscodeToPlaywrightKey ) {
50+ keys [ i ] = vscodeToPlaywrightKey [ keys [ i ] ] ;
5051 }
5152 await page . keyboard . down ( keys [ i ] ) ;
5253 keysDown . push ( keys [ i ] ) ;
@@ -68,7 +69,7 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver
6869 await driver . click ( windowId , selector , 0 , 0 ) ;
6970 await timeout ( 100 ) ;
7071 } ,
71- setValue : async ( windowId , selector , text ) => page . evaluate ( `window.driver.setValue('${ selector } ', '${ text } ')` ) ,
72+ setValue : async ( windowId , selector , text ) => page . evaluate ( `window.driver.setValue('${ selector } ', '${ text } ')` ) . then ( undefined ) ,
7273 getTitle : ( windowId ) => page . evaluate ( `window.driver.getTitle()` ) ,
7374 isActiveElement : ( windowId , selector ) => page . evaluate ( `window.driver.isActiveElement('${ selector } ')` ) ,
7475 getElements : ( windowId , selector , recursive ) => page . evaluate ( `window.driver.getElements('${ selector } ', ${ recursive } )` ) ,
@@ -86,31 +87,32 @@ function timeout(ms: number): Promise<void> {
8687
8788// function runInDriver(call: string, args: (string | boolean)[]): Promise<any> {}
8889
89- let args : string [ ] | undefined ;
9090let server : ChildProcess | undefined ;
9191let endpoint : string | undefined ;
92+ let workspacePath : string | undefined ;
9293
93- export async function launch ( _args : string [ ] ) : Promise < void > {
94- args = _args ;
95- const agentFolder = args . filter ( e => e . includes ( '--user-data-dir=' ) ) [ 0 ] . replace ( '--user-data-dir=' , '' ) ;
94+ export async function launch ( userDataDir : string , _workspacePath : string , codeServerPath = process . env . VSCODE_REMOTE_SERVER_PATH ) : Promise < void > {
95+ workspacePath = _workspacePath ;
96+ const agentFolder = userDataDir ;
9697 await promisify ( mkdir ) ( agentFolder ) ;
9798 const env = {
9899 VSCODE_AGENT_FOLDER : agentFolder ,
100+ VSCODE_REMOTE_SERVER_PATH : codeServerPath ,
99101 ...process . env
100102 } ;
101103 let serverLocation : string | undefined ;
102- if ( process . env . VSCODE_REMOTE_SERVER_PATH ) {
103- serverLocation = join ( process . env . VSCODE_REMOTE_SERVER_PATH , `server.${ process . platform === 'win32' ? 'cmd' : 'sh' } ` ) ;
104+ if ( codeServerPath ) {
105+ serverLocation = join ( codeServerPath , `server.${ process . platform === 'win32' ? 'cmd' : 'sh' } ` ) ;
104106 } else {
105- serverLocation = join ( args [ 0 ] , `resources/server/web.${ process . platform === 'win32' ? 'bat' : 'sh' } ` ) ;
107+ serverLocation = join ( __dirname , '..' , '..' , '..' , `resources/server/web.${ process . platform === 'win32' ? 'bat' : 'sh' } ` ) ;
106108 }
107109 server = spawn (
108110 serverLocation ,
109111 [ '--browser' , 'none' , '--driver' , 'web' ] ,
110112 { env }
111113 ) ;
112- server . stderr . on ( 'data' , e => console . log ( 'Server stderr: ' + e ) ) ;
113- server . stdout . on ( 'data' , e => console . log ( 'Server stdout: ' + e ) ) ;
114+ server . stderr ? .on ( 'data' , e => console . log ( 'Server stderr: ' + e ) ) ;
115+ server . stdout ? .on ( 'data' , e => console . log ( 'Server stdout: ' + e ) ) ;
114116 process . on ( 'exit' , teardown ) ;
115117 process . on ( 'SIGINT' , teardown ) ;
116118 process . on ( 'SIGTERM' , teardown ) ;
@@ -126,7 +128,7 @@ function teardown(): void {
126128
127129function waitForEndpoint ( ) : Promise < string > {
128130 return new Promise < string > ( r => {
129- server ! . stdout . on ( 'data' , ( d : Buffer ) => {
131+ server ! . stdout ? .on ( 'data' , ( d : Buffer ) => {
130132 const matches = d . toString ( 'ascii' ) . match ( / W e b U I a v a i l a b l e a t ( .+ ) / ) ;
131133 if ( matches !== null ) {
132134 r ( matches [ 1 ] ) ;
@@ -135,20 +137,18 @@ function waitForEndpoint(): Promise<string> {
135137 } ) ;
136138}
137139
138- export function connect ( headless : boolean , outPath : string , handle : string ) : Promise < { client : IDisposable , driver : IDriver } > {
140+ export function connect ( headless : boolean , engine : 'chromium' | 'webkit' | 'firefox' = 'chromium' ) : Promise < { client : IDisposable , driver : IDriver } > {
139141 return new Promise ( async ( c ) => {
140- const browser = await puppeteer . launch ( {
142+ const browser = await playwright [ engine ] . launch ( {
141143 // Run in Edge dev on macOS
142144 // executablePath: '/Applications/Microsoft\ Edge\ Dev.app/Contents/MacOS/Microsoft\ Edge\ Dev',
143- headless,
144- slowMo : 80 ,
145- args : [ `--window-size=${ width } ,${ height } ` ]
145+ headless
146146 } ) ;
147- const page = ( await browser . pages ( ) ) [ 0 ] ;
147+ const page = ( await browser . defaultContext ( ) . pages ( ) ) [ 0 ] ;
148148 await page . setViewport ( { width, height } ) ;
149- await page . goto ( `${ endpoint } &folder=vscode-remote://localhost:9888${ args ! [ 1 ] } ` ) ;
149+ await page . goto ( `${ endpoint } &folder=vscode-remote://localhost:9888${ URI . file ( workspacePath ! ) . path } ` ) ;
150150 const result = {
151- client : { dispose : ( ) => teardown } ,
151+ client : { dispose : ( ) => teardown ( ) } ,
152152 driver : buildDriver ( browser , page )
153153 } ;
154154 c ( result ) ;
0 commit comments