SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
29.79k stars 8.02k forks source link

[🚀 Feature]: Reconnect WebSockets for BiDi #13762

Open joerg1985 opened 3 months ago

joerg1985 commented 3 months ago

Feature and motivation

In the past the HttpClient did take care of stale connections and did reconnect the TCP socket. When switching to WebSockets / BiDi this has to be handled by the application. Otherwise users might have negative experience when selenium will switch to BiDi and there might be alot of issue tickets (as users did use selenium in the past without problems).

I have experienced this when testing BiDi via VPN and the VPN did break and reconnect automatically.

It might be good to reconnect the WebSocket when it breaks. This might require the server to have a outgoing message que and the client to check the message has been received before (in case the server did resent due to a IOException while sending the last time). The reconnect has to be initiated by the client, this might require sending ping / pong requests in case the connection is idle (to detect the sockets are broken).

What do you think, is this needed? Or at least have a plan if users complain about this?

Usage example

Running tests in a world of not perfect connectivity (VPN / switch from WiFi to docking)

github-actions[bot] commented 3 months ago

@joerg1985, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

github-actions[bot] commented 3 months ago

This issue is looking for contributors.

Please comment below or reach out to us through our IRC/Slack/Matrix channels if you are interested.

joerg1985 commented 3 days ago

After thinking about this, it is really hard to reconnect the websocket and this will add complexity / overhead to the websocket handling. But there might be a easy way, by falling back to http request as follows:

  1. The JdkHttpClient could read an environment variable (or what ever) to enable this fallback. In this case the openSocket could return an alternative WebSocket implementation which is using http requests.

  2. The alternative WebSocket implementation will call a new endpoint e.g. "session/{id}/se/fallback". This will let the Node connect to the websocket of the driver and to start to write all recived messages with a sequence number to a buffer.

  3. The alternative WebSocket implementation must POST to the "session/{id}/se/fallback" endpoint to send messages. To receive them the "session/{id}/se/fallback" endpoint must be polled, this could return a batch of messages and drop the consumed messages.

I will create a branch and give it a try in the future, to see if this works for the Java binding. The other bindings could easily adopt this, as most of the logic is in the Node.