diff --git a/packages/puppeteer-core/src/bidi/Frame.ts b/packages/puppeteer-core/src/bidi/Frame.ts index fe83ce14892..07e4bf69710 100644 --- a/packages/puppeteer-core/src/bidi/Frame.ts +++ b/packages/puppeteer-core/src/bidi/Frame.ts @@ -16,6 +16,15 @@ import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js'; +import { + type Observable, + firstValueFrom, + from, + fromEvent, + merge, + raceWith, + switchMap, +} from '../../third_party/rxjs/rxjs.js'; import {type CDPSession} from '../api/CDPSession.js'; import { Frame, @@ -30,9 +39,9 @@ import {type Awaitable} from '../common/types.js'; import { UTILITY_WORLD_NAME, setPageContent, - waitForEvent, waitWithTimeout, } from '../common/util.js'; +import {timeout} from '../common/util.js'; import {Deferred} from '../util/Deferred.js'; import {disposeSymbol} from '../util/disposable.js'; @@ -70,7 +79,7 @@ export class BidiFrame extends Frame { #page: BidiPage; #context: BrowsingContext; #timeoutSettings: TimeoutSettings; - #abortDeferred = Deferred.create(); + #abortDeferred = Deferred.create(); #disposed = false; sandboxes: SandboxChart; override _id: string; @@ -201,48 +210,32 @@ export class BidiFrame extends Frame { ): Promise { const { waitUntil = 'load', - timeout = this.#timeoutSettings.navigationTimeout(), + timeout: ms = this.#timeoutSettings.navigationTimeout(), } = options; const waitUntilEvent = lifeCycleToSubscribedEvent.get( getWaitUntilSingle(waitUntil) ) as string; - const [info] = await Deferred.race([ - // TODO(lightning00blade): Should also keep tack of - // navigationAborted and navigationFailed - Promise.all([ - waitForEvent( + const info = await firstValueFrom( + merge( + fromEvent( this.#context, - waitUntilEvent, - () => { - return true; - }, - timeout, - this.#abortDeferred.valueOrThrow() + Bidi.ChromiumBidi.BrowsingContext.EventNames.NavigationStarted + ).pipe( + switchMap(() => { + return fromEvent( + this.#context, + waitUntilEvent + ) as Observable; + }) ), - waitForEvent( + fromEvent( this.#context, - Bidi.ChromiumBidi.BrowsingContext.EventNames.NavigationStarted, - () => { - return true; - }, - timeout, - this.#abortDeferred.valueOrThrow() - ), - ]), - waitForEvent( - this.#context, - Bidi.ChromiumBidi.BrowsingContext.EventNames.FragmentNavigated, - () => { - return true; - }, - timeout, - this.#abortDeferred.valueOrThrow() - ).then(info => { - return [info, undefined]; - }), - ]); + Bidi.ChromiumBidi.BrowsingContext.EventNames.FragmentNavigated + ) as Observable + ).pipe(raceWith(timeout(ms), from(this.#abortDeferred.valueOrThrow()))) + ); return this.#page.getNavigationResponse(info.navigation); }