parent
7fdd7a20fb
commit
9ad9b6b316
|
|
@ -179,6 +179,8 @@ async function mergeReports(reportDir: string | undefined, opts: { [key: string]
|
|||
const configLoader = new ConfigLoader();
|
||||
const config = await (configFile ? configLoader.loadConfigFile(configFile) : configLoader.loadEmptyConfig(process.cwd()));
|
||||
const dir = path.resolve(process.cwd(), reportDir || 'playwright-report');
|
||||
if (!(await fs.promises.stat(dir)).isDirectory())
|
||||
throw new Error('Directory does not exist: ' + dir);
|
||||
await createMergedReport(config, dir, opts.reporter || 'list');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@
|
|||
../utilsBundle.ts
|
||||
|
||||
[blob.ts]
|
||||
../runner/loadUtils.ts
|
||||
../runner/reporters.ts
|
||||
|
|
|
|||
|
|
@ -16,25 +16,18 @@
|
|||
|
||||
import type { EventEmitter } from 'events';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { ManualPromise, ZipFile, calculateSha1, removeFolders } from 'playwright-core/lib/utils';
|
||||
import { mime } from 'playwright-core/lib/utilsBundle';
|
||||
import { yazl } from 'playwright-core/lib/zipBundle';
|
||||
import { Readable } from 'stream';
|
||||
import type { FullConfig, FullResult, Reporter, TestResult } from '../../types/testReporter';
|
||||
import type { BuiltInReporter, FullConfigInternal } from '../common/config';
|
||||
import type { FullConfig, FullResult, TestResult } from '../../types/testReporter';
|
||||
import type { FullConfigInternal } from '../common/config';
|
||||
import type { Suite } from '../common/test';
|
||||
import { TeleReporterReceiver, type JsonEvent, type JsonProject, type JsonSuite, type JsonTestResultEnd } from '../isomorphic/teleReceiver';
|
||||
import DotReporter from '../reporters/dot';
|
||||
import EmptyReporter from '../reporters/empty';
|
||||
import GitHubReporter from '../reporters/github';
|
||||
import JSONReporter from '../reporters/json';
|
||||
import JUnitReporter from '../reporters/junit';
|
||||
import LineReporter from '../reporters/line';
|
||||
import ListReporter from '../reporters/list';
|
||||
import { loadReporter } from '../runner/loadUtils';
|
||||
import HtmlReporter, { defaultReportFolder } from './html';
|
||||
import { createReporters } from '../runner/reporters';
|
||||
import { defaultReportFolder } from './html';
|
||||
import { TeleReporterEmitter } from './teleEmitter';
|
||||
|
||||
|
||||
|
|
@ -120,40 +113,15 @@ export async function createMergedReport(config: FullConfigInternal, dir: string
|
|||
const events = mergeEvents(shardReports);
|
||||
patchAttachmentPaths(events, resourceDir);
|
||||
|
||||
const defaultReporters: {[key in BuiltInReporter]: new(arg: any) => Reporter} = {
|
||||
dot: DotReporter,
|
||||
line: LineReporter,
|
||||
list: ListReporter,
|
||||
github: GitHubReporter,
|
||||
json: JSONReporter,
|
||||
junit: JUnitReporter,
|
||||
null: EmptyReporter,
|
||||
html: HtmlReporter,
|
||||
blob: BlobReporter,
|
||||
};
|
||||
reporterName ??= 'list';
|
||||
|
||||
const arg = config.config.reporter.find(([reporter, arg]) => reporter === reporterName)?.[1];
|
||||
const options = {
|
||||
...arg,
|
||||
configDir: process.cwd(),
|
||||
};
|
||||
|
||||
let reporter: Reporter | undefined;
|
||||
if (reporterName in defaultReporters) {
|
||||
reporter = new defaultReporters[reporterName as keyof typeof defaultReporters](options);
|
||||
} else {
|
||||
const reporterConstructor = await loadReporter(config, reporterName);
|
||||
reporter = new reporterConstructor(options);
|
||||
}
|
||||
|
||||
const receiver = new TeleReporterReceiver(path.sep, reporter);
|
||||
const reporters = await createReporters(config, 'merge', [reporterName]);
|
||||
const receiver = new TeleReporterReceiver(path.sep, reporters[0]);
|
||||
for (const event of events)
|
||||
await receiver.dispatch(event);
|
||||
} finally {
|
||||
await removeFolders([resourceDir]);
|
||||
}
|
||||
console.log(`Done.`);
|
||||
}
|
||||
|
||||
async function extractReports(dir: string, shardFiles: string[], resourceDir: string): Promise<string[]> {
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ import JSONReporter from '../reporters/json';
|
|||
import JUnitReporter from '../reporters/junit';
|
||||
import LineReporter from '../reporters/line';
|
||||
import ListReporter from '../reporters/list';
|
||||
import { Multiplexer } from '../reporters/multiplexer';
|
||||
import type { Suite } from '../common/test';
|
||||
import type { BuiltInReporter, FullConfigInternal } from '../common/config';
|
||||
import { loadReporter } from './loadUtils';
|
||||
import { BlobReporter } from '../reporters/blob';
|
||||
import type { ReporterDescription } from '../../types/test';
|
||||
|
||||
export async function createReporter(config: FullConfigInternal, mode: 'list' | 'run' | 'ui', additionalReporters: Reporter[] = []): Promise<Multiplexer> {
|
||||
export async function createReporters(config: FullConfigInternal, mode: 'list' | 'run' | 'ui' | 'merge', reporterNames?: string[]): Promise<Reporter[]> {
|
||||
const defaultReporters: {[key in BuiltInReporter]: new(arg: any) => Reporter} = {
|
||||
dot: mode === 'list' ? ListModeReporter : DotReporter,
|
||||
line: mode === 'list' ? ListModeReporter : LineReporter,
|
||||
|
|
@ -44,7 +44,10 @@ export async function createReporter(config: FullConfigInternal, mode: 'list' |
|
|||
blob: BlobReporter,
|
||||
};
|
||||
const reporters: Reporter[] = [];
|
||||
for (const r of config.config.reporter) {
|
||||
const descriptions: ReporterDescription[] = reporterNames ?
|
||||
reporterNames.map(name => [name, config.config.reporter.find(([reporterName]) => reporterName === name)]) :
|
||||
config.config.reporter;
|
||||
for (const r of descriptions) {
|
||||
const [name, arg] = r;
|
||||
const options = { ...arg, configDir: config.configDir };
|
||||
if (name in defaultReporters) {
|
||||
|
|
@ -54,7 +57,6 @@ export async function createReporter(config: FullConfigInternal, mode: 'list' |
|
|||
reporters.push(new reporterConstructor(options));
|
||||
}
|
||||
}
|
||||
reporters.push(...additionalReporters);
|
||||
if (process.env.PW_TEST_REPORTER) {
|
||||
const reporterConstructor = await loadReporter(config, process.env.PW_TEST_REPORTER);
|
||||
reporters.push(new reporterConstructor());
|
||||
|
|
@ -64,7 +66,7 @@ export async function createReporter(config: FullConfigInternal, mode: 'list' |
|
|||
const prints = r.printsToStdio ? r.printsToStdio() : true;
|
||||
return prints;
|
||||
});
|
||||
if (reporters.length && !someReporterPrintsToStdio) {
|
||||
if (reporters.length && !someReporterPrintsToStdio && mode !== 'merge') {
|
||||
// Add a line/dot/list-mode reporter for convenience.
|
||||
// Important to put it first, jsut in case some other reporter stalls onEnd.
|
||||
if (mode === 'list')
|
||||
|
|
@ -72,7 +74,7 @@ export async function createReporter(config: FullConfigInternal, mode: 'list' |
|
|||
else
|
||||
reporters.unshift(!process.env.CI ? new LineReporter({ omitFailures: true }) : new DotReporter());
|
||||
}
|
||||
return new Multiplexer(reporters);
|
||||
return reporters;
|
||||
}
|
||||
|
||||
export class ListModeReporter implements Reporter {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@ import { monotonicTime } from 'playwright-core/lib/utils';
|
|||
import type { FullResult } from '../../types/testReporter';
|
||||
import { webServerPluginsForConfig } from '../plugins/webServerPlugin';
|
||||
import { collectFilesForProject, filterProjects } from './projectUtils';
|
||||
import { createReporter } from './reporters';
|
||||
import { createReporters } from './reporters';
|
||||
import { TestRun, createTaskRunner, createTaskRunnerForList } from './tasks';
|
||||
import type { FullConfigInternal } from '../common/config';
|
||||
import { colors } from 'playwright-core/lib/utilsBundle';
|
||||
import { runWatchModeLoop } from './watchMode';
|
||||
import { runUIMode } from './uiMode';
|
||||
import { Multiplexer } from '../reporters/multiplexer';
|
||||
|
||||
export class Runner {
|
||||
private _config: FullConfigInternal;
|
||||
|
|
@ -68,7 +69,7 @@ export class Runner {
|
|||
// Legacy webServer support.
|
||||
webServerPluginsForConfig(config).forEach(p => config.plugins.push({ factory: p }));
|
||||
|
||||
const reporter = await createReporter(config, listOnly ? 'list' : 'run');
|
||||
const reporter = new Multiplexer(await createReporters(config, listOnly ? 'list' : 'run'));
|
||||
const taskRunner = listOnly ? createTaskRunnerForList(config, reporter, 'in-process')
|
||||
: createTaskRunner(config, reporter);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { clearCompilationCache, collectAffectedTestFiles, dependenciesForTestFil
|
|||
import type { FullConfigInternal } from '../common/config';
|
||||
import { Multiplexer } from '../reporters/multiplexer';
|
||||
import { TeleReporterEmitter } from '../reporters/teleEmitter';
|
||||
import { createReporter } from './reporters';
|
||||
import { createReporters } from './reporters';
|
||||
import { TestRun, createTaskRunnerForList, createTaskRunnerForWatch, createTaskRunnerForWatchSetup } from './tasks';
|
||||
import { chokidar } from '../utilsBundle';
|
||||
import type { FSWatcher } from 'chokidar';
|
||||
|
|
@ -167,8 +167,9 @@ class UIMode {
|
|||
this._config.cliListOnly = false;
|
||||
this._config.testIdMatcher = id => !testIdSet || testIdSet.has(id);
|
||||
|
||||
const runReporter = new TeleReporterEmitter(e => this._dispatchEvent(e));
|
||||
const reporter = await createReporter(this._config, 'ui', [runReporter]);
|
||||
const reporters = await createReporters(this._config, 'ui');
|
||||
reporters.push(new TeleReporterEmitter(e => this._dispatchEvent(e)));
|
||||
const reporter = new Multiplexer(reporters);
|
||||
const taskRunner = createTaskRunnerForWatch(this._config, reporter);
|
||||
const testRun = new TestRun(this._config, reporter);
|
||||
clearCompilationCache();
|
||||
|
|
|
|||
Loading…
Reference in a new issue