Skip to content

Commit 2e013bd

Browse files
committed
[grid] Add BiDi enable flag. Add "se:bidi" from local node.
1 parent 7e0978c commit 2e013bd

File tree

5 files changed

+76
-2
lines changed

5 files changed

+76
-2
lines changed

java/src/org/openqa/selenium/grid/node/config/NodeFlags.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import static org.openqa.selenium.grid.config.StandardGridRoles.NODE_ROLE;
3535
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_DETECT_DRIVERS;
3636
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_DRAIN_AFTER_SESSION_COUNT;
37+
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_ENABLE_BIDI;
3738
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_ENABLE_CDP;
3839
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_HEARTBEAT_PERIOD;
3940
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_MAX_SESSIONS;
@@ -204,6 +205,14 @@ public class NodeFlags implements HasRoles {
204205
@ConfigValue(section = NODE_SECTION, name = "enable-cdp", example = "true")
205206
public Boolean enableCdp = DEFAULT_ENABLE_CDP;
206207

208+
@Parameter(
209+
names = {"--enable-bidi"},
210+
arity = 1,
211+
description = "Enable BiDi proxying in Grid. A Grid admin can disable BiDi if the network does "
212+
+ "not allow websockets. True by default")
213+
@ConfigValue(section = NODE_SECTION, name = "enable-bidi", example = "true")
214+
public Boolean enableBiDi = DEFAULT_ENABLE_BIDI;
215+
207216
@Parameter(
208217
names = {"--node-implementation"},
209218
description = "Full classname of non-default Node implementation. This is used to manage "

java/src/org/openqa/selenium/grid/node/config/NodeOptions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public class NodeOptions {
7171
public static final int DEFAULT_SESSION_TIMEOUT = 300;
7272
public static final int DEFAULT_DRAIN_AFTER_SESSION_COUNT = 0;
7373
public static final boolean DEFAULT_ENABLE_CDP = true;
74+
public static final boolean DEFAULT_ENABLE_BIDI = true;
7475
static final String NODE_SECTION = "node";
7576
static final boolean DEFAULT_DETECT_DRIVERS = true;
7677
static final boolean OVERRIDE_MAX_SESSIONS = false;
@@ -238,6 +239,10 @@ public boolean isCdpEnabled() {
238239
return config.getBool(NODE_SECTION, "enable-cdp").orElse(DEFAULT_ENABLE_CDP);
239240
}
240241

242+
public boolean isBiDiEnabled() {
243+
return config.getBool(NODE_SECTION, "enable-bidi").orElse(DEFAULT_ENABLE_BIDI);
244+
}
245+
241246
public int getDrainAfterSessionCount() {
242247
return Math.max(
243248
config.getInt(NODE_SECTION, "drain-after-session-count")

java/src/org/openqa/selenium/grid/node/local/LocalNode.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ public class LocalNode extends Node {
121121
private final int maxSessionCount;
122122
private final int configuredSessionCount;
123123
private final boolean cdpEnabled;
124+
125+
private final boolean bidiEnabled;
124126
private final AtomicBoolean drainAfterSessions = new AtomicBoolean();
125127
private final List<SessionSlot> factories;
126128
private final Cache<SessionId, SessionSlot> currentSessions;
@@ -137,6 +139,7 @@ private LocalNode(
137139
int maxSessionCount,
138140
int drainAfterSessionCount,
139141
boolean cdpEnabled,
142+
boolean bidiEnabled,
140143
Ticker ticker,
141144
Duration sessionTimeout,
142145
Duration heartbeatPeriod,
@@ -157,6 +160,7 @@ private LocalNode(
157160
this.drainAfterSessions.set(this.configuredSessionCount > 0);
158161
this.sessionCount.set(drainAfterSessionCount);
159162
this.cdpEnabled = cdpEnabled;
163+
this.bidiEnabled = bidiEnabled;
160164

161165
this.healthCheck = healthCheck == null ?
162166
() -> {
@@ -390,6 +394,7 @@ public Either<WebDriverException, CreateSessionResponse> newSession(CreateSessio
390394
session,
391395
externalUri,
392396
slotToUse.isSupportingCdp(),
397+
slotToUse.isSupportingBiDi(),
393398
sessionRequest.getDesiredCapabilities());
394399

395400
String sessionCreatedMessage = "Session created by the Node";
@@ -427,6 +432,7 @@ public Session getSession(SessionId id) throws NoSuchSessionException {
427432
slot.getSession(),
428433
externalUri,
429434
slot.isSupportingCdp(),
435+
slot.isSupportingBiDi(),
430436
slot.getSession().getCapabilities());
431437
}
432438

@@ -515,8 +521,11 @@ private void stopAllSessions() {
515521
}
516522
}
517523

518-
private Session createExternalSession(ActiveSession other, URI externalUri,
519-
boolean isSupportingCdp, Capabilities requestCapabilities) {
524+
private Session createExternalSession(ActiveSession other,
525+
URI externalUri,
526+
boolean isSupportingCdp,
527+
boolean isSupportingBiDi,
528+
Capabilities requestCapabilities) {
520529
// We merge the session request capabilities and the session ones to keep the values sent
521530
// by the user in the session information
522531
Capabilities toUse = ImmutableCapabilities
@@ -535,6 +544,21 @@ private Session createExternalSession(ActiveSession other, URI externalUri,
535544
}
536545
});
537546
toUse = new PersistentCapabilities(cdpFiltered).setCapability("se:cdpEnabled", false);
547+
}
548+
549+
// Add se:bidi if necessary to send the bidi url back
550+
if ((isSupportingBiDi || toUse.getCapability("se:bidi") != null) && bidiEnabled) {
551+
String bidiPath = String.format("/session/%s/se/bidi", other.getId());
552+
toUse = new PersistentCapabilities(toUse).setCapability("se:bidi", rewrite(bidiPath));
553+
} else {
554+
// Remove any se:bidi* from the response, BiDi is not supported nor enabled
555+
MutableCapabilities bidiFiltered = new MutableCapabilities();
556+
toUse.asMap().forEach((key, value) -> {
557+
if (!key.startsWith("se:bidi")) {
558+
bidiFiltered.setCapability(key, value);
559+
}
560+
});
561+
toUse = new PersistentCapabilities(bidiFiltered).setCapability("se:bidiEnabled", false);
538562
}
539563

540564
// If enabled, set the VNC endpoint for live view
@@ -665,6 +689,7 @@ public static class Builder {
665689
private int maxSessions = NodeOptions.DEFAULT_MAX_SESSIONS;
666690
private int drainAfterSessionCount = NodeOptions.DEFAULT_DRAIN_AFTER_SESSION_COUNT;
667691
private boolean cdpEnabled = NodeOptions.DEFAULT_ENABLE_CDP;
692+
private boolean bidiEnabled = NodeOptions.DEFAULT_ENABLE_BIDI;
668693
private Ticker ticker = Ticker.systemTicker();
669694
private Duration sessionTimeout = Duration.ofSeconds(NodeOptions.DEFAULT_SESSION_TIMEOUT);
670695
private HealthCheck healthCheck;
@@ -708,6 +733,11 @@ public Builder enableCdp(boolean cdpEnabled) {
708733
return this;
709734
}
710735

736+
public Builder enableBiDi(boolean bidiEnabled) {
737+
this.bidiEnabled = bidiEnabled;
738+
return this;
739+
}
740+
711741
public Builder sessionTimeout(Duration timeout) {
712742
sessionTimeout = timeout;
713743
return this;
@@ -728,6 +758,7 @@ public LocalNode build() {
728758
maxSessions,
729759
drainAfterSessionCount,
730760
cdpEnabled,
761+
bidiEnabled,
731762
ticker,
732763
sessionTimeout,
733764
heartbeatPeriod,

java/src/org/openqa/selenium/grid/node/local/LocalNodeFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public static Node create(Config config) {
7070
.sessionTimeout(sessionTimeout)
7171
.drainAfterSessionCount(nodeOptions.getDrainAfterSessionCount())
7272
.enableCdp(nodeOptions.isCdpEnabled())
73+
.enableBiDi(nodeOptions.isBiDiEnabled())
7374
.heartbeatPeriod(nodeOptions.getHeartbeatPeriod());
7475

7576
List<DriverService.Builder<?, ?>> builders = new ArrayList<>();

java/test/org/openqa/selenium/grid/node/local/LocalNodeTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,4 +302,32 @@ void cdpIsDisabledAndResponseCapsShowThat() throws URISyntaxException {
302302
assertThat(cdpEnabled).isNotNull();
303303
assertThat(Boolean.parseBoolean(cdpEnabled.toString())).isFalse();
304304
}
305+
306+
@Test
307+
void bidiIsDisabledAndResponseCapsShowThat() throws URISyntaxException {
308+
Tracer tracer = DefaultTestTracer.createTracer();
309+
EventBus bus = new GuavaEventBus();
310+
URI uri = new URI("http://localhost:7890");
311+
Capabilities stereotype = new ImmutableCapabilities("browserName", "cheese");
312+
313+
LocalNode.Builder builder = LocalNode.builder(tracer, bus, uri, uri, registrationSecret)
314+
.enableBiDi(false)
315+
.add(stereotype,
316+
new TestSessionFactory((id, caps)
317+
-> new Session(id, uri, stereotype, caps, Instant.now())));
318+
LocalNode localNode = builder.build();
319+
320+
Either<WebDriverException, CreateSessionResponse> response = localNode.newSession(
321+
new CreateSessionRequest(
322+
ImmutableSet.of(W3C),
323+
stereotype,
324+
ImmutableMap.of()));
325+
assertThat(response.isRight()).isTrue();
326+
327+
CreateSessionResponse sessionResponse = response.right();
328+
Capabilities capabilities = sessionResponse.getSession().getCapabilities();
329+
Object bidiEnabled = capabilities.getCapability("se:bidiEnabled");
330+
assertThat(bidiEnabled).isNotNull();
331+
assertThat(Boolean.parseBoolean(bidiEnabled.toString())).isFalse();
332+
}
305333
}

0 commit comments

Comments
 (0)