diff --git a/package.json b/package.json index 13bdd1caecd06..ea306196a02e5 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,11 @@ "test": "c8 --check-coverage --lines 93 run-s test:chrome:* test:firefox", "test:types": "tsd", "test:install": "scripts/test-install.sh", - "test:firefox": "cross-env PUPPETEER_PRODUCT=firefox MOZ_WEBRENDER=0 mocha", + "test:firefox": "cross-env PUPPETEER_PRODUCT=firefox MOZ_WEBRENDER=0 PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha", "test:chrome": "run-s test:chrome:*", - "test:chrome:headless": "cross-env HEADLESS=true mocha", - "test:chrome:headless-chrome": "cross-env HEADLESS=chrome mocha", - "test:chrome:headful": "cross-env HEADLESS=false mocha", + "test:chrome:headless": "cross-env HEADLESS=true PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha", + "test:chrome:headless-chrome": "cross-env HEADLESS=chrome PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha", + "test:chrome:headful": "cross-env HEADLESS=false PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha", "prepublishOnly": "npm run build", "prepare": "node typescript-if-required.js && husky install", "lint": "run-s lint:prettier lint:eslint", diff --git a/src/common/FrameManager.ts b/src/common/FrameManager.ts index 182dc1a17a212..e027cc62cb3c0 100644 --- a/src/common/FrameManager.ts +++ b/src/common/FrameManager.ts @@ -17,7 +17,7 @@ import {Protocol} from 'devtools-protocol'; import {assert} from '../util/assert.js'; import { - createDeferredPromiseWithTimer, + createDebuggableDeferredPromise, DeferredPromise, } from '../util/DeferredPromise.js'; import {isErrorLike} from '../util/ErrorLike.js'; @@ -150,7 +150,7 @@ export class FrameManager extends EventEmitter { if (!this.#framesPendingTargetInit.has(targetId)) { this.#framesPendingTargetInit.set( targetId, - createDeferredPromiseWithTimer( + createDebuggableDeferredPromise( `Waiting for target frame ${targetId} failed` ) ); @@ -318,7 +318,7 @@ export class FrameManager extends EventEmitter { if (!this.#framesPendingAttachment.has(frameId)) { this.#framesPendingAttachment.set( frameId, - createDeferredPromiseWithTimer( + createDebuggableDeferredPromise( `Waiting for frame ${frameId} to attach failed` ) ); diff --git a/src/common/NetworkManager.ts b/src/common/NetworkManager.ts index f128892f4b1e6..4aaacd4c9faeb 100644 --- a/src/common/NetworkManager.ts +++ b/src/common/NetworkManager.ts @@ -24,7 +24,7 @@ import {HTTPResponse} from './HTTPResponse.js'; import {FetchRequestId, NetworkEventManager} from './NetworkEventManager.js'; import {debugError, isString} from './util.js'; import { - createDeferredPromiseWithTimer, + createDebuggableDeferredPromise, DeferredPromise, } from '../util/DeferredPromise.js'; @@ -144,9 +144,8 @@ export class NetworkManager extends EventEmitter { if (this.#deferredInitPromise) { return this.#deferredInitPromise; } - this.#deferredInitPromise = createDeferredPromiseWithTimer( - 'NetworkManager initialization timed out', - 30000 + this.#deferredInitPromise = createDebuggableDeferredPromise( + 'NetworkManager initialization timed out' ); const init = Promise.all([ this.#ignoreHTTPSErrors diff --git a/src/environment.ts b/src/environment.ts index 5ceca84a0e333..876eac8f15db1 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -18,3 +18,12 @@ * @internal */ export const isNode = !!(typeof process !== 'undefined' && process.version); + +/** + * @internal + */ +export const deferredPromiseDebugTimeout = + typeof process !== 'undefined' && + typeof process.env['PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT'] !== 'undefined' + ? Number(process.env['PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT']) + : -1; diff --git a/src/util/DeferredPromise.ts b/src/util/DeferredPromise.ts index cc8d7f154d115..a91f5d9672ce1 100644 --- a/src/util/DeferredPromise.ts +++ b/src/util/DeferredPromise.ts @@ -1,15 +1,16 @@ import {TimeoutError} from '../common/Errors.js'; +import {deferredPromiseDebugTimeout} from '../environment.js'; /** * @internal */ - export interface DeferredPromise extends Promise { finished: () => boolean; resolved: () => boolean; resolve: (_: T) => void; reject: (_: Error) => void; } + /** * Creates an returns a promise along with the resolve/reject functions. * @@ -18,7 +19,6 @@ export interface DeferredPromise extends Promise { * * @internal */ - export function createDeferredPromiseWithTimer( timeoutMessage: string, timeout = 5000 @@ -54,12 +54,12 @@ export function createDeferredPromiseWithTimer( }, }); } + /** * Creates an returns a promise along with the resolve/reject functions. * * @internal */ - export function createDeferredPromise(): DeferredPromise { let isResolved = false; let isRejected = false; @@ -86,3 +86,18 @@ export function createDeferredPromise(): DeferredPromise { }, }); } + +/** + * @internal + */ +export function createDebuggableDeferredPromise( + timeoutMessage: string +): DeferredPromise { + if (deferredPromiseDebugTimeout > 0) { + return createDeferredPromiseWithTimer( + timeoutMessage, + deferredPromiseDebugTimeout + ); + } + return createDeferredPromise(); +}