Skip to content

Commit fc0774e

Browse files
committed
typeInEditor API
1 parent 7bd69c0 commit fc0774e

7 files changed

Lines changed: 65 additions & 23 deletions

File tree

src/vs/platform/driver/common/driver.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export interface IDriver {
3333
getTitle(windowId: number): TPromise<string>;
3434
isActiveElement(windowId: number, selector: string): TPromise<boolean>;
3535
getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]>;
36+
typeInEditor(windowId: number, selector: string, text: string): TPromise<void>;
3637
selectorExecute<P>(windowId: number, selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P>;
3738
}
3839
//*END
@@ -47,6 +48,7 @@ export interface IDriverChannel extends IChannel {
4748
call(command: 'getTitle', arg: [number]): TPromise<string>;
4849
call(command: 'isActiveElement', arg: [number, string]): TPromise<boolean>;
4950
call(command: 'getElements', arg: [number, string, boolean]): TPromise<IElement[]>;
51+
call(command: 'typeInEditor', arg: [number, string, string]): TPromise<void>;
5052
call(command: 'selectorExecute', arg: [number, string, string, any[]]): TPromise<any>;
5153
call(command: string, arg: any): TPromise<any>;
5254
}
@@ -66,6 +68,7 @@ export class DriverChannel implements IDriverChannel {
6668
case 'getTitle': return this.driver.getTitle(arg[0]);
6769
case 'isActiveElement': return this.driver.isActiveElement(arg[0], arg[1]);
6870
case 'getElements': return this.driver.getElements(arg[0], arg[1], arg[2]);
71+
case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1], arg[2]);
6972

7073
// TODO@joao
7174
case 'selectorExecute': return this.driver.selectorExecute(arg[0], arg[1], arg[1], ...arg[2]);
@@ -117,6 +120,10 @@ export class DriverChannelClient implements IDriver {
117120
return this.channel.call('getElements', [windowId, selector, recursive]);
118121
}
119122

123+
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
124+
return this.channel.call('typeInEditor', [windowId, selector, text]);
125+
}
126+
120127
selectorExecute<P>(windowId: number, selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P> {
121128
// TODO@joao
122129
return this.channel.call('selectorExecute', [windowId, selector, script.toString(), args]);
@@ -164,6 +171,7 @@ export interface IWindowDriver {
164171
getTitle(): TPromise<string>;
165172
isActiveElement(selector: string): TPromise<boolean>;
166173
getElements(selector: string, recursive: boolean): TPromise<IElement[]>;
174+
typeInEditor(selector: string, text: string): TPromise<void>;
167175
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P>;
168176
}
169177

@@ -175,6 +183,7 @@ export interface IWindowDriverChannel extends IChannel {
175183
call(command: 'getTitle'): TPromise<string>;
176184
call(command: 'isActiveElement', arg: string): TPromise<boolean>;
177185
call(command: 'getElements', arg: [string, boolean]): TPromise<IElement[]>;
186+
call(command: 'typeInEditor', arg: [string, string]): TPromise<void>;
178187
call(command: 'selectorExecute', arg: [string, string, any[]]): TPromise<any>;
179188
call(command: string, arg: any): TPromise<any>;
180189
}
@@ -192,6 +201,7 @@ export class WindowDriverChannel implements IWindowDriverChannel {
192201
case 'getTitle': return this.driver.getTitle();
193202
case 'isActiveElement': return this.driver.isActiveElement(arg);
194203
case 'getElements': return this.driver.getElements(arg[0], arg[1]);
204+
case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1]);
195205
// TODO@joao
196206
case 'selectorExecute': return this.driver.selectorExecute(arg[0], arg[1], ...arg[2]);
197207
}
@@ -234,6 +244,10 @@ export class WindowDriverChannelClient implements IWindowDriver {
234244
return this.channel.call('getElements', [selector, recursive]);
235245
}
236246

247+
typeInEditor(selector: string, text: string): TPromise<void> {
248+
return this.channel.call('typeInEditor', [selector, text]);
249+
}
250+
237251
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P> {
238252
// TODO@joao
239253
return this.channel.call('selectorExecute', [selector, script.toString(), args]);

src/vs/platform/driver/electron-browser/driver.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,29 @@ class WindowDriver implements IWindowDriver {
8787
return result;
8888
}
8989

90+
async typeInEditor(selector: string, text: string): TPromise<void> {
91+
const element = document.querySelector(selector);
92+
93+
if (!element) {
94+
throw new Error('Editor not found: ' + selector);
95+
}
96+
97+
const textarea = element as HTMLTextAreaElement;
98+
99+
console.log(textarea);
100+
101+
const start = textarea.selectionStart;
102+
const newStart = start + text.length;
103+
const value = textarea.value;
104+
const newValue = value.substr(0, start) + text + value.substr(start);
105+
106+
textarea.value = newValue;
107+
textarea.setSelectionRange(newStart, newStart);
108+
109+
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
110+
textarea.dispatchEvent(event);
111+
}
112+
90113
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): TPromise<P> {
91114
return TPromise.wrapError(new Error('not implemented'));
92115
}

src/vs/platform/driver/electron-main/driver.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ export class Driver implements IDriver, IWindowDriverRegistry {
137137
return windowDriver.selectorExecute(selector, script, ...args);
138138
}
139139

140+
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
141+
const windowDriver = this.getWindowDriver(windowId);
142+
return windowDriver.typeInEditor(selector, text);
143+
}
144+
140145
private getWindowDriver(windowId: number): IWindowDriver {
141146
const router = new WindowRouter(windowId);
142147
const windowDriverChannel = this.windowServer.getChannel<IWindowDriverChannel>('windowDriver', router);

test/smoke/src/api.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ export class API {
8080
return this.driver.selectorExecute(selector, script, ...args);
8181
}
8282

83+
typeInEditor(selector: string, text: string): Promise<void> {
84+
return this.driver.typeInEditor(selector, text);
85+
}
86+
8387
private running = false;
8488
async waitFor<T>(func: () => T | Promise<T | undefined>, accept?: (result: T) => boolean | Promise<boolean>, timeoutMessage?: string, retryCount?: number): Promise<T>;
8589
async waitFor<T>(func: () => T | Promise<T>, accept: (result: T) => boolean | Promise<boolean> = result => !!result, timeoutMessage?: string, retryCount?: number): Promise<T> {

test/smoke/src/areas/editor/editor.ts

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { API } from '../../api';
99

1010
const RENAME_BOX = '.monaco-editor .monaco-editor.rename-box';
1111
const RENAME_INPUT = `${RENAME_BOX} .rename-input`;
12+
const EDITOR = filename => `.monaco-editor[data-uri$="${filename}"]`;
1213

1314
export class Editor {
1415

@@ -87,39 +88,20 @@ export class Editor {
8788
}
8889

8990
async waitForTypeInEditor(filename: string, text: string, selectorPrefix = ''): Promise<any> {
90-
const editor = [
91-
selectorPrefix || '',
92-
`.monaco-editor[data-uri$="${filename}"]`
93-
].join(' ');
91+
const editor = [selectorPrefix || '', EDITOR(filename)].join(' ');
9492

9593
await this.api.waitForElement(editor);
9694

9795
const textarea = `${editor} textarea`;
9896
await this.api.waitForActiveElement(textarea);
9997

100-
// https://github.com/Microsoft/vscode/issues/34203#issuecomment-334441786
101-
await this.api.selectorExecute(textarea, (elements, text) => {
102-
const textarea = (Array.isArray(elements) ? elements : [elements])[0] as HTMLTextAreaElement;
103-
const start = textarea.selectionStart;
104-
const newStart = start + text.length;
105-
const value = textarea.value;
106-
const newValue = value.substr(0, start) + text + value.substr(start);
107-
108-
textarea.value = newValue;
109-
textarea.setSelectionRange(newStart, newStart);
110-
111-
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
112-
textarea.dispatchEvent(event);
113-
}, text);
98+
await this.api.typeInEditor(textarea, text);
11499

115100
await this.waitForEditorContents(filename, c => c.indexOf(text) > -1, selectorPrefix);
116101
}
117102

118103
async waitForEditorContents(filename: string, accept: (contents: string) => boolean, selectorPrefix = ''): Promise<any> {
119-
const selector = [
120-
selectorPrefix || '',
121-
`.monaco-editor[data-uri$="${filename}"] .view-lines`
122-
].join(' ');
104+
const selector = [selectorPrefix || '', `${EDITOR(filename)} .view-lines`].join(' ');
123105

124106
return this.api.waitForTextContent(selector, undefined, c => accept(c.replace(/\u00a0/g, ' ')));
125107
}

test/smoke/src/driver.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface Driver {
2323

2424
isActiveElement(selector: string): Promise<boolean>;
2525
getElements(selector: string, recursive?: boolean): Promise<Element[]>;
26+
typeInEditor(selector: string, text: string): Promise<void>;
2627
selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): Promise<P>;
2728
}
2829

@@ -116,6 +117,10 @@ export class SpectronDriver implements Driver {
116117
return result.value;
117118
}
118119

120+
typeInEditor(selector: string, text: string): Promise<void> {
121+
throw new Error('Method not implemented.');
122+
}
123+
119124
async selectorExecute<P>(selector: string, script: (elements: HTMLElement[], ...args: any[]) => P, ...args: any[]): Promise<P> {
120125
if (this.verbose) {
121126
console.log('- selectorExecute:', selector);
@@ -217,6 +222,15 @@ export class CodeDriver implements Driver {
217222
return await this.driver.selectorExecute(windowId, selector, script, ...args);
218223
}
219224

225+
async typeInEditor(selector: string, text: string): Promise<void> {
226+
if (this.verbose) {
227+
console.log('- typeInEditor:', selector, text);
228+
}
229+
230+
const windowId = await this.getWindowId();
231+
return await this.driver.typeInEditor(windowId, selector, text);
232+
}
233+
220234
private async getWindowId(): Promise<number> {
221235
if (typeof this._activeWindowId !== 'number') {
222236
const windows = await this.driver.getWindowIds();

test/smoke/test/mocha.opts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
--timeout 10000
1+
--timeout 20000
22
--slow 2000
33
out/main.js

0 commit comments

Comments
 (0)