feat(html): automatically use console reporter with html (#9559)

This commit is contained in:
Pavel Feldman 2021-10-15 18:18:56 -08:00 committed by GitHub
parent 3e054e9ad6
commit 99f3389b3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 29 additions and 38 deletions

View file

@ -261,10 +261,9 @@ Running 124 tests using 6 workers
### HTML reporter
HTML reporter produces a self-contained folder that contains report for the test run that can be served as a web page.
It is usually used together with some terminal reporter like `dot` or `line`.
```bash
npx playwright test --reporter=html,dot
npx playwright test --reporter=html
```
By default, report is written into the `playwright-report` folder in the current working directory. One can override

View file

@ -62,6 +62,11 @@ export class BaseReporter implements Reporter {
fileDurations = new Map<string, number>();
monotonicStartTime: number = 0;
private printTestOutput = !process.env.PWTEST_SKIP_TEST_OUTPUT;
protected _omitFailures: boolean;
constructor(options: { omitFailures?: boolean } = {}) {
this._omitFailures = options.omitFailures || false;
}
onBegin(config: FullConfig, suite: Suite) {
this.monotonicStartTime = monotonicTime();
@ -113,7 +118,6 @@ export class BaseReporter implements Reporter {
protected generateSummaryMessage({ skipped, expected, unexpected, flaky }: TestSummary) {
const tokens: string[] = [];
tokens.push('');
if (unexpected.length) {
tokens.push(colors.red(` ${unexpected.length} failed`));
for (const test of unexpected)
@ -169,7 +173,7 @@ export class BaseReporter implements Reporter {
epilogue(full: boolean) {
const summary = this.generateSummary();
const summaryMessage = this.generateSummaryMessage(summary);
if (full && summary.failuresToPrint.length)
if (full && summary.failuresToPrint.length && !this._omitFailures)
this._printFailures(summary.failuresToPrint);
this._printSlowTests();
this._printSummary(summaryMessage);
@ -191,9 +195,11 @@ export class BaseReporter implements Reporter {
});
}
private _printSummary(summary: string){
console.log('');
console.log(summary);
private _printSummary(summary: string) {
if (summary.trim()) {
console.log('');
console.log(summary);
}
}
willRetry(test: TestCase): boolean {

View file

@ -31,11 +31,9 @@ type GitHubLogOptions = Partial<{
}>;
class GitHubLogger {
private _isGitHubAction: boolean = !!process.env.GITHUB_ACTION;
private _log(message: string, type: GitHubLogType = 'notice', options: GitHubLogOptions = {}) {
if (this._isGitHubAction)
message = message.replace(/\n/g, '%0A');
message = message.replace(/\n/g, '%0A');
const configs = Object.entries(options)
.map(([key, option]) => `${key}=${option}`)
.join(',');

View file

@ -129,13 +129,11 @@ class HtmlReporter {
if (!stats.ok && !process.env.CI && !process.env.PWTEST_SKIP_TEST_OUTPUT) {
await showHTMLReport(reportFolder);
} else {
console.log('');
console.log('');
console.log('All tests passed. To open last HTML report run:');
console.log(colors.cyan(`
npx playwright show-report
`));
console.log('');
}
}
}

View file

@ -59,7 +59,8 @@ class LineReporter extends BaseReporter {
const width = process.stdout.columns! - 1;
const title = `[${++this._current}/${this._total}] ${formatTestTitle(this.config, test)}`.substring(0, width);
process.stdout.write(`\u001B[1A\u001B[2K${title}\n`);
if (!this.willRetry(test) && (test.outcome() === 'flaky' || test.outcome() === 'unexpected')) {
if (!this._omitFailures && !this.willRetry(test) && (test.outcome() === 'flaky' || test.outcome() === 'unexpected')) {
process.stdout.write(`\u001B[1A\u001B[2K`);
console.log(formatFailure(this.config, test, {
index: ++this._failures

View file

@ -32,8 +32,8 @@ class ListReporter extends BaseReporter {
private readonly _liveTerminal: string | boolean | undefined;
private readonly _ttyWidthForTest: number;
constructor() {
super();
constructor(options: { omitFailures?: boolean } = {}) {
super(options);
this._ttyWidthForTest = parseInt(process.env.PWTEST_TTY_WIDTH || '', 10);
this._liveTerminal = process.stdout.isTTY || process.env.PWTEST_SKIP_TEST_OUTPUT || !!this._ttyWidthForTest;
}

View file

@ -77,6 +77,13 @@ export class Runner {
html: HtmlReporter,
};
const reporters: Reporter[] = [];
const reporterConfig = this._loader.fullConfig().reporter;
if (reporterConfig.length === 1 && reporterConfig[0][0] === 'html') {
// For html reporter, add a line/dot report for convenience.
// Important to put html last because it stalls onEnd.
reporterConfig.unshift([process.stdout.isTTY && !process.env.CI ? 'line' : 'dot', { omitFailures: true }]);
}
for (const r of this._loader.fullConfig().reporter) {
const [name, arg] = r;
if (name in defaultReporters) {

View file

@ -31,30 +31,13 @@ test('print GitHub annotations for success', async ({ runInlineTest }) => {
expect(1 + 1).toBe(2);
});
`
}, { reporter: 'github' }, { GITHUB_ACTION: 'true' });
}, { reporter: 'github' });
const text = stripAscii(result.output);
expect(text).not.toContain('::error');
expect(text).toContain('::notice title=🎭 Playwright Run Summary::%0A 1 passed');
expect(text).toContain('::notice title=🎭 Playwright Run Summary:: 1 passed');
expect(result.exitCode).toBe(0);
});
test('print GitHub annotations with newline if not in CI', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.js': `
const { test } = pwt;
test('example1', async ({}) => {
expect(1 + 1).toBe(2);
});
`
}, { reporter: 'github' }, { GITHUB_ACTION: '' });
const text = stripAscii(result.output);
expect(text).not.toContain('::error');
expect(text).toContain(`::notice title=🎭 Playwright Run Summary::
1 passed `);
expect(result.exitCode).toBe(0);
});
test('print GitHub annotations for failed tests', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
'a.test.js': `
@ -63,7 +46,7 @@ test('print GitHub annotations for failed tests', async ({ runInlineTest }, test
expect(1 + 1).toBe(3);
});
`
}, { retries: 3, reporter: 'github' }, { GITHUB_ACTION: 'true', GITHUB_WORKSPACE: process.cwd() });
}, { retries: 3, reporter: 'github' }, { GITHUB_WORKSPACE: process.cwd() });
const text = stripAscii(result.output);
const testPath = relativeFilePath(testInfo.outputPath('a.test.js'));
expect(text).toContain(`::error file=${testPath},title=a.test.js:6:7 example,line=7,col=23:: 1) a.test.js:6:7 example =======================================================================%0A%0A Retry #1`);
@ -72,7 +55,6 @@ test('print GitHub annotations for failed tests', async ({ runInlineTest }, test
expect(result.exitCode).toBe(1);
});
test('print GitHub annotations for slow tests', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': `
@ -86,9 +68,9 @@ test('print GitHub annotations for slow tests', async ({ runInlineTest }) => {
await new Promise(f => setTimeout(f, 200));
});
`
}, { retries: 3, reporter: 'github' }, { GITHUB_ACTION: 'true', GITHUB_WORKSPACE: '' });
}, { retries: 3, reporter: 'github' }, { GITHUB_WORKSPACE: '' });
const text = stripAscii(result.output);
expect(text).toContain('::warning title=Slow Test,file=a.test.js::a.test.js took');
expect(text).toContain('::notice title=🎭 Playwright Run Summary::%0A 1 passed');
expect(text).toContain('::notice title=🎭 Playwright Run Summary:: 1 passed');
expect(result.exitCode).toBe(0);
});