Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/src/test-api/class-testinfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ test('basic test', async ({ page }, testInfo) => {
- type: <[Array]<[Object]>>
- `type` <[string]> Annotation type, for example `'skip'` or `'fail'`.
- `description` ?<[string]> Optional description.
- `location` ?<[Location]> Optional location in the source where the annotation is added.

The list of annotations applicable to the current test. Includes annotations from the test, annotations from all [`method: Test.describe`] groups the test belongs to and file-level annotations for the test file.

Expand Down
1 change: 0 additions & 1 deletion docs/src/test-reporter-api/class-testcase.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
- type: <[Array]<[Object]>>
- `type` <[string]> Annotation type, for example `'skip'` or `'fail'`.
- `description` ?<[string]> Optional description.
- `location` ?<[Location]> Optional location in the source where the annotation is added.

[`property: TestResult.annotations`] of the last test run.

Expand Down
1 change: 0 additions & 1 deletion docs/src/test-reporter-api/class-testresult.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ The list of files or buffers attached during the test execution through [`proper
- type: <[Array]<[Object]>>
- `type` <[string]> Annotation type, for example `'skip'` or `'fail'`.
- `description` ?<[string]> Optional description.
- `location` ?<[Location]> Optional location in the source where the annotation is added.

The list of annotations applicable to the current test. Includes:
* annotations defined on the test or suite via [`method: Test.(call)`] and [`method: Test.describe`];
Expand Down
1 change: 0 additions & 1 deletion docs/src/test-reporter-api/class-teststep.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ List of steps inside this step.
- type: <[Array]<[Object]>>
- `type` <[string]> Annotation type, for example `'skip'`.
- `description` ?<[string]> Optional description.
- `location` ?<[Location]> Optional location in the source where the annotation is added.

The list of annotations applicable to the current test step.

Expand Down
3 changes: 1 addition & 2 deletions packages/html-reporter/src/testCaseView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
limitations under the License.
*/

import type { TestAnnotation } from '@playwright/test';
import type { TestCase, TestCaseSummary } from './types';
import type { TestCase, TestAnnotation, TestCaseSummary } from './types';
import * as React from 'react';
import { TabbedPane } from './tabbedPane';
import { AutoChip } from './chip';
Expand Down
4 changes: 3 additions & 1 deletion packages/html-reporter/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type { TestAnnotation, Metadata } from '@playwright/test';
import type { Metadata } from '@playwright/test';

export type Stats = {
total: number;
Expand Down Expand Up @@ -59,6 +59,8 @@ export type TestFileSummary = {
stats: Stats;
};

export type TestAnnotation = { type: string, description?: string };

export type TestCaseSummary = {
testId: string,
title: string;
Expand Down
1 change: 1 addition & 0 deletions packages/playwright/src/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type FixturesWithLocation = {
fixtures: Fixtures;
location: Location;
};
export type Annotation = { type: string, description?: string };

export const defaultTimeout = 30000;

Expand Down
7 changes: 3 additions & 4 deletions packages/playwright/src/common/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
import { rootTestType } from './testType';
import { computeTestCaseOutcome } from '../isomorphic/teleReceiver';

import type { FixturesWithLocation, FullProjectInternal } from './config';
import type { Annotation, FixturesWithLocation, FullProjectInternal } from './config';
import type { FixturePool } from './fixtures';
import type { TestTypeImpl } from './testType';
import type { TestAnnotation } from '../../types/test';
import type * as reporterTypes from '../../types/testReporter';
import type { FullProject, Location } from '../../types/testReporter';

Expand Down Expand Up @@ -51,7 +50,7 @@ export class Suite extends Base {
_timeout: number | undefined;
_retries: number | undefined;
// Annotations known statically before running the test, e.g. `test.describe.skip()` or `test.describe({ annotation }, body)`.
_staticAnnotations: TestAnnotation[] = [];
_staticAnnotations: Annotation[] = [];
// Explicitly declared tags that are not a part of the title.
_tags: string[] = [];
_modifiers: Modifier[] = [];
Expand Down Expand Up @@ -253,7 +252,7 @@ export class TestCase extends Base implements reporterTypes.TestCase {

expectedStatus: reporterTypes.TestStatus = 'passed';
timeout = 0;
annotations: TestAnnotation[] = [];
annotations: Annotation[] = [];
retries = 0;
repeatEachIndex = 0;

Expand Down
21 changes: 10 additions & 11 deletions packages/playwright/src/common/testType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class TestTypeImpl {
details = fnOrDetails;
}

const validatedDetails = validateTestDetails(details, location);
const validatedDetails = validateTestDetails(details);
const test = new TestCase(title, body, this, location);
test._requireFile = suite._requireFile;
test.annotations.push(...validatedDetails.annotations);
Expand All @@ -114,9 +114,9 @@ export class TestTypeImpl {
if (type === 'only' || type === 'fail.only')
test._only = true;
if (type === 'skip' || type === 'fixme' || type === 'fail')
test.annotations.push({ type, location });
test.annotations.push({ type });
else if (type === 'fail.only')
test.annotations.push({ type: 'fail', location });
test.annotations.push({ type: 'fail' });
}

private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only' | 'skip' | 'fixme', location: Location, titleOrFn: string | Function, fnOrDetails?: TestDetails | Function, fn?: Function) {
Expand All @@ -143,7 +143,7 @@ export class TestTypeImpl {
body = fn!;
}

const validatedDetails = validateTestDetails(details, location);
const validatedDetails = validateTestDetails(details);
const child = new Suite(title, 'describe');
child._requireFile = suite._requireFile;
child.location = location;
Expand All @@ -158,7 +158,7 @@ export class TestTypeImpl {
if (type === 'parallel' || type === 'parallel.only')
child._parallelMode = 'parallel';
if (type === 'skip' || type === 'fixme')
child._staticAnnotations.push({ type, location });
child._staticAnnotations.push({ type });

for (let parent: Suite | undefined = suite; parent; parent = parent.parent) {
if (parent._parallelMode === 'serial' && child._parallelMode === 'parallel')
Expand Down Expand Up @@ -229,7 +229,7 @@ export class TestTypeImpl {
if (modifierArgs.length >= 1 && !modifierArgs[0])
return;
const description = modifierArgs[1];
suite._staticAnnotations.push({ type, description, location });
suite._staticAnnotations.push({ type, description });
}
return;
}
Expand All @@ -239,7 +239,7 @@ export class TestTypeImpl {
throw new Error(`test.${type}() can only be called inside test, describe block or fixture`);
if (typeof modifierArgs[0] === 'function')
throw new Error(`test.${type}() with a function can only be called inside describe block`);
testInfo._modifier(type, location, modifierArgs as [any, any]);
testInfo[type](...modifierArgs as [any, any]);
}

private _setTimeout(location: Location, timeout: number) {
Expand Down Expand Up @@ -276,7 +276,7 @@ export class TestTypeImpl {
let result: Awaited<ReturnType<typeof raceAgainstDeadline<T>>> | undefined = undefined;
result = await raceAgainstDeadline(async () => {
try {
return await step.info._runStepBody(expectation === 'skip', body, step.location);
return await step.info._runStepBody(expectation === 'skip', body);
} catch (e) {
// If the step timed out, the test fixtures will tear down, which in turn
// will abort unfinished actions in the step body. Record such errors here.
Expand Down Expand Up @@ -315,9 +315,8 @@ function throwIfRunningInsideJest() {
}
}

function validateTestDetails(details: TestDetails, location: Location) {
const originalAnnotations = Array.isArray(details.annotation) ? details.annotation : (details.annotation ? [details.annotation] : []);
const annotations = originalAnnotations.map(annotation => ({ ...annotation, location }));
function validateTestDetails(details: TestDetails) {
const annotations = Array.isArray(details.annotation) ? details.annotation : (details.annotation ? [details.annotation] : []);
const tags = Array.isArray(details.tag) ? details.tag : (details.tag ? [details.tag] : []);
for (const tag of tags) {
if (tag[0] !== '@')
Expand Down
23 changes: 8 additions & 15 deletions packages/playwright/src/isomorphic/teleReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
* limitations under the License.
*/

import type { Metadata, TestAnnotation } from '../../types/test';
import type { Metadata } from '../../types/test';
import type * as reporterTypes from '../../types/testReporter';
import type { Annotation } from '../common/config';
import type { ReporterV2 } from '../reporters/reporterV2';

export type StringIntern = (s: string) => string;
Expand Down Expand Up @@ -67,7 +68,7 @@ export type JsonTestCase = {
retries: number;
tags?: string[];
repeatEachIndex: number;
annotations?: TestAnnotation[];
annotations?: Annotation[];
};

export type JsonTestEnd = {
Expand All @@ -94,7 +95,7 @@ export type JsonTestResultEnd = {
status: reporterTypes.TestStatus;
errors: reporterTypes.TestError[];
attachments: JsonAttachment[];
annotations?: TestAnnotation[];
annotations?: Annotation[];
};

export type JsonTestStepStart = {
Expand All @@ -111,7 +112,7 @@ export type JsonTestStepEnd = {
duration: number;
error?: reporterTypes.TestError;
attachments?: number[]; // index of JsonTestResultEnd.attachments
annotations?: TestAnnotation[];
annotations?: Annotation[];
};

export type JsonFullResult = {
Expand Down Expand Up @@ -242,7 +243,7 @@ export class TeleReporterReceiver {
result.error = result.errors?.[0];
result.attachments = this._parseAttachments(payload.attachments);
if (payload.annotations) {
result.annotations = this._absoluteAnnotationLocations(payload.annotations);
result.annotations = payload.annotations;
test.annotations = result.annotations;
}
this._reporter.onTestEnd?.(test, result);
Expand Down Expand Up @@ -374,18 +375,10 @@ export class TeleReporterReceiver {
test.location = this._absoluteLocation(payload.location);
test.retries = payload.retries;
test.tags = payload.tags ?? [];
test.annotations = this._absoluteAnnotationLocations(payload.annotations ?? []);
test.annotations = payload.annotations ?? [];
return test;
}

private _absoluteAnnotationLocations(annotations: TestAnnotation[]): TestAnnotation[] {
return annotations.map(annotation => {
if (annotation.location)
annotation.location = this._absoluteLocation(annotation.location);
return annotation;
});
}

private _absoluteLocation(location: reporterTypes.Location): reporterTypes.Location;
private _absoluteLocation(location?: reporterTypes.Location): reporterTypes.Location | undefined;
private _absoluteLocation(location: reporterTypes.Location | undefined): reporterTypes.Location | undefined {
Expand Down Expand Up @@ -486,7 +479,7 @@ export class TeleTestCase implements reporterTypes.TestCase {

expectedStatus: reporterTypes.TestStatus = 'passed';
timeout = 0;
annotations: TestAnnotation[] = [];
annotations: Annotation[] = [];
retries = 0;
tags: string[] = [];
repeatEachIndex = 0;
Expand Down
22 changes: 0 additions & 22 deletions packages/playwright/src/reporters/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { getEastAsianWidth } from '../utilsBundle';
import type { ReporterV2 } from './reporterV2';
import type { FullConfig, FullResult, Location, Suite, TestCase, TestError, TestResult, TestStep } from '../../types/testReporter';
import type { Colors } from '@isomorphic/colors';
import type { TestAnnotation } from '../../types/test';

export type TestResultOutput = { chunk: string | Buffer, type: 'stdout' | 'stderr' };
export const kOutputSymbol = Symbol('output');
Expand Down Expand Up @@ -377,27 +376,6 @@ export function formatFailure(screen: Screen, config: FullConfig, test: TestCase
return lines.join('\n');
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function formatTestWarning(screen: Screen, config: FullConfig, warnings: TestAnnotation[]): string[] {
warnings.sort((a, b) => {
const aLocationKey = a.location ? `${a.location.file}:${a.location.line}:${a.location.column}` : undefined;
const bLocationKey = b.location ? `${b.location.file}:${b.location.line}:${b.location.column}` : undefined;

if (!aLocationKey && !bLocationKey)
return 0;
if (!aLocationKey)
return 1;
if (!bLocationKey)
return -1;
return aLocationKey.localeCompare(bLocationKey);
});

return warnings.filter(w => !!w.description).map(w => {
const location = !!w.location ? `${relativeFilePath(screen, config, w.location.file)}:${w.location.line}:${w.location.column}: ` : '';
return `${screen.colors.yellow(` Warning: ${location}${w.description}`)}`;
});
}

export function formatRetry(screen: Screen, result: TestResult) {
const retryLines = [];
if (result.retry) {
Expand Down
6 changes: 3 additions & 3 deletions packages/playwright/src/reporters/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ import { codeFrameColumns } from '../transform/babelBundle';
import { resolveReporterOutputPath, stripAnsiEscapes } from '../util';

import type { ReporterV2 } from './reporterV2';
import type { Metadata, TestAnnotation } from '../../types/test';
import type { Metadata } from '../../types/test';
import type * as api from '../../types/testReporter';
import type { HTMLReport, Stats, TestAttachment, TestCase, TestCaseSummary, TestFile, TestFileSummary, TestResult, TestStep } from '@html-reporter/types';
import type { HTMLReport, Stats, TestAttachment, TestCase, TestCaseSummary, TestFile, TestFileSummary, TestResult, TestStep, TestAnnotation } from '@html-reporter/types';
import type { ZipFile } from 'playwright-core/lib/zipBundle';
import type { TransformCallback } from 'stream';

Expand Down Expand Up @@ -503,7 +503,7 @@ class HtmlBuilder {

private _serializeAnnotations(annotations: api.TestCase['annotations']): TestAnnotation[] {
// Annotations can be pushed directly, with a wrong type.
return annotations.map(a => ({ type: a.type, description: a.description === undefined ? undefined : String(a.description), location: a.location }));
return annotations.map(a => ({ type: a.type, description: a.description === undefined ? undefined : String(a.description) }));
}

private _createTestResult(test: api.TestCase, result: api.TestResult): TestResult {
Expand Down
18 changes: 4 additions & 14 deletions packages/playwright/src/reporters/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import { createReporters } from '../runner/reporters';
import { relativeFilePath } from '../util';

import type { BlobReportMetadata } from './blob';
import type { ReporterDescription, TestAnnotation } from '../../types/test';
import type { ReporterDescription } from '../../types/test';
import type { TestError } from '../../types/testReporter';
import type { FullConfigInternal } from '../common/config';
import type { JsonConfig, JsonEvent, JsonFullResult, JsonLocation, JsonProject, JsonSuite, JsonTestCase, JsonTestEnd, JsonTestResultEnd, JsonTestStepEnd, JsonTestStepStart } from '../isomorphic/teleReceiver';
import type { JsonConfig, JsonEvent, JsonFullResult, JsonLocation, JsonProject, JsonSuite, JsonTestCase, JsonTestResultEnd, JsonTestStepEnd, JsonTestStepStart } from '../isomorphic/teleReceiver';
import type * as blobV1 from './versions/blobV1';

type StatusCallback = (message: string) => void;
Expand Down Expand Up @@ -474,10 +474,7 @@ class PathSeparatorPatcher {
return;
}
if (jsonEvent.method === 'onTestEnd') {
const test = jsonEvent.params.test as JsonTestEnd;
test.annotations?.forEach(annotation => this._updateAnnotationLocations(annotation));
const testResult = jsonEvent.params.result as JsonTestResultEnd;
testResult.annotations?.forEach(annotation => this._updateAnnotationLocations(annotation));
testResult.errors.forEach(error => this._updateErrorLocations(error));
testResult.attachments.forEach(attachment => {
if (attachment.path)
Expand All @@ -493,7 +490,6 @@ class PathSeparatorPatcher {
if (jsonEvent.method === 'onStepEnd') {
const step = jsonEvent.params.step as JsonTestStepEnd;
this._updateErrorLocations(step.error);
step.annotations?.forEach(annotation => this._updateAnnotationLocations(annotation));
return;
}
}
Expand All @@ -510,12 +506,10 @@ class PathSeparatorPatcher {
if (isFileSuite)
suite.title = this._updatePath(suite.title);
for (const entry of suite.entries) {
if ('testId' in entry) {
if ('testId' in entry)
this._updateLocation(entry.location);
entry.annotations?.forEach(annotation => this._updateAnnotationLocations(annotation));
} else {
else
this._updateSuite(entry);
}
}
}

Expand All @@ -526,10 +520,6 @@ class PathSeparatorPatcher {
}
}

private _updateAnnotationLocations(annotation: TestAnnotation) {
this._updateLocation(annotation.location);
}

private _updateLocation(location?: JsonLocation) {
if (location)
location.file = this._updatePath(location.file);
Expand Down
Loading
Loading