chore: iterate towards tele reporter reuse in vscode (#29803)

This commit is contained in:
Pavel Feldman 2024-03-04 11:08:40 -08:00 committed by GitHub
parent de73af99fa
commit 743a6ffe1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 40 additions and 26 deletions

View file

@ -313,7 +313,6 @@ export class TeleReporterReceiver {
}
private _onExit(): Promise<void> | void {
// Free up the memory from the string pool.
return this._reporter.onExit?.();
}
@ -416,7 +415,7 @@ export class TeleReporterReceiver {
}
}
export class TeleSuite {
export class TeleSuite implements reporterTypes.Suite {
title: string;
location?: reporterTypes.Location;
parent?: TeleSuite;

View file

@ -128,7 +128,7 @@ class HtmlReporter extends EmptyReporter {
const shouldOpen = this._open === 'always' || (!ok && this._open === 'on-failure');
if (shouldOpen) {
await showHTMLReport(this._outputFolder, this._options.host, this._options.port, singleTestId);
} else if (this._options._mode === 'run') {
} else if (this._options._mode === 'test') {
const packageManagerCommand = getPackageManagerExecCommand();
const relativeReportPath = this._outputFolder === standaloneDefaultFolder() ? '' : ' ' + path.relative(process.cwd(), this._outputFolder);
const hostArg = this._options.host ? ` --host ${this._options.host}` : '';

View file

@ -316,7 +316,7 @@ export function loadGlobalHook(config: FullConfigInternal, file: string): Promis
return requireOrImportDefaultFunction(path.resolve(config.config.rootDir, file), false);
}
export function loadReporter(config: FullConfigInternal | undefined, file: string): Promise<new (arg?: any) => Reporter> {
export function loadReporter(config: FullConfigInternal, file: string): Promise<new (arg?: any) => Reporter> {
return requireOrImportDefaultFunction(config ? path.resolve(config.config.rootDir, file) : file, true);
}

View file

@ -33,7 +33,7 @@ import { BlobReporter } from '../reporters/blob';
import type { ReporterDescription } from '../../types/test';
import { type ReporterV2, wrapReporterAsV2 } from '../reporters/reporterV2';
export async function createReporters(config: FullConfigInternal, mode: 'list' | 'run' | 'ui' | 'merge', descriptions?: ReporterDescription[]): Promise<ReporterV2[]> {
export async function createReporters(config: FullConfigInternal, mode: 'list' | 'test' | 'ui' | 'merge', descriptions?: ReporterDescription[]): Promise<ReporterV2[]> {
const defaultReporters: { [key in BuiltInReporter]: new(arg: any) => ReporterV2 } = {
blob: BlobReporter,
dot: mode === 'list' ? ListModeReporter : DotReporter,
@ -50,7 +50,7 @@ export async function createReporters(config: FullConfigInternal, mode: 'list' |
descriptions ??= config.config.reporter;
if (config.configCLIOverrides.additionalReporters)
descriptions = [...descriptions, ...config.configCLIOverrides.additionalReporters];
const runOptions = { configDir: config.configDir, _mode: mode };
const runOptions = reporterOptions(config, mode);
for (const r of descriptions) {
const [name, arg] = r;
const options = { ...runOptions, ...arg };
@ -63,7 +63,7 @@ export async function createReporters(config: FullConfigInternal, mode: 'list' |
}
if (process.env.PW_TEST_REPORTER) {
const reporterConstructor = await loadReporter(config, process.env.PW_TEST_REPORTER);
reporters.push(wrapReporterAsV2(new reporterConstructor()));
reporters.push(wrapReporterAsV2(new reporterConstructor(runOptions)));
}
const someReporterPrintsToStdio = reporters.some(r => r.printsToStdio());
@ -78,6 +78,21 @@ export async function createReporters(config: FullConfigInternal, mode: 'list' |
return reporters;
}
export async function createReporterForTestServer(config: FullConfigInternal, file: string, mode: 'test' | 'list', messageSink: (message: any) => void): Promise<ReporterV2> {
const reporterConstructor = await loadReporter(config, file);
const runOptions = reporterOptions(config, mode, messageSink);
const instance = new reporterConstructor(runOptions);
return wrapReporterAsV2(instance);
}
function reporterOptions(config: FullConfigInternal, mode: 'list' | 'test' | 'ui' | 'merge', send?: (message: any) => void) {
return {
configDir: config.configDir,
send,
_mode: mode,
};
}
class ListModeReporter extends EmptyReporter {
private config!: FullConfig;

View file

@ -83,7 +83,7 @@ export class Runner {
// Legacy webServer support.
webServerPluginsForConfig(config).forEach(p => config.plugins.push({ factory: p }));
const reporter = new InternalReporter(new Multiplexer(await createReporters(config, listOnly ? 'list' : 'run')));
const reporter = new InternalReporter(new Multiplexer(await createReporters(config, listOnly ? 'list' : 'test')));
const taskRunner = listOnly ? createTaskRunnerForList(config, reporter, 'in-process', { failOnLoadErrors: true })
: createTaskRunner(config, reporter);

View file

@ -23,7 +23,7 @@ import type { FullResult, TestError } from 'playwright/types/testReporter';
import { loadConfig, restartWithExperimentalTsEsm } from '../common/configLoader';
import { InternalReporter } from '../reporters/internalReporter';
import { Multiplexer } from '../reporters/multiplexer';
import { createReporters } from './reporters';
import { createReporterForTestServer, createReporters } from './reporters';
import { TestRun, createTaskRunnerForList, createTaskRunnerForTestServer } from './tasks';
import type { ConfigCLIOverrides } from '../common/ipc';
import { Runner } from './runner';
@ -32,8 +32,6 @@ import type { FullConfigInternal } from '../common/config';
import type { TestServerInterface } from './testServerInterface';
import { serializeError } from '../util';
import { prepareErrorStack } from '../reporters/base';
import { loadReporter } from './loadUtils';
import { wrapReporterAsV2 } from '../reporters/reporterV2';
export async function runTestServer() {
if (restartWithExperimentalTsEsm(undefined, true))
@ -116,13 +114,13 @@ class Dispatcher implements TestServerInterface {
async listTests(params: {
configFile: string;
locations: string[];
reporter: string;
reporters: { file: string, event: string }[];
env: NodeJS.ProcessEnv;
}) {
const config = await this._loadConfig(params.configFile);
config.cliArgs = params.locations || [];
const wireReporter = await this._createReporter(params.reporter);
const reporter = new InternalReporter(new Multiplexer([wireReporter]));
const wireReporters = await this._wireReporters(config, 'list', params.reporters);
const reporter = new InternalReporter(new Multiplexer(wireReporters));
const taskRunner = createTaskRunnerForList(config, reporter, 'out-of-process', { failOnLoadErrors: true });
const testRun = new TestRun(config, reporter);
reporter.onConfigure(config.config);
@ -140,7 +138,7 @@ class Dispatcher implements TestServerInterface {
async test(params: {
configFile: string;
locations: string[];
reporter: string;
reporters: { file: string, event: string }[];
env: NodeJS.ProcessEnv;
headed?: boolean;
oneWorker?: boolean;
@ -171,9 +169,9 @@ class Dispatcher implements TestServerInterface {
config.cliGrep = params.grep;
config.cliProjectFilter = params.projects?.length ? params.projects : undefined;
const wireReporter = await this._createReporter(params.reporter);
const configReporters = await createReporters(config, 'run');
const reporter = new InternalReporter(new Multiplexer([...configReporters, wireReporter]));
const wireReporters = await this._wireReporters(config, 'test', params.reporters);
const configReporters = await createReporters(config, 'test');
const reporter = new InternalReporter(new Multiplexer([...configReporters, ...wireReporters]));
const taskRunner = createTaskRunnerForTestServer(config, reporter);
const testRun = new TestRun(config, reporter);
reporter.onConfigure(config.config);
@ -188,6 +186,14 @@ class Dispatcher implements TestServerInterface {
await run;
}
private async _wireReporters(config: FullConfigInternal, mode: 'test' | 'list', reporters: { file: string, event: string }[]) {
return await Promise.all(reporters.map(r => {
return createReporterForTestServer(config, r.file, mode, message => {
this._dispatchEvent(r.event, message);
});
}));
}
async findRelatedTestFiles(params: {
configFile: string;
files: string[];
@ -219,12 +225,6 @@ class Dispatcher implements TestServerInterface {
private async _loadConfig(configFile: string, overrides?: ConfigCLIOverrides): Promise<FullConfigInternal> {
return loadConfig({ resolvedConfigFile: configFile, configDir: path.dirname(configFile) }, overrides);
}
private async _createReporter(file: string) {
const reporterConstructor = await loadReporter(undefined, file);
const instance = new reporterConstructor((message: any) => this._dispatchEvent('report', message));
return wrapReporterAsV2(instance);
}
}
function chunkToPayload(type: 'stdout' | 'stderr', chunk: Buffer | string) {

View file

@ -33,13 +33,13 @@ export interface TestServerInterface {
listTests(params: {
configFile: string;
locations: string[];
reporter: string;
reporters: { file: string, event: string }[];
}): Promise<void>;
test(params: {
configFile: string;
locations: string[];
reporter: string;
reporters: { file: string, event: string }[];
headed?: boolean;
oneWorker?: boolean;
trace?: 'on' | 'off';