Merge from vscode 1ce89e2cb720d69c496c2815c4696ee4fd4429a6 (#6779)

* Merge from vscode 1ce89e2cb720d69c496c2815c4696ee4fd4429a6

* redisable accounts because of issues
This commit is contained in:
Anthony Dresser
2019-08-15 23:56:46 -07:00
committed by GitHub
parent fb4e3c6a05
commit 6f297efb88
166 changed files with 1941 additions and 1279 deletions

View File

@@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom';
import { coalesce } from 'vs/base/common/arrays';
import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver';
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);
if (attr) {
attributes[attr.name] = attr.value;
}
}
const children: IElement[] = [];
if (recursive) {
for (let i = 0; i < element.children.length; i++) {
const child = element.children.item(i);
if (child) {
children.push(serializeElement(child, true));
}
}
}
const { left, top } = getTopLeftOffset(element as HTMLElement);
return {
tagName: element.tagName,
className: element.className,
textContent: element.textContent || '',
attributes,
children,
left,
top
};
}
export abstract class BaseWindowDriver implements IWindowDriver {
constructor() { }
abstract click(selector: string, xoffset?: number, yoffset?: number): Promise<void>;
abstract doubleClick(selector: string): Promise<void>;
async setValue(selector: string, text: string): Promise<void> {
const element = document.querySelector(selector);
if (!element) {
return Promise.reject(new Error(`Element not found: ${selector}`));
}
const inputElement = element as HTMLInputElement;
inputElement.value = text;
const event = new Event('input', { bubbles: true, cancelable: true });
inputElement.dispatchEvent(event);
}
async getTitle(): Promise<string> {
return document.title;
}
async isActiveElement(selector: string): Promise<boolean> {
const element = document.querySelector(selector);
if (element !== document.activeElement) {
const chain: string[] = [];
let el = document.activeElement;
while (el) {
const tagName = el.tagName;
const id = el.id ? `#${el.id}` : '';
const classes = coalesce(el.className.split(/\s+/g).map(c => c.trim())).map(c => `.${c}`).join('');
chain.unshift(`${tagName}${id}${classes}`);
el = el.parentElement;
}
throw new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`);
}
return true;
}
async getElements(selector: string, recursive: boolean): Promise<IElement[]> {
const query = document.querySelectorAll(selector);
const result: IElement[] = [];
for (let i = 0; i < query.length; i++) {
const element = query.item(i);
result.push(serializeElement(element, recursive));
}
return result;
}
async getElementXY(selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }> {
const offset = typeof xoffset === 'number' && typeof yoffset === 'number' ? { x: xoffset, y: yoffset } : undefined;
return this._getElementXY(selector, offset);
}
async typeInEditor(selector: string, text: string): Promise<void> {
const element = document.querySelector(selector);
if (!element) {
throw new Error(`Editor not found: ${selector}`);
}
const textarea = element 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);
}
async getTerminalBuffer(selector: string): Promise<string[]> {
const element = document.querySelector(selector);
if (!element) {
throw new Error(`Terminal not found: ${selector}`);
}
const xterm = (element as any).xterm;
if (!xterm) {
throw new Error(`Xterm not found: ${selector}`);
}
const lines: string[] = [];
for (let i = 0; i < xterm.buffer.length; i++) {
lines.push(xterm.buffer.getLine(i)!.translateToString(true));
}
return lines;
}
async writeInTerminal(selector: string, text: string): Promise<void> {
const element = document.querySelector(selector);
if (!element) {
throw new Error(`Element not found: ${selector}`);
}
const xterm = (element as any).xterm;
if (!xterm) {
throw new Error(`Xterm not found: ${selector}`);
}
xterm._core._coreService.triggerDataEvent(text);
}
protected async _getElementXY(selector: string, offset?: { x: number, y: number }): Promise<{ x: number; y: number; }> {
const element = document.querySelector(selector);
if (!element) {
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 (offset) {
x = left + offset.x;
y = top + offset.y;
} else {
x = left + (width / 2);
y = top + (height / 2);
}
x = Math.round(x);
y = Math.round(y);
return { x, y };
}
abstract async openDevTools(): Promise<void>;
}

View File

@@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { BaseWindowDriver } from 'vs/platform/driver/browser/baseDriver';
class BrowserWindowDriver extends BaseWindowDriver {
click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise<void> {
throw new Error('Method not implemented.');
}
doubleClick(selector: string): Promise<void> {
throw new Error('Method not implemented.');
}
openDevTools(): Promise<void> {
throw new Error('Method not implemented.');
}
}
export async function registerWindowDriver(): Promise<IDisposable> {
(<any>window).driver = new BrowserWindowDriver();
return toDisposable(() => {
return { dispose: () => { } };
});
}