Skip to content

[🐛 Bug]: WDIO always displays "ERROR webdriver: Could not connect to Bidi protocol of any candidate url in time" #14430

@tinklern

Description

@tinklern

Have you read the Contributing Guidelines on issues?

WebdriverIO Version

v9.12.7

Node.js Version

v22.14.0

Mode

WDIO Testrunner

Which capabilities are you using?

{
    'wdio:maxInstances': 1,
    browserName: 'chrome',
    acceptInsecureCerts: true,
    webSocketUrl: true,
    'goog:chromeOptions': {
      extensions: [get_chrome_extension()],
      args: ['--no-sandbox', '--disable-gpu'],
    },
  };

What happened?

WDIO always displays the error:

Could not connect to Bidi protocol of any candidate url in time

This is relatively minor, but the error log made me spend quite a bit of time double checking that a recent selenium docker setup was working as expected with BiDi, and it turns out that the error log is just incorrect.

When attempting to connect to BiDi, the ConnectionTimeoutPromise code sets a timeout which includes an error log, and then races this promise against the real connection attempt.

Which is fine, but it leaves the setTimeout hanging around even when the real connection is successful and wins the race. Because the setTimeout is never cleared, the error log is always displayed, even when a bidi connection is established.

What is your expected behavior?

I expect an error indicating that BiDi connection was unsuccessful to only be displayed when it's actually unsuccessful.

Suggestion:
Either clear the timeout after the promise.race call:

    let timeoutId;

    const connectionTimeoutPromise = new Promise<undefined>((resolve) => {
        timeoutId = setTimeout(() => {
            log.error(`Could not connect to Bidi protocol of any candidate url in time: "${candidateUrls.join('", "')}"`)
            return resolve(undefined)
        }, CONNECTION_TIMEOUT)
    })

    const wsInfo = await Promise.race([
        firstResolved(wsConnectPromises),
        connectionTimeoutPromise,
    ])

    clearTimeout(timeoutId)

Or move the error log down below the race and check for an undefined result

    const connectionTimeoutPromise = new Promise<undefined>((resolve) => {
        setTimeout(() => {
            return resolve(undefined)
        }, CONNECTION_TIMEOUT)
    })

    const wsInfo = await Promise.race([
        firstResolved(wsConnectPromises),
        connectionTimeoutPromise,
    ])

    if(typeof wsInfo === 'undefined') {
        log.error(`Could not connect to Bidi protocol of any candidate url in time: "${candidateUrls.join('", "')}"`)
    }

How to reproduce the bug.

Run against a bidi capable node with a fairly minimal WDIO config. In this example I am using Chrome with the above capabilities, and the simple selenium-hub & selenium/node-chrome docker images.

Relevant log output

[0-0] 2025-04-24T19:04:37.472Z INFO webdriver: BIDI COMMAND script.addPreloadScript { functionDeclaration: <PreloadScript[442 bytes]>, contexts: ["8F0F60ECF3B0CAC3B1284DE54859BC9A"] }
[0-0] 2025-04-24T19:04:37.698Z INFO webdriver: BIDI RESULT {"id":40,"result":{"realm":"7503068843460801072.-8294574137326953758","result":{"type":"undefined"},"type":"success"},"type":"success"}
[0-0] 2025-04-24T19:04:37.699Z INFO webdriver: BIDI RESULT {"id":41,"result":{"script":"067599e5-af9c-484e-9080-75475162ca56"},"type":"success"}
[0-0] 2025-04-24T19:04:43.413Z ERROR webdriver: Could not connect to Bidi protocol of any candidate url in time: "ws://127.0.0.1:4444/session/17486691bb7d1f71b8b0a9d6b598b97a/se/bidi"

Code of Conduct

  • I agree to follow this project's Code of Conduct

Is there an existing issue for this?

  • I have searched the existing issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bug 🐛help wantedIssues that are free to take by anyone interested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions