diff --git a/src/McpContext.ts b/src/McpContext.ts index cdde1200b..9fe062601 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -61,6 +61,8 @@ interface McpContextOptions { // Whether this context replaces a previous one after a browser reconnect. // Surfaces a one-time note in the next response. reconnected?: boolean; + // Custom navigation timeout in milliseconds to override default. + navigationTimeout?: number; } // Page ids are handed out from a process-wide counter so they stay unique @@ -503,6 +505,7 @@ export class McpContext implements Context { isolatedContextName: this.#getBrowserContextToNameMap().get( page.browserContext(), ), + navigationTimeout: this.#options.navigationTimeout, }); this.#mcpPages.set(page, mcpPage); await mcpPage.init(); diff --git a/src/McpPage.ts b/src/McpPage.ts index 21d9ca93a..c03b9cfbb 100644 --- a/src/McpPage.ts +++ b/src/McpPage.ts @@ -139,6 +139,7 @@ export class McpPage implements ContextPage { #hasNetworkBlockOrAllowlist: boolean; #locatorClass: typeof Locator; + #navigationTimeout: number; constructor( page: Page, @@ -147,10 +148,12 @@ export class McpPage implements ContextPage { hasNetworkBlockOrAllowlist: boolean; locatorClass: typeof Locator; isolatedContextName?: string; + navigationTimeout?: number; }, ) { this.#hasNetworkBlockOrAllowlist = options.hasNetworkBlockOrAllowlist; this.#locatorClass = options.locatorClass; + this.#navigationTimeout = options.navigationTimeout ?? NAVIGATION_TIMEOUT; this.pptrPage = page; this.id = id; this.isolatedContextName = options.isolatedContextName; @@ -409,7 +412,14 @@ export class McpPage implements ContextPage { cpuMultiplier: number, networkMultiplier: number, ): WaitForHelper { - return new WaitForHelper(this.pptrPage, cpuMultiplier, networkMultiplier); + const navigationTimeout = + this.#navigationTimeout * networkMultiplier * cpuMultiplier; + return new WaitForHelper( + this.pptrPage, + cpuMultiplier, + networkMultiplier, + navigationTimeout, + ); } waitForEventsAfterAction( @@ -827,7 +837,7 @@ export class McpPage implements ContextPage { this.networkConditions, ); this.pptrPage.setDefaultNavigationTimeout( - NAVIGATION_TIMEOUT * networkMultiplier * cpuMultiplier, + this.#navigationTimeout * networkMultiplier * cpuMultiplier, ); } diff --git a/src/WaitForHelper.ts b/src/WaitForHelper.ts index 7724b3589..2428a53a5 100644 --- a/src/WaitForHelper.ts +++ b/src/WaitForHelper.ts @@ -27,11 +27,13 @@ export class WaitForHelper { page: Page, cpuTimeoutMultiplier: number, networkTimeoutMultiplier: number, + navigationTimeout?: number, ) { this.#stableDomTimeout = 3000 * cpuTimeoutMultiplier; this.#stableDomFor = 100 * cpuTimeoutMultiplier; this.#expectNavigationIn = 100 * cpuTimeoutMultiplier; - this.#navigationTimeout = 3000 * networkTimeoutMultiplier; + this.#navigationTimeout = + navigationTimeout ?? 3000 * networkTimeoutMultiplier; this.#page = page as unknown as CdpPage; this.#initialUrl = page.url(); } diff --git a/tests/utils.ts b/tests/utils.ts index 61b759927..32555470e 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -183,6 +183,7 @@ export async function withMcpContext( allowList: options.allowedUrlPattern, blocklist: options.blockedUrlPattern, allowUnrestrictedPaths: options.allowUnrestrictedPaths ?? false, + navigationTimeout: process.platform === 'win32' ? 20000 : undefined }, Locator, );