diff --git a/java/src/org/openqa/selenium/remote/HttpCommandExecutor.java b/java/src/org/openqa/selenium/remote/HttpCommandExecutor.java index 03fc84bc45b19..1eb3283eae014 100644 --- a/java/src/org/openqa/selenium/remote/HttpCommandExecutor.java +++ b/java/src/org/openqa/selenium/remote/HttpCommandExecutor.java @@ -25,6 +25,8 @@ import java.io.IOException; import java.net.URL; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; import org.openqa.selenium.NoSuchSessionException; import org.openqa.selenium.SessionNotCreatedException; @@ -109,11 +111,34 @@ public HttpCommandExecutor( ClientConfig config, HttpClient.Factory httpClientFactory) { remoteServer = Require.nonNull("HTTP client configuration", config).baseUrl(); - this.additionalCommands = Require.nonNull("Additional commands", additionalCommands); + this.additionalCommands = + new HashMap<>(Require.nonNull("Additional commands", additionalCommands)); this.httpClientFactory = Require.nonNull("HTTP client factory", httpClientFactory); this.client = this.httpClientFactory.createClient(config); } + /** + * Returns an immutable view of the additional commands. + * + * @return an unmodifiable map of additional commands. + */ + public Map getAdditionalCommands() { + return Collections.unmodifiableMap(additionalCommands); + } + + /** + * Adds or updates additional commands. This method is protected to allow subclasses to define + * their commands. + * + * @param commandName the name of the command to add or update. + * @param info the CommandInfo for the command. + */ + protected void addAdditionalCommand(String commandName, CommandInfo info) { + Require.nonNull("Command name", commandName); + Require.nonNull("Command info", info); + this.additionalCommands.put(commandName, info); + } + /** * It may be useful to extend the commands understood by this {@code HttpCommandExecutor} at run * time, and this can be achieved via this method. Note, this is protected, and expected usage is diff --git a/java/test/org/openqa/selenium/remote/RemoteWebDriverInitializationTest.java b/java/test/org/openqa/selenium/remote/RemoteWebDriverInitializationTest.java index 111cac68e5085..8c01983488ed3 100644 --- a/java/test/org/openqa/selenium/remote/RemoteWebDriverInitializationTest.java +++ b/java/test/org/openqa/selenium/remote/RemoteWebDriverInitializationTest.java @@ -51,6 +51,7 @@ import org.openqa.selenium.remote.http.ClientConfig; import org.openqa.selenium.remote.http.Contents; import org.openqa.selenium.remote.http.HttpClient; +import org.openqa.selenium.remote.http.HttpMethod; import org.openqa.selenium.remote.http.HttpResponse; @Tag("UnitTests") @@ -234,4 +235,22 @@ public void quit() { quitCalled = true; } } + + @Test + void additionalCommandsCanBeModified() throws MalformedURLException { + HttpClient client = mock(HttpClient.class); + HttpClient.Factory factory = mock(HttpClient.Factory.class); + + when(factory.createClient(any(ClientConfig.class))).thenReturn(client); + + URL url = new URL("http://localhost:4444/"); + HttpCommandExecutor executor = + new HttpCommandExecutor(emptyMap(), ClientConfig.defaultConfig().baseUrl(url), factory); + + String commandName = "customCommand"; + CommandInfo commandInfo = new CommandInfo("/session/:sessionId/custom", HttpMethod.GET); + executor.addAdditionalCommand(commandName, commandInfo); + + assertThat(executor.getAdditionalCommands()).containsEntry(commandName, commandInfo); + } }