fix: consider project suffix when computing id (#23270)

This commit is contained in:
Yury Semikhatsky 2023-05-25 10:36:34 -07:00 committed by GitHub
parent e0600f4799
commit dce730c3be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 31 deletions

View file

@ -154,6 +154,10 @@ export class FullProjectInternal {
deps: FullProjectInternal[] = [];
teardown: FullProjectInternal | undefined;
static from(config: FullProject): FullProjectInternal {
return (config as any)[projectInternalSymbol];
}
constructor(configDir: string, config: Config, fullConfig: FullConfigInternal, projectConfig: Project, configCLIOverrides: ConfigCLIOverrides, throwawayArtifactsPath: string) {
this.fullConfig = fullConfig;
const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);

View file

@ -19,7 +19,6 @@ import path from 'path';
import type { FullConfig, TestCase, Suite, TestResult, TestError, FullResult, TestStep, Location, Reporter } from '../../types/testReporter';
import type { SuitePrivate } from '../../types/reporterPrivate';
import { monotonicTime } from 'playwright-core/lib/utils';
import type { FullProject } from '../../types/test';
export type TestResultOutput = { chunk: string | Buffer, type: 'stdout' | 'stderr' };
export const kOutputSymbol = Symbol('output');
@ -498,23 +497,6 @@ function fitToWidth(line: string, width: number, prefix?: string): string {
return taken.reverse().join('');
}
export function uniqueProjectIds(projects: FullProject[]): Map<FullProject, string> {
const usedNames = new Set<string>();
const result = new Map<FullProject, string>();
for (const p of projects) {
const name = p.name || '';
for (let i = 0; i < projects.length; ++i) {
const candidate = name + (i ? i : '');
if (usedNames.has(candidate))
continue;
result.set(p, candidate);
usedNames.add(candidate);
break;
}
}
return result;
}
function belongsToNodeModules(file: string) {
return file.includes(`${path.sep}node_modules${path.sep}`);
}

View file

@ -17,10 +17,10 @@
import fs from 'fs';
import path from 'path';
import type { FullConfig, TestCase, Suite, TestResult, TestError, TestStep, FullResult, Location, Reporter, JSONReport, JSONReportSuite, JSONReportSpec, JSONReportTest, JSONReportTestResult, JSONReportTestStep, JSONReportError } from '../../types/testReporter';
import { formatError, prepareErrorStack, uniqueProjectIds } from './base';
import { formatError, prepareErrorStack } from './base';
import { MultiMap } from 'playwright-core/lib/utils';
import { assert } from 'playwright-core/lib/utils';
import type { FullProject } from '../../types/test';
import { FullProjectInternal } from '../common/config';
export function toPosixPath(aPath: string): string {
return aPath.split(path.sep).join(path.posix.sep);
@ -54,7 +54,6 @@ class JSONReporter implements Reporter {
}
private _serializeReport(): JSONReport {
const projectIds = uniqueProjectIds(this.config.projects);
return {
config: {
...removePrivateFields(this.config),
@ -65,7 +64,7 @@ class JSONReporter implements Reporter {
repeatEach: project.repeatEach,
retries: project.retries,
metadata: project.metadata,
id: projectIds.get(project)!,
id: FullProjectInternal.from(project).id,
name: project.name,
testDir: toPosixPath(project.testDir),
testIgnore: serializePatterns(project.testIgnore),
@ -74,15 +73,15 @@ class JSONReporter implements Reporter {
};
})
},
suites: this._mergeSuites(this.suite.suites, projectIds),
suites: this._mergeSuites(this.suite.suites),
errors: this._errors
};
}
private _mergeSuites(suites: Suite[], projectIds: Map<FullProject, string>): JSONReportSuite[] {
private _mergeSuites(suites: Suite[]): JSONReportSuite[] {
const fileSuites = new MultiMap<string, JSONReportSuite>();
for (const projectSuite of suites) {
const projectId = projectIds.get(projectSuite.project()!)!;
const projectId = FullProjectInternal.from(projectSuite.project()!).id;
const projectName = projectSuite.project()!.name;
for (const fileSuite of projectSuite.suites) {
const file = fileSuite.location!.file;

View file

@ -23,7 +23,6 @@ import { createGuid } from 'playwright-core/lib/utils';
import { serializeRegexPatterns } from '../isomorphic/teleReceiver';
import path from 'path';
import type { FullProject } from '../../types/test';
import { uniqueProjectIds } from './base';
export class TeleReporterEmitter implements Reporter {
private _messageSink: (message: any) => void;
@ -36,7 +35,7 @@ export class TeleReporterEmitter implements Reporter {
onBegin(config: FullConfig, suite: Suite) {
this._rootDir = config.rootDir;
const projects: any[] = [];
const projectIds = uniqueProjectIds(config.projects);
const projectIds = this._uniqueProjectIds(config.projects);
for (const projectSuite of suite.suites) {
const report = this._serializeProject(projectSuite, projectIds);
projects.push(report);
@ -139,6 +138,23 @@ export class TeleReporterEmitter implements Reporter {
};
}
private _uniqueProjectIds(projects: FullProject[]): Map<FullProject, string> {
const usedNames = new Set<string>();
const result = new Map<FullProject, string>();
for (const p of projects) {
const name = this._serializeProjectName(p.name);
for (let i = 0; i < projects.length; ++i) {
const candidate = name + (i ? i : '');
if (usedNames.has(candidate))
continue;
result.set(p, candidate);
usedNames.add(candidate);
break;
}
}
return result;
}
private _serializeProject(suite: Suite, projectIds: Map<FullProject, string>): JsonProject {
const project = suite.project()!;
const report: JsonProject = {

View file

@ -908,7 +908,6 @@ test('custom project suffix', async ({ runInlineTest, mergeReports }) => {
`,
'playwright.config.ts': `
module.exports = {
retries: 1,
reporter: 'blob',
projects: [
{ name: 'foo' },
@ -918,9 +917,7 @@ test('custom project suffix', async ({ runInlineTest, mergeReports }) => {
`,
'a.test.js': `
import { test, expect } from '@playwright/test';
test('math 1', async ({}) => {
expect(1 + 1).toBe(2);
});
test('math 1', async ({}) => {});
`,
};
@ -930,3 +927,40 @@ test('custom project suffix', async ({ runInlineTest, mergeReports }) => {
expect(exitCode).toBe(0);
expect(output).toContain(`projects: [ 'foo-suffix', 'bar-suffix' ]`);
});
test('same project different suffixes', async ({ runInlineTest, mergeReports }) => {
const files = {
'echo-reporter.js': `
import fs from 'fs';
class EchoReporter {
onBegin(config, suite) {
const projects = suite.suites.map(s => s.project().name);
projects.sort();
console.log('projects:', projects);
}
}
module.exports = EchoReporter;
`,
'playwright.config.ts': `
module.exports = {
reporter: 'blob',
projects: [
{ name: 'foo' },
]
};
`,
'a.test.js': `
import { test, expect } from '@playwright/test';
test('math 1', async ({}) => {});
`,
};
await runInlineTest(files, undefined, { PWTEST_BLOB_SUFFIX: '-first' });
await runInlineTest(files, undefined, { PWTEST_BLOB_SUFFIX: '-second' });
const reportDir = test.info().outputPath('blob-report');
const { exitCode, output } = await mergeReports(reportDir, {}, { additionalArgs: ['--reporter', test.info().outputPath('echo-reporter.js')] });
expect(exitCode).toBe(0);
expect(output).toContain(`projects: [ 'foo-first', 'foo-second' ]`);
});