chore(reporter): normalize reporter option types (#35641)

This commit is contained in:
Adam Gastineau 2025-04-30 09:08:13 -07:00 committed by GitHub
parent e547c377c3
commit 2dee41910f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 53 additions and 63 deletions

View File

@ -46,6 +46,13 @@ type TestSummary = {
fatalErrors: TestError[];
};
export type CommonReporterOptions = {
configDir: string,
_mode: 'list' | 'test' | 'merge',
_isTestServer: boolean,
_commandHash: string,
};
export type Screen = {
resolveFiles: 'cwd' | 'rootDir';
colors: Colors;
@ -591,7 +598,7 @@ export function resolveOutputFile(reporterName: string, options: {
fileName: string,
outputDir: string,
}
}): { outputFile: string, outputDir?: string } |undefined {
}): { outputFile: string, outputDir?: string } | undefined {
const name = reporterName.toUpperCase();
let outputFile = resolveFromEnv(`PLAYWRIGHT_${name}_OUTPUT_FILE`);
if (!outputFile && options.outputFile)

View File

@ -23,21 +23,14 @@ import { ManualPromise, calculateSha1, createGuid, getUserAgent } from 'playwrig
import { mime } from 'playwright-core/lib/utilsBundle';
import { yazl } from 'playwright-core/lib/zipBundle';
import { resolveOutputFile } from './base';
import { resolveOutputFile, CommonReporterOptions } from './base';
import { TeleReporterEmitter } from './teleEmitter';
import type { BlobReporterOptions } from '../../types/test';
import type { FullConfig, FullResult, TestResult } from '../../types/testReporter';
import type { JsonAttachment, JsonEvent } from '../isomorphic/teleReceiver';
import type { EventEmitter } from 'events';
type BlobReporterOptions = {
configDir: string;
outputDir?: string;
fileName?: string;
outputFile?: string;
_commandHash: string;
};
export const currentBlobReportVersion = 2;
export type BlobReportMetadata = {
@ -51,11 +44,11 @@ export type BlobReportMetadata = {
export class BlobReporter extends TeleReporterEmitter {
private readonly _messages: JsonEvent[] = [];
private readonly _attachments: { originalPath: string, zipEntryPath: string }[] = [];
private readonly _options: BlobReporterOptions;
private readonly _options: BlobReporterOptions & CommonReporterOptions;
private readonly _salt: string;
private _config!: FullConfig;
constructor(options: BlobReporterOptions) {
constructor(options: BlobReporterOptions & CommonReporterOptions) {
super(message => this._messages.push(message));
this._options = options;
if (this._options.fileName && !this._options.fileName.endsWith('.zip'))

View File

@ -24,12 +24,12 @@ import { open } from 'playwright-core/lib/utilsBundle';
import { mime } from 'playwright-core/lib/utilsBundle';
import { yazl } from 'playwright-core/lib/zipBundle';
import { formatError, formatResultFailure, internalScreen } from './base';
import { CommonReporterOptions, formatError, formatResultFailure, internalScreen } from './base';
import { codeFrameColumns } from '../transform/babelBundle';
import { resolveReporterOutputPath, stripAnsiEscapes } from '../util';
import type { ReporterV2 } from './reporterV2';
import type { Metadata, TestAnnotation } from '../../types/test';
import type { HtmlReporterOptions as HtmlReporterConfigOptions, Metadata, TestAnnotation } from '../../types/test';
import type * as api from '../../types/testReporter';
import type { HTMLReport, Stats, TestAttachment, TestCase, TestCaseSummary, TestFile, TestFileSummary, TestResult, TestStep } from '@html-reporter/types';
import type { ZipFile } from 'playwright-core/lib/zipBundle';
@ -40,29 +40,17 @@ type TestEntry = {
testCaseSummary: TestCaseSummary
};
const htmlReportOptions = ['always', 'never', 'on-failure'];
type HtmlReportOpenOption = (typeof htmlReportOptions)[number];
type HtmlReportOpenOption = NonNullable<HtmlReporterConfigOptions['open']>;
const htmlReportOptions: HtmlReportOpenOption[] = ['always', 'never', 'on-failure'];
const isHtmlReportOption = (type: string): type is HtmlReportOpenOption => {
return htmlReportOptions.includes(type);
};
type HtmlReporterOptions = {
configDir: string,
outputFolder?: string,
open?: HtmlReportOpenOption,
host?: string,
port?: number,
attachmentsBaseURL?: string,
title?: string,
_mode?: 'test' | 'list';
_isTestServer?: boolean;
return htmlReportOptions.includes(type as HtmlReportOpenOption);
};
class HtmlReporter implements ReporterV2 {
private config!: api.FullConfig;
private suite!: api.Suite;
private _options: HtmlReporterOptions;
private _options: HtmlReporterConfigOptions & CommonReporterOptions;
private _outputFolder!: string;
private _attachmentsBaseURL!: string;
private _open: string | undefined;
@ -72,7 +60,7 @@ class HtmlReporter implements ReporterV2 {
private _buildResult: { ok: boolean, singleTestId: string | undefined } | undefined;
private _topLevelErrors: api.TestError[] = [];
constructor(options: HtmlReporterOptions) {
constructor(options: HtmlReporterConfigOptions & CommonReporterOptions) {
this._options = options;
}

View File

@ -19,24 +19,20 @@ import path from 'path';
import { toPosixPath, MultiMap } from 'playwright-core/lib/utils';
import { formatError, nonTerminalScreen, prepareErrorStack, resolveOutputFile } from './base';
import { formatError, nonTerminalScreen, prepareErrorStack, resolveOutputFile, CommonReporterOptions } from './base';
import { getProjectId } from '../common/config';
import type { ReporterV2 } from './reporterV2';
import type { JsonReporterOptions } from '../../types/test';
import type { FullConfig, FullResult, JSONReport, JSONReportError, JSONReportSpec, JSONReportSuite, JSONReportTest, JSONReportTestResult, JSONReportTestStep, Location, Suite, TestCase, TestError, TestResult, TestStep } from '../../types/testReporter';
type JSONOptions = {
outputFile?: string,
configDir: string,
};
class JSONReporter implements ReporterV2 {
config!: FullConfig;
suite!: Suite;
private _errors: TestError[] = [];
private _resolvedOutputFile: string | undefined;
constructor(options: JSONOptions) {
constructor(options: JsonReporterOptions & CommonReporterOptions) {
this._resolvedOutputFile = resolveOutputFile('JSON', options)?.outputFile;
}

View File

@ -19,20 +19,13 @@ import path from 'path';
import { getAsBooleanFromENV } from 'playwright-core/lib/utils';
import { formatFailure, nonTerminalScreen, resolveOutputFile } from './base';
import { CommonReporterOptions, formatFailure, nonTerminalScreen, resolveOutputFile } from './base';
import { stripAnsiEscapes } from '../util';
import type { ReporterV2 } from './reporterV2';
import type { JUnitReporterOptions } from '../../types/test';
import type { FullConfig, FullResult, Suite, TestCase } from '../../types/testReporter';
type JUnitOptions = {
outputFile?: string,
stripANSIControlSequences?: boolean,
includeProjectInTestName?: boolean,
configDir: string,
};
class JUnitReporter implements ReporterV2 {
private config!: FullConfig;
private configDir: string;
@ -45,7 +38,7 @@ class JUnitReporter implements ReporterV2 {
private stripANSIControlSequences = false;
private includeProjectInTestName = false;
constructor(options: JUnitOptions) {
constructor(options: JUnitReporterOptions & CommonReporterOptions) {
this.stripANSIControlSequences = getAsBooleanFromENV('PLAYWRIGHT_JUNIT_STRIP_ANSI', !!options.stripANSIControlSequences);
this.includeProjectInTestName = getAsBooleanFromENV('PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME', !!options.includeProjectInTestName);
this.configDir = options.configDir;

View File

@ -20,7 +20,9 @@ import { ms as milliseconds } from 'playwright-core/lib/utilsBundle';
import { TerminalReporter, stepSuffix } from './base';
import { stripAnsiEscapes } from '../util';
import type { ListReporterOptions } from '../../types/test';
import type { FullResult, Suite, TestCase, TestError, TestResult, TestStep } from '../../types/testReporter';
import type { CommonReporterOptions } from './base';
// Allow it in the Visual Studio Code Terminal and the new Windows Terminal
const DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === 'win32' && process.env.TERM_PROGRAM !== 'vscode' && !process.env.WT_SESSION;
@ -37,9 +39,9 @@ class ListReporter extends TerminalReporter {
private _needNewLine = false;
private _printSteps: boolean;
constructor(options: { printSteps?: boolean } = {}) {
constructor(options?: ListReporterOptions & CommonReporterOptions) {
super();
this._printSteps = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_STEPS', options.printSteps);
this._printSteps = getAsBooleanFromENV('PLAYWRIGHT_LIST_PRINT_STEPS', options?.printSteps);
}
override onBegin(suite: Suite) {

View File

@ -35,10 +35,9 @@ import type { ReporterDescription } from '../../types/test';
import type { FullConfig, TestError } from '../../types/testReporter';
import type { BuiltInReporter, FullConfigInternal } from '../common/config';
import type { Suite } from '../common/test';
import type { Screen } from '../reporters/base';
import type { CommonReporterOptions, Screen } from '../reporters/base';
import type { ReporterV2 } from '../reporters/reporterV2';
export async function createReporters(config: FullConfigInternal, mode: 'list' | 'test' | 'merge', isTestServer: boolean, descriptions?: ReporterDescription[]): Promise<ReporterV2[]> {
const defaultReporters: { [key in BuiltInReporter]: new(arg: any) => ReporterV2 } = {
blob: BlobReporter,
@ -107,7 +106,7 @@ export function createErrorCollectingReporter(screen: Screen, writeToConsole?: b
};
}
function reporterOptions(config: FullConfigInternal, mode: 'list' | 'test' | 'merge', isTestServer: boolean) {
function reporterOptions(config: FullConfigInternal, mode: 'list' | 'test' | 'merge', isTestServer: boolean): CommonReporterOptions {
return {
configDir: config.configDir,
_mode: mode,

View File

@ -18,15 +18,21 @@
import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core';
export * from 'playwright-core';
export type BlobReporterOptions = { outputDir?: string, fileName?: string };
export type ListReporterOptions = { printSteps?: boolean };
export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean };
export type JsonReporterOptions = { outputFile?: string };
export type HtmlReporterOptions = { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string, title?: string };
export type ReporterDescription = Readonly<
['blob'] | ['blob', { outputDir?: string, fileName?: string }] |
['blob'] | ['blob', BlobReporterOptions] |
['dot'] |
['line'] |
['list'] | ['list', { printSteps?: boolean }] |
['list'] | ['list', ListReporterOptions] |
['github'] |
['junit'] | ['junit', { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean }] |
['json'] | ['json', { outputFile?: string }] |
['html'] | ['html', { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string, title?: string }] |
['junit'] | ['junit', JUnitReporterOptions] |
['json'] | ['json', JsonReporterOptions] |
['html'] | ['html', HtmlReporterOptions] |
['null'] |
[string] | [string, any]
>;

View File

@ -17,15 +17,21 @@
import type { APIRequestContext, Browser, BrowserContext, BrowserContextOptions, Page, LaunchOptions, ViewportSize, Geolocation, HTTPCredentials, Locator, APIResponse, PageScreenshotOptions } from 'playwright-core';
export * from 'playwright-core';
export type BlobReporterOptions = { outputDir?: string, fileName?: string };
export type ListReporterOptions = { printSteps?: boolean };
export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean };
export type JsonReporterOptions = { outputFile?: string };
export type HtmlReporterOptions = { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string, title?: string };
export type ReporterDescription = Readonly<
['blob'] | ['blob', { outputDir?: string, fileName?: string }] |
['blob'] | ['blob', BlobReporterOptions] |
['dot'] |
['line'] |
['list'] | ['list', { printSteps?: boolean }] |
['list'] | ['list', ListReporterOptions] |
['github'] |
['junit'] | ['junit', { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean }] |
['json'] | ['json', { outputFile?: string }] |
['html'] | ['html', { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string, title?: string }] |
['junit'] | ['junit', JUnitReporterOptions] |
['json'] | ['json', JsonReporterOptions] |
['html'] | ['html', HtmlReporterOptions] |
['null'] |
[string] | [string, any]
>;