fix(test runner): improve error message for unexpected calls (#12240)

This commit is contained in:
Dmitry Gozman 2022-02-18 18:25:18 -08:00 committed by GitHub
parent ee0dd6ec71
commit d3c4323021
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 21 deletions

View file

@ -63,12 +63,24 @@ export class TestTypeImpl {
this.test = test;
}
private _ensureCurrentSuite(location: Location, title: string): Suite {
const suite = currentlyLoadingFileSuite();
if (!suite) {
throw errorWithLocation(location, [
`Playwright Test did not expect ${title} to be called here.`,
`Most common reasons include:`,
`- You are calling ${title} in a configuration file.`,
`- You are calling ${title} in a file that is imported by the configuration file.`,
`- You have two different versions of @playwright/test. This usually happens`,
` when one of the dependenices in your package.json depends on @playwright/test.`,
].join('\n'));
}
return suite;
}
private _createTest(type: 'default' | 'only' | 'skip' | 'fixme', location: Location, title: string, fn: Function) {
throwIfRunningInsideJest();
const suite = currentlyLoadingFileSuite();
if (!suite)
throw errorWithLocation(location, `test() can only be called in a test file`);
const suite = this._ensureCurrentSuite(location, 'test()');
const test = new TestCase('test', title, fn, nextOrdinalInFile(suite._requireFile), this, location);
test._requireFile = suite._requireFile;
suite._addTest(test);
@ -81,10 +93,7 @@ export class TestTypeImpl {
private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only', location: Location, title: string, fn: Function) {
throwIfRunningInsideJest();
const suite = currentlyLoadingFileSuite();
if (!suite)
throw errorWithLocation(location, `describe() can only be called in a test file`);
const suite = this._ensureCurrentSuite(location, 'test.describe()');
if (typeof title === 'function') {
throw errorWithLocation(location, [
'It looks like you are calling describe() without the title. Pass the title as a first argument:',
@ -120,9 +129,7 @@ export class TestTypeImpl {
}
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, fn: Function) {
const suite = currentlyLoadingFileSuite();
if (!suite)
throw errorWithLocation(location, `${name} hook can only be called in a test file`);
const suite = this._ensureCurrentSuite(location, `test.${name}()`);
if (name === 'beforeAll' || name === 'afterAll') {
const sameTypeCount = suite.hooks.filter(hook => hook._type === name).length;
const suffix = sameTypeCount ? String(sameTypeCount) : '';
@ -136,10 +143,7 @@ export class TestTypeImpl {
private _configure(location: Location, options: { mode?: 'parallel' | 'serial' }) {
throwIfRunningInsideJest();
const suite = currentlyLoadingFileSuite();
if (!suite)
throw errorWithLocation(location, `describe.configure() can only be called in a test file`);
const suite = this._ensureCurrentSuite(location, `test.describe.configure()`);
if (!options.mode)
return;
if (suite._parallelMode !== 'default')
@ -196,9 +200,7 @@ export class TestTypeImpl {
}
private _use(location: Location, fixtures: Fixtures) {
const suite = currentlyLoadingFileSuite();
if (!suite)
throw errorWithLocation(location, `test.use() can only be called in a test file and can only be nested in test.describe()`);
const suite = this._ensureCurrentSuite(location, `test.use()`);
suite._use.push({ fixtures, location });
}

View file

@ -218,7 +218,7 @@ test('should throw when test() is called in config file', async ({ runInlineTest
});
`,
});
expect(result.output).toContain('test() can only be called in a test file');
expect(result.output).toContain('Playwright Test did not expect test() to be called here');
});
test('should filter by project, case-insensitive', async ({ runInlineTest }) => {

View file

@ -197,7 +197,7 @@ test('beforeAll from a helper file should throw', async ({ runInlineTest }) => {
`,
});
expect(result.exitCode).toBe(1);
expect(result.output).toContain('beforeAll hook can only be called in a test file');
expect(result.output).toContain('Playwright Test did not expect test.beforeAll() to be called here');
});
test('beforeAll hooks are skipped when no tests in the suite are run', async ({ runInlineTest }) => {

View file

@ -176,6 +176,6 @@ test('test.use() should throw if called from beforeAll ', async ({ runInlineTest
`,
});
expect(result.exitCode).toBe(1);
expect(result.output).toContain('test.use() can only be called in a test file and can only be nested in test.describe()');
expect(result.output).toContain('Playwright Test did not expect test.use() to be called here');
});