mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
faet(test runner): help when describe() is misused (#7753)
This commit is contained in:
parent
cc4af54402
commit
03ebe21323
@ -19,6 +19,7 @@ import { currentlyLoadingFileSuite, currentTestInfo, setCurrentlyLoadingFileSuit
|
|||||||
import { TestCase, Suite } from './test';
|
import { TestCase, Suite } from './test';
|
||||||
import { wrapFunctionWithLocation } from './transform';
|
import { wrapFunctionWithLocation } from './transform';
|
||||||
import { Fixtures, FixturesWithLocation, Location, TestType } from './types';
|
import { Fixtures, FixturesWithLocation, Location, TestType } from './types';
|
||||||
|
import { errorWithLocation } from './util';
|
||||||
|
|
||||||
const countByFile = new Map<string, number>();
|
const countByFile = new Map<string, number>();
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ export class TestTypeImpl {
|
|||||||
test.fixme = wrapFunctionWithLocation(this._modifier.bind(this, 'fixme'));
|
test.fixme = wrapFunctionWithLocation(this._modifier.bind(this, 'fixme'));
|
||||||
test.fail = wrapFunctionWithLocation(this._modifier.bind(this, 'fail'));
|
test.fail = wrapFunctionWithLocation(this._modifier.bind(this, 'fail'));
|
||||||
test.slow = wrapFunctionWithLocation(this._modifier.bind(this, 'slow'));
|
test.slow = wrapFunctionWithLocation(this._modifier.bind(this, 'slow'));
|
||||||
test.setTimeout = this._setTimeout.bind(this);
|
test.setTimeout = wrapFunctionWithLocation(this._setTimeout.bind(this));
|
||||||
test.use = wrapFunctionWithLocation(this._use.bind(this));
|
test.use = wrapFunctionWithLocation(this._use.bind(this));
|
||||||
test.extend = wrapFunctionWithLocation(this._extend.bind(this));
|
test.extend = wrapFunctionWithLocation(this._extend.bind(this));
|
||||||
test.declare = wrapFunctionWithLocation(this._declare.bind(this));
|
test.declare = wrapFunctionWithLocation(this._declare.bind(this));
|
||||||
@ -58,7 +59,7 @@ export class TestTypeImpl {
|
|||||||
throwIfRunningInsideJest();
|
throwIfRunningInsideJest();
|
||||||
const suite = currentlyLoadingFileSuite();
|
const suite = currentlyLoadingFileSuite();
|
||||||
if (!suite)
|
if (!suite)
|
||||||
throw new Error(`test() can only be called in a test file`);
|
throw errorWithLocation(location, `test() can only be called in a test file`);
|
||||||
|
|
||||||
const ordinalInFile = countByFile.get(suite._requireFile) || 0;
|
const ordinalInFile = countByFile.get(suite._requireFile) || 0;
|
||||||
countByFile.set(suite._requireFile, ordinalInFile + 1);
|
countByFile.set(suite._requireFile, ordinalInFile + 1);
|
||||||
@ -75,7 +76,16 @@ export class TestTypeImpl {
|
|||||||
throwIfRunningInsideJest();
|
throwIfRunningInsideJest();
|
||||||
const suite = currentlyLoadingFileSuite();
|
const suite = currentlyLoadingFileSuite();
|
||||||
if (!suite)
|
if (!suite)
|
||||||
throw new Error(`describe() can only be called in a test file`);
|
throw errorWithLocation(location, `describe() can only be called in a test file`);
|
||||||
|
|
||||||
|
if (typeof title === 'function') {
|
||||||
|
throw errorWithLocation(location, [
|
||||||
|
'It looks like you are calling describe() without the title. Pass the title as a first argument:',
|
||||||
|
`test.describe('my test group', () => {`,
|
||||||
|
` // Declare tests here`,
|
||||||
|
`});`,
|
||||||
|
].join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
const child = new Suite(title);
|
const child = new Suite(title);
|
||||||
child._requireFile = suite._requireFile;
|
child._requireFile = suite._requireFile;
|
||||||
@ -93,7 +103,7 @@ export class TestTypeImpl {
|
|||||||
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, fn: Function) {
|
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, fn: Function) {
|
||||||
const suite = currentlyLoadingFileSuite();
|
const suite = currentlyLoadingFileSuite();
|
||||||
if (!suite)
|
if (!suite)
|
||||||
throw new Error(`${name} hook can only be called in a test file`);
|
throw errorWithLocation(location, `${name} hook can only be called in a test file`);
|
||||||
suite._hooks.push({ type: name, fn, location });
|
suite._hooks.push({ type: name, fn, location });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,13 +123,13 @@ export class TestTypeImpl {
|
|||||||
|
|
||||||
const testInfo = currentTestInfo();
|
const testInfo = currentTestInfo();
|
||||||
if (!testInfo)
|
if (!testInfo)
|
||||||
throw new Error(`test.${type}() can only be called inside test, describe block or fixture`);
|
throw errorWithLocation(location, `test.${type}() can only be called inside test, describe block or fixture`);
|
||||||
if (typeof modifierArgs[0] === 'function')
|
if (typeof modifierArgs[0] === 'function')
|
||||||
throw new Error(`test.${type}() with a function can only be called inside describe block`);
|
throw errorWithLocation(location, `test.${type}() with a function can only be called inside describe block`);
|
||||||
testInfo[type](...modifierArgs as [any, any]);
|
testInfo[type](...modifierArgs as [any, any]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setTimeout(timeout: number) {
|
private _setTimeout(location: Location, timeout: number) {
|
||||||
const suite = currentlyLoadingFileSuite();
|
const suite = currentlyLoadingFileSuite();
|
||||||
if (suite) {
|
if (suite) {
|
||||||
suite._timeout = timeout;
|
suite._timeout = timeout;
|
||||||
@ -128,14 +138,14 @@ export class TestTypeImpl {
|
|||||||
|
|
||||||
const testInfo = currentTestInfo();
|
const testInfo = currentTestInfo();
|
||||||
if (!testInfo)
|
if (!testInfo)
|
||||||
throw new Error(`test.setTimeout() can only be called from a test file`);
|
throw errorWithLocation(location, `test.setTimeout() can only be called from a test file`);
|
||||||
testInfo.setTimeout(timeout);
|
testInfo.setTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _use(location: Location, fixtures: Fixtures) {
|
private _use(location: Location, fixtures: Fixtures) {
|
||||||
const suite = currentlyLoadingFileSuite();
|
const suite = currentlyLoadingFileSuite();
|
||||||
if (!suite)
|
if (!suite)
|
||||||
throw new Error(`test.use() can only be called in a test file`);
|
throw errorWithLocation(location, `test.use() can only be called in a test file`);
|
||||||
suite._fixtureOverrides = { ...suite._fixtureOverrides, ...fixtures };
|
suite._fixtureOverrides = { ...suite._fixtureOverrides, ...fixtures };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,3 +162,7 @@ export function formatLocation(location: Location) {
|
|||||||
export function errorWithFile(file: string, message: string) {
|
export function errorWithFile(file: string, message: string) {
|
||||||
return new Error(`${relativeFilePath(file)}: ${message}`);
|
return new Error(`${relativeFilePath(file)}: ${message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function errorWithLocation(location: Location, message: string) {
|
||||||
|
return new Error(`${formatLocation(location)}: ${message}`);
|
||||||
|
}
|
||||||
|
@ -351,3 +351,18 @@ test('should work with test helper', async ({ runInlineTest }) => {
|
|||||||
'%%suite2.test2',
|
'%%suite2.test2',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should help with describe() misuse', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.spec.js': `
|
||||||
|
pwt.test.describe(() => {});
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.output).toContain([
|
||||||
|
'Error: a.spec.js:5:16: It looks like you are calling describe() without the title. Pass the title as a first argument:',
|
||||||
|
`test.describe('my test group', () => {`,
|
||||||
|
` // Declare tests here`,
|
||||||
|
`});`,
|
||||||
|
].join('\n'));
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user