Skip to content

Commit e1cb6a5

Browse files
VietND96diemol
andauthored
[grid] Session can be deleted via Grid UI (#15808)
* [grid] Session can be deleted via Grid UI * Add notification on the flag to disable session deletion * Use Node config to disable delete session on UI * Add unit test Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com> * Run format * Disable by default * Run format --------- Signed-off-by: Viet Nguyen Duc <nguyenducviet4496@gmail.com> Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
1 parent 507b007 commit e1cb6a5

File tree

5 files changed

+557
-10
lines changed

5 files changed

+557
-10
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.openqa.selenium.grid.config.StandardGridRoles.NODE_ROLE;
2121
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_CONNECTION_LIMIT;
22+
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_DELETE_SESSION_ON_UI;
2223
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_DETECT_DRIVERS;
2324
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_DRAIN_AFTER_SESSION_COUNT;
2425
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_ENABLE_BIDI;
@@ -241,6 +242,13 @@ public class NodeFlags implements HasRoles {
241242
@ConfigValue(section = NODE_SECTION, name = "drain-after-session-count", example = "1")
242243
public int drainAfterSessionCount = DEFAULT_DRAIN_AFTER_SESSION_COUNT;
243244

245+
@Parameter(
246+
names = {"--delete-session-on-ui"},
247+
arity = 1,
248+
description = "Enable capability to support deleting session on Grid UI. False by default")
249+
@ConfigValue(section = NODE_SECTION, name = "delete-session-on-ui", example = "true")
250+
public Boolean deleteSessionOnUi = DEFAULT_DELETE_SESSION_ON_UI;
251+
244252
@Parameter(
245253
names = {"--enable-cdp"},
246254
arity = 1,

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public class NodeOptions {
7777
public static final int DEFAULT_SESSION_TIMEOUT = 300;
7878
public static final int DEFAULT_DRAIN_AFTER_SESSION_COUNT = 0;
7979
public static final int DEFAULT_CONNECTION_LIMIT = 10;
80+
public static final boolean DEFAULT_DELETE_SESSION_ON_UI = false;
8081
public static final boolean DEFAULT_ENABLE_CDP = true;
8182
public static final boolean DEFAULT_ENABLE_BIDI = true;
8283
static final String NODE_SECTION = "node";
@@ -303,6 +304,13 @@ public int getDrainAfterSessionCount() {
303304
DEFAULT_DRAIN_AFTER_SESSION_COUNT);
304305
}
305306

307+
@VisibleForTesting
308+
boolean isSessionDeletedOnUi() {
309+
return config
310+
.getBool(NODE_SECTION, "delete-session-on-ui")
311+
.orElse(DEFAULT_DELETE_SESSION_ON_UI);
312+
}
313+
306314
@VisibleForTesting
307315
boolean isVncEnabled() {
308316
List<String> vncEnvVars = DEFAULT_VNC_ENV_VARS;
@@ -750,6 +758,10 @@ public Capabilities enhanceStereotype(Capabilities capabilities) {
750758
.setCapability("se:vncEnabled", true)
751759
.setCapability("se:noVncPort", noVncPort());
752760
}
761+
if (isSessionDeletedOnUi()) {
762+
capabilities =
763+
new PersistentCapabilities(capabilities).setCapability("se:deleteSessionOnUi", true);
764+
}
753765
if (isManagedDownloadsEnabled() && canConfigureDownloadsDir(capabilities)) {
754766
capabilities = new PersistentCapabilities(capabilities).setCapability(ENABLE_DOWNLOADS, true);
755767
}

java/test/org/openqa/selenium/grid/node/config/NodeOptionsTest.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,110 @@ void testIsVncEnabledAcceptSingleEnvVar() {
764764
assertThat(nodeOptionsEnabled.isVncEnabled()).isFalse();
765765
}
766766

767+
@Test
768+
void deleteSessionOnUiIsEnabledByDefault() {
769+
Config config = new MapConfig(singletonMap("node", singletonMap("detect-drivers", "false")));
770+
NodeOptions nodeOptions = new NodeOptions(config);
771+
assertThat(nodeOptions.isSessionDeletedOnUi()).isFalse();
772+
}
773+
774+
@Test
775+
void deleteSessionOnUiCanBeEnabledExplicitly() {
776+
Config config =
777+
new MapConfig(
778+
singletonMap(
779+
"node",
780+
ImmutableMap.of("detect-drivers", "false", "delete-session-on-ui", "true")));
781+
NodeOptions nodeOptions = new NodeOptions(config);
782+
assertThat(nodeOptions.isSessionDeletedOnUi()).isTrue();
783+
}
784+
785+
@Test
786+
void deleteSessionOnUiCanBeDisabled() {
787+
Config config =
788+
new MapConfig(
789+
singletonMap(
790+
"node",
791+
ImmutableMap.of("detect-drivers", "false", "delete-session-on-ui", "false")));
792+
NodeOptions nodeOptions = new NodeOptions(config);
793+
assertThat(nodeOptions.isSessionDeletedOnUi()).isFalse();
794+
}
795+
796+
@Test
797+
void deleteSessionOnUiCapabilityIsAddedWhenEnabled() {
798+
assumeTrue(
799+
new ChromeDriverInfo().isPresent() || new GeckoDriverInfo().isPresent(),
800+
"A driver needs to be available");
801+
802+
Config config =
803+
new MapConfig(
804+
singletonMap(
805+
"node", ImmutableMap.of("detect-drivers", "true", "delete-session-on-ui", "true")));
806+
807+
List<Capabilities> reported = new ArrayList<>();
808+
new NodeOptions(config)
809+
.getSessionFactories(
810+
caps -> {
811+
reported.add(caps);
812+
return Collections.singleton(HelperFactory.create(config, caps));
813+
});
814+
815+
assertThat(reported)
816+
.filteredOn(capabilities -> capabilities.getCapability("se:deleteSessionOnUi") != null)
817+
.hasSize(reported.size());
818+
819+
assertThat(reported)
820+
.allMatch(
821+
capabilities ->
822+
Boolean.TRUE.equals(capabilities.getCapability("se:deleteSessionOnUi")));
823+
}
824+
825+
@Test
826+
void deleteSessionOnUiCapabilityIsNotAddedWhenDisabled() {
827+
assumeTrue(
828+
new ChromeDriverInfo().isPresent() || new GeckoDriverInfo().isPresent(),
829+
"A driver needs to be available");
830+
831+
Config config =
832+
new MapConfig(
833+
singletonMap(
834+
"node",
835+
ImmutableMap.of("detect-drivers", "true", "delete-session-on-ui", "false")));
836+
837+
List<Capabilities> reported = new ArrayList<>();
838+
new NodeOptions(config)
839+
.getSessionFactories(
840+
caps -> {
841+
reported.add(caps);
842+
return Collections.singleton(HelperFactory.create(config, caps));
843+
});
844+
845+
assertThat(reported)
846+
.filteredOn(capabilities -> capabilities.getCapability("se:deleteSessionOnUi") == null)
847+
.hasSize(reported.size());
848+
}
849+
850+
@Test
851+
void deleteSessionOnUiCapabilityIsAddedByDefault() {
852+
assumeTrue(
853+
new ChromeDriverInfo().isPresent() || new GeckoDriverInfo().isPresent(),
854+
"A driver needs to be available");
855+
856+
Config config = new MapConfig(singletonMap("node", singletonMap("detect-drivers", "true")));
857+
858+
List<Capabilities> reported = new ArrayList<>();
859+
new NodeOptions(config)
860+
.getSessionFactories(
861+
caps -> {
862+
reported.add(caps);
863+
return Collections.singleton(HelperFactory.create(config, caps));
864+
});
865+
866+
assertThat(reported)
867+
.filteredOn(capabilities -> capabilities.getCapability("se:deleteSessionOnUi") == null)
868+
.hasSize(reported.size());
869+
}
870+
767871
private Condition<? super List<? extends Capabilities>> supporting(String name) {
768872
return new Condition<>(
769873
caps -> caps.stream().anyMatch(cap -> name.equals(cap.getBrowserName())),

0 commit comments

Comments
 (0)