33 *--------------------------------------------------------*/
44
55import { DebugProtocol } from 'vscode-debugprotocol' ;
6- import { chromeConnection , ISourceMapPathOverrides , telemetry } from 'vscode-chrome-debug-core' ;
6+ import { chromeConnection , ISourceMapPathOverrides , telemetry , utils as coreUtils , ChromeDebugSession } from 'vscode-chrome-debug-core' ;
77
88import * as mockery from 'mockery' ;
99import { EventEmitter } from 'events' ;
@@ -30,6 +30,7 @@ suite('ChromeDebugAdapter', () => {
3030 let mockEventEmitter : EventEmitter ;
3131 let mockChrome : IMockChromeConnectionAPI ;
3232
33+ let mockChromeDebugSession : IMock < MockChromeDebugSession > ;
3334 let chromeDebugAdapter : _ChromeDebugAdapter ;
3435
3536 setup ( ( ) => {
@@ -41,6 +42,14 @@ suite('ChromeDebugAdapter', () => {
4142 mockChromeConnection = Mock . ofType ( chromeConnection . ChromeConnection , MockBehavior . Strict ) ;
4243 mockChrome = getMockChromeConnectionApi ( ) ;
4344 mockEventEmitter = mockChrome . mockEventEmitter ;
45+ mockChromeDebugSession = Mock . ofType ( MockChromeDebugSession , MockBehavior . Strict ) ;
46+ mockChromeDebugSession
47+ . setup ( x => x . sendEvent ( It . isAny ( ) ) )
48+ . verifiable ( Times . atLeast ( 0 ) ) ;
49+ mockChromeDebugSession
50+ . setup ( x => x . sendRequest ( It . isAnyString ( ) , It . isAny ( ) , It . isAnyNumber ( ) , It . isAny ( ) ) )
51+ . verifiable ( Times . atLeast ( 0 ) ) ;
52+
4453 mockChromeConnection
4554 . setup ( x => x . api )
4655 . returns ( ( ) => mockChrome . apiObjects )
@@ -67,7 +76,7 @@ suite('ChromeDebugAdapter', () => {
6776
6877 // Instantiate the ChromeDebugAdapter, injecting the mock ChromeConnection
6978 const cDAClass : typeof _ChromeDebugAdapter = require ( MODULE_UNDER_TEST ) . ChromeDebugAdapter ;
70- chromeDebugAdapter = new cDAClass ( { chromeConnection : function ( ) { return mockChromeConnection . object ; } } as any , new MockChromeDebugSession ( ) as any ) ;
79+ chromeDebugAdapter = new cDAClass ( { chromeConnection : function ( ) { return mockChromeConnection . object ; } } as any , mockChromeDebugSession . object as any ) ;
7180 } ) ;
7281
7382 teardown ( ( ) => {
@@ -82,6 +91,17 @@ suite('ChromeDebugAdapter', () => {
8291 let originalSpawn : any ;
8392 let originalStatSync : any ;
8493
94+ setup ( ( ) => {
95+ mockChromeConnection
96+ . setup ( x => x . attach ( It . isValue ( undefined ) , It . isAnyNumber ( ) , It . isAnyString ( ) , It . isValue ( undefined ) , It . isValue ( undefined ) ) )
97+ . returns ( ( ) => Promise . resolve ( ) )
98+ . verifiable ( ) ;
99+
100+ mockChrome . Runtime
101+ . setup ( x => x . evaluate ( It . isAny ( ) ) )
102+ . returns ( ( ) => Promise . resolve < any > ( { result : { type : 'string' , value : '123' } } ) ) ;
103+ } ) ;
104+
85105 teardown ( ( ) => {
86106 // Hacky mock cleanup
87107 require ( 'child_process' ) . fork = originalFork ;
@@ -117,19 +137,85 @@ suite('ChromeDebugAdapter', () => {
117137 originalStatSync = require ( 'fs' ) . statSync ;
118138 require ( 'fs' ) . statSync = ( ) => true ;
119139
120- mockChromeConnection
121- . setup ( x => x . attach ( It . isValue ( undefined ) , It . isAnyNumber ( ) , It . isAnyString ( ) , It . isValue ( undefined ) , It . isValue ( undefined ) ) )
122- . returns ( ( ) => Promise . resolve ( ) )
123- . verifiable ( ) ;
124-
125- mockChrome . Runtime
126- . setup ( x => x . evaluate ( It . isAny ( ) ) )
127- . returns ( ( ) => Promise . resolve < any > ( { result : { type : 'string' , value : '123' } } ) ) ;
128-
129140 return chromeDebugAdapter . launch ( { file : 'c:\\path with space\\index.html' , runtimeArgs : [ 'abc' , 'def' ] } ,
130141 new telemetry . TelemetryPropertyCollector ( ) )
131142 . then ( ( ) => assert ( spawnCalled ) ) ;
132143 } ) ;
144+
145+ test ( 'launches unelevated with client' , async ( ) => {
146+ let telemetryPropertyCollector = new telemetry . TelemetryPropertyCollector ( ) ;
147+ chromeDebugAdapter . initialize ( {
148+ adapterID : 'test debug adapter' ,
149+ pathFormat : 'path' ,
150+ supportsLaunchUnelevatedProcessRequest : true
151+ } ) ;
152+
153+ const originalGetPlatform = require ( 'os' ) . platform ;
154+ require ( 'os' ) . platform = ( ) => { return 'win32' ; } ;
155+
156+ const originalGetBrowser = require ( '../src/utils' ) . getBrowserPath ;
157+ require ( '../src/utils' ) . getBrowserPath = ( ) => { return 'c:\\someplace\\chrome.exe' ; } ;
158+
159+ const expectedProcessId = 325 ;
160+ let collectedLaunchParams : any ;
161+ mockChromeDebugSession
162+ . setup ( x => x . sendRequest ( 'launchUnelevated' ,
163+ It . is ( ( x : any ) => {
164+ collectedLaunchParams = x ;
165+ return true ;
166+ } ) ,
167+ 10000 ,
168+ It . is (
169+ ( callback : ( response : DebugProtocol . Response ) => void ) => {
170+ callback ( {
171+ seq : null ,
172+ type : 'command' ,
173+ request_seq : 100 ,
174+ command : 'launchUnelevated' ,
175+ success : true ,
176+ body : {
177+ processId : expectedProcessId
178+ }
179+ } ) ;
180+ return true ;
181+ } ) ) )
182+ . verifiable ( Times . atLeast ( 1 ) ) ;
183+
184+ await chromeDebugAdapter . launch ( {
185+ file : 'c:\\path with space\\index.html' ,
186+ runtimeArgs : [ 'abc' , 'def' ] ,
187+ shouldLaunchChromeUnelevated : true
188+ } , telemetryPropertyCollector ) ;
189+
190+ assert . equal ( expectedProcessId , ( < any > chromeDebugAdapter ) . _chromePID , 'Debug Adapter should receive the Chrome process id' ) ;
191+ assert ( collectedLaunchParams . process != null ) ;
192+ assert ( collectedLaunchParams . process . match ( / c h r o m e / i) ) ;
193+ assert ( collectedLaunchParams . args != null ) ;
194+
195+ assert ( collectedLaunchParams . args . filter ( ( x ) => x == '--no-default-browser-check' ) . length != 0 ,
196+ 'Should have seen the --no-default-browser-check parameter' ) ;
197+ assert ( collectedLaunchParams . args . filter ( ( x ) => x == '--no-first-run' ) . length != 0 ,
198+ 'Should have seen the --no-first-run parameter' ) ;
199+ assert ( collectedLaunchParams . args . filter ( ( x ) => x == 'abc' ) . length != 0 ,
200+ 'Should have seen the abc parameter' ) ;
201+ assert ( collectedLaunchParams . args . filter ( ( x ) => x == 'def' ) . length != 0 ,
202+ 'Should have seen the def parameter' ) ;
203+ assert ( collectedLaunchParams . args . filter ( ( x ) => x == 'about:blank' ) . length != 0 ,
204+ 'Should have seen the about:blank parameter' ) ;
205+ assert ( collectedLaunchParams . args . filter ( ( x ) => x . match ( / r e m o t e - d e b u g g i n g - p o r t / ) ) . length != 0 ,
206+ 'Should have seen a parameter like remote-debugging-port' ) ;
207+ assert ( collectedLaunchParams . args . filter ( ( x ) => x . match ( / u s e r - d a t a - d i r / ) ) . length != 0 ,
208+ 'Should have seen a parameter like user-data-dir' ) ;
209+
210+ const telemetryProperties = telemetryPropertyCollector . getProperties ( ) ;
211+ assert . equal ( telemetryProperties . shouldLaunchChromeUnelevated , 'true' , "Should send telemetry that Chrome is requested to be launched unelevated.'" ) ;
212+ assert . equal ( telemetryProperties . doesHostSupportLaunchUnelevated , 'true' , "Should send telemetry that host supports launcheing Chrome unelevated.'" ) ;
213+
214+ require ( 'os' ) . platform = originalGetPlatform ;
215+ require ( '../src/utils' ) . getBrowserPath = originalGetBrowser ;
216+
217+ return Promise . resolve ( ) ;
218+ } ) ;
133219 } ) ;
134220
135221 suite ( 'resolveWebRootPattern' , ( ) => {
0 commit comments