From e8fb5a6337f540555501f5513d00ddfd530f11ac Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 9 May 2022 20:38:20 +0100 Subject: [PATCH] fix(test runner): ensure that hooks run before fixtures teardown after timeout (#14035) We had common cleanup exiting early after timeout, because we did not reset the time slot. --- packages/playwright-test/src/workerRunner.ts | 1 + tests/playwright-test/timeout.spec.ts | 34 ++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/packages/playwright-test/src/workerRunner.ts b/packages/playwright-test/src/workerRunner.ts index 6d9da0bd34..706ebd0bf3 100644 --- a/packages/playwright-test/src/workerRunner.ts +++ b/packages/playwright-test/src/workerRunner.ts @@ -379,6 +379,7 @@ export class WorkerRunner extends EventEmitter { if (testInfo.status === 'timedOut') { // A timed-out test gets a full additional timeout to run after hooks. afterHooksSlot = { timeout: this._project.timeout, elapsed: 0 }; + testInfo._timeoutManager.setCurrentRunnable({ type: 'afterEach', slot: afterHooksSlot }); } await testInfo._runWithTimeout(async () => { // Note: do not wrap all teardown steps together, because failure in any of them diff --git a/tests/playwright-test/timeout.spec.ts b/tests/playwright-test/timeout.spec.ts index 382d8a7c53..1169e178c3 100644 --- a/tests/playwright-test/timeout.spec.ts +++ b/tests/playwright-test/timeout.spec.ts @@ -306,3 +306,37 @@ test('fixture time in beforeEach hook should affect test', async ({ runInlineTes expect(result.failed).toBe(1); expect(result.output).toContain('Timeout of 1000ms exceeded'); }); + +test('test timeout should still run hooks before fixtures teardown', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'a.spec.ts': ` + const test = pwt.test.extend({ + auto: [async ({}, use) => { + console.log('\\n%%before-auto'); + await use('hey'); + console.log('\\n%%after-auto'); + }, { auto: true }] + }); + test.afterAll(async () => { + console.log('\\n%%afterAll-1'); + await new Promise(f => setTimeout(f, 500)); + console.log('\\n%%afterAll-2'); + }); + test('test fail', async ({}) => { + test.setTimeout(100); + console.log('\\n%%test'); + await new Promise(f => setTimeout(f, 800)); + }); + ` + }); + expect(result.exitCode).toBe(1); + expect(result.failed).toBe(1); + expect(result.output).toContain('Timeout of 100ms exceeded'); + expect(result.output.split('\n').filter(line => line.startsWith('%%'))).toEqual([ + '%%before-auto', + '%%test', + '%%afterAll-1', + '%%afterAll-2', + '%%after-auto', + ]); +});