feat(test runner): support test.setTimeout for the whole block (#7387)

This enables `test.setTimeout()` outside of the test body, that
affects all tests in the block (either file or describe).
This commit is contained in:
Dmitry Gozman 2021-06-29 13:33:13 -07:00 committed by GitHub
parent 2166b98efc
commit 6b3614fd4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 1 deletions

View file

@ -78,6 +78,7 @@ export class Suite extends Base implements reporterTypes.Suite {
fn: Function,
location: Location,
}[] = [];
_timeout: number | undefined;
_addSpec(spec: Spec) {
spec.parent = this;

View file

@ -125,9 +125,15 @@ export class TestTypeImpl {
}
private _setTimeout(timeout: number) {
const suite = currentlyLoadingFileSuite();
if (suite) {
suite._timeout = timeout;
return;
}
const testInfo = currentTestInfo();
if (!testInfo)
throw new Error(`test.setTimeout() can only be called inside test or fixture`);
throw new Error(`test.setTimeout() can only be called from a test file`);
testInfo.setTimeout(timeout);
}

View file

@ -243,6 +243,15 @@ export class WorkerRunner extends EventEmitter {
deadlineRunner.setDeadline(deadline());
},
};
// Inherit test.setTimeout() from parent suites.
for (let suite = spec.parent; suite; suite = suite.parent) {
if (suite._timeout !== undefined) {
testInfo.setTimeout(suite._timeout);
break;
}
}
this._setCurrentTest({ testInfo, testId });
const deadline = () => {
return testInfo.timeout ? startTime + testInfo.timeout : undefined;

View file

@ -68,6 +68,35 @@ test('should respect test.setTimeout', async ({ runInlineTest }) => {
expect(result.output).toContain('Timeout of 1000ms exceeded');
});
test('should respect test.setTimeout outside of the test', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `
const { test } = pwt;
test.setTimeout(500);
test('fails', async ({}) => {
await new Promise(f => setTimeout(f, 1000));
});
test('passes', async ({}) => {
await new Promise(f => setTimeout(f, 100));
});
test.describe('suite', () => {
test.setTimeout(50);
test('fails', async ({}) => {
await new Promise(f => setTimeout(f, 100));
});
test('passes', async ({}) => {
});
});
`
});
expect(result.exitCode).toBe(1);
expect(result.failed).toBe(2);
expect(result.passed).toBe(2);
expect(result.output).toContain('Timeout of 500ms exceeded');
});
test('should timeout when calling test.setTimeout too late', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts': `