diff --git a/packages/puppeteer-core/src/api/Page.ts b/packages/puppeteer-core/src/api/Page.ts index a8f613363a5..0476ca67259 100644 --- a/packages/puppeteer-core/src/api/Page.ts +++ b/packages/puppeteer-core/src/api/Page.ts @@ -601,7 +601,7 @@ export abstract class Page extends EventEmitter { #requestHandlers = new WeakMap, Handler>(); - #inflight$ = new ReplaySubject(1); + #inflight$ = new ReplaySubject<[number, number]>(1); /** * @internal @@ -613,7 +613,7 @@ export abstract class Page extends EventEmitter { .pipe( mergeMap(originalRequest => { return concat( - of(1), + of([1, Infinity] as [number, number]), merge( fromEmitterEvent(this, PageEvent.RequestFailed), fromEmitterEvent(this, PageEvent.RequestFinished), @@ -628,16 +628,19 @@ export abstract class Page extends EventEmitter { }), take(1), map(() => { - return -1; + return [-1, Infinity] as [number, number]; }) ) ); }), - mergeScan((acc, addend) => { - return of(acc + addend); - }, 0), + mergeScan( + (acc, addend) => { + return of([acc[0] + addend[0], Date.now()] as [number, number]); + }, + [0, Infinity] as [number, number] + ), takeUntil(fromEmitterEvent(this, PageEvent.Close)), - startWith(0) + startWith([0, Date.now()] as [number, number]) ) .subscribe(this.#inflight$); } @@ -1752,10 +1755,10 @@ export abstract class Page extends EventEmitter { return this.#inflight$.pipe( switchMap(inflight => { - if (inflight > concurrency) { + if (inflight[0] > concurrency) { return EMPTY; } - return timer(idleTime); + return timer(new Date(inflight[1] + idleTime)); }), map(() => {}), raceWith( diff --git a/test/src/page.spec.ts b/test/src/page.spec.ts index d64a73bcbf5..a0de46dffb5 100644 --- a/test/src/page.spec.ts +++ b/test/src/page.spec.ts @@ -922,6 +922,23 @@ describe('Page', function () { ]); expect(t2).toBeGreaterThan(t1); }); + it('should resolve if network was idle for longer then idleTime', async () => { + const {page, server} = await getTestState(); + + const idleTime = 25; + await page.goto(server.EMPTY_PAGE); + await new Promise(resolve => { + return setTimeout(resolve, idleTime * 2); + }); + const [t1, t2] = await Promise.all([ + page.waitForNetworkIdle({idleTime}).then(() => { + return Date.now(); + }), + // Add a little bit of time due to async operations + Promise.resolve(Date.now() + 10), + ]); + expect(t2).toBeGreaterThan(t1); + }); it('should work with no timeout', async () => { const {page, server} = await getTestState(); await page.goto(server.EMPTY_PAGE);