diff --git a/docs/src/api/class-browsertype.md b/docs/src/api/class-browsertype.md index 6b7021fece..71041170d7 100644 --- a/docs/src/api/class-browsertype.md +++ b/docs/src/api/class-browsertype.md @@ -115,7 +115,7 @@ Logger sink for Playwright logging. Optional. - `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to -`30000` (30 seconds). Pass `0` to disable timeout. +`0` (no timeout). ## async method: BrowserType.connectOverCDP - returns: <[Browser]> diff --git a/docs/src/test-api/class-testoptions.md b/docs/src/test-api/class-testoptions.md index 4457552583..4cceddbd24 100644 --- a/docs/src/test-api/class-testoptions.md +++ b/docs/src/test-api/class-testoptions.md @@ -114,6 +114,7 @@ Learn more about [various timeouts](../test-timeouts.md). - type: <[void]|[Object]> - `wsEndpoint` <[string]> A browser websocket endpoint to connect to. - `headers` <[void]|[Object]<[string], [string]>> Additional HTTP headers to be sent with web socket connect request. Optional. + - `timeout` <[int]> Timeout in milliseconds for the connection to be established. Optional, defaults to no timeout. When connect options are specified, default [`property: Fixtures.browser`], [`property: Fixtures.context`] and [`property: Fixtures.page`] use the remote browser instead of launching a browser locally, and any launch options like [`property: TestOptions.headless`] or [`property: TestOptions.channel`] are ignored. diff --git a/packages/playwright-core/src/server/transport.ts b/packages/playwright-core/src/server/transport.ts index a716c5d3aa..b3751fd2c0 100644 --- a/packages/playwright-core/src/server/transport.ts +++ b/packages/playwright-core/src/server/transport.ts @@ -80,7 +80,8 @@ export class WebSocketTransport implements ConnectionTransport { this._ws = new WebSocket(url, [], { perMessageDeflate: false, maxPayload: 256 * 1024 * 1024, // 256Mb, - handshakeTimeout: progress.timeUntilDeadline(), + // Prevent internal http client error when passing negative timeout. + handshakeTimeout: Math.max(progress.timeUntilDeadline(), 1), headers, followRedirects, }); diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 0fc5024195..9716fc0275 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -15715,8 +15715,7 @@ export interface ConnectOptions { slowMo?: number; /** - * Maximum time in milliseconds to wait for the connection to be established. Defaults to `30000` (30 seconds). Pass `0` to - * disable timeout. + * Maximum time in milliseconds to wait for the connection to be established. Defaults to `0` (no timeout). */ timeout?: number; } diff --git a/packages/playwright-test/src/index.ts b/packages/playwright-test/src/index.ts index 6ba1fc361a..82aefe58a3 100644 --- a/packages/playwright-test/src/index.ts +++ b/packages/playwright-test/src/index.ts @@ -115,7 +115,8 @@ export const test = _baseTest.extend({ 'x-playwright-browser': channel || browserName, 'x-playwright-headless': headless ? '1' : '0', ...connectOptions.headers, - } + }, + timeout: connectOptions.timeout, }); await use(browser); await browser.close(); diff --git a/packages/playwright-test/types/test.d.ts b/packages/playwright-test/types/test.d.ts index a930bdd3b9..cbccd8b95f 100644 --- a/packages/playwright-test/types/test.d.ts +++ b/packages/playwright-test/types/test.d.ts @@ -2853,6 +2853,11 @@ type ConnectOptions = { * Additional HTTP headers to be sent with web socket connect request. */ headers?: { [key: string]: string; }; + + /** + * Timeout in milliseconds for the connection to be established. Optional, defaults to no timeout. + */ + timeout?: number; }; /** diff --git a/tests/playwright-test/playwright.spec.ts b/tests/playwright-test/playwright.spec.ts index 6de0702689..5a76b53997 100644 --- a/tests/playwright-test/playwright.spec.ts +++ b/tests/playwright-test/playwright.spec.ts @@ -620,3 +620,26 @@ test('should throw with bad connectOptions', async ({ runInlineTest }) => { expect(result.passed).toBe(0); expect(result.output).toContain('browserType.connect:'); }); + +test('should respect connectOptions.timeout', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'playwright.config.js': ` + module.exports = { + use: { + connectOptions: { + wsEndpoint: 'wss://locahost:5678', + timeout: 1, + }, + }, + }; + `, + 'a.test.ts': ` + const { test } = pwt; + test('pass', async ({ page }) => { + }); + `, + }); + expect(result.exitCode).toBe(1); + expect(result.passed).toBe(0); + expect(result.output).toContain('browserType.connect: Timeout 1ms exceeded.'); +}); diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 4a359e414a..5bd0072bc7 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -369,6 +369,11 @@ type ConnectOptions = { * Additional HTTP headers to be sent with web socket connect request. */ headers?: { [key: string]: string; }; + + /** + * Timeout in milliseconds for the connection to be established. Optional, defaults to no timeout. + */ + timeout?: number; }; export interface PlaywrightWorkerOptions {