mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: move Location type from testReporter.d.ts to test.d.ts (#32687)
This commit is contained in:
parent
ddd43d0f20
commit
523ec83cad
20
packages/playwright/types/test.d.ts
vendored
20
packages/playwright/types/test.d.ts
vendored
@ -7772,6 +7772,26 @@ interface SnapshotAssertions {
|
|||||||
}): void;
|
}): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a location in the source code where [TestCase] or [Suite] is defined.
|
||||||
|
*/
|
||||||
|
export interface Location {
|
||||||
|
/**
|
||||||
|
* Column number in the source file.
|
||||||
|
*/
|
||||||
|
column: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to the source file.
|
||||||
|
*/
|
||||||
|
file: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Line number in the source file.
|
||||||
|
*/
|
||||||
|
line: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `TestInfo` contains information about currently running test. It is available to test functions,
|
* `TestInfo` contains information about currently running test. It is available to test functions,
|
||||||
* [test.beforeEach([title, hookFunction])](https://playwright.dev/docs/api/class-test#test-before-each),
|
* [test.beforeEach([title, hookFunction])](https://playwright.dev/docs/api/class-test#test-before-each),
|
||||||
|
|||||||
24
packages/playwright/types/testReporter.d.ts
vendored
24
packages/playwright/types/testReporter.d.ts
vendored
@ -15,8 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject } from './test';
|
import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location } from './test';
|
||||||
export type { FullConfig, FullProject, TestStatus } from './test';
|
export type { FullConfig, FullProject, TestStatus, Location } from './test';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result of the full test run.
|
* Result of the full test run.
|
||||||
@ -319,26 +319,6 @@ export type JSONReportSTDIOEntry = { text: string } | { buffer: string };
|
|||||||
export {};
|
export {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a location in the source code where {@link TestCase} or {@link Suite} is defined.
|
|
||||||
*/
|
|
||||||
export interface Location {
|
|
||||||
/**
|
|
||||||
* Column number in the source file.
|
|
||||||
*/
|
|
||||||
column: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Path to the source file.
|
|
||||||
*/
|
|
||||||
file: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Line number in the source file.
|
|
||||||
*/
|
|
||||||
line: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `Suite` is a group of tests. All tests in Playwright Test form the following hierarchy:
|
* `Suite` is a group of tests. All tests in Playwright Test form the following hierarchy:
|
||||||
* - Root suite has a child suite for each {@link FullProject}.
|
* - Root suite has a child suite for each {@link FullProject}.
|
||||||
|
|||||||
@ -17,37 +17,41 @@
|
|||||||
import { test, expect, stripAnsi } from './playwright-test-fixtures';
|
import { test, expect, stripAnsi } from './playwright-test-fixtures';
|
||||||
|
|
||||||
const stepIndentReporter = `
|
const stepIndentReporter = `
|
||||||
|
import { FullConfig, Location, Reporter, Suite, TestStep } from '@playwright/test/reporter';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
function formatPrefix(str) {
|
function formatPrefix(str: string) {
|
||||||
return str.padEnd(10, ' ') + '|';
|
return str.padEnd(10, ' ') + '|';
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatLocation(location) {
|
function formatLocation(location?: Location) {
|
||||||
|
if (!location)
|
||||||
|
throw new Error('Location is missing');
|
||||||
return ' @ ' + path.basename(location.file) + ':' + location.line;
|
return ' @ ' + path.basename(location.file) + ':' + location.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatStack(indent, stack) {
|
function formatStack(indent: string, rawStack: string) {
|
||||||
stack = stack.split('\\n').filter(s => s.startsWith(' at '));
|
let stack = rawStack.split('\\n').filter(s => s.startsWith(' at '));
|
||||||
stack = stack.map(s => {
|
stack = stack.map(s => {
|
||||||
const match = /^( at.* )\\(?([^ )]+)\\)?/.exec(s);
|
const match = /^( at.* )\\(?([^ )]+)\\)?/.exec(s);
|
||||||
let location = match[2];
|
let location = match![2];
|
||||||
location = location.substring(location.lastIndexOf(path.sep) + 1);
|
location = location.substring(location.lastIndexOf(path.sep) + 1);
|
||||||
return ' at ' + location;
|
return ' at ' + location;
|
||||||
});
|
});
|
||||||
return indent + stack.join('\\n' + indent);
|
return indent + stack.join('\\n' + indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Reporter {
|
export default class MyReporter implements Reporter {
|
||||||
printErrorLocation: boolean;
|
printErrorLocation: boolean;
|
||||||
skipErrorMessage: boolean;
|
skipErrorMessage: boolean;
|
||||||
|
suite!: Suite;
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options: { printErrorLocation: boolean, skipErrorMessage: boolean }) {
|
||||||
this.printErrorLocation = options.printErrorLocation;
|
this.printErrorLocation = options.printErrorLocation;
|
||||||
this.skipErrorMessage = options.skipErrorMessage;
|
this.skipErrorMessage = options.skipErrorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
trimError(message) {
|
trimError(message: string) {
|
||||||
if (this.skipErrorMessage)
|
if (this.skipErrorMessage)
|
||||||
return '<error message>';
|
return '<error message>';
|
||||||
const lines = message.split('\\n');
|
const lines = message.split('\\n');
|
||||||
@ -59,24 +63,24 @@ class Reporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For easier debugging.
|
// For easier debugging.
|
||||||
onStdOut(data) {
|
onStdOut(data: string|Buffer) {
|
||||||
process.stdout.write(data.toString());
|
process.stdout.write(data.toString());
|
||||||
}
|
}
|
||||||
// For easier debugging.
|
// For easier debugging.
|
||||||
onStdErr(data) {
|
onStdErr(data: string|Buffer) {
|
||||||
process.stderr.write(data.toString());
|
process.stderr.write(data.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
printStep(step, indent) {
|
printStep(step: TestStep, indent: string) {
|
||||||
let location = '';
|
let location = '';
|
||||||
if (step.location)
|
if (step.location)
|
||||||
location = formatLocation(step.location);
|
location = formatLocation(step.location);
|
||||||
console.log(formatPrefix(step.category) + indent + step.title + location);
|
console.log(formatPrefix(step.category) + indent + step.title + location);
|
||||||
if (step.error) {
|
if (step.error) {
|
||||||
const errorLocation = this.printErrorLocation ? formatLocation(step.error.location) : '';
|
const errorLocation = this.printErrorLocation ? formatLocation(step.error.location) : '';
|
||||||
console.log(formatPrefix(step.category) + indent + '↪ error: ' + this.trimError(step.error.message) + errorLocation);
|
console.log(formatPrefix(step.category) + indent + '↪ error: ' + this.trimError(step.error.message!) + errorLocation);
|
||||||
if (this.printErrorLocation)
|
if (this.printErrorLocation)
|
||||||
console.log(formatStack(formatPrefix(step.category) + indent, step.error.stack));
|
console.log(formatStack(formatPrefix(step.category) + indent, step.error.stack!));
|
||||||
}
|
}
|
||||||
indent += ' ';
|
indent += ' ';
|
||||||
for (const child of step.steps)
|
for (const child of step.steps)
|
||||||
@ -94,9 +98,9 @@ class Reporter {
|
|||||||
this.printStep(step, '');
|
this.printStep(step, '');
|
||||||
for (const error of result.errors) {
|
for (const error of result.errors) {
|
||||||
const errorLocation = this.printErrorLocation ? formatLocation(error.location) : '';
|
const errorLocation = this.printErrorLocation ? formatLocation(error.location) : '';
|
||||||
console.log(formatPrefix('') + this.trimError(error.message) + errorLocation);
|
console.log(formatPrefix('') + this.trimError(error.message!) + errorLocation);
|
||||||
if (this.printErrorLocation)
|
if (this.printErrorLocation)
|
||||||
console.log(formatStack(formatPrefix(''), error.stack));
|
console.log(formatStack(formatPrefix(''), error.stack!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,7 +108,6 @@ class Reporter {
|
|||||||
processSuite(this.suite);
|
processSuite(this.suite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = Reporter;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
test('should report api step hierarchy', async ({ runInlineTest }) => {
|
test('should report api step hierarchy', async ({ runInlineTest }) => {
|
||||||
@ -1247,14 +1250,14 @@ fixture | fixture: context
|
|||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('test location to test.step', async ({ runInlineTest }) => {
|
test('should allow passing location to test.step', async ({ runInlineTest, runTSC }) => {
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
'reporter.ts': stepIndentReporter,
|
'reporter.ts': stepIndentReporter,
|
||||||
'helper.ts': `
|
'helper.ts': `
|
||||||
import { test } from '@playwright/test';
|
import { Location, TestType } from '@playwright/test';
|
||||||
|
|
||||||
export async function dummyStep(test, title, action, location) {
|
export async function dummyStep(test: TestType<{}, {}>, title: string, action: () => void, location: Location) {
|
||||||
return await test.step(title, action, { location });
|
await test.step(title, action, { location });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCustomLocation() {
|
export function getCustomLocation() {
|
||||||
@ -1272,8 +1275,7 @@ test('test location to test.step', async ({ runInlineTest }) => {
|
|||||||
|
|
||||||
test('custom location test', async () => {
|
test('custom location test', async () => {
|
||||||
const location = getCustomLocation();
|
const location = getCustomLocation();
|
||||||
await dummyStep(test, 'Perform a dummy step', async () => {
|
await dummyStep(test, 'Perform a dummy step', async () => {}, location);
|
||||||
}, location);
|
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
}, { reporter: '', workers: 1 });
|
}, { reporter: '', workers: 1 });
|
||||||
@ -1284,4 +1286,15 @@ hook |Before Hooks
|
|||||||
test.step |Perform a dummy step @ dummy-file.ts:123
|
test.step |Perform a dummy step @ dummy-file.ts:123
|
||||||
hook |After Hooks
|
hook |After Hooks
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
const { exitCode } = await runTSC({
|
||||||
|
'a.test.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('should work', async () => {
|
||||||
|
const location = { file: 'dummy-file.ts', line: 123, column: 45 };
|
||||||
|
await test.step('step1', () => {}, { location });
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
expect(exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject } from './test';
|
import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location } from './test';
|
||||||
export type { FullConfig, FullProject, TestStatus } from './test';
|
export type { FullConfig, FullProject, TestStatus, Location } from './test';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result of the full test run.
|
* Result of the full test run.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user