feat(test runner): descrbe.skip (#12865)
`describe.skip` declares a test group that is skipped.
This commit is contained in:
parent
2ec3866f7c
commit
209bde5000
|
|
@ -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
|
## property: Test.expect
|
||||||
- type: <[Object]>
|
- type: <[Object]>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export class Suite extends Base implements reporterTypes.Suite {
|
||||||
parent?: Suite;
|
parent?: Suite;
|
||||||
_use: FixturesWithLocation[] = [];
|
_use: FixturesWithLocation[] = [];
|
||||||
_isDescribe = false;
|
_isDescribe = false;
|
||||||
|
_skipped = false;
|
||||||
_entries: (Suite | TestCase)[] = [];
|
_entries: (Suite | TestCase)[] = [];
|
||||||
_hooks: { type: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', fn: Function, location: Location }[] = [];
|
_hooks: { type: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', fn: Function, location: Location }[] = [];
|
||||||
_timeout: number | undefined;
|
_timeout: number | undefined;
|
||||||
|
|
@ -108,6 +109,7 @@ export class Suite extends Base implements reporterTypes.Suite {
|
||||||
suite._isDescribe = this._isDescribe;
|
suite._isDescribe = this._isDescribe;
|
||||||
suite._parallelMode = this._parallelMode;
|
suite._parallelMode = this._parallelMode;
|
||||||
suite._projectConfig = this._projectConfig;
|
suite._projectConfig = this._projectConfig;
|
||||||
|
suite._skipped = this._skipped;
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ export class TestTypeImpl {
|
||||||
test.describe.parallel.only = wrapFunctionWithLocation(this._describe.bind(this, 'parallel.only'));
|
test.describe.parallel.only = wrapFunctionWithLocation(this._describe.bind(this, 'parallel.only'));
|
||||||
test.describe.serial = wrapFunctionWithLocation(this._describe.bind(this, 'serial'));
|
test.describe.serial = wrapFunctionWithLocation(this._describe.bind(this, 'serial'));
|
||||||
test.describe.serial.only = wrapFunctionWithLocation(this._describe.bind(this, 'serial.only'));
|
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.beforeEach = wrapFunctionWithLocation(this._hook.bind(this, 'beforeEach'));
|
||||||
test.afterEach = wrapFunctionWithLocation(this._hook.bind(this, 'afterEach'));
|
test.afterEach = wrapFunctionWithLocation(this._hook.bind(this, 'afterEach'));
|
||||||
test.beforeAll = wrapFunctionWithLocation(this._hook.bind(this, 'beforeAll'));
|
test.beforeAll = wrapFunctionWithLocation(this._hook.bind(this, 'beforeAll'));
|
||||||
|
|
@ -89,9 +90,13 @@ export class TestTypeImpl {
|
||||||
test._only = true;
|
test._only = true;
|
||||||
if (type === 'skip' || type === 'fixme')
|
if (type === 'skip' || type === 'fixme')
|
||||||
test.expectedStatus = 'skipped';
|
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();
|
throwIfRunningInsideJest();
|
||||||
const suite = this._ensureCurrentSuite(location, 'test.describe()');
|
const suite = this._ensureCurrentSuite(location, 'test.describe()');
|
||||||
if (typeof title === 'function') {
|
if (typeof title === 'function') {
|
||||||
|
|
@ -115,6 +120,8 @@ export class TestTypeImpl {
|
||||||
child._parallelMode = 'serial';
|
child._parallelMode = 'serial';
|
||||||
if (type === 'parallel' || type === 'parallel.only')
|
if (type === 'parallel' || type === 'parallel.only')
|
||||||
child._parallelMode = 'parallel';
|
child._parallelMode = 'parallel';
|
||||||
|
if (type === 'skip')
|
||||||
|
child._skipped = true;
|
||||||
|
|
||||||
for (let parent: Suite | undefined = suite; parent; parent = parent.parent) {
|
for (let parent: Suite | undefined = suite; parent; parent = parent.parent) {
|
||||||
if (parent._parallelMode === 'serial' && child._parallelMode === 'parallel')
|
if (parent._parallelMode === 'serial' && child._parallelMode === 'parallel')
|
||||||
|
|
|
||||||
18
packages/playwright-test/types/test.d.ts
vendored
18
packages/playwright-test/types/test.d.ts
vendored
|
|
@ -1795,6 +1795,24 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
||||||
*/
|
*/
|
||||||
only: SuiteFunction;
|
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
|
* 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.
|
* skipped. All tests in a group are retried together.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -442,3 +442,29 @@ test('should allow unhandled expects in test.fail', async ({ runInlineTest }) =>
|
||||||
expect(result.passed).toBe(1);
|
expect(result.passed).toBe(1);
|
||||||
expect(result.output).not.toContain(`Error: expect`);
|
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');
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,21 @@ test('basics should work', async ({ runTSC }) => {
|
||||||
const { test } = pwt;
|
const { test } = pwt;
|
||||||
test.describe('suite', () => {
|
test.describe('suite', () => {
|
||||||
test.beforeEach(async () => {});
|
test.beforeEach(async () => {});
|
||||||
|
test.afterEach(async () => {});
|
||||||
|
test.beforeAll(async () => {});
|
||||||
|
test.afterAll(async () => {});
|
||||||
test('my test', async({}, testInfo) => {
|
test('my test', async({}, testInfo) => {
|
||||||
expect(testInfo.title).toBe('my test');
|
expect(testInfo.title).toBe('my test');
|
||||||
testInfo.annotations[0].type;
|
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
|
// @ts-expect-error
|
||||||
test.foo();
|
test.foo();
|
||||||
`
|
`
|
||||||
|
|
|
||||||
1
utils/generate_types/overrides-test.d.ts
vendored
1
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -290,6 +290,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
|
||||||
only: TestFunction<TestArgs & WorkerArgs>;
|
only: TestFunction<TestArgs & WorkerArgs>;
|
||||||
describe: SuiteFunction & {
|
describe: SuiteFunction & {
|
||||||
only: SuiteFunction;
|
only: SuiteFunction;
|
||||||
|
skip: SuiteFunction;
|
||||||
serial: SuiteFunction & {
|
serial: SuiteFunction & {
|
||||||
only: SuiteFunction;
|
only: SuiteFunction;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue