mirror of
https://github.com/microsoft/playwright.git
synced 2024-09-11 20:37:54 +03:00
feat(merge): prepend bot name to global errors (#29055)
This way one can figure out where does the error come from. An example merged report that exhibits the issue: https://mspwblobreport.z1.web.core.windows.net/run-7563628632-1-2328b83af75801ab76bb06c214fee483cf5bc07c/index.html#?q=s%3Afailed%20s%3Aflaky
This commit is contained in:
parent
c76f5294ce
commit
b7d22b64e8
@ -26,12 +26,14 @@ import { Multiplexer } from './multiplexer';
|
|||||||
import { ZipFile, calculateSha1 } from 'playwright-core/lib/utils';
|
import { ZipFile, calculateSha1 } from 'playwright-core/lib/utils';
|
||||||
import { currentBlobReportVersion, type BlobReportMetadata } from './blob';
|
import { currentBlobReportVersion, type BlobReportMetadata } from './blob';
|
||||||
import { relativeFilePath } from '../util';
|
import { relativeFilePath } from '../util';
|
||||||
|
import type { TestError } from '../../types/testReporter';
|
||||||
|
|
||||||
type StatusCallback = (message: string) => void;
|
type StatusCallback = (message: string) => void;
|
||||||
|
|
||||||
type ReportData = {
|
type ReportData = {
|
||||||
eventPatchers: JsonEventPatchers;
|
eventPatchers: JsonEventPatchers;
|
||||||
reportFile: string;
|
reportFile: string;
|
||||||
|
metadata: BlobReportMetadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function createMergedReport(config: FullConfigInternal, dir: string, reporterDescriptions: ReporterDescription[], rootDirOverride: string | undefined) {
|
export async function createMergedReport(config: FullConfigInternal, dir: string, reporterDescriptions: ReporterDescription[], rootDirOverride: string | undefined) {
|
||||||
@ -65,11 +67,13 @@ export async function createMergedReport(config: FullConfigInternal, dir: string
|
|||||||
};
|
};
|
||||||
|
|
||||||
await dispatchEvents(eventData.prologue);
|
await dispatchEvents(eventData.prologue);
|
||||||
for (const { reportFile, eventPatchers } of eventData.reports) {
|
for (const { reportFile, eventPatchers, metadata } of eventData.reports) {
|
||||||
const reportJsonl = await fs.promises.readFile(reportFile);
|
const reportJsonl = await fs.promises.readFile(reportFile);
|
||||||
const events = parseTestEvents(reportJsonl);
|
const events = parseTestEvents(reportJsonl);
|
||||||
new JsonStringInternalizer(stringPool).traverse(events);
|
new JsonStringInternalizer(stringPool).traverse(events);
|
||||||
eventPatchers.patchers.push(new AttachmentPathPatcher(dir));
|
eventPatchers.patchers.push(new AttachmentPathPatcher(dir));
|
||||||
|
if (metadata.name)
|
||||||
|
eventPatchers.patchers.push(new GlobalErrorPatcher(metadata.name));
|
||||||
eventPatchers.patchEvents(events);
|
eventPatchers.patchEvents(events);
|
||||||
await dispatchEvents(events);
|
await dispatchEvents(events);
|
||||||
}
|
}
|
||||||
@ -213,6 +217,7 @@ async function mergeEvents(dir: string, shardReportFiles: string[], stringPool:
|
|||||||
reports.push({
|
reports.push({
|
||||||
eventPatchers,
|
eventPatchers,
|
||||||
reportFile: localPath,
|
reportFile: localPath,
|
||||||
|
metadata,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +470,24 @@ class PathSeparatorPatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GlobalErrorPatcher {
|
||||||
|
private _prefix: string;
|
||||||
|
|
||||||
|
constructor(botName: string) {
|
||||||
|
this._prefix = `(${botName}) `;
|
||||||
|
}
|
||||||
|
|
||||||
|
patchEvent(event: JsonEvent) {
|
||||||
|
if (event.method !== 'onError')
|
||||||
|
return;
|
||||||
|
const error = event.params.error as TestError;
|
||||||
|
if (error.message !== undefined)
|
||||||
|
error.message = this._prefix + error.message;
|
||||||
|
if (error.stack !== undefined)
|
||||||
|
error.stack = this._prefix + error.stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface JsonEventPatcher {
|
interface JsonEventPatcher {
|
||||||
patchEvent(event: JsonEvent): void;
|
patchEvent(event: JsonEvent): void;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +904,7 @@ test('onError in the report', async ({ runInlineTest, mergeReports, showReport,
|
|||||||
test.skip('skipped 3', async ({}) => {});
|
test.skip('skipped 3', async ({}) => {});
|
||||||
`
|
`
|
||||||
};
|
};
|
||||||
const result = await runInlineTest(files, { shard: `1/3` });
|
const result = await runInlineTest(files, { shard: `1/3` }, { PWTEST_BOT_NAME: 'macos-node16-ttest' });
|
||||||
expect(result.exitCode).toBe(1);
|
expect(result.exitCode).toBe(1);
|
||||||
|
|
||||||
const { exitCode } = await mergeReports(reportDir, { 'PW_TEST_HTML_REPORT_OPEN': 'never' }, { additionalArgs: ['--reporter', 'html'] });
|
const { exitCode } = await mergeReports(reportDir, { 'PW_TEST_HTML_REPORT_OPEN': 'never' }, { additionalArgs: ['--reporter', 'html'] });
|
||||||
@ -917,6 +917,7 @@ test('onError in the report', async ({ runInlineTest, mergeReports, showReport,
|
|||||||
await expect(page.locator('.subnav-item:has-text("Failed") .counter')).toHaveText('0');
|
await expect(page.locator('.subnav-item:has-text("Failed") .counter')).toHaveText('0');
|
||||||
await expect(page.locator('.subnav-item:has-text("Flaky") .counter')).toHaveText('0');
|
await expect(page.locator('.subnav-item:has-text("Flaky") .counter')).toHaveText('0');
|
||||||
await expect(page.locator('.subnav-item:has-text("Skipped") .counter')).toHaveText('1');
|
await expect(page.locator('.subnav-item:has-text("Skipped") .counter')).toHaveText('1');
|
||||||
|
await expect(page.getByTestId('report-errors')).toContainText('(macos-node16-ttest) Error: Error in teardown');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('preserve config fields', async ({ runInlineTest, mergeReports }) => {
|
test('preserve config fields', async ({ runInlineTest, mergeReports }) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user