提交 6a47ecce 编写于 作者: J Joao Moreno

green extensions tests

上级 d18d3012
...@@ -131,10 +131,12 @@ export class DriverChannelClient implements IDriver { ...@@ -131,10 +131,12 @@ export class DriverChannelClient implements IDriver {
export interface IWindowDriverRegistry { export interface IWindowDriverRegistry {
registerWindowDriver(windowId: number): TPromise<void>; registerWindowDriver(windowId: number): TPromise<void>;
reloadWindowDriver(windowId: number): TPromise<void>;
} }
export interface IWindowDriverRegistryChannel extends IChannel { export interface IWindowDriverRegistryChannel extends IChannel {
call(command: 'registerWindowDriver', arg: number): TPromise<void>; call(command: 'registerWindowDriver', arg: number): TPromise<void>;
call(command: 'reloadWindowDriver', arg: number): TPromise<void>;
call(command: string, arg: any): TPromise<any>; call(command: string, arg: any): TPromise<any>;
} }
...@@ -145,6 +147,7 @@ export class WindowDriverRegistryChannel implements IWindowDriverRegistryChannel ...@@ -145,6 +147,7 @@ export class WindowDriverRegistryChannel implements IWindowDriverRegistryChannel
call(command: string, arg?: any): TPromise<any> { call(command: string, arg?: any): TPromise<any> {
switch (command) { switch (command) {
case 'registerWindowDriver': return this.registry.registerWindowDriver(arg); case 'registerWindowDriver': return this.registry.registerWindowDriver(arg);
case 'reloadWindowDriver': return this.registry.reloadWindowDriver(arg);
} }
return undefined; return undefined;
...@@ -160,6 +163,10 @@ export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry ...@@ -160,6 +163,10 @@ export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry
registerWindowDriver(windowId: number): TPromise<void> { registerWindowDriver(windowId: number): TPromise<void> {
return this.channel.call('registerWindowDriver', windowId); return this.channel.call('registerWindowDriver', windowId);
} }
reloadWindowDriver(windowId: number): TPromise<void> {
return this.channel.call('reloadWindowDriver', windowId);
}
} }
export interface IWindowDriver { export interface IWindowDriver {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
'use strict'; 'use strict';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable } from 'vs/base/common/lifecycle'; import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/common/driver'; import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/common/driver';
import { IPCClient } from 'vs/base/parts/ipc/common/ipc'; import { IPCClient } from 'vs/base/parts/ipc/common/ipc';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
...@@ -180,5 +180,6 @@ export async function registerWindowDriver( ...@@ -180,5 +180,6 @@ export async function registerWindowDriver(
await windowDriverRegistry.registerWindowDriver(windowId); await windowDriverRegistry.registerWindowDriver(windowId);
return client; const disposable = toDisposable(() => windowDriverRegistry.reloadWindowDriver(windowId));
return combinedDisposable([disposable, client]);
} }
\ No newline at end of file
...@@ -15,6 +15,7 @@ import { IPCServer, IClientRouter } from 'vs/base/parts/ipc/common/ipc'; ...@@ -15,6 +15,7 @@ import { IPCServer, IClientRouter } from 'vs/base/parts/ipc/common/ipc';
import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes'; import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
import { OS } from 'vs/base/common/platform'; import { OS } from 'vs/base/common/platform';
import { Emitter, toPromise } from 'vs/base/common/event';
// TODO@joao: bad layering! // TODO@joao: bad layering!
import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO';
...@@ -38,24 +39,33 @@ export class Driver implements IDriver, IWindowDriverRegistry { ...@@ -38,24 +39,33 @@ export class Driver implements IDriver, IWindowDriverRegistry {
_serviceBrand: any; _serviceBrand: any;
private registeredWindowIds = new Set<number>(); private registeredWindowIds = new Set<number>();
private reloadingWindowIds = new Set<number>();
private onDidReloadingChange = new Emitter<void>();
constructor( constructor(
private windowServer: IPCServer, private windowServer: IPCServer,
@IWindowsMainService private windowsService: IWindowsMainService @IWindowsMainService private windowsService: IWindowsMainService
) { } ) { }
registerWindowDriver(windowId: number): TPromise<void> { async registerWindowDriver(windowId: number): TPromise<void> {
this.registeredWindowIds.add(windowId); this.registeredWindowIds.add(windowId);
return TPromise.as(null); this.reloadingWindowIds.delete(windowId);
this.onDidReloadingChange.fire();
}
async reloadWindowDriver(windowId: number): TPromise<void> {
this.reloadingWindowIds.add(windowId);
} }
async getWindowIds(): TPromise<number[]> { async getWindowIds(): TPromise<number[]> {
return this.windowsService.getWindows() return this.windowsService.getWindows()
.map(w => w.id) .map(w => w.id)
.filter(id => this.registeredWindowIds.has(id)); .filter(id => this.registeredWindowIds.has(id) && !this.reloadingWindowIds.has(id));
} }
async dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> { async dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> {
await this.whenUnfrozen(windowId);
const [first, second] = KeybindingIO._readUserBinding(keybinding); const [first, second] = KeybindingIO._readUserBinding(keybinding);
await this._dispatchKeybinding(windowId, first); await this._dispatchKeybinding(windowId, first);
...@@ -105,56 +115,64 @@ export class Driver implements IDriver, IWindowDriverRegistry { ...@@ -105,56 +115,64 @@ export class Driver implements IDriver, IWindowDriverRegistry {
await TPromise.timeout(100); await TPromise.timeout(100);
} }
click(windowId: number, selector: string, xoffset?: number, yoffset?: number): TPromise<void> { async click(windowId: number, selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.click(selector, xoffset, yoffset); return windowDriver.click(selector, xoffset, yoffset);
} }
doubleClick(windowId: number, selector: string): TPromise<void> { async doubleClick(windowId: number, selector: string): TPromise<void> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.doubleClick(selector); return windowDriver.doubleClick(selector);
} }
move(windowId: number, selector: string): TPromise<void> { async move(windowId: number, selector: string): TPromise<void> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.move(selector); return windowDriver.move(selector);
} }
setValue(windowId: number, selector: string, text: string): TPromise<void> { async setValue(windowId: number, selector: string, text: string): TPromise<void> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.setValue(selector, text); return windowDriver.setValue(selector, text);
} }
getTitle(windowId: number): TPromise<string> { async getTitle(windowId: number): TPromise<string> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.getTitle(); return windowDriver.getTitle();
} }
isActiveElement(windowId: number, selector: string): TPromise<boolean> { async isActiveElement(windowId: number, selector: string): TPromise<boolean> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.isActiveElement(selector); return windowDriver.isActiveElement(selector);
} }
getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> { async getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.getElements(selector, recursive); return windowDriver.getElements(selector, recursive);
} }
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> { async typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.typeInEditor(selector, text); return windowDriver.typeInEditor(selector, text);
} }
getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> { async getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> {
const windowDriver = this.getWindowDriver(windowId); const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.getTerminalBuffer(selector); return windowDriver.getTerminalBuffer(selector);
} }
private getWindowDriver(windowId: number): IWindowDriver { private async getWindowDriver(windowId: number): TPromise<IWindowDriver> {
await this.whenUnfrozen(windowId);
const router = new WindowRouter(windowId); const router = new WindowRouter(windowId);
const windowDriverChannel = this.windowServer.getChannel<IWindowDriverChannel>('windowDriver', router); const windowDriverChannel = this.windowServer.getChannel<IWindowDriverChannel>('windowDriver', router);
return new WindowDriverChannelClient(windowDriverChannel); return new WindowDriverChannelClient(windowDriverChannel);
} }
private async whenUnfrozen(windowId: number): TPromise<void> {
while (this.reloadingWindowIds.has(windowId)) {
await toPromise(this.onDidReloadingChange.event);
}
}
} }
export async function serve( export async function serve(
......
...@@ -120,8 +120,10 @@ export class SpectronApplication { ...@@ -120,8 +120,10 @@ export class SpectronApplication {
} }
async reload(): Promise<any> { async reload(): Promise<any> {
await this.workbench.runCommand('Reload Window'); this.workbench.runCommand('Reload Window')
// TODO @sandy: Find a proper condition to wait for reload .catch(err => null); // ignore the connection drop errors
// needs to be enough to propagate the 'Reload Window' command
await new Promise(c => setTimeout(c, 1500)); await new Promise(c => setTimeout(c, 1500));
await this.checkWindowReady(); await this.checkWindowReady();
} }
...@@ -278,7 +280,7 @@ export class SpectronApplication { ...@@ -278,7 +280,7 @@ export class SpectronApplication {
let retries = 0; let retries = 0;
while (++retries < 50) { while (++retries < 300) { // 30 seconds
const ids = await this.codeInstance.driver.getWindowIds(); const ids = await this.codeInstance.driver.getWindowIds();
if (ids.length > 0) { if (ids.length > 0) {
......
...@@ -30,14 +30,10 @@ export class Extensions extends Viewlet { ...@@ -30,14 +30,10 @@ export class Extensions extends Viewlet {
await this.api.setValue(SEARCH_BOX, name); await this.api.setValue(SEARCH_BOX, name);
} }
async installExtension(name: string): Promise<boolean> { async installExtension(name: string): Promise<void> {
await this.searchForExtension(name); await this.searchForExtension(name);
// we might want to wait for a while longer since the Marketplace can be slow await this.api.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${name}"] .extension li[class='action-item'] .extension-action.install`);
// a minute should do
await this.api.waitFor(() => this.api.waitAndClick(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${name}"] .extension li[class='action-item'] .extension-action.install`), void 0, 'waiting for install button', 600);
await this.api.waitForElement(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${name}"] .extension li[class='action-item'] .extension-action.reload`); await this.api.waitForElement(`div.extensions-viewlet[id="workbench.view.extensions"] .monaco-list-row[aria-label="${name}"] .extension li[class='action-item'] .extension-action.reload`);
return true;
} }
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册