Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/node/driver';
import { IPCClient } from 'vs/base/parts/ipc/node/ipc';
@@ -13,20 +12,26 @@ import * as electron from 'electron';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { Terminal } from 'vscode-xterm';
import { timeout } from 'vs/base/common/async';
import { coalesce } from 'vs/base/common/arrays';
function serializeElement(element: Element, recursive: boolean): IElement {
const attributes = Object.create(null);
for (let j = 0; j < element.attributes.length; j++) {
const attr = element.attributes.item(j);
attributes[attr.name] = attr.value;
if (attr) {
attributes[attr.name] = attr.value;
}
}
const children: IElement[] = [];
if (recursive) {
for (let i = 0; i < element.children.length; i++) {
children.push(serializeElement(element.children.item(i), true));
const child = element.children.item(i);
if (child) {
children.push(serializeElement(child, true));
}
}
}
@@ -46,31 +51,32 @@ function serializeElement(element: Element, recursive: boolean): IElement {
class WindowDriver implements IWindowDriver {
constructor(
@IWindowService private windowService: IWindowService
@IWindowService private readonly windowService: IWindowService
) { }
click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
return this._click(selector, 1, xoffset, yoffset);
click(selector: string, xoffset?: number, yoffset?: number): Promise<void> {
const offset = typeof xoffset === 'number' && typeof yoffset === 'number' ? { x: xoffset, y: yoffset } : undefined;
return this._click(selector, 1, offset);
}
doubleClick(selector: string): TPromise<void> {
doubleClick(selector: string): Promise<void> {
return this._click(selector, 2);
}
private _getElementXY(selector: string, xoffset?: number, yoffset?: number): TPromise<{ x: number; y: number; }> {
private async _getElementXY(selector: string, offset?: { x: number, y: number }): Promise<{ x: number; y: number; }> {
const element = document.querySelector(selector);
if (!element) {
return TPromise.wrapError(new Error(`Element not found: ${selector}`));
return Promise.reject(new Error(`Element not found: ${selector}`));
}
const { left, top } = getTopLeftOffset(element as HTMLElement);
const { width, height } = getClientArea(element as HTMLElement);
let x: number, y: number;
if ((typeof xoffset === 'number') || (typeof yoffset === 'number')) {
x = left + xoffset;
y = top + yoffset;
if (offset) {
x = left + offset.x;
y = top + offset.y;
} else {
x = left + (width / 2);
y = top + (height / 2);
@@ -79,27 +85,25 @@ class WindowDriver implements IWindowDriver {
x = Math.round(x);
y = Math.round(y);
return TPromise.as({ x, y });
return { x, y };
}
private _click(selector: string, clickCount: number, xoffset?: number, yoffset?: number): TPromise<void> {
return this._getElementXY(selector, xoffset, yoffset).then(({ x, y }) => {
private async _click(selector: string, clickCount: number, offset?: { x: number, y: number }): Promise<void> {
const { x, y } = await this._getElementXY(selector, offset);
const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents();
webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any);
const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents();
webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any);
await timeout(10);
return TPromise.wrap(timeout(10)).then(() => {
webContents.sendInputEvent({ type: 'mouseUp', x, y, button: 'left', clickCount } as any);
return TPromise.wrap(timeout(100));
});
});
webContents.sendInputEvent({ type: 'mouseUp', x, y, button: 'left', clickCount } as any);
await timeout(100);
}
setValue(selector: string, text: string): TPromise<void> {
async setValue(selector: string, text: string): Promise<void> {
const element = document.querySelector(selector);
if (!element) {
return TPromise.wrapError(new Error(`Element not found: ${selector}`));
return Promise.reject(new Error(`Element not found: ${selector}`));
}
const inputElement = element as HTMLInputElement;
@@ -107,15 +111,13 @@ class WindowDriver implements IWindowDriver {
const event = new Event('input', { bubbles: true, cancelable: true });
inputElement.dispatchEvent(event);
return TPromise.as(null);
}
getTitle(): TPromise<string> {
return TPromise.as(document.title);
async getTitle(): Promise<string> {
return document.title;
}
isActiveElement(selector: string): TPromise<boolean> {
async isActiveElement(selector: string): Promise<boolean> {
const element = document.querySelector(selector);
if (element !== document.activeElement) {
@@ -125,19 +127,19 @@ class WindowDriver implements IWindowDriver {
while (el) {
const tagName = el.tagName;
const id = el.id ? `#${el.id}` : '';
const classes = el.className.split(/\s+/g).map(c => c.trim()).filter(c => !!c).map(c => `.${c}`).join('');
const classes = coalesce(el.className.split(/\s+/g).map(c => c.trim())).map(c => `.${c}`).join('');
chain.unshift(`${tagName}${id}${classes}`);
el = el.parentElement;
}
return TPromise.wrapError(new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`));
throw new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`);
}
return TPromise.as(true);
return true;
}
getElements(selector: string, recursive: boolean): TPromise<IElement[]> {
async getElements(selector: string, recursive: boolean): Promise<IElement[]> {
const query = document.querySelectorAll(selector);
const result: IElement[] = [];
@@ -146,14 +148,14 @@ class WindowDriver implements IWindowDriver {
result.push(serializeElement(element, recursive));
}
return TPromise.as(result);
return result;
}
typeInEditor(selector: string, text: string): TPromise<void> {
async typeInEditor(selector: string, text: string): Promise<void> {
const element = document.querySelector(selector);
if (!element) {
return TPromise.wrapError(new Error(`Editor not found: ${selector}`));
throw new Error(`Editor not found: ${selector}`);
}
const textarea = element as HTMLTextAreaElement;
@@ -167,21 +169,19 @@ class WindowDriver implements IWindowDriver {
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
textarea.dispatchEvent(event);
return TPromise.as(null);
}
getTerminalBuffer(selector: string): TPromise<string[]> {
async getTerminalBuffer(selector: string): Promise<string[]> {
const element = document.querySelector(selector);
if (!element) {
return TPromise.wrapError(new Error(`Terminal not found: ${selector}`));
throw new Error(`Terminal not found: ${selector}`);
}
const xterm: Terminal = (element as any).xterm;
if (!xterm) {
return TPromise.wrapError(new Error(`Xterm not found: ${selector}`));
throw new Error(`Xterm not found: ${selector}`);
}
const lines: string[] = [];
@@ -190,29 +190,27 @@ class WindowDriver implements IWindowDriver {
lines.push(xterm._core.buffer.translateBufferLineToString(i, true));
}
return TPromise.as(lines);
return lines;
}
writeInTerminal(selector: string, text: string): TPromise<void> {
async writeInTerminal(selector: string, text: string): Promise<void> {
const element = document.querySelector(selector);
if (!element) {
return TPromise.wrapError(new Error(`Element not found: ${selector}`));
throw new Error(`Element not found: ${selector}`);
}
const xterm: Terminal = (element as any).xterm;
if (!xterm) {
return TPromise.wrapError(new Error(`Xterm not found: ${selector}`));
throw new Error(`Xterm not found: ${selector}`);
}
xterm._core.handler(text);
return TPromise.as(null);
}
openDevTools(): TPromise<void> {
return this.windowService.openDevTools({ mode: 'detach' });
async openDevTools(): Promise<void> {
await this.windowService.openDevTools({ mode: 'detach' });
}
}

View File

@@ -12,7 +12,7 @@ import { IPCServer, StaticRouter } from 'vs/base/parts/ipc/node/ipc';
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 { Emitter, Event } from 'vs/base/common/event';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ScanCodeBinding } from 'vs/base/common/scanCode';
import { KeybindingParser } from 'vs/base/common/keybindingParser';
@@ -33,7 +33,7 @@ export class Driver implements IDriver, IWindowDriverRegistry {
constructor(
private windowServer: IPCServer,
private options: IDriverOptions,
@IWindowsMainService private windowsService: IWindowsMainService
@IWindowsMainService private readonly windowsService: IWindowsMainService
) { }
async registerWindowDriver(windowId: number): Promise<IDriverOptions> {
@@ -71,6 +71,10 @@ export class Driver implements IDriver, IWindowDriverRegistry {
this.windowsService.reload(window);
}
async exitApplication(): Promise<void> {
return this.windowsService.quit();
}
async dispatchKeybinding(windowId: number, keybinding: string): Promise<void> {
await this.whenUnfrozen(windowId);
@@ -183,7 +187,7 @@ export class Driver implements IDriver, IWindowDriverRegistry {
private async whenUnfrozen(windowId: number): Promise<void> {
while (this.reloadingWindowIds.has(windowId)) {
await toPromise(this.onDidReloadingChange.event);
await Event.toPromise(this.onDidReloadingChange.event);
}
}
}

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { connect as connectNet, Client } from 'vs/base/parts/ipc/node/ipc.net';
import { TPromise } from 'vs/base/common/winjs.base';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/node/ipc';
import { Event } from 'vs/base/common/event';
@@ -28,19 +27,20 @@ export interface IElement {
export interface IDriver {
_serviceBrand: any;
getWindowIds(): TPromise<number[]>;
capturePage(windowId: number): TPromise<string>;
reloadWindow(windowId: number): TPromise<void>;
dispatchKeybinding(windowId: number, keybinding: string): TPromise<void>;
click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>;
doubleClick(windowId: number, selector: string): TPromise<void>;
setValue(windowId: number, selector: string, text: string): TPromise<void>;
getTitle(windowId: number): TPromise<string>;
isActiveElement(windowId: number, selector: string): TPromise<boolean>;
getElements(windowId: number, selector: string, recursive?: boolean): TPromise<IElement[]>;
typeInEditor(windowId: number, selector: string, text: string): TPromise<void>;
getTerminalBuffer(windowId: number, selector: string): TPromise<string[]>;
writeInTerminal(windowId: number, selector: string, text: string): TPromise<void>;
getWindowIds(): Promise<number[]>;
capturePage(windowId: number): Promise<string>;
reloadWindow(windowId: number): Promise<void>;
exitApplication(): Promise<void>;
dispatchKeybinding(windowId: number, keybinding: string): Promise<void>;
click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<void>;
doubleClick(windowId: number, selector: string): Promise<void>;
setValue(windowId: number, selector: string, text: string): Promise<void>;
getTitle(windowId: number): Promise<string>;
isActiveElement(windowId: number, selector: string): Promise<boolean>;
getElements(windowId: number, selector: string, recursive?: boolean): Promise<IElement[]>;
typeInEditor(windowId: number, selector: string, text: string): Promise<void>;
getTerminalBuffer(windowId: number, selector: string): Promise<string[]>;
writeInTerminal(windowId: number, selector: string, text: string): Promise<void>;
}
//*END
@@ -52,11 +52,12 @@ export class DriverChannel implements IServerChannel {
throw new Error('No event found');
}
call(_, command: string, arg?: any): TPromise<any> {
call(_, command: string, arg?: any): Promise<any> {
switch (command) {
case 'getWindowIds': return this.driver.getWindowIds();
case 'capturePage': return this.driver.capturePage(arg);
case 'reloadWindow': return this.driver.reloadWindow(arg);
case 'exitApplication': return this.driver.exitApplication();
case 'dispatchKeybinding': return this.driver.dispatchKeybinding(arg[0], arg[1]);
case 'click': return this.driver.click(arg[0], arg[1], arg[2], arg[3]);
case 'doubleClick': return this.driver.doubleClick(arg[0], arg[1]);
@@ -79,56 +80,60 @@ export class DriverChannelClient implements IDriver {
constructor(private channel: IChannel) { }
getWindowIds(): TPromise<number[]> {
return TPromise.wrap(this.channel.call('getWindowIds'));
getWindowIds(): Promise<number[]> {
return this.channel.call('getWindowIds');
}
capturePage(windowId: number): TPromise<string> {
return TPromise.wrap(this.channel.call('capturePage', windowId));
capturePage(windowId: number): Promise<string> {
return this.channel.call('capturePage', windowId);
}
reloadWindow(windowId: number): TPromise<void> {
return TPromise.wrap(this.channel.call('reloadWindow', windowId));
reloadWindow(windowId: number): Promise<void> {
return this.channel.call('reloadWindow', windowId);
}
dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> {
return TPromise.wrap(this.channel.call('dispatchKeybinding', [windowId, keybinding]));
exitApplication(): Promise<void> {
return this.channel.call('exitApplication');
}
click(windowId: number, selector: string, xoffset: number | undefined, yoffset: number | undefined): TPromise<void> {
return TPromise.wrap(this.channel.call('click', [windowId, selector, xoffset, yoffset]));
dispatchKeybinding(windowId: number, keybinding: string): Promise<void> {
return this.channel.call('dispatchKeybinding', [windowId, keybinding]);
}
doubleClick(windowId: number, selector: string): TPromise<void> {
return TPromise.wrap(this.channel.call('doubleClick', [windowId, selector]));
click(windowId: number, selector: string, xoffset: number | undefined, yoffset: number | undefined): Promise<void> {
return this.channel.call('click', [windowId, selector, xoffset, yoffset]);
}
setValue(windowId: number, selector: string, text: string): TPromise<void> {
return TPromise.wrap(this.channel.call('setValue', [windowId, selector, text]));
doubleClick(windowId: number, selector: string): Promise<void> {
return this.channel.call('doubleClick', [windowId, selector]);
}
getTitle(windowId: number): TPromise<string> {
return TPromise.wrap(this.channel.call('getTitle', [windowId]));
setValue(windowId: number, selector: string, text: string): Promise<void> {
return this.channel.call('setValue', [windowId, selector, text]);
}
isActiveElement(windowId: number, selector: string): TPromise<boolean> {
return TPromise.wrap(this.channel.call('isActiveElement', [windowId, selector]));
getTitle(windowId: number): Promise<string> {
return this.channel.call('getTitle', [windowId]);
}
getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> {
return TPromise.wrap(this.channel.call('getElements', [windowId, selector, recursive]));
isActiveElement(windowId: number, selector: string): Promise<boolean> {
return this.channel.call('isActiveElement', [windowId, selector]);
}
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
return TPromise.wrap(this.channel.call('typeInEditor', [windowId, selector, text]));
getElements(windowId: number, selector: string, recursive: boolean): Promise<IElement[]> {
return this.channel.call('getElements', [windowId, selector, recursive]);
}
getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> {
return TPromise.wrap(this.channel.call('getTerminalBuffer', [windowId, selector]));
typeInEditor(windowId: number, selector: string, text: string): Promise<void> {
return this.channel.call('typeInEditor', [windowId, selector, text]);
}
writeInTerminal(windowId: number, selector: string, text: string): TPromise<void> {
return TPromise.wrap(this.channel.call('writeInTerminal', [windowId, selector, text]));
getTerminalBuffer(windowId: number, selector: string): Promise<string[]> {
return this.channel.call('getTerminalBuffer', [windowId, selector]);
}
writeInTerminal(windowId: number, selector: string, text: string): Promise<void> {
return this.channel.call('writeInTerminal', [windowId, selector, text]);
}
}
@@ -137,8 +142,8 @@ export interface IDriverOptions {
}
export interface IWindowDriverRegistry {
registerWindowDriver(windowId: number): TPromise<IDriverOptions>;
reloadWindowDriver(windowId: number): TPromise<void>;
registerWindowDriver(windowId: number): Promise<IDriverOptions>;
reloadWindowDriver(windowId: number): Promise<void>;
}
export class WindowDriverRegistryChannel implements IServerChannel {
@@ -149,7 +154,7 @@ export class WindowDriverRegistryChannel implements IServerChannel {
throw new Error(`Event not found: ${event}`);
}
call(_, command: string, arg?: any): Thenable<any> {
call(_, command: string, arg?: any): Promise<any> {
switch (command) {
case 'registerWindowDriver': return this.registry.registerWindowDriver(arg);
case 'reloadWindowDriver': return this.registry.reloadWindowDriver(arg);
@@ -165,25 +170,25 @@ export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry
constructor(private channel: IChannel) { }
registerWindowDriver(windowId: number): TPromise<IDriverOptions> {
return TPromise.wrap(this.channel.call('registerWindowDriver', windowId));
registerWindowDriver(windowId: number): Promise<IDriverOptions> {
return this.channel.call('registerWindowDriver', windowId);
}
reloadWindowDriver(windowId: number): TPromise<void> {
return TPromise.wrap(this.channel.call('reloadWindowDriver', windowId));
reloadWindowDriver(windowId: number): Promise<void> {
return this.channel.call('reloadWindowDriver', windowId);
}
}
export interface IWindowDriver {
click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>;
doubleClick(selector: string): TPromise<void>;
setValue(selector: string, text: string): TPromise<void>;
getTitle(): TPromise<string>;
isActiveElement(selector: string): TPromise<boolean>;
getElements(selector: string, recursive: boolean): TPromise<IElement[]>;
typeInEditor(selector: string, text: string): TPromise<void>;
getTerminalBuffer(selector: string): TPromise<string[]>;
writeInTerminal(selector: string, text: string): TPromise<void>;
click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<void>;
doubleClick(selector: string): Promise<void>;
setValue(selector: string, text: string): Promise<void>;
getTitle(): Promise<string>;
isActiveElement(selector: string): Promise<boolean>;
getElements(selector: string, recursive: boolean): Promise<IElement[]>;
typeInEditor(selector: string, text: string): Promise<void>;
getTerminalBuffer(selector: string): Promise<string[]>;
writeInTerminal(selector: string, text: string): Promise<void>;
}
export class WindowDriverChannel implements IServerChannel {
@@ -194,7 +199,7 @@ export class WindowDriverChannel implements IServerChannel {
throw new Error(`No event found: ${event}`);
}
call(_, command: string, arg?: any): Thenable<any> {
call(_, command: string, arg?: any): Promise<any> {
switch (command) {
case 'click': return this.driver.click(arg[0], arg[1], arg[2]);
case 'doubleClick': return this.driver.doubleClick(arg);
@@ -217,40 +222,40 @@ export class WindowDriverChannelClient implements IWindowDriver {
constructor(private channel: IChannel) { }
click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
return TPromise.wrap(this.channel.call('click', [selector, xoffset, yoffset]));
click(selector: string, xoffset?: number, yoffset?: number): Promise<void> {
return this.channel.call('click', [selector, xoffset, yoffset]);
}
doubleClick(selector: string): TPromise<void> {
return TPromise.wrap(this.channel.call('doubleClick', selector));
doubleClick(selector: string): Promise<void> {
return this.channel.call('doubleClick', selector);
}
setValue(selector: string, text: string): TPromise<void> {
return TPromise.wrap(this.channel.call('setValue', [selector, text]));
setValue(selector: string, text: string): Promise<void> {
return this.channel.call('setValue', [selector, text]);
}
getTitle(): TPromise<string> {
return TPromise.wrap(this.channel.call('getTitle'));
getTitle(): Promise<string> {
return this.channel.call('getTitle');
}
isActiveElement(selector: string): TPromise<boolean> {
return TPromise.wrap(this.channel.call('isActiveElement', selector));
isActiveElement(selector: string): Promise<boolean> {
return this.channel.call('isActiveElement', selector);
}
getElements(selector: string, recursive: boolean): TPromise<IElement[]> {
return TPromise.wrap(this.channel.call('getElements', [selector, recursive]));
getElements(selector: string, recursive: boolean): Promise<IElement[]> {
return this.channel.call('getElements', [selector, recursive]);
}
typeInEditor(selector: string, text: string): TPromise<void> {
return TPromise.wrap(this.channel.call('typeInEditor', [selector, text]));
typeInEditor(selector: string, text: string): Promise<void> {
return this.channel.call('typeInEditor', [selector, text]);
}
getTerminalBuffer(selector: string): TPromise<string[]> {
return TPromise.wrap(this.channel.call('getTerminalBuffer', selector));
getTerminalBuffer(selector: string): Promise<string[]> {
return this.channel.call('getTerminalBuffer', selector);
}
writeInTerminal(selector: string, text: string): TPromise<void> {
return TPromise.wrap(this.channel.call('writeInTerminal', [selector, text]));
writeInTerminal(selector: string, text: string): Promise<void> {
return this.channel.call('writeInTerminal', [selector, text]);
}
}