mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-11 12:33:45 +03:00
fix: preserve steps in merged report (#23120)
This commit is contained in:
parent
acdb71878e
commit
a1fc8ff07d
@ -28,7 +28,7 @@ export type JsonConfig = Pick<FullConfig, 'configFile' | 'globalTimeout' | 'maxF
|
||||
listOnly: boolean;
|
||||
};
|
||||
|
||||
export type MergeReporterConfig = Pick<FullConfig, 'configFile' | 'reportSlowTests' | 'quiet' >;
|
||||
export type MergeReporterConfig = Pick<FullConfig, 'configFile' | 'quiet' | 'reportSlowTests' | 'rootDir' >;
|
||||
|
||||
export type JsonPattern = {
|
||||
s?: string;
|
||||
@ -171,7 +171,7 @@ export class TeleReporterReceiver {
|
||||
}
|
||||
|
||||
private _onBegin(config: JsonConfig, projects: JsonProject[]) {
|
||||
this._rootDir = config.rootDir;
|
||||
this._rootDir = this._reportConfig?.rootDir || config.rootDir;
|
||||
for (const project of projects) {
|
||||
let projectSuite = this._rootSuite.suites.find(suite => suite.project()!.id === project.id);
|
||||
if (!projectSuite) {
|
||||
@ -247,6 +247,8 @@ export class TeleReporterReceiver {
|
||||
};
|
||||
if (parentStep)
|
||||
parentStep.steps.push(step);
|
||||
else
|
||||
result.steps.push(step);
|
||||
result.stepMap.set(payload.id, step);
|
||||
this._reporter.onStepBegin?.(test, result, step);
|
||||
}
|
||||
@ -286,6 +288,7 @@ export class TeleReporterReceiver {
|
||||
const result = { ...baseFullConfig, ...config };
|
||||
if (this._reportConfig) {
|
||||
result.configFile = this._reportConfig.configFile;
|
||||
result.rootDir = this._reportConfig.rootDir;
|
||||
result.reportSlowTests = this._reportConfig.reportSlowTests;
|
||||
result.quiet = this._reportConfig.quiet;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import type { FullConfig, ReporterDescription } from '../../types/test';
|
||||
import type { ReporterDescription } from '../../types/test';
|
||||
import type { FullResult } from '../../types/testReporter';
|
||||
import type { FullConfigInternal } from '../common/config';
|
||||
import { TeleReporterReceiver, type JsonEvent, type JsonProject, type JsonSuite, type JsonTestResultEnd, type JsonConfig } from '../isomorphic/teleReceiver';
|
||||
@ -25,7 +25,7 @@ import { Multiplexer } from './multiplexer';
|
||||
|
||||
export async function createMergedReport(config: FullConfigInternal, dir: string, reporterDescriptions: ReporterDescription[], resolvePaths: boolean) {
|
||||
const shardFiles = await sortedShardFiles(dir);
|
||||
const events = await mergeEvents(dir, shardFiles, config.config);
|
||||
const events = await mergeEvents(dir, shardFiles);
|
||||
if (resolvePaths)
|
||||
patchAttachmentPaths(events, dir);
|
||||
|
||||
@ -53,7 +53,7 @@ function parseEvents(reportJsonl: string): JsonEvent[] {
|
||||
return reportJsonl.toString().split('\n').filter(line => line.length).map(line => JSON.parse(line)) as JsonEvent[];
|
||||
}
|
||||
|
||||
async function mergeEvents(dir: string, shardReportFiles: string[], reportConfig: FullConfig) {
|
||||
async function mergeEvents(dir: string, shardReportFiles: string[]) {
|
||||
const events: JsonEvent[] = [];
|
||||
const beginEvents: JsonEvent[] = [];
|
||||
const endEvents: JsonEvent[] = [];
|
||||
@ -69,10 +69,10 @@ async function mergeEvents(dir: string, shardReportFiles: string[], reportConfig
|
||||
events.push(event);
|
||||
}
|
||||
}
|
||||
return [mergeBeginEvents(beginEvents, reportConfig), ...events, mergeEndEvents(endEvents), { method: 'onExit', params: undefined }];
|
||||
return [mergeBeginEvents(beginEvents), ...events, mergeEndEvents(endEvents), { method: 'onExit', params: undefined }];
|
||||
}
|
||||
|
||||
function mergeBeginEvents(beginEvents: JsonEvent[], reportConfig: FullConfig): JsonEvent {
|
||||
function mergeBeginEvents(beginEvents: JsonEvent[]): JsonEvent {
|
||||
if (!beginEvents.length)
|
||||
throw new Error('No begin events found');
|
||||
const projects: JsonProject[] = [];
|
||||
|
@ -47,10 +47,11 @@ const test = baseTest.extend<{
|
||||
if (options.additionalArgs)
|
||||
command.push(...options.additionalArgs);
|
||||
|
||||
const cwd = options.cwd ? path.resolve(test.info().outputDir, options.cwd) : test.info().outputDir;
|
||||
const testProcess = childProcess({
|
||||
command,
|
||||
env: cleanEnv(env),
|
||||
cwd: test.info().outputDir,
|
||||
cwd,
|
||||
});
|
||||
const { exitCode } = await testProcess.exited;
|
||||
return { exitCode, output: testProcess.output.toString() };
|
||||
@ -409,14 +410,12 @@ test('preserve attachments', async ({ runInlineTest, mergeReports, showReport, p
|
||||
|
||||
await showReport();
|
||||
|
||||
// Check file attachment.
|
||||
await page.getByText('first').click();
|
||||
await expect(page.getByText('file-attachment')).toBeVisible();
|
||||
|
||||
// Check file attachment content.
|
||||
const popupPromise = page.waitForEvent('popup');
|
||||
await page.getByText('file-attachment').click();
|
||||
// Check file attachment.
|
||||
await page.getByRole('link', { name: 'file-attachment' }).click();
|
||||
const popup = await popupPromise;
|
||||
// Check file attachment content.
|
||||
await expect(popup.locator('body')).toHaveText('hello!');
|
||||
await popup.close();
|
||||
await page.goBack();
|
||||
@ -484,15 +483,14 @@ test('generate html with attachment urls', async ({ runInlineTest, mergeReports,
|
||||
return oldSeveFile.call(server, req, res, filePath);
|
||||
};
|
||||
|
||||
// Check file attachment.
|
||||
await page.goto(`${server.PREFIX}/index.html`);
|
||||
await page.getByText('first').click();
|
||||
await expect(page.getByText('file-attachment')).toBeVisible();
|
||||
|
||||
// Check file attachment content.
|
||||
const popupPromise = page.waitForEvent('popup');
|
||||
await page.getByText('file-attachment').click();
|
||||
// Check file attachment.
|
||||
await page.getByRole('link', { name: 'file-attachment' }).click();
|
||||
const popup = await popupPromise;
|
||||
// Check file attachment content.
|
||||
await expect(popup.locator('body')).toHaveText('hello!');
|
||||
await popup.close();
|
||||
await page.goBack();
|
||||
@ -846,4 +844,58 @@ test('preserve config fields', async ({ runInlineTest, mergeReports }) => {
|
||||
expect(json.reportSlowTests).toEqual(mergeConfig.reportSlowTests);
|
||||
expect(json.configFile).toEqual(test.info().outputPath('merge.config.ts'));
|
||||
expect(json.quiet).toEqual(mergeConfig.quiet);
|
||||
});
|
||||
|
||||
test('preserve steps in html report', async ({ runInlineTest, mergeReports, showReport, page }) => {
|
||||
test.slow();
|
||||
const reportDir = test.info().outputPath('blob-report');
|
||||
const files = {
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
reporter: [['blob']]
|
||||
};
|
||||
`,
|
||||
'tests/a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test.beforeAll(() => {
|
||||
expect(1).toBe(1);
|
||||
})
|
||||
test('test 1', async ({}) => {
|
||||
await test.step('my step', async () => {
|
||||
expect(2).toBe(2);
|
||||
});
|
||||
});
|
||||
`,
|
||||
};
|
||||
await runInlineTest(files);
|
||||
const reportFiles = await fs.promises.readdir(reportDir);
|
||||
reportFiles.sort();
|
||||
expect(reportFiles).toEqual([expect.stringMatching(/report-.*.jsonl/), 'resources']);
|
||||
// Run merger in a different directory to make sure relative paths will not be resolved
|
||||
// relative to the current directory.
|
||||
const mergeCwd = test.info().outputPath('foo');
|
||||
await fs.promises.mkdir(mergeCwd, { recursive: true });
|
||||
const { exitCode, output } = await mergeReports(reportDir, { 'PW_TEST_HTML_REPORT_OPEN': 'never' }, { additionalArgs: ['--reporter', 'html'], cwd: mergeCwd });
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
expect(output).toContain('To open last HTML report run:');
|
||||
|
||||
await showReport();
|
||||
|
||||
await expect(page.locator('.subnav-item:has-text("All") .counter')).toHaveText('1');
|
||||
await expect(page.locator('.subnav-item:has-text("Passed") .counter')).toHaveText('1');
|
||||
|
||||
await page.getByRole('link', { name: 'test 1' }).click();
|
||||
|
||||
await page.getByText('Before Hooks').click();
|
||||
await page.getByText('beforeAll hook').click();
|
||||
await expect(page.getByText('expect.toBe')).toBeVisible();
|
||||
// Collapse hooks.
|
||||
await page.getByText('Before Hooks').click();
|
||||
await expect(page.getByText('expect.toBe')).not.toBeVisible();
|
||||
|
||||
// Check that 'my step' location is relative.
|
||||
await expect(page.getByText('— tests/a.test.js:7')).toBeVisible();
|
||||
await page.getByText('my step').click();
|
||||
await expect(page.getByText('expect.toBe')).toBeVisible();
|
||||
});
|
Loading…
Reference in New Issue
Block a user