Skip to content

Commit 53b667b

Browse files
committed
Add WebSocket timeout and interval configuration to Chromium and Firefox drivers
1 parent f8e3191 commit 53b667b

File tree

4 files changed

+158
-7
lines changed

4 files changed

+158
-7
lines changed

java/src/org/openqa/selenium/chromium/ChromiumDriver.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import java.net.URI;
2525
import java.net.URISyntaxException;
26+
import java.time.Duration;
2627
import java.util.HashMap;
2728
import java.util.List;
2829
import java.util.Map;
@@ -119,7 +120,21 @@ protected ChromiumDriver(
119120
return null;
120121
});
121122

122-
this.biDi = createBiDi(biDiUri);
123+
// Extract WebSocket configuration from capabilities
124+
Duration webSocketTimeout = Duration.ofSeconds(30); // Default value
125+
Duration webSocketInterval = Duration.ofMillis(100); // Default value
126+
127+
Object timeoutCapability = originalCapabilities.getCapability("se:webSocketTimeout");
128+
if (timeoutCapability instanceof Number) {
129+
webSocketTimeout = Duration.ofSeconds(((Number) timeoutCapability).longValue());
130+
}
131+
132+
Object intervalCapability = originalCapabilities.getCapability("se:webSocketInterval");
133+
if (intervalCapability instanceof Number) {
134+
webSocketInterval = Duration.ofMillis(((Number) intervalCapability).longValue());
135+
}
136+
137+
this.biDi = createBiDi(biDiUri, webSocketTimeout, webSocketInterval);
123138

124139
Optional<URI> reportedUri =
125140
CdpEndpointFinder.getReportedUri(capabilityKey, originalCapabilities);
@@ -295,7 +310,7 @@ public Optional<DevTools> maybeGetDevTools() {
295310
return devTools;
296311
}
297312

298-
private Optional<BiDi> createBiDi(Optional<URI> biDiUri) {
313+
private Optional<BiDi> createBiDi(Optional<URI> biDiUri, Duration webSocketTimeout, Duration webSocketInterval) {
299314
if (biDiUri.isEmpty()) {
300315
return Optional.empty();
301316
}
@@ -308,7 +323,10 @@ private Optional<BiDi> createBiDi(Optional<URI> biDiUri) {
308323
+ " capability is set."));
309324

310325
HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();
311-
ClientConfig wsConfig = ClientConfig.defaultConfig().baseUri(wsUri);
326+
ClientConfig wsConfig = ClientConfig.defaultConfig()
327+
.baseUri(wsUri)
328+
.webSocketTimeout(webSocketTimeout)
329+
.webSocketInterval(webSocketInterval);
312330
HttpClient wsClient = clientFactory.createClient(wsConfig);
313331

314332
org.openqa.selenium.bidi.Connection biDiConnection =

java/src/org/openqa/selenium/chromium/ChromiumOptions.java

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.File;
2525
import java.io.IOException;
2626
import java.nio.file.Files;
27+
import java.time.Duration;
2728
import java.util.*;
2829
import java.util.stream.Stream;
2930
import org.openqa.selenium.Capabilities;
@@ -61,6 +62,8 @@ public class ChromiumOptions<T extends ChromiumOptions<?>>
6162
private final List<String> extensions = new ArrayList<>();
6263
private final Map<String, Object> experimentalOptions = new HashMap<>();
6364
private Map<String, Object> androidOptions = new HashMap<>();
65+
private Duration webSocketTimeout = Duration.ofSeconds(30);
66+
private Duration webSocketInterval = Duration.ofMillis(100);
6467

6568
private final String capabilityName;
6669

@@ -219,14 +222,67 @@ private T setAndroidCapability(String name, Object value) {
219222
return (T) this;
220223
}
221224

225+
/**
226+
* Sets the WebSocket response wait timeout (in seconds) used for communicating with the browser.
227+
*
228+
* @param timeout WebSocket response wait timeout
229+
* @return A self reference.
230+
*/
231+
public T setWebSocketTimeout(Duration timeout) {
232+
this.webSocketTimeout = Require.nonNull("WebSocket timeout", timeout);
233+
return (T) this;
234+
}
235+
236+
/**
237+
* Gets the WebSocket response wait timeout (in seconds) used for communicating with the browser.
238+
*
239+
* @return WebSocket response wait timeout
240+
*/
241+
public Duration getWebSocketTimeout() {
242+
return webSocketTimeout;
243+
}
244+
245+
/**
246+
* Sets the WebSocket response wait interval (in seconds) used for communicating with the browser.
247+
*
248+
* @param interval WebSocket response wait interval
249+
* @return A self reference.
250+
*/
251+
public T setWebSocketInterval(Duration interval) {
252+
this.webSocketInterval = Require.nonNull("WebSocket interval", interval);
253+
return (T) this;
254+
}
255+
256+
/**
257+
* Gets the WebSocket response wait interval (in seconds) used for communicating with the browser.
258+
*
259+
* @return WebSocket response wait interval
260+
*/
261+
public Duration getWebSocketInterval() {
262+
return webSocketInterval;
263+
}
264+
222265
@Override
223266
protected Set<String> getExtraCapabilityNames() {
224-
return Collections.singleton(capabilityName);
267+
Set<String> names = new HashSet<>();
268+
names.add(capabilityName);
269+
names.add("se:webSocketTimeout");
270+
names.add("se:webSocketInterval");
271+
return names;
225272
}
226273

227274
@Override
228275
protected Object getExtraCapability(String capabilityName) {
229276
Require.nonNull("Capability name", capabilityName);
277+
278+
// Handle WebSocket configuration capabilities
279+
if ("se:webSocketTimeout".equals(capabilityName)) {
280+
return webSocketTimeout.toSeconds();
281+
}
282+
if ("se:webSocketInterval".equals(capabilityName)) {
283+
return webSocketInterval.toMillis();
284+
}
285+
230286
if (!this.capabilityName.equals(capabilityName)) {
231287
return null;
232288
}
@@ -319,6 +375,14 @@ protected void mergeInPlace(Capabilities capabilities) {
319375

320376
Optional.ofNullable(options.androidOptions)
321377
.ifPresent(opts -> opts.forEach(this::setAndroidCapability));
378+
379+
// Merge WebSocket configuration
380+
if (options.webSocketTimeout != null) {
381+
setWebSocketTimeout(options.webSocketTimeout);
382+
}
383+
if (options.webSocketInterval != null) {
384+
setWebSocketInterval(options.webSocketInterval);
385+
}
322386
}
323387
}
324388

java/src/org/openqa/selenium/firefox/FirefoxDriver.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.net.URI;
2323
import java.net.URISyntaxException;
2424
import java.nio.file.Path;
25+
import java.time.Duration;
2526
import java.util.Map;
2627
import java.util.Optional;
2728
import java.util.logging.Logger;
@@ -156,7 +157,21 @@ private FirefoxDriver(
156157
return null;
157158
});
158159

159-
this.biDi = createBiDi(biDiUri);
160+
// Extract WebSocket configuration from capabilities
161+
Duration webSocketTimeout = Duration.ofSeconds(30); // default
162+
Duration webSocketInterval = Duration.ofMillis(100); // default
163+
164+
Object timeoutCapability = capabilities.getCapability("se:webSocketTimeout");
165+
if (timeoutCapability instanceof Number) {
166+
webSocketTimeout = Duration.ofMillis(((Number) timeoutCapability).longValue());
167+
}
168+
169+
Object intervalCapability = capabilities.getCapability("se:webSocketInterval");
170+
if (intervalCapability instanceof Number) {
171+
webSocketInterval = Duration.ofMillis(((Number) intervalCapability).longValue());
172+
}
173+
174+
this.biDi = createBiDi(biDiUri, webSocketTimeout, webSocketInterval);
160175

161176
this.capabilities = new ImmutableCapabilities(capabilities);
162177
}
@@ -240,7 +255,7 @@ public void setContext(FirefoxCommandContext commandContext) {
240255
context.setContext(commandContext);
241256
}
242257

243-
private Optional<BiDi> createBiDi(Optional<URI> biDiUri) {
258+
private Optional<BiDi> createBiDi(Optional<URI> biDiUri, Duration webSocketTimeout, Duration webSocketInterval) {
244259
if (biDiUri.isEmpty()) {
245260
return Optional.empty();
246261
}
@@ -253,7 +268,10 @@ private Optional<BiDi> createBiDi(Optional<URI> biDiUri) {
253268
+ " capability is set."));
254269

255270
HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();
256-
ClientConfig wsConfig = ClientConfig.defaultConfig().baseUri(wsUri);
271+
ClientConfig wsConfig = ClientConfig.defaultConfig()
272+
.baseUri(wsUri)
273+
.webSocketTimeout(webSocketTimeout)
274+
.webSocketInterval(webSocketInterval);
257275
HttpClient wsClient = clientFactory.createClient(wsConfig);
258276

259277
org.openqa.selenium.bidi.Connection biDiConnection =

java/src/org/openqa/selenium/firefox/FirefoxOptions.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.IOException;
2424
import java.io.UncheckedIOException;
2525
import java.nio.file.Path;
26+
import java.time.Duration;
2627
import java.util.ArrayList;
2728
import java.util.Arrays;
2829
import java.util.Collections;
@@ -55,6 +56,8 @@ public class FirefoxOptions extends AbstractDriverOptions<FirefoxOptions> {
5556
public static final String FIREFOX_OPTIONS = "moz:firefoxOptions";
5657

5758
private Map<String, Object> firefoxOptions = Collections.unmodifiableMap(new TreeMap<>());
59+
private Duration webSocketTimeout = Duration.ofSeconds(30);
60+
private Duration webSocketInterval = Duration.ofMillis(100);
5861

5962
public FirefoxOptions() {
6063
setCapability(CapabilityType.BROWSER_NAME, FIREFOX.browserName());
@@ -265,11 +268,53 @@ public FirefoxOptions enableBiDi() {
265268
return this;
266269
}
267270

271+
/**
272+
* Sets the WebSocket timeout for BiDi connections.
273+
*
274+
* @param webSocketTimeout the WebSocket timeout duration
275+
* @return A self reference.
276+
*/
277+
public FirefoxOptions setWebSocketTimeout(Duration webSocketTimeout) {
278+
this.webSocketTimeout = Require.nonNull("WebSocket timeout", webSocketTimeout);
279+
return this;
280+
}
281+
282+
/**
283+
* Gets the WebSocket timeout for BiDi connections.
284+
*
285+
* @return the WebSocket timeout duration
286+
*/
287+
public Duration getWebSocketTimeout() {
288+
return webSocketTimeout;
289+
}
290+
291+
/**
292+
* Sets the WebSocket interval for BiDi connections.
293+
*
294+
* @param webSocketInterval the WebSocket interval duration
295+
* @return A self reference.
296+
*/
297+
public FirefoxOptions setWebSocketInterval(Duration webSocketInterval) {
298+
this.webSocketInterval = Require.nonNull("WebSocket interval", webSocketInterval);
299+
return this;
300+
}
301+
302+
/**
303+
* Gets the WebSocket interval for BiDi connections.
304+
*
305+
* @return the WebSocket interval duration
306+
*/
307+
public Duration getWebSocketInterval() {
308+
return webSocketInterval;
309+
}
310+
268311
@Override
269312
protected Set<String> getExtraCapabilityNames() {
270313
Set<String> names = new TreeSet<>();
271314

272315
names.add(FIREFOX_OPTIONS);
316+
names.add("se:webSocketTimeout");
317+
names.add("se:webSocketInterval");
273318

274319
return Collections.unmodifiableSet(names);
275320
}
@@ -281,6 +326,12 @@ protected Object getExtraCapability(String capabilityName) {
281326
if (FIREFOX_OPTIONS.equals(capabilityName)) {
282327
return Collections.unmodifiableMap(firefoxOptions);
283328
}
329+
if ("se:webSocketTimeout".equals(capabilityName)) {
330+
return webSocketTimeout.toMillis();
331+
}
332+
if ("se:webSocketInterval".equals(capabilityName)) {
333+
return webSocketInterval.toMillis();
334+
}
284335
return null;
285336
}
286337

0 commit comments

Comments
 (0)