diff --git a/packages/playwright/src/reporters/versions/blobV1.ts b/packages/playwright/src/reporters/versions/blobV1.ts new file mode 100644 index 0000000000..5ea9350285 --- /dev/null +++ b/packages/playwright/src/reporters/versions/blobV1.ts @@ -0,0 +1,127 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Metadata } from '../../../types/test'; +import type * as reporterTypes from '../../../types/testReporter'; + +export type JsonLocation = reporterTypes.Location; +export type JsonError = string; +export type JsonStackFrame = { file: string, line: number, column: number }; + +export type JsonStdIOType = 'stdout' | 'stderr'; + +export type JsonConfig = Pick; + +export type JsonPattern = { + s?: string; + r?: { source: string, flags: string }; +}; + +export type JsonProject = { + grep: JsonPattern[]; + grepInvert: JsonPattern[]; + metadata: Metadata; + name: string; + dependencies: string[]; + // This is relative to root dir. + snapshotDir: string; + // This is relative to root dir. + outputDir: string; + repeatEach: number; + retries: number; + suites: JsonSuite[]; + teardown?: string; + // This is relative to root dir. + testDir: string; + testIgnore: JsonPattern[]; + testMatch: JsonPattern[]; + timeout: number; +}; + +export type JsonSuite = { + title: string; + location?: JsonLocation; + suites: JsonSuite[]; + tests: JsonTestCase[]; +}; + +export type JsonTestCase = { + testId: string; + title: string; + location: JsonLocation; + retries: number; + tags?: string[]; + repeatEachIndex: number; +}; + +export type JsonTestEnd = { + testId: string; + expectedStatus: reporterTypes.TestStatus; + timeout: number; + annotations: { type: string, description?: string }[]; +}; + +export type JsonTestResultStart = { + id: string; + retry: number; + workerIndex: number; + parallelIndex: number; + startTime: number; +}; + +export type JsonAttachment = Omit & { base64?: string }; + +export type JsonTestResultEnd = { + id: string; + duration: number; + status: reporterTypes.TestStatus; + errors: reporterTypes.TestError[]; + attachments: JsonAttachment[]; +}; + +export type JsonTestStepStart = { + id: string; + parentStepId?: string; + title: string; + category: string, + startTime: number; + location?: reporterTypes.Location; +}; + +export type JsonTestStepEnd = { + id: string; + duration: number; + error?: reporterTypes.TestError; +}; + +export type JsonFullResult = { + status: reporterTypes.FullResult['status']; + startTime: number; + duration: number; +}; + +export type JsonEvent = { + method: string; + params: any +}; + +export type BlobReportMetadata = { + version: number; + userAgent: string; + name?: string; + shard?: { total: number, current: number }; + pathSeparator?: string; +}; diff --git a/tests/assets/blob-1.42.zip b/tests/assets/blob-1.42.zip new file mode 100644 index 0000000000..da16671ccc Binary files /dev/null and b/tests/assets/blob-1.42.zip differ diff --git a/tests/playwright-test/reporter-blob.spec.ts b/tests/playwright-test/reporter-blob.spec.ts index e12ec3c069..adf1f56ab0 100644 --- a/tests/playwright-test/reporter-blob.spec.ts +++ b/tests/playwright-test/reporter-blob.spec.ts @@ -1741,3 +1741,52 @@ test('TestSuite.project() should return owning project', async ({ runInlineTest, expect(exitCode).toBe(0); expect(output).toContain(`test project: my-project`); }); + +test('open blob-1.42', async ({ runInlineTest, mergeReports }) => { + test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29984' }); + await runInlineTest({ + 'echo-reporter.js': ` + export default class EchoReporter { + lines = []; + onTestBegin(test) { + this.lines.push(test.titlePath().join(' > ')); + } + onEnd() { + console.log(this.lines.join('\\n')); + } + }; + `, + 'merge.config.ts': `module.exports = { + testDir: 'mergeRoot', + reporter: './echo-reporter.js' + };`, + }); + + const blobDir = test.info().outputPath('blob-report'); + await fs.promises.mkdir(blobDir, { recursive: true }); + await fs.promises.copyFile(path.join(__dirname, '../assets/blob-1.42.zip'), path.join(blobDir, 'blob-1.42.zip')); + + const { exitCode, output } = await mergeReports(blobDir, undefined, { additionalArgs: ['--config', 'merge.config.ts'] }); + expect(exitCode).toBe(0); + expect(output).toContain(` > chromium > example.spec.ts > test 0 + > chromium > example.spec.ts > describe 1 > describe 2 > test 3 + > chromium > example.spec.ts > describe 1 > describe 2 > test 4 + > chromium > example.spec.ts > describe 1 > describe 2 > test 2 + > chromium > example.spec.ts > describe 1 > test 1 + > chromium > example.spec.ts > describe 1 > test 5 + > chromium > example.spec.ts > test 6 + > firefox > example.spec.ts > describe 1 > describe 2 > test 2 + > firefox > example.spec.ts > describe 1 > describe 2 > test 3 + > firefox > example.spec.ts > test 0 + > firefox > example.spec.ts > describe 1 > describe 2 > test 4 + > firefox > example.spec.ts > describe 1 > test 1 + > firefox > example.spec.ts > test 6 + > firefox > example.spec.ts > describe 1 > test 5 + > webkit > example.spec.ts > describe 1 > describe 2 > test 4 + > webkit > example.spec.ts > test 0 + > webkit > example.spec.ts > describe 1 > test 1 + > webkit > example.spec.ts > describe 1 > describe 2 > test 2 + > webkit > example.spec.ts > describe 1 > describe 2 > test 3 + > webkit > example.spec.ts > test 6 + > webkit > example.spec.ts > describe 1 > test 5`); +});