mirror of
https://github.com/Microsoft/vscode
synced 2024-08-26 20:39:37 +00:00
log file
This commit is contained in:
parent
528efc5bbb
commit
7adef9d244
|
@ -7,6 +7,7 @@ import { Workbench } from './areas/workbench/workbench';
|
|||
import * as fs from 'fs';
|
||||
import * as cp from 'child_process';
|
||||
import { Code, spawn, SpawnOptions } from './vscode/code';
|
||||
import { Logger } from './logger';
|
||||
|
||||
export enum Quality {
|
||||
Dev,
|
||||
|
@ -19,7 +20,6 @@ export interface ApplicationOptions extends SpawnOptions {
|
|||
workspacePath: string;
|
||||
workspaceFilePath: string;
|
||||
waitTime: number;
|
||||
verbose: boolean;
|
||||
}
|
||||
|
||||
export class Application {
|
||||
|
@ -42,6 +42,10 @@ export class Application {
|
|||
return this._workbench;
|
||||
}
|
||||
|
||||
get logger(): Logger {
|
||||
return this.options.logger;
|
||||
}
|
||||
|
||||
get workspacePath(): string {
|
||||
return this.options.workspacePath;
|
||||
}
|
||||
|
@ -103,7 +107,7 @@ export class Application {
|
|||
workspacePath: workspaceOrFolder,
|
||||
userDataDir: this.options.userDataDir,
|
||||
extensionsPath: this.options.extensionsPath,
|
||||
verbose: this.options.verbose,
|
||||
logger: this.options.logger,
|
||||
extraArgs
|
||||
});
|
||||
|
||||
|
|
42
test/smoke/src/logger.ts
Normal file
42
test/smoke/src/logger.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { appendFileSync, writeFileSync } from 'fs';
|
||||
import { format } from 'util';
|
||||
import { EOL } from 'os';
|
||||
|
||||
export interface Logger {
|
||||
log(message: string, ...args: any[]): void;
|
||||
}
|
||||
|
||||
export class ConsoleLogger implements Logger {
|
||||
|
||||
log(message: string, ...args: any[]): void {
|
||||
console.log('**', message, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
export class FileLogger implements Logger {
|
||||
|
||||
constructor(private path: string) {
|
||||
writeFileSync(path, '');
|
||||
}
|
||||
|
||||
log(message: string, ...args: any[]): void {
|
||||
const date = new Date().toISOString();
|
||||
appendFileSync(this.path, `[${date}] ${format(message, ...args)}${EOL}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class MultiLogger implements Logger {
|
||||
|
||||
constructor(private loggers: Logger[]) { }
|
||||
|
||||
log(message: string, ...args: any[]): void {
|
||||
for (const logger of this.loggers) {
|
||||
logger.log(message, ...args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ import { setup as setupDataExtensionTests } from './areas/extensions/extensions.
|
|||
import { setup as setupTerminalTests } from './areas/terminal/terminal.test';
|
||||
import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test';
|
||||
import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test';
|
||||
import { polling } from './vscode/code';
|
||||
import { MultiLogger, Logger, ConsoleLogger, FileLogger } from './logger';
|
||||
|
||||
const tmpDir = tmp.dirSync({ prefix: 't' }) as { name: string; removeCallback: Function; };
|
||||
const testDataPath = tmpDir.name;
|
||||
|
@ -41,7 +41,8 @@ const opts = minimist(args, {
|
|||
'wait-time',
|
||||
'test-repo',
|
||||
'keybindings',
|
||||
'screenshots'
|
||||
'screenshots',
|
||||
'log'
|
||||
],
|
||||
boolean: [
|
||||
'verbose'
|
||||
|
@ -238,6 +239,16 @@ async function setup(): Promise<void> {
|
|||
}
|
||||
|
||||
function createApp(quality: Quality): Application {
|
||||
const loggers: Logger[] = [];
|
||||
|
||||
if (opts.verbose) {
|
||||
loggers.push(new ConsoleLogger());
|
||||
}
|
||||
|
||||
if (opts.log) {
|
||||
loggers.push(new FileLogger(opts.log));
|
||||
}
|
||||
|
||||
return new Application({
|
||||
quality,
|
||||
codePath: opts.build,
|
||||
|
@ -246,7 +257,7 @@ function createApp(quality: Quality): Application {
|
|||
extensionsPath,
|
||||
workspaceFilePath,
|
||||
waitTime: parseInt(opts['wait-time'] || '0') || 20,
|
||||
verbose: opts.verbose
|
||||
logger: new MultiLogger(loggers)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -289,11 +300,23 @@ describe('Test', () => {
|
|||
const name = this.currentTest.fullTitle().replace(/[^a-z0-9\-]/ig, '_');
|
||||
const screenshotPath = path.join(screenshotsPath, `${name}.png`);
|
||||
|
||||
console.log('Last poll message: ', polling.lastTimeoutMessage);
|
||||
if (opts.log) {
|
||||
app.logger.log('*** Scr eenshot recorded:', screenshotPath);
|
||||
}
|
||||
|
||||
fs.writeFileSync(screenshotPath, buffer);
|
||||
});
|
||||
}
|
||||
|
||||
if (opts.log) {
|
||||
beforeEach(async function () {
|
||||
const app = this.app as Application;
|
||||
const title = this.currentTest.fullTitle();
|
||||
|
||||
app.logger.log('***', title.replace(/./g, '='));
|
||||
});
|
||||
}
|
||||
|
||||
setupDataLossTests();
|
||||
setupDataExplorerTests();
|
||||
setupDataPreferencesTests();
|
||||
|
|
|
@ -8,6 +8,7 @@ import * as cp from 'child_process';
|
|||
import * as os from 'os';
|
||||
import { tmpName } from 'tmp';
|
||||
import { IDriver, connect as connectDriver, IDisposable, IElement } from './driver';
|
||||
import { Logger } from '../logger';
|
||||
|
||||
const repoPath = path.join(__dirname, '../../../..');
|
||||
|
||||
|
@ -57,13 +58,13 @@ function getBuildOutPath(root: string): string {
|
|||
}
|
||||
}
|
||||
|
||||
async function connect(child: cp.ChildProcess, outPath: string, handlePath: string, verbose: boolean): Promise<Code> {
|
||||
async function connect(child: cp.ChildProcess, outPath: string, handlePath: string, logger: Logger): Promise<Code> {
|
||||
let errCount = 0;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
const { client, driver } = await connectDriver(outPath, handlePath);
|
||||
return new Code(child, client, driver, verbose);
|
||||
return new Code(child, client, driver, logger);
|
||||
} catch (err) {
|
||||
if (++errCount > 50) {
|
||||
child.kill();
|
||||
|
@ -85,7 +86,7 @@ export interface SpawnOptions {
|
|||
workspacePath: string;
|
||||
userDataDir: string;
|
||||
extensionsPath: string;
|
||||
verbose: boolean;
|
||||
logger: Logger;
|
||||
extraArgs?: string[];
|
||||
}
|
||||
|
||||
|
@ -127,22 +128,14 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
|
|||
|
||||
const spawnOptions: cp.SpawnOptions = {};
|
||||
|
||||
if (options.verbose) {
|
||||
spawnOptions.stdio = 'inherit';
|
||||
}
|
||||
|
||||
const child = cp.spawn(electronPath, args, spawnOptions);
|
||||
|
||||
instances.add(child);
|
||||
child.once('exit', () => instances.delete(child));
|
||||
|
||||
return connect(child, outPath, handle, options.verbose);
|
||||
return connect(child, outPath, handle, options.logger);
|
||||
}
|
||||
|
||||
export const polling = {
|
||||
lastTimeoutMessage: ''
|
||||
};
|
||||
|
||||
async function poll<T>(
|
||||
fn: () => Promise<T>,
|
||||
acceptFn: (result: T) => boolean,
|
||||
|
@ -159,7 +152,6 @@ async function poll<T>(
|
|||
|
||||
let result;
|
||||
try {
|
||||
polling.lastTimeoutMessage = timeoutMessage;
|
||||
result = await fn();
|
||||
|
||||
if (acceptFn(result)) {
|
||||
|
@ -187,24 +179,20 @@ export class Code {
|
|||
private process: cp.ChildProcess,
|
||||
private client: IDisposable,
|
||||
driver: IDriver,
|
||||
verbose: boolean
|
||||
readonly logger: Logger
|
||||
) {
|
||||
if (verbose) {
|
||||
this.driver = new Proxy(driver, {
|
||||
get(target, prop, receiver) {
|
||||
if (typeof target[prop] !== 'function') {
|
||||
return target[prop];
|
||||
}
|
||||
|
||||
return function (...args) {
|
||||
console.log('** ', prop, ...args.filter(a => typeof a === 'string'));
|
||||
return target[prop].apply(this, args);
|
||||
};
|
||||
this.driver = new Proxy(driver, {
|
||||
get(target, prop, receiver) {
|
||||
if (typeof target[prop] !== 'function') {
|
||||
return target[prop];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.driver = driver;
|
||||
}
|
||||
|
||||
return function (...args) {
|
||||
logger.log(`${prop}`, ...args.filter(a => typeof a === 'string'));
|
||||
return target[prop].apply(this, args);
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async capturePage(): Promise<string> {
|
||||
|
|
Loading…
Reference in a new issue