feat(test runner): descrbe.skip (#12865)

`describe.skip` declares a test group that is skipped.
This commit is contained in:
Dmitry Gozman 2022-03-18 16:07:11 -07:00 committed by GitHub
parent 2ec3866f7c
commit 209bde5000
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 1 deletions

View file

@ -459,6 +459,38 @@ A callback that is run immediately when calling [`method: Test.describe.serial.o
## method: Test.describe.skip
Declares a skipped test group, similarly to [`method: Test.describe`]. Tests in the skipped group are never run.
```js js-flavor=js
test.describe.skip('skipped group', () => {
test('example', async ({ page }) => {
// This test will not run
});
});
```
```js js-flavor=ts
test.describe.skip('skipped group', () => {
test('example', async ({ page }) => {
// This test will not run
});
});
```
### param: Test.describe.skip.title
- `title` <[string]>
Group title.
### param: Test.describe.skip.callback
- `callback` <[function]>
A callback that is run immediately when calling [`method: Test.describe.skip`]. Any tests added in this callback will belong to the group, and will not be run.
## property: Test.expect
- type: <[Object]>

View file

@ -44,6 +44,7 @@ export class Suite extends Base implements reporterTypes.Suite {
parent?: Suite;
_use: FixturesWithLocation[] = [];
_isDescribe = false;
_skipped = false;
_entries: (Suite | TestCase)[] = [];
_hooks: { type: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', fn: Function, location: Location }[] = [];
_timeout: number | undefined;
@ -108,6 +109,7 @@ export class Suite extends Base implements reporterTypes.Suite {
suite._isDescribe = this._isDescribe;
suite._parallelMode = this._parallelMode;
suite._projectConfig = this._projectConfig;
suite._skipped = this._skipped;
return suite;
}

View file

@ -41,6 +41,7 @@ export class TestTypeImpl {
test.describe.parallel.only = wrapFunctionWithLocation(this._describe.bind(this, 'parallel.only'));
test.describe.serial = wrapFunctionWithLocation(this._describe.bind(this, 'serial'));
test.describe.serial.only = wrapFunctionWithLocation(this._describe.bind(this, 'serial.only'));
test.describe.skip = wrapFunctionWithLocation(this._describe.bind(this, 'skip'));
test.beforeEach = wrapFunctionWithLocation(this._hook.bind(this, 'beforeEach'));
test.afterEach = wrapFunctionWithLocation(this._hook.bind(this, 'afterEach'));
test.beforeAll = wrapFunctionWithLocation(this._hook.bind(this, 'beforeAll'));
@ -89,9 +90,13 @@ export class TestTypeImpl {
test._only = true;
if (type === 'skip' || type === 'fixme')
test.expectedStatus = 'skipped';
for (let parent: Suite | undefined = suite; parent; parent = parent.parent) {
if (parent._skipped)
test.expectedStatus = 'skipped';
}
}
private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only', location: Location, title: string, fn: Function) {
private _describe(type: 'default' | 'only' | 'serial' | 'serial.only' | 'parallel' | 'parallel.only' | 'skip', location: Location, title: string, fn: Function) {
throwIfRunningInsideJest();
const suite = this._ensureCurrentSuite(location, 'test.describe()');
if (typeof title === 'function') {
@ -115,6 +120,8 @@ export class TestTypeImpl {
child._parallelMode = 'serial';
if (type === 'parallel' || type === 'parallel.only')
child._parallelMode = 'parallel';
if (type === 'skip')
child._skipped = true;
for (let parent: Suite | undefined = suite; parent; parent = parent.parent) {
if (parent._parallelMode === 'serial' && child._parallelMode === 'parallel')

View file

@ -1795,6 +1795,24 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
*/
only: SuiteFunction;
/**
* Declares a skipped test group, similarly to
* [test.describe(title, callback)](https://playwright.dev/docs/api/class-test#test-describe). Tests in the skipped group
* are never run.
*
* ```ts
* test.describe.skip('skipped group', () => {
* test('example', async ({ page }) => {
* // This test will not run
* });
* });
* ```
*
* @param title Group title.
* @param callback A callback that is run immediately when calling [test.describe.skip(title, callback)](https://playwright.dev/docs/api/class-test#test-describe-skip). Any tests added in
* this callback will belong to the group, and will not be run.
*/
skip: SuiteFunction;
/**
* Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are
* skipped. All tests in a group are retried together.
*

View file

@ -442,3 +442,29 @@ test('should allow unhandled expects in test.fail', async ({ runInlineTest }) =>
expect(result.passed).toBe(1);
expect(result.output).not.toContain(`Error: expect`);
});
test('should support describe.skip', async ({ runInlineTest }) => {
const result = await runInlineTest({
'nested-skip.spec.js': `
const { test } = pwt;
test.describe.skip('skipped', () => {
test.describe('nested', () => {
test('test1', () => {});
});
test('test2', () => {});
});
test.describe('not skipped', () => {
test.describe.skip('skipped', () => {
test('test4', () => {});
});
test('test4', () => {
console.log('heytest4');
});
});
`
});
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1);
expect(result.skipped).toBe(3);
expect(result.output).toContain('heytest4');
});

View file

@ -22,11 +22,21 @@ test('basics should work', async ({ runTSC }) => {
const { test } = pwt;
test.describe('suite', () => {
test.beforeEach(async () => {});
test.afterEach(async () => {});
test.beforeAll(async () => {});
test.afterAll(async () => {});
test('my test', async({}, testInfo) => {
expect(testInfo.title).toBe('my test');
testInfo.annotations[0].type;
});
test.skip('my test', async () => {});
test.fixme('my test', async () => {});
});
test.describe.parallel('suite', () => {});
test.describe.parallel.only('suite', () => {});
test.describe.serial('suite', () => {});
test.describe.serial.only('suite', () => {});
test.describe.skip('suite', () => {});
// @ts-expect-error
test.foo();
`

View file

@ -290,6 +290,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
only: TestFunction<TestArgs & WorkerArgs>;
describe: SuiteFunction & {
only: SuiteFunction;
skip: SuiteFunction;
serial: SuiteFunction & {
only: SuiteFunction;
};