diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 60c8b78835b..ea93934523a 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -289,7 +289,7 @@ export class CodeApplication { // Create driver if (this.environmentService.driverHandle) { - serveDriver(this.electronIpcServer, this.environmentService.driverHandle, appInstantiationService).then(server => { + serveDriver(this.electronIpcServer, this.environmentService.driverHandle, this.environmentService, appInstantiationService).then(server => { this.logService.info('Driver started at:', this.environmentService.driverHandle); this.toDispose.push(server); }); diff --git a/src/vs/platform/driver/common/driver.ts b/src/vs/platform/driver/common/driver.ts index b40326a162b..b3f472863c6 100644 --- a/src/vs/platform/driver/common/driver.ts +++ b/src/vs/platform/driver/common/driver.ts @@ -150,13 +150,17 @@ export class DriverChannelClient implements IDriver { } } +export interface IDriverOptions { + verbose: boolean; +} + export interface IWindowDriverRegistry { - registerWindowDriver(windowId: number): TPromise; + registerWindowDriver(windowId: number): TPromise; reloadWindowDriver(windowId: number): TPromise; } export interface IWindowDriverRegistryChannel extends IChannel { - call(command: 'registerWindowDriver', arg: number): TPromise; + call(command: 'registerWindowDriver', arg: number): TPromise; call(command: 'reloadWindowDriver', arg: number): TPromise; call(command: string, arg: any): TPromise; } @@ -181,7 +185,7 @@ export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry constructor(private channel: IWindowDriverRegistryChannel) { } - registerWindowDriver(windowId: number): TPromise { + registerWindowDriver(windowId: number): TPromise { return this.channel.call('registerWindowDriver', windowId); } diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index 60bce74b113..897401df06e 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -12,6 +12,7 @@ import { IPCClient } from 'vs/base/parts/ipc/common/ipc'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom'; import * as electron from 'electron'; +import { IWindowService } from 'vs/platform/windows/common/windows'; function serializeElement(element: Element, recursive: boolean): IElement { const attributes = Object.create(null); @@ -40,7 +41,9 @@ function serializeElement(element: Element, recursive: boolean): IElement { class WindowDriver implements IWindowDriver { - constructor() { } + constructor( + @IWindowService private windowService: IWindowService + ) { } async click(selector: string, xoffset?: number, yoffset?: number): TPromise { return this._click(selector, 1, xoffset, yoffset); @@ -183,6 +186,10 @@ class WindowDriver implements IWindowDriver { return lines; } + + async openDevTools(): TPromise { + await this.windowService.openDevTools({ mode: 'detach' }); + } } export async function registerWindowDriver( @@ -197,7 +204,11 @@ export async function registerWindowDriver( const windowDriverRegistryChannel = client.getChannel('windowDriverRegistry'); const windowDriverRegistry = new WindowDriverRegistryChannelClient(windowDriverRegistryChannel); - await windowDriverRegistry.registerWindowDriver(windowId); + const options = await windowDriverRegistry.registerWindowDriver(windowId); + + if (options.verbose) { + windowDriver.openDevTools(); + } const disposable = toDisposable(() => windowDriverRegistry.reloadWindowDriver(windowId)); return combinedDisposable([disposable, client]); diff --git a/src/vs/platform/driver/electron-main/driver.ts b/src/vs/platform/driver/electron-main/driver.ts index badeeab4a1f..89cce0f3717 100644 --- a/src/vs/platform/driver/electron-main/driver.ts +++ b/src/vs/platform/driver/electron-main/driver.ts @@ -6,7 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDriver, DriverChannel, IElement, IWindowDriverChannel, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IWindowDriver } from 'vs/platform/driver/common/driver'; +import { IDriver, DriverChannel, IElement, IWindowDriverChannel, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IWindowDriver, IDriverOptions } from 'vs/platform/driver/common/driver'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; import { serve as serveNet } from 'vs/base/parts/ipc/node/ipc.net'; import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -16,6 +16,7 @@ import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { OS } from 'vs/base/common/platform'; import { Emitter, toPromise } from 'vs/base/common/event'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; // TODO@joao: bad layering! import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; @@ -45,13 +46,15 @@ export class Driver implements IDriver, IWindowDriverRegistry { constructor( private windowServer: IPCServer, + private options: IDriverOptions, @IWindowsMainService private windowsService: IWindowsMainService ) { } - async registerWindowDriver(windowId: number): TPromise { + async registerWindowDriver(windowId: number): TPromise { this.registeredWindowIds.add(windowId); this.reloadingWindowIds.delete(windowId); this.onDidReloadingChange.fire(); + return this.options; } async reloadWindowDriver(windowId: number): TPromise { @@ -203,9 +206,11 @@ export class Driver implements IDriver, IWindowDriverRegistry { export async function serve( windowServer: IPCServer, handle: string, + environmentService: IEnvironmentService, instantiationService: IInstantiationService ): TPromise { - const driver = instantiationService.createInstance(Driver, windowServer); + const verbose = environmentService.driverVerbose; + const driver = instantiationService.createInstance(Driver, windowServer, { verbose }); const windowDriverRegistryChannel = new WindowDriverRegistryChannel(driver); windowServer.registerChannel('windowDriverRegistry', windowDriverRegistryChannel); diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 7b9d2d42259..06f80764726 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -58,6 +58,7 @@ export interface ParsedArgs { 'file-chmod'?: boolean; 'upload-logs'?: string; 'driver'?: string; + 'driver-verbose'?: boolean; } export const IEnvironmentService = createDecorator('environmentService'); @@ -133,4 +134,5 @@ export interface IEnvironmentService { disableCrashReporter: boolean; driverHandle: string; + driverVerbose: boolean; } diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 7f14ec4ce06..39f51476eab 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -62,7 +62,8 @@ const options: minimist.Opts = { 'skip-add-to-recently-opened', 'status', 'file-write', - 'file-chmod' + 'file-chmod', + 'driver-verbose' ], alias: { add: 'a', diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index cd875edaccd..381202a6d1b 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -171,6 +171,7 @@ export class EnvironmentService implements IEnvironmentService { get disableCrashReporter(): boolean { return !!this._args['disable-crash-reporter']; } get driverHandle(): string { return this._args['driver']; } + get driverVerbose(): boolean { return this._args['driver-verbose']; } constructor(private _args: ParsedArgs, private _execPath: string) { if (!process.env['VSCODE_LOGS']) { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index fea8cb45f4f..bb161524a50 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -92,6 +92,10 @@ export interface OpenDialogOptions { message?: string; } +export interface IDevToolsOptions { + mode: 'right' | 'bottom' | 'undocked' | 'detach'; +} + export interface IWindowsService { _serviceBrand: any; @@ -110,7 +114,7 @@ export interface IWindowsService { showOpenDialog(windowId: number, options: OpenDialogOptions): TPromise; reloadWindow(windowId: number, args?: ParsedArgs): TPromise; - openDevTools(windowId: number): TPromise; + openDevTools(windowId: number, options?: IDevToolsOptions): TPromise; toggleDevTools(windowId: number): TPromise; closeWorkspace(windowId: number): TPromise; createAndEnterWorkspace(windowId: number, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise; @@ -185,7 +189,7 @@ export interface IWindowService { pickFolderAndOpen(options: INativeOpenDialogOptions): TPromise; pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise; reloadWindow(args?: ParsedArgs): TPromise; - openDevTools(): TPromise; + openDevTools(options?: IDevToolsOptions): TPromise; toggleDevTools(): TPromise; closeWorkspace(): TPromise; updateTouchBar(items: ICommandAction[][]): TPromise; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index b7f82cc8472..e6bd74f3dd9 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Event, buffer } from 'vs/base/common/event'; import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc'; -import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions } from 'vs/platform/windows/common/windows'; +import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IDevToolsOptions } from 'vs/platform/windows/common/windows'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ICommandAction } from 'vs/platform/actions/common/actions'; @@ -93,7 +93,7 @@ export class WindowsChannel implements IWindowsChannel { case 'showSaveDialog': return this.service.showSaveDialog(arg[0], arg[1]); case 'showOpenDialog': return this.service.showOpenDialog(arg[0], arg[1]); case 'reloadWindow': return this.service.reloadWindow(arg[0], arg[1]); - case 'openDevTools': return this.service.openDevTools(arg); + case 'openDevTools': return this.service.openDevTools(arg[0], arg[1]); case 'toggleDevTools': return this.service.toggleDevTools(arg); case 'closeWorkspace': return this.service.closeWorkspace(arg); case 'createAndEnterWorkspace': { @@ -197,8 +197,8 @@ export class WindowsChannelClient implements IWindowsService { return this.channel.call('reloadWindow', [windowId, args]); } - openDevTools(windowId: number): TPromise { - return this.channel.call('openDevTools', windowId); + openDevTools(windowId: number, options?: IDevToolsOptions): TPromise { + return this.channel.call('openDevTools', [windowId, options]); } toggleDevTools(windowId: number): TPromise { diff --git a/src/vs/platform/windows/electron-browser/windowService.ts b/src/vs/platform/windows/electron-browser/windowService.ts index bfaca695a5b..fbc0aa9b39d 100644 --- a/src/vs/platform/windows/electron-browser/windowService.ts +++ b/src/vs/platform/windows/electron-browser/windowService.ts @@ -7,7 +7,7 @@ import { Event, filterEvent, mapEvent, anyEvent } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IWindowService, IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IWindowConfiguration } from 'vs/platform/windows/common/windows'; +import { IWindowService, IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IWindowConfiguration, IDevToolsOptions } from 'vs/platform/windows/common/windows'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ICommandAction } from 'vs/platform/actions/common/actions'; import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; @@ -65,8 +65,8 @@ export class WindowService implements IWindowService { return this.windowsService.reloadWindow(this.windowId, args); } - openDevTools(): TPromise { - return this.windowsService.openDevTools(this.windowId); + openDevTools(options?: IDevToolsOptions): TPromise { + return this.windowsService.openDevTools(this.windowId, options); } toggleDevTools(): TPromise { diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index e8587efa62f..24c7924ff9a 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -11,7 +11,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; import URI from 'vs/base/common/uri'; import product from 'vs/platform/node/product'; -import { IWindowsService, OpenContext, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult } from 'vs/platform/windows/common/windows'; +import { IWindowsService, OpenContext, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, IDevToolsOptions } from 'vs/platform/windows/common/windows'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { shell, crashReporter, app, Menu, clipboard } from 'electron'; import { Event, fromNodeEventEmitter, mapEvent, filterEvent, anyEvent } from 'vs/base/common/event'; @@ -112,12 +112,12 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable return TPromise.as(null); } - openDevTools(windowId: number): TPromise { + openDevTools(windowId: number, options?: IDevToolsOptions): TPromise { this.logService.trace('windowsService#openDevTools', windowId); const codeWindow = this.windowsMainService.getWindowById(windowId); if (codeWindow) { - codeWindow.win.webContents.openDevTools(); + codeWindow.win.webContents.openDevTools(options); } return TPromise.as(null); diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index cd63330d0ab..9f7d0e4f376 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -108,7 +108,8 @@ export class Application { userDataDir: this.options.userDataDir, extensionsPath: this.options.extensionsPath, logger: this.options.logger, - extraArgs + verbose: this.options.verbose, + extraArgs, }); this._workbench = new Workbench(this._code, this.keybindings, this.userDataPath); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index eb74ad61c79..1015813ac2b 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -257,7 +257,8 @@ function createApp(quality: Quality): Application { extensionsPath, workspaceFilePath, waitTime: parseInt(opts['wait-time'] || '0') || 20, - logger: new MultiLogger(loggers) + logger: new MultiLogger(loggers), + verbose: opts.verbose }); } diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index c60984c6441..9f5cf3f7e78 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -87,6 +87,7 @@ export interface SpawnOptions { userDataDir: string; extensionsPath: string; logger: Logger; + verbose?: boolean; extraArgs?: string[]; } @@ -122,6 +123,10 @@ export async function spawn(options: SpawnOptions): Promise { args.unshift(repoPath); } + if (options.verbose) { + args.push('--driver-verbose'); + } + if (options.extraArgs) { args.push(...options.extraArgs); }