mirror of
https://github.com/Microsoft/vscode
synced 2024-07-17 02:57:19 +00:00
This commit is contained in:
parent
75dee28a6d
commit
5eba2f631f
|
@ -6,11 +6,39 @@
|
||||||
import { getClientArea, getTopLeftOffset } from 'vs/base/browser/dom';
|
import { getClientArea, getTopLeftOffset } from 'vs/base/browser/dom';
|
||||||
import { coalesce } from 'vs/base/common/arrays';
|
import { coalesce } from 'vs/base/common/arrays';
|
||||||
import { language, locale } from 'vs/base/common/platform';
|
import { language, locale } from 'vs/base/common/platform';
|
||||||
import { IElement, ILocaleInfo, ILocalizedStrings, IWindowDriver } from 'vs/platform/driver/common/driver';
|
import { IElement, ILocaleInfo, ILocalizedStrings, ILogFile, IWindowDriver } from 'vs/platform/driver/common/driver';
|
||||||
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import localizedStrings from 'vs/platform/languagePacks/common/localizedStrings';
|
import localizedStrings from 'vs/platform/languagePacks/common/localizedStrings';
|
||||||
|
|
||||||
export class BrowserWindowDriver implements IWindowDriver {
|
export class BrowserWindowDriver implements IWindowDriver {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@IFileService private readonly fileService: IFileService,
|
||||||
|
@IEnvironmentService private readonly environmentService: IEnvironmentService
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
async getLogs(): Promise<ILogFile[]> {
|
||||||
|
const result: ILogFile[] = [];
|
||||||
|
|
||||||
|
const logs = await this.fileService.resolve(this.environmentService.logsHome);
|
||||||
|
|
||||||
|
for (const { name, isDirectory, resource } of logs.children || []) {
|
||||||
|
if (isDirectory) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const contents = (await this.fileService.readFile(resource)).value.toString();
|
||||||
|
if (contents) {
|
||||||
|
result.push({ name, contents });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
async setValue(selector: string, text: string): Promise<void> {
|
async setValue(selector: string, text: string): Promise<void> {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
|
@ -199,6 +227,6 @@ export class BrowserWindowDriver implements IWindowDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerWindowDriver(): void {
|
export function registerWindowDriver(instantiationService: IInstantiationService): void {
|
||||||
Object.assign(window, { driver: new BrowserWindowDriver() });
|
Object.assign(window, { driver: instantiationService.createInstance(BrowserWindowDriver) });
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,29 @@
|
||||||
|
|
||||||
//*START
|
//*START
|
||||||
export interface IElement {
|
export interface IElement {
|
||||||
tagName: string;
|
readonly tagName: string;
|
||||||
className: string;
|
readonly className: string;
|
||||||
textContent: string;
|
readonly textContent: string;
|
||||||
attributes: { [name: string]: string };
|
readonly attributes: { [name: string]: string };
|
||||||
children: IElement[];
|
readonly children: IElement[];
|
||||||
top: number;
|
readonly top: number;
|
||||||
left: number;
|
readonly left: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILocaleInfo {
|
export interface ILocaleInfo {
|
||||||
language: string;
|
readonly language: string;
|
||||||
locale?: string;
|
readonly locale?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILocalizedStrings {
|
export interface ILocalizedStrings {
|
||||||
open: string;
|
readonly open: string;
|
||||||
close: string;
|
readonly close: string;
|
||||||
find: string;
|
readonly find: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ILogFile {
|
||||||
|
readonly name: string;
|
||||||
|
readonly contents: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWindowDriver {
|
export interface IWindowDriver {
|
||||||
|
@ -37,6 +42,7 @@ export interface IWindowDriver {
|
||||||
writeInTerminal(selector: string, text: string): Promise<void>;
|
writeInTerminal(selector: string, text: string): Promise<void>;
|
||||||
getLocaleInfo(): Promise<ILocaleInfo>;
|
getLocaleInfo(): Promise<ILocaleInfo>;
|
||||||
getLocalizedStrings(): Promise<ILocalizedStrings>;
|
getLocalizedStrings(): Promise<ILocalizedStrings>;
|
||||||
|
getLogs(): Promise<ILogFile[]>;
|
||||||
exitApplication(): Promise<void>;
|
exitApplication(): Promise<void>;
|
||||||
}
|
}
|
||||||
//*END
|
//*END
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { BrowserWindowDriver } from 'vs/platform/driver/browser/driver';
|
import { BrowserWindowDriver } from 'vs/platform/driver/browser/driver';
|
||||||
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
|
|
||||||
interface INativeWindowDriverHelper {
|
interface INativeWindowDriverHelper {
|
||||||
exitApplication(): Promise<void>;
|
exitApplication(): Promise<void>;
|
||||||
|
@ -11,8 +14,12 @@ interface INativeWindowDriverHelper {
|
||||||
|
|
||||||
class NativeWindowDriver extends BrowserWindowDriver {
|
class NativeWindowDriver extends BrowserWindowDriver {
|
||||||
|
|
||||||
constructor(private readonly helper: INativeWindowDriverHelper) {
|
constructor(
|
||||||
super();
|
private readonly helper: INativeWindowDriverHelper,
|
||||||
|
@IFileService fileService: IFileService,
|
||||||
|
@IEnvironmentService environmentService: IEnvironmentService
|
||||||
|
) {
|
||||||
|
super(fileService, environmentService);
|
||||||
}
|
}
|
||||||
|
|
||||||
override exitApplication(): Promise<void> {
|
override exitApplication(): Promise<void> {
|
||||||
|
@ -20,6 +27,6 @@ class NativeWindowDriver extends BrowserWindowDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function registerWindowDriver(helper: INativeWindowDriverHelper): void {
|
export function registerWindowDriver(instantiationService: IInstantiationService, helper: INativeWindowDriverHelper): void {
|
||||||
Object.assign(window, { driver: new NativeWindowDriver(helper) });
|
Object.assign(window, { driver: instantiationService.createInstance(NativeWindowDriver, helper) });
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { localize } from 'vs/nls';
|
||||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||||
import { IDialogService, IPromptButton } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService, IPromptButton } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { registerWindowDriver } from 'vs/platform/driver/browser/driver';
|
import { registerWindowDriver } from 'vs/platform/driver/browser/driver';
|
||||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener';
|
import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener';
|
||||||
import { IProductService } from 'vs/platform/product/common/productService';
|
import { IProductService } from 'vs/platform/product/common/productService';
|
||||||
|
@ -36,7 +36,8 @@ export class BrowserWindow extends Disposable {
|
||||||
@ILabelService private readonly labelService: ILabelService,
|
@ILabelService private readonly labelService: ILabelService,
|
||||||
@IProductService private readonly productService: IProductService,
|
@IProductService private readonly productService: IProductService,
|
||||||
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
|
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
|
||||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
|
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||||
|
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ export class BrowserWindow extends Disposable {
|
||||||
|
|
||||||
private setupDriver(): void {
|
private setupDriver(): void {
|
||||||
if (this.environmentService.enableSmokeTestDriver) {
|
if (this.environmentService.enableSmokeTestDriver) {
|
||||||
registerWindowDriver();
|
registerWindowDriver(this.instantiationService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -795,7 +795,7 @@ export class NativeWindow extends Disposable {
|
||||||
const that = this;
|
const that = this;
|
||||||
let pendingQuit = false;
|
let pendingQuit = false;
|
||||||
|
|
||||||
registerWindowDriver({
|
registerWindowDriver(this.instantiationService, {
|
||||||
async exitApplication(): Promise<void> {
|
async exitApplication(): Promise<void> {
|
||||||
if (pendingQuit) {
|
if (pendingQuit) {
|
||||||
that.logService.info('[driver] not handling exitApplication() due to pending quit() call');
|
that.logService.info('[driver] not handling exitApplication() due to pending quit() call');
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import * as cp from 'child_process';
|
import * as cp from 'child_process';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as treekill from 'tree-kill';
|
import * as treekill from 'tree-kill';
|
||||||
import { IElement, ILocaleInfo, ILocalizedStrings } from './driver';
|
import { IElement, ILocaleInfo, ILocalizedStrings, ILogFile } from './driver';
|
||||||
import { Logger, measureAndLog } from './logger';
|
import { Logger, measureAndLog } from './logger';
|
||||||
import { launch as launchPlaywrightBrowser } from './playwrightBrowser';
|
import { launch as launchPlaywrightBrowser } from './playwrightBrowser';
|
||||||
import { PlaywrightDriver } from './playwrightDriver';
|
import { PlaywrightDriver } from './playwrightDriver';
|
||||||
|
@ -242,14 +242,18 @@ export class Code {
|
||||||
await this.poll(() => this.driver.writeInTerminal(selector, value), () => true, `writeInTerminal '${selector}'`);
|
await this.poll(() => this.driver.writeInTerminal(selector, value), () => true, `writeInTerminal '${selector}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLocaleInfo(): Promise<ILocaleInfo> {
|
getLocaleInfo(): Promise<ILocaleInfo> {
|
||||||
return this.driver.getLocaleInfo();
|
return this.driver.getLocaleInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLocalizedStrings(): Promise<ILocalizedStrings> {
|
getLocalizedStrings(): Promise<ILocalizedStrings> {
|
||||||
return this.driver.getLocalizedStrings();
|
return this.driver.getLocalizedStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLogs(): Promise<ILogFile[]> {
|
||||||
|
return this.driver.getLogs();
|
||||||
|
}
|
||||||
|
|
||||||
private async poll<T>(
|
private async poll<T>(
|
||||||
fn: () => Promise<T>,
|
fn: () => Promise<T>,
|
||||||
acceptFn: (result: T) => boolean,
|
acceptFn: (result: T) => boolean,
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as playwright from '@playwright/test';
|
import * as playwright from '@playwright/test';
|
||||||
import { join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
|
import { promises } from 'fs';
|
||||||
import { IWindowDriver } from './driver';
|
import { IWindowDriver } from './driver';
|
||||||
import { PageFunction } from 'playwright-core/types/structs';
|
import { PageFunction } from 'playwright-core/types/structs';
|
||||||
import { measureAndLog } from './logger';
|
import { measureAndLog } from './logger';
|
||||||
|
@ -107,6 +108,15 @@ export class PlaywrightDriver {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Web: Extract client logs
|
||||||
|
if (this.options.web) {
|
||||||
|
try {
|
||||||
|
await measureAndLog(() => this.saveWebClientLogs(), 'saveWebClientLogs()', this.options.logger);
|
||||||
|
} catch (error) {
|
||||||
|
this.options.logger.log(`Error saving web client logs (${error})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Web: exit via `close` method
|
// Web: exit via `close` method
|
||||||
if (this.options.web) {
|
if (this.options.web) {
|
||||||
try {
|
try {
|
||||||
|
@ -131,6 +141,17 @@ export class PlaywrightDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async saveWebClientLogs(): Promise<void> {
|
||||||
|
const logs = await this.getLogs();
|
||||||
|
|
||||||
|
for (const log of logs) {
|
||||||
|
const absoluteLogsPath = join(this.options.logsPath, log.name);
|
||||||
|
|
||||||
|
await promises.mkdir(dirname(absoluteLogsPath), { recursive: true });
|
||||||
|
await promises.writeFile(absoluteLogsPath, log.contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async dispatchKeybinding(keybinding: string) {
|
async dispatchKeybinding(keybinding: string) {
|
||||||
const chords = keybinding.split(' ');
|
const chords = keybinding.split(' ');
|
||||||
for (let i = 0; i < chords.length; i++) {
|
for (let i = 0; i < chords.length; i++) {
|
||||||
|
@ -206,6 +227,10 @@ export class PlaywrightDriver {
|
||||||
return this.evaluateWithDriver(([driver]) => driver.getLocalizedStrings());
|
return this.evaluateWithDriver(([driver]) => driver.getLocalizedStrings());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getLogs() {
|
||||||
|
return this.page.evaluate(([driver]) => driver.getLogs(), [await this.getDriverHandle()] as const);
|
||||||
|
}
|
||||||
|
|
||||||
private async evaluateWithDriver<T>(pageFunction: PageFunction<playwright.JSHandle<IWindowDriver>[], T>) {
|
private async evaluateWithDriver<T>(pageFunction: PageFunction<playwright.JSHandle<IWindowDriver>[], T>) {
|
||||||
return this.page.evaluate(pageFunction, [await this.getDriverHandle()]);
|
return this.page.evaluate(pageFunction, [await this.getDriverHandle()]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue