Revert "fix(test): do not allow mixing tests from different types (#29284)" (#33002)

This reverts commit 4784139bb0.

Closes https://github.com/microsoft/playwright/issues/29734
This commit is contained in:
Max Schmitt 2024-10-08 16:00:40 +02:00 committed by GitHub
parent 042161e1ce
commit d0f2170e21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 12 additions and 39 deletions

View File

@ -56,12 +56,10 @@ export class Suite extends Base {
_fullProject: FullProjectInternal | undefined; _fullProject: FullProjectInternal | undefined;
_fileId: string | undefined; _fileId: string | undefined;
readonly _type: 'root' | 'project' | 'file' | 'describe'; readonly _type: 'root' | 'project' | 'file' | 'describe';
readonly _testTypeImpl: TestTypeImpl | undefined;
constructor(title: string, type: 'root' | 'project' | 'file' | 'describe', testTypeImpl?: TestTypeImpl) { constructor(title: string, type: 'root' | 'project' | 'file' | 'describe') {
super(title); super(title);
this._type = type; this._type = type;
this._testTypeImpl = testTypeImpl;
} }
get type(): 'root' | 'project' | 'file' | 'describe' { get type(): 'root' | 'project' | 'file' | 'describe' {

View File

@ -38,7 +38,7 @@ export class TestTypeImpl {
test.only = wrapFunctionWithLocation(this._createTest.bind(this, 'only')); test.only = wrapFunctionWithLocation(this._createTest.bind(this, 'only'));
test.describe = wrapFunctionWithLocation(this._describe.bind(this, 'default')); test.describe = wrapFunctionWithLocation(this._describe.bind(this, 'default'));
test.describe.only = wrapFunctionWithLocation(this._describe.bind(this, 'only')); test.describe.only = wrapFunctionWithLocation(this._describe.bind(this, 'only'));
test.describe.configure = this._configure.bind(this); test.describe.configure = wrapFunctionWithLocation(this._configure.bind(this));
test.describe.fixme = wrapFunctionWithLocation(this._describe.bind(this, 'fixme')); test.describe.fixme = wrapFunctionWithLocation(this._describe.bind(this, 'fixme'));
test.describe.parallel = wrapFunctionWithLocation(this._describe.bind(this, 'parallel')); test.describe.parallel = wrapFunctionWithLocation(this._describe.bind(this, 'parallel'));
test.describe.parallel.only = wrapFunctionWithLocation(this._describe.bind(this, 'parallel.only')); test.describe.parallel.only = wrapFunctionWithLocation(this._describe.bind(this, 'parallel.only'));
@ -53,7 +53,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.step = this._step.bind(this); test.step = this._step.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));
@ -66,7 +66,7 @@ export class TestTypeImpl {
this.test = test; this.test = test;
} }
private _currentSuite(title: string): Suite | undefined { private _currentSuite(location: Location, title: string): Suite | undefined {
const suite = currentlyLoadingFileSuite(); const suite = currentlyLoadingFileSuite();
if (!suite) { if (!suite) {
throw new Error([ throw new Error([
@ -78,18 +78,12 @@ export class TestTypeImpl {
` when one of the dependencies in your package.json depends on @playwright/test.`, ` when one of the dependencies in your package.json depends on @playwright/test.`,
].join('\n')); ].join('\n'));
} }
if (suite._testTypeImpl && suite._testTypeImpl !== this) {
throw new Error([
`Can't call ${title} inside a describe() suite of a different test type.`,
`Make sure to use the same "test" function (created by the test.extend() call) for all declarations inside a suite.`,
].join('\n'));
}
return suite; return suite;
} }
private _createTest(type: 'default' | 'only' | 'skip' | 'fixme' | 'fail', location: Location, title: string, fnOrDetails: Function | TestDetails, fn?: Function) { private _createTest(type: 'default' | 'only' | 'skip' | 'fixme' | 'fail', location: Location, title: string, fnOrDetails: Function | TestDetails, fn?: Function) {
throwIfRunningInsideJest(); throwIfRunningInsideJest();
const suite = this._currentSuite('test()'); const suite = this._currentSuite(location, 'test()');
if (!suite) if (!suite)
return; return;
@ -118,7 +112,7 @@ export class TestTypeImpl {
private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only' | 'skip' | 'fixme', location: Location, titleOrFn: string | Function, fnOrDetails?: TestDetails | Function, fn?: Function) { private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only' | 'skip' | 'fixme', location: Location, titleOrFn: string | Function, fnOrDetails?: TestDetails | Function, fn?: Function) {
throwIfRunningInsideJest(); throwIfRunningInsideJest();
const suite = this._currentSuite('test.describe()'); const suite = this._currentSuite(location, 'test.describe()');
if (!suite) if (!suite)
return; return;
@ -141,7 +135,7 @@ export class TestTypeImpl {
} }
const validatedDetails = validateTestDetails(details); const validatedDetails = validateTestDetails(details);
const child = new Suite(title, 'describe', this); const child = new Suite(title, 'describe');
child._requireFile = suite._requireFile; child._requireFile = suite._requireFile;
child.location = location; child.location = location;
child._staticAnnotations.push(...validatedDetails.annotations); child._staticAnnotations.push(...validatedDetails.annotations);
@ -170,7 +164,7 @@ export class TestTypeImpl {
} }
private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, title: string | Function, fn?: Function) { private _hook(name: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', location: Location, title: string | Function, fn?: Function) {
const suite = this._currentSuite(`test.${name}()`); const suite = this._currentSuite(location, `test.${name}()`);
if (!suite) if (!suite)
return; return;
if (typeof title === 'function') { if (typeof title === 'function') {
@ -181,9 +175,9 @@ export class TestTypeImpl {
suite._hooks.push({ type: name, fn: fn!, title, location }); suite._hooks.push({ type: name, fn: fn!, title, location });
} }
private _configure(options: { mode?: 'default' | 'parallel' | 'serial', retries?: number, timeout?: number }) { private _configure(location: Location, options: { mode?: 'default' | 'parallel' | 'serial', retries?: number, timeout?: number }) {
throwIfRunningInsideJest(); throwIfRunningInsideJest();
const suite = this._currentSuite(`test.describe.configure()`); const suite = this._currentSuite(location, `test.describe.configure()`);
if (!suite) if (!suite)
return; return;
@ -239,7 +233,7 @@ export class TestTypeImpl {
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;
@ -253,7 +247,7 @@ export class TestTypeImpl {
} }
private _use(location: Location, fixtures: Fixtures) { private _use(location: Location, fixtures: Fixtures) {
const suite = this._currentSuite(`test.use()`); const suite = this._currentSuite(location, `test.use()`);
if (!suite) if (!suite)
return; return;
suite._use.push({ fixtures, location }); suite._use.push({ fixtures, location });

View File

@ -550,22 +550,3 @@ test('should support describe.fixme', async ({ runInlineTest }) => {
expect(result.skipped).toBe(3); expect(result.skipped).toBe(3);
expect(result.output).toContain('heytest4'); expect(result.output).toContain('heytest4');
}); });
test('should not allow mixing test types', async ({ runInlineTest }) => {
const result = await runInlineTest({
'mixed.spec.ts': `
import { test } from '@playwright/test';
export const test2 = test.extend({
value: 42,
});
test.describe("test1 suite", () => {
test2("test 2", async () => {});
});
`
});
expect(result.exitCode).toBe(1);
expect(result.output).toContain(`Can't call test() inside a describe() suite of a different test type.`);
expect(result.output).toContain('> 9 | test2(');
});