mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 05:28:19 -05:00
typeInEditor API
This commit is contained in:
@@ -33,6 +33,7 @@ export interface IDriver {
|
||||
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>;
|
||||
selectorExecute<P>(windowId: number, selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P>;
|
||||
}
|
||||
//*END
|
||||
@@ -47,6 +48,7 @@ export interface IDriverChannel extends IChannel {
|
||||
call(command: 'getTitle', arg: [number]): TPromise<string>;
|
||||
call(command: 'isActiveElement', arg: [number, string]): TPromise<boolean>;
|
||||
call(command: 'getElements', arg: [number, string, boolean]): TPromise<IElement[]>;
|
||||
call(command: 'typeInEditor', arg: [number, string, string]): TPromise<void>;
|
||||
call(command: 'selectorExecute', arg: [number, string, string, any[]]): TPromise<any>;
|
||||
call(command: string, arg: any): TPromise<any>;
|
||||
}
|
||||
@@ -66,6 +68,7 @@ export class DriverChannel implements IDriverChannel {
|
||||
case 'getTitle': return this.driver.getTitle(arg[0]);
|
||||
case 'isActiveElement': return this.driver.isActiveElement(arg[0], arg[1]);
|
||||
case 'getElements': return this.driver.getElements(arg[0], arg[1], arg[2]);
|
||||
case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1], arg[2]);
|
||||
|
||||
// TODO@joao
|
||||
case 'selectorExecute': return this.driver.selectorExecute(arg[0], arg[1], arg[1], ...arg[2]);
|
||||
@@ -117,6 +120,10 @@ export class DriverChannelClient implements IDriver {
|
||||
return this.channel.call('getElements', [windowId, selector, recursive]);
|
||||
}
|
||||
|
||||
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
|
||||
return this.channel.call('typeInEditor', [windowId, selector, text]);
|
||||
}
|
||||
|
||||
selectorExecute<P>(windowId: number, selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P> {
|
||||
// TODO@joao
|
||||
return this.channel.call('selectorExecute', [windowId, selector, script.toString(), args]);
|
||||
@@ -164,6 +171,7 @@ export interface IWindowDriver {
|
||||
getTitle(): TPromise<string>;
|
||||
isActiveElement(selector: string): TPromise<boolean>;
|
||||
getElements(selector: string, recursive: boolean): TPromise<IElement[]>;
|
||||
typeInEditor(selector: string, text: string): TPromise<void>;
|
||||
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P>;
|
||||
}
|
||||
|
||||
@@ -175,6 +183,7 @@ export interface IWindowDriverChannel extends IChannel {
|
||||
call(command: 'getTitle'): TPromise<string>;
|
||||
call(command: 'isActiveElement', arg: string): TPromise<boolean>;
|
||||
call(command: 'getElements', arg: [string, boolean]): TPromise<IElement[]>;
|
||||
call(command: 'typeInEditor', arg: [string, string]): TPromise<void>;
|
||||
call(command: 'selectorExecute', arg: [string, string, any[]]): TPromise<any>;
|
||||
call(command: string, arg: any): TPromise<any>;
|
||||
}
|
||||
@@ -192,6 +201,7 @@ export class WindowDriverChannel implements IWindowDriverChannel {
|
||||
case 'getTitle': return this.driver.getTitle();
|
||||
case 'isActiveElement': return this.driver.isActiveElement(arg);
|
||||
case 'getElements': return this.driver.getElements(arg[0], arg[1]);
|
||||
case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1]);
|
||||
// TODO@joao
|
||||
case 'selectorExecute': return this.driver.selectorExecute(arg[0], arg[1], ...arg[2]);
|
||||
}
|
||||
@@ -234,6 +244,10 @@ export class WindowDriverChannelClient implements IWindowDriver {
|
||||
return this.channel.call('getElements', [selector, recursive]);
|
||||
}
|
||||
|
||||
typeInEditor(selector: string, text: string): TPromise<void> {
|
||||
return this.channel.call('typeInEditor', [selector, text]);
|
||||
}
|
||||
|
||||
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P> {
|
||||
// TODO@joao
|
||||
return this.channel.call('selectorExecute', [selector, script.toString(), args]);
|
||||
|
||||
@@ -87,6 +87,29 @@ class WindowDriver implements IWindowDriver {
|
||||
return result;
|
||||
}
|
||||
|
||||
async typeInEditor(selector: string, text: string): TPromise<void> {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Editor not found: ' + selector);
|
||||
}
|
||||
|
||||
const textarea = element as HTMLTextAreaElement;
|
||||
|
||||
console.log(textarea);
|
||||
|
||||
const start = textarea.selectionStart;
|
||||
const newStart = start + text.length;
|
||||
const value = textarea.value;
|
||||
const newValue = value.substr(0, start) + text + value.substr(start);
|
||||
|
||||
textarea.value = newValue;
|
||||
textarea.setSelectionRange(newStart, newStart);
|
||||
|
||||
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
|
||||
textarea.dispatchEvent(event);
|
||||
}
|
||||
|
||||
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P> {
|
||||
return TPromise.wrapError(new Error('not implemented'));
|
||||
}
|
||||
|
||||
@@ -137,6 +137,11 @@ export class Driver implements IDriver, IWindowDriverRegistry {
|
||||
return windowDriver.selectorExecute(selector, script, ...args);
|
||||
}
|
||||
|
||||
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
|
||||
const windowDriver = this.getWindowDriver(windowId);
|
||||
return windowDriver.typeInEditor(selector, text);
|
||||
}
|
||||
|
||||
private getWindowDriver(windowId: number): IWindowDriver {
|
||||
const router = new WindowRouter(windowId);
|
||||
const windowDriverChannel = this.windowServer.getChannel<IWindowDriverChannel>('windowDriver', router);
|
||||
|
||||
@@ -80,6 +80,10 @@ export class API {
|
||||
return this.driver.selectorExecute(selector, script, ...args);
|
||||
}
|
||||
|
||||
typeInEditor(selector: string, text: string): Promise<void> {
|
||||
return this.driver.typeInEditor(selector, text);
|
||||
}
|
||||
|
||||
private running = false;
|
||||
async waitFor<T>(func: () => T | Promise<T | undefined>, accept?: (result: T) => boolean | Promise<boolean>, timeoutMessage?: string, retryCount?: number): Promise<T>;
|
||||
async waitFor<T>(func: () => T | Promise<T>, accept: (result: T) => boolean | Promise<boolean> = result => !!result, timeoutMessage?: string, retryCount?: number): Promise<T> {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { API } from '../../api';
|
||||
|
||||
const RENAME_BOX = '.monaco-editor .monaco-editor.rename-box';
|
||||
const RENAME_INPUT = `${RENAME_BOX} .rename-input`;
|
||||
const EDITOR = filename => `.monaco-editor[data-uri$="${filename}"]`;
|
||||
|
||||
export class Editor {
|
||||
|
||||
@@ -87,39 +88,20 @@ export class Editor {
|
||||
}
|
||||
|
||||
async waitForTypeInEditor(filename: string, text: string, selectorPrefix = ''): Promise<any> {
|
||||
const editor = [
|
||||
selectorPrefix || '',
|
||||
`.monaco-editor[data-uri$="${filename}"]`
|
||||
].join(' ');
|
||||
const editor = [selectorPrefix || '', EDITOR(filename)].join(' ');
|
||||
|
||||
await this.api.waitForElement(editor);
|
||||
|
||||
const textarea = `${editor} textarea`;
|
||||
await this.api.waitForActiveElement(textarea);
|
||||
|
||||
// https://github.com/Microsoft/vscode/issues/34203#issuecomment-334441786
|
||||
await this.api.selectorExecute(textarea, (elements, text) => {
|
||||
const textarea = (Array.isArray(elements) ? elements : [elements])[0] as HTMLTextAreaElement;
|
||||
const start = textarea.selectionStart;
|
||||
const newStart = start + text.length;
|
||||
const value = textarea.value;
|
||||
const newValue = value.substr(0, start) + text + value.substr(start);
|
||||
|
||||
textarea.value = newValue;
|
||||
textarea.setSelectionRange(newStart, newStart);
|
||||
|
||||
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
|
||||
textarea.dispatchEvent(event);
|
||||
}, text);
|
||||
await this.api.typeInEditor(textarea, text);
|
||||
|
||||
await this.waitForEditorContents(filename, c => c.indexOf(text) > -1, selectorPrefix);
|
||||
}
|
||||
|
||||
async waitForEditorContents(filename: string, accept: (contents: string) => boolean, selectorPrefix = ''): Promise<any> {
|
||||
const selector = [
|
||||
selectorPrefix || '',
|
||||
`.monaco-editor[data-uri$="${filename}"] .view-lines`
|
||||
].join(' ');
|
||||
const selector = [selectorPrefix || '', `${EDITOR(filename)} .view-lines`].join(' ');
|
||||
|
||||
return this.api.waitForTextContent(selector, undefined, c => accept(c.replace(/\u00a0/g, ' ')));
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface Driver {
|
||||
|
||||
isActiveElement(selector: string): Promise<boolean>;
|
||||
getElements(selector: string, recursive?: boolean): Promise<Element[]>;
|
||||
typeInEditor(selector: string, text: string): Promise<void>;
|
||||
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): Promise<P>;
|
||||
}
|
||||
|
||||
@@ -116,6 +117,10 @@ export class SpectronDriver implements Driver {
|
||||
return result.value;
|
||||
}
|
||||
|
||||
typeInEditor(selector: string, text: string): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
async selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): Promise<P> {
|
||||
if (this.verbose) {
|
||||
console.log('- selectorExecute:', selector);
|
||||
@@ -217,6 +222,15 @@ export class CodeDriver implements Driver {
|
||||
return await this.driver.selectorExecute(windowId, selector, script, ...args);
|
||||
}
|
||||
|
||||
async typeInEditor(selector: string, text: string): Promise<void> {
|
||||
if (this.verbose) {
|
||||
console.log('- typeInEditor:', selector, text);
|
||||
}
|
||||
|
||||
const windowId = await this.getWindowId();
|
||||
return await this.driver.typeInEditor(windowId, selector, text);
|
||||
}
|
||||
|
||||
private async getWindowId(): Promise<number> {
|
||||
if (typeof this._activeWindowId !== 'number') {
|
||||
const windows = await this.driver.getWindowIds();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
--timeout 10000
|
||||
--timeout 20000
|
||||
--slow 2000
|
||||
out/main.js
|
||||
Reference in New Issue
Block a user