diff --git a/packages/playwright-test/src/testInfo.ts b/packages/playwright-test/src/testInfo.ts index e32e3bb686..0dbd7c1dcd 100644 --- a/packages/playwright-test/src/testInfo.ts +++ b/packages/playwright-test/src/testInfo.ts @@ -76,7 +76,7 @@ export class TestInfoImpl implements TestInfo { } get timeout(): number { - return this._timeoutManager.defaultTimeout(); + return this._timeoutManager.defaultSlotTimings().timeout; } set timeout(timeout: number) { @@ -178,7 +178,7 @@ export class TestInfoImpl implements TestInfo { this.status = 'timedOut'; this.errors.push(timeoutError); } - this.duration = (monotonicTime() - this._startTime) | 0; + this.duration = this._timeoutManager.defaultSlotTimings().elapsed | 0; } async _runFn(fn: Function, skips?: 'allowSkips'): Promise { diff --git a/packages/playwright-test/src/timeoutManager.ts b/packages/playwright-test/src/timeoutManager.ts index 6cdca9b590..6d0dc6472b 100644 --- a/packages/playwright-test/src/timeoutManager.ts +++ b/packages/playwright-test/src/timeoutManager.ts @@ -60,8 +60,10 @@ export class TimeoutManager { this._updateRunnables(this._runnable, fixture); } - defaultTimeout() { - return this._defaultSlot.timeout; + defaultSlotTimings() { + const slot = this._currentSlot(); + slot.elapsed = this._timeoutRunner.elapsed(); + return this._defaultSlot; } slow() { diff --git a/tests/playwright-test/timeout.spec.ts b/tests/playwright-test/timeout.spec.ts index 092471b961..65faf00dfe 100644 --- a/tests/playwright-test/timeout.spec.ts +++ b/tests/playwright-test/timeout.spec.ts @@ -340,3 +340,41 @@ test('test timeout should still run hooks before fixtures teardown', async ({ ru '%%after-auto', ]); }); + +test('should not include fixtures with own timeout and beforeAll in test duration', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'c.spec.ts': ` + const test = pwt.test.extend({ + foo: [async ({}, use) => { + await new Promise(f => setTimeout(f, 1000)); + await use('foo'); + }, { timeout: 0 }], + + bar: async ({}, use) => { + await new Promise(f => setTimeout(f, 300)); + await use('bar'); + }, + }); + + test.beforeAll(async () => { + await new Promise(f => setTimeout(f, 1000)); + }); + + test.beforeEach(async () => { + await new Promise(f => setTimeout(f, 300)); + }); + + test.afterEach(async () => { + await new Promise(f => setTimeout(f, 300)); + }); + + test('works', async ({ foo, bar }) => { + await new Promise(f => setTimeout(f, 300)); + }); + ` + }, { timeout: 5000 }); + expect(result.exitCode).toBe(0); + const duration = result.results[0].duration; + expect(duration).toBeGreaterThanOrEqual(300 * 4); // Includes test, beforeEach, afterEach and bar. + expect(duration).toBeLessThan(300 * 4 + 1000); // Does not include beforeAll and foo. +});