Skip to content

Commit 5ee5a52

Browse files
committed
[java] Add support for BiDi for Grid use case in the RemoteWebDriver
1 parent 8ea30a6 commit 5ee5a52

File tree

7 files changed

+73
-121
lines changed

7 files changed

+73
-121
lines changed

java/src/org/openqa/selenium/bidi/BiDiProvider.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,7 @@ public HasBiDi getImplementation(Capabilities caps, ExecuteMethod executeMethod)
5252
HttpClient wsClient = clientFactory.createClient(wsConfig);
5353
Connection connection = new Connection(wsClient, wsUri.toString());
5454

55-
return new HasBiDi() {
56-
@Override
57-
public Optional<BiDi> maybeGetBiDi() {
58-
return Optional.of(new BiDi(connection));
59-
}
60-
61-
@Override
62-
public void setBiDi(BiDi bidi) {}
63-
};
55+
return () -> Optional.of(new BiDi(connection));
6456
}
6557

6658
private Optional<URI> getBiDiUrl(Capabilities caps) {

java/src/org/openqa/selenium/bidi/HasBiDi.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,9 @@
2525

2626
public interface HasBiDi {
2727
Optional<BiDi> maybeGetBiDi();
28-
29-
void setBiDi(BiDi bidi);
30-
28+
3129
default BiDi getBiDi() {
3230
return maybeGetBiDi()
3331
.orElseThrow(() -> new BiDiException("Unable to create a BiDi connection"));
3432
}
35-
36-
default Optional<BiDi> createBiDi(Optional<URI> biDiUri) {
37-
if (!biDiUri.isPresent()) {
38-
return Optional.empty();
39-
}
40-
41-
URI wsUri =
42-
biDiUri.orElseThrow(
43-
() ->
44-
new BiDiException("This version of Firefox or geckodriver does not support BiDi"));
45-
46-
HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();
47-
ClientConfig wsConfig = ClientConfig.defaultConfig().baseUri(wsUri);
48-
HttpClient wsClient = clientFactory.createClient(wsConfig);
49-
50-
org.openqa.selenium.bidi.Connection biDiConnection =
51-
new org.openqa.selenium.bidi.Connection(wsClient, wsUri.toString());
52-
53-
return Optional.of(new BiDi(biDiConnection));
54-
}
5533
}

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

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import static org.openqa.selenium.remote.Browser.OPERA;
2323

2424
import java.net.URI;
25-
import java.net.URISyntaxException;
2625
import java.util.HashMap;
2726
import java.util.List;
2827
import java.util.Map;
@@ -42,9 +41,6 @@
4241
import org.openqa.selenium.ScriptKey;
4342
import org.openqa.selenium.WebDriver;
4443
import org.openqa.selenium.WebDriverException;
45-
import org.openqa.selenium.bidi.BiDi;
46-
import org.openqa.selenium.bidi.BiDiException;
47-
import org.openqa.selenium.bidi.HasBiDi;
4844
import org.openqa.selenium.devtools.CdpEndpointFinder;
4945
import org.openqa.selenium.devtools.CdpInfo;
5046
import org.openqa.selenium.devtools.CdpVersionFinder;
@@ -67,7 +63,6 @@
6763
import org.openqa.selenium.remote.RemoteWebDriver;
6864
import org.openqa.selenium.remote.html5.RemoteLocationContext;
6965
import org.openqa.selenium.remote.html5.RemoteWebStorage;
70-
import org.openqa.selenium.remote.http.ClientConfig;
7166
import org.openqa.selenium.remote.http.ConnectionFailedException;
7267
import org.openqa.selenium.remote.http.HttpClient;
7368
import org.openqa.selenium.remote.mobile.RemoteNetworkConnection;
@@ -78,7 +73,6 @@
7873
*/
7974
public class ChromiumDriver extends RemoteWebDriver
8075
implements HasAuthentication,
81-
HasBiDi,
8276
HasCasting,
8377
HasCdp,
8478
HasDevTools,
@@ -103,8 +97,6 @@ public class ChromiumDriver extends RemoteWebDriver
10397
private final HasLaunchApp launch;
10498
private Optional<Connection> connection;
10599
private final Optional<DevTools> devTools;
106-
private final Optional<URI> biDiUri;
107-
private Optional<BiDi> biDi;
108100
protected HasCasting casting;
109101
protected HasCdp cdp;
110102
private final Map<Integer, ScriptKey> scriptKeys = new HashMap<>();
@@ -122,23 +114,7 @@ protected ChromiumDriver(
122114

123115
HttpClient.Factory factory = HttpClient.Factory.createDefault();
124116
Capabilities originalCapabilities = super.getCapabilities();
125-
126-
Optional<String> webSocketUrl =
127-
Optional.ofNullable((String) originalCapabilities.getCapability("webSocketUrl"));
128-
129-
this.biDiUri =
130-
webSocketUrl.map(
131-
uri -> {
132-
try {
133-
return new URI(uri);
134-
} catch (URISyntaxException e) {
135-
LOG.warning(e.getMessage());
136-
}
137-
return null;
138-
});
139-
140-
this.biDi = createBiDi(biDiUri);
141-
117+
142118
Optional<URI> reportedUri =
143119
CdpEndpointFinder.getReportedUri(capabilityKey, originalCapabilities);
144120
Optional<HttpClient> client =
@@ -339,17 +315,7 @@ public Map<String, Object> executeCdpCommand(String commandName, Map<String, Obj
339315
public Optional<DevTools> maybeGetDevTools() {
340316
return devTools;
341317
}
342-
343-
@Override
344-
public Optional<BiDi> maybeGetBiDi() {
345-
return biDi;
346-
}
347-
348-
@Override
349-
public void setBiDi(BiDi bidi) {
350-
this.biDi = Optional.of(bidi);
351-
}
352-
318+
353319
@Override
354320
public List<Map<String, String>> getCastSinks() {
355321
return casting.getCastSinks();

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

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@
3636
import org.openqa.selenium.PersistentCapabilities;
3737
import org.openqa.selenium.Proxy;
3838
import org.openqa.selenium.WebDriverException;
39-
import org.openqa.selenium.bidi.BiDi;
40-
import org.openqa.selenium.bidi.BiDiException;
41-
import org.openqa.selenium.bidi.HasBiDi;
4239
import org.openqa.selenium.devtools.CdpEndpointFinder;
4340
import org.openqa.selenium.devtools.CdpInfo;
4441
import org.openqa.selenium.devtools.CdpVersionFinder;
@@ -79,7 +76,7 @@
7976
* </pre>
8077
*/
8178
public class FirefoxDriver extends RemoteWebDriver
82-
implements WebStorage, HasExtensions, HasFullPageScreenshot, HasContext, HasDevTools, HasBiDi {
79+
implements WebStorage, HasExtensions, HasFullPageScreenshot, HasContext, HasDevTools {
8380

8481
private static final Logger LOG = Logger.getLogger(FirefoxDriver.class.getName());
8582
private final Capabilities capabilities;
@@ -88,10 +85,8 @@ public class FirefoxDriver extends RemoteWebDriver
8885
private final HasFullPageScreenshot fullPageScreenshot;
8986
private final HasContext context;
9087
private final Optional<URI> cdpUri;
91-
private Optional<URI> biDiUri = Optional.empty();
9288
private Connection connection;
9389
private DevTools devTools;
94-
private Optional<BiDi> biDi = Optional.empty();
9590

9691
/**
9792
* Creates a new FirefoxDriver using the {@link GeckoDriverService#createDefaultService)} server
@@ -190,25 +185,7 @@ private FirefoxDriver(
190185
+ reportedUri.get(),
191186
e);
192187
}
193-
194-
Optional<String> webSocketUrl =
195-
Optional.ofNullable((String) capabilities.getCapability("webSocketUrl"));
196-
197-
if (!this.biDi.isPresent()) {
198-
this.biDiUri =
199-
webSocketUrl.map(
200-
uri -> {
201-
try {
202-
return new URI(uri);
203-
} catch (URISyntaxException e) {
204-
LOG.warning(e.getMessage());
205-
}
206-
return null;
207-
});
208-
209-
this.biDi = createBiDi(biDiUri);
210-
}
211-
188+
212189
this.cdpUri = cdpUri;
213190
this.capabilities =
214191
cdpUri
@@ -354,17 +331,7 @@ public DevTools getDevTools() {
354331
return maybeGetDevTools()
355332
.orElseThrow(() -> new DevToolsException("Unable to initialize CDP connection"));
356333
}
357-
358-
@Override
359-
public Optional<BiDi> maybeGetBiDi() {
360-
return biDi;
361-
}
362-
363-
@Override
364-
public void setBiDi(BiDi bidi) {
365-
this.biDi = Optional.ofNullable(bidi);
366-
}
367-
334+
368335
@Override
369336
public void quit() {
370337
super.quit();

java/src/org/openqa/selenium/remote/RemoteWebDriver.java

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
public class RemoteWebDriver
108108
implements WebDriver,
109109
JavascriptExecutor,
110+
HasBiDi,
110111
HasCapabilities,
111112
HasDownloads,
112113
HasFederatedCredentialManagement,
@@ -130,6 +131,8 @@ public class RemoteWebDriver
130131
private Logs remoteLogs;
131132
private LocalLogs localLogs;
132133

134+
private Optional<BiDi> biDi = Optional.empty();
135+
133136
// For cglib
134137
protected RemoteWebDriver() {
135138
this.capabilities = init(new ImmutableCapabilities());
@@ -171,23 +174,17 @@ public RemoteWebDriver(CommandExecutor executor, Capabilities capabilities) {
171174

172175
// Firefox returns the capability back as it is if it is not supported
173176
// So we need to check before proceeding
174-
// Add a test to check
175-
if (webSocketUrl.isPresent() && getCommandExecutor() instanceof Delegator) {
176-
Optional<BiDi> biDi =
177-
((HasBiDi) this)
178-
.createBiDi(
179-
webSocketUrl.map(
180-
uri -> {
181-
try {
182-
return new URI(uri);
183-
} catch (URISyntaxException e) {
184-
LOG.warning(e.getMessage());
185-
}
186-
return null;
187-
}));
188-
189-
biDi.ifPresent(connection -> ((HasBiDi) this).setBiDi(connection));
190-
((Delegator) (getCommandExecutor())).setBiDiCommandExecutor(new BiDiCommandExecutor(this));
177+
if (webSocketUrl.isPresent()) {
178+
this.biDi = createBiDi(webSocketUrl.get());
179+
CommandExecutor commandExecutor = executor;
180+
181+
if (commandExecutor instanceof TracedCommandExecutor) {
182+
commandExecutor = ((TracedCommandExecutor) executor).getDelegate();
183+
}
184+
185+
if (commandExecutor instanceof Delegator) {
186+
((Delegator) (commandExecutor)).setBiDiCommandExecutor(new BiDiCommandExecutor(this));
187+
}
191188
}
192189
} catch (RuntimeException e) {
193190
try {
@@ -852,6 +849,27 @@ public String toString() {
852849
getClass().getSimpleName(), caps.getBrowserName(), platformName, getSessionId());
853850
}
854851

852+
@Override
853+
public Optional<BiDi> maybeGetBiDi() {
854+
return this.biDi;
855+
}
856+
857+
private Optional<BiDi> createBiDi(String biDiUri) {
858+
try {
859+
URI wsUri = new URI(biDiUri);
860+
HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();
861+
ClientConfig wsConfig = ClientConfig.defaultConfig().baseUri(wsUri);
862+
HttpClient wsClient = clientFactory.createClient(wsConfig);
863+
864+
org.openqa.selenium.bidi.Connection biDiConnection =
865+
new org.openqa.selenium.bidi.Connection(wsClient, wsUri.toString());
866+
867+
return Optional.of(new BiDi(biDiConnection));
868+
} catch (URISyntaxException e) {
869+
throw new RuntimeException(e);
870+
}
871+
}
872+
855873
public enum When {
856874
BEFORE,
857875
AFTER,

java/src/org/openqa/selenium/remote/TracedCommandExecutor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,8 @@ public Response execute(Command command) throws IOException {
5151
return delegate.execute(command);
5252
}
5353
}
54+
55+
public CommandExecutor getDelegate() {
56+
return delegate;
57+
}
5458
}

java/test/org/openqa/selenium/grid/router/RemoteWebDriverBiDiTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,33 @@ void ensureBiDiSessionCreation() {
8080
}
8181
}
8282

83+
@Test
84+
void canPortNavigateToBiDi() {
85+
Browser browser = Browser.FIREFOX;
86+
87+
Deployment deployment =
88+
DeploymentTypes.STANDALONE.start(
89+
browser.getCapabilities(),
90+
new TomlConfig(
91+
new StringReader(
92+
"[node]\n"
93+
+ "selenium-manager = false\n"
94+
+ "driver-implementation = "
95+
+ browser.displayName())));
96+
97+
AppServer server = new NettyAppServer();
98+
server.start();
99+
100+
FirefoxOptions options = createFirefoxOptions();
101+
// Enable BiDi
102+
options.setCapability("webSocketUrl", true);
103+
options.merge(Browser.FIREFOX.getCapabilities());
104+
105+
WebDriver driver = new RemoteWebDriver(deployment.getServer().getUrl(), options);
106+
String page = server.whereIs("/bidi/logEntryAdded.html");
107+
driver.get(page);
108+
}
109+
83110
@Test
84111
void canListenToLogs() throws ExecutionException, InterruptedException, TimeoutException {
85112
Browser browser = Browser.FIREFOX;

0 commit comments

Comments
 (0)