Skip to content

Commit

Permalink
Add supports for list-of-table options
Browse files Browse the repository at this point in the history
  • Loading branch information
sbabcoc committed Jul 16, 2023
1 parent 276240d commit 1c2aac1
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 27 deletions.
19 changes: 19 additions & 0 deletions java/src/org/openqa/selenium/grid/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@

package org.openqa.selenium.grid.config;

import com.google.common.collect.ImmutableList;
import org.openqa.selenium.json.Json;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
Expand Down Expand Up @@ -55,4 +59,19 @@ default <X> X getClass(String section, String option, Class<X> typeOfClass, Stri
throw new IllegalArgumentException("Unable to find class: " + clazz, e);
}
}

default List<String> toEntryList(Map<String, Object> mapItem) {
return mapItem.entrySet().stream()
.map(entry -> {
return String.format("%s=%s", entry.getKey(), toJson(entry.getValue()));
})
.sorted()
.collect(ImmutableList.toImmutableList());
}

default String toJson(Object value) {
StringBuilder jsonStr = new StringBuilder();
new Json().newOutput(jsonStr).setPrettyPrint(false).write(value);
return jsonStr.toString();
}
}
30 changes: 29 additions & 1 deletion java/src/org/openqa/selenium/grid/config/MapConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.openqa.selenium.internal.Require;

public class MapConfig implements Config {
Expand Down Expand Up @@ -65,7 +67,33 @@ public Optional<List<String>> getAll(String section, String option) {
}

Object value = rawSection.get(option);
return value == null ? Optional.empty() : Optional.of(ImmutableList.of(String.valueOf(value)));
if (value == null) {
return Optional.empty();
}

if (value instanceof Collection) {
Collection<?> collection = (Collection<?>) value;
// Case when an array of map is used as config
if (collection.stream().anyMatch(item -> item instanceof Map)) {
return Optional.of(collection.stream()
.map(item -> (Map<String, Object>) item)
.map(this::toEntryList)
.flatMap(Collection::stream)
.collect(ImmutableList.toImmutableList()));
}

return Optional.of(
collection.stream()
.filter(item -> (!(item instanceof Collection)))
.map(String::valueOf)
.collect(ImmutableList.toImmutableList()));
}

if (value instanceof Map) {
return Optional.of(toEntryList((Map<String, Object>) value));
}

return Optional.of(ImmutableList.of(String.valueOf(value)));
}

@Override
Expand Down
34 changes: 17 additions & 17 deletions java/src/org/openqa/selenium/grid/config/TomlConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
import io.ous.jtoml.ParseException;
import io.ous.jtoml.Toml;
import io.ous.jtoml.TomlTable;
import org.openqa.selenium.internal.Require;

import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.openqa.selenium.internal.Require;

public class TomlConfig implements Config {

Expand Down Expand Up @@ -87,24 +87,24 @@ public Optional<List<String>> getAll(String section, String option) {
// Case when an array of tables is used as config
// https://toml.io/en/v1.0.0-rc.3#array-of-tables
if (collection.stream().anyMatch(item -> item instanceof TomlTable)) {
List<String> toReturn = new ArrayList<>();
collection.stream()
return Optional.of(
collection.stream()
.map(item -> (TomlTable) item)
.forEach(
tomlTable ->
tomlTable.toMap().entrySet().stream()
.map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue()))
.sorted()
.forEach(toReturn::add));
return Optional.of(toReturn);
.map(TomlTable::toMap)
.map(this::toEntryList)
.flatMap(Collection::stream)
.collect(ImmutableList.toImmutableList()));
}
List<String> values =
collection.stream()
.filter(item -> (!(item instanceof Collection)))
.map(String::valueOf)
.collect(ImmutableList.toImmutableList());

return Optional.of(values);
return Optional.of(
collection.stream()
.filter(item -> (!(item instanceof Collection)))
.map(String::valueOf)
.collect(ImmutableList.toImmutableList()));
}

if (value instanceof TomlTable) {
return Optional.of(toEntryList(((TomlTable) value).toMap()));
}

return Optional.of(ImmutableList.of(String.valueOf(value)));
Expand Down
12 changes: 11 additions & 1 deletion java/src/org/openqa/selenium/grid/node/config/NodeOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import java.io.File;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
Expand Down Expand Up @@ -57,6 +58,7 @@
import org.openqa.selenium.grid.node.SessionFactory;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.json.JsonInput;
import org.openqa.selenium.json.JsonOutput;
import org.openqa.selenium.net.NetworkUtils;
import org.openqa.selenium.net.Urls;
Expand Down Expand Up @@ -390,7 +392,7 @@ private void addDriverConfigs(
.forEach(
keyValue -> {
String[] values = keyValue.split("=", 2);
configMap.put(values[0], values[1]);
configMap.put(values[0], unquote(values[1]));
});
driversMap.add(configMap);
}
Expand Down Expand Up @@ -716,4 +718,12 @@ private void report(Map.Entry<WebDriverInfo, Collection<SessionFactory>> entry)
entry.getValue().size(),
entry.getKey().isPresent() ? "Host" : "SM"));
}

private String unquote(String input) {
int len = input.length();
if ((input.charAt(0) == '"') && (input.charAt(len - 1) == '"')) {
return new Json().newInput(new StringReader(input)).read(Json.OBJECT_TYPE);
}
return input;
}
}
10 changes: 6 additions & 4 deletions java/test/org/openqa/selenium/firefox/FirefoxOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,12 @@ void binaryPathNeedNotExist() {

@Test
void shouldKeepRelativePathToBinaryAsIs() {
FirefoxOptions options = new FirefoxOptions().setBinary("some/path");
String path = String.join(File.separator, "some", "path");
FirefoxOptions options = new FirefoxOptions().setBinary(path);
assertThat(options.getBinary())
.extracting(FirefoxBinary::getFile)
.extracting(String::valueOf)
.isEqualTo("some/path");
.isEqualTo(path);
}

@Test
Expand Down Expand Up @@ -138,11 +139,12 @@ void stringBasedBinaryRemainsAbsoluteIfSetAsAbsolute() {

@Test
void pathBasedBinaryRemainsAbsoluteIfSetAsAbsolute() {
String path = String.join(File.separator, "", "i", "like", "cheese");
Map<String, Object> json = new FirefoxOptions().setBinary(Paths.get("/i/like/cheese")).asMap();

assertThat(json.get(FIREFOX_OPTIONS))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsEntry("binary", "/i/like/cheese");
.containsEntry("binary", path);
}

@Test
Expand Down Expand Up @@ -311,7 +313,7 @@ void canConvertOptionsWithBinaryToCapabilitiesAndRestoreBack() throws IOExceptio
Object options2 = options.asMap().get(FirefoxOptions.FIREFOX_OPTIONS);
assertThat(options2)
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsEntry("binary", tempFile.toFile().getPath().replaceAll("\\\\", "/"));
.containsEntry("binary", tempFile.toFile().getPath());
}

@Test
Expand Down
1 change: 1 addition & 0 deletions java/test/org/openqa/selenium/grid/config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ java_test_suite(
deps = [
"//java/src/org/openqa/selenium:core",
"//java/src/org/openqa/selenium/grid/config",
"//java/src/org/openqa/selenium/json",
artifact("com.beust:jcommander"),
artifact("com.google.guava:guava"),
artifact("io.ous:jtoml"),
Expand Down
83 changes: 83 additions & 0 deletions java/test/org/openqa/selenium/grid/config/JsonConfigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
import static org.assertj.core.api.Assertions.assertThat;

import java.io.StringReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import org.junit.jupiter.api.Test;

class JsonConfigTest {
Expand All @@ -32,4 +36,83 @@ void shouldUseATableAsASection() {

assertThat(config.get("cheeses", "selected")).isEqualTo(Optional.of("brie"));
}

@Test
void ensureCanReadListOfStrings() {
String raw = String.join("", "",
"{",
"`relay`: {",
"`configs`: [`2`, `{\\`browserName\\`: \\`chrome\\`}`]",
"}",
"}"
).replace("`", "\"");
Config config = new JsonConfig(new StringReader(raw));

List<String> expected = Arrays.asList(
"2",
"{\"browserName\": \"chrome\"}"
);
Optional<List<String>> content = config.getAll("relay", "configs");
assertThat(content).isEqualTo(Optional.of(expected));
}

@Test
void shouldContainConfigFromArrayOfTables() {
String raw = String.join("", "",
"{",
"`cheeses`: {",
"`default`: `manchego`,",
"`type`: [",
"{",
"`name`: `soft cheese`,",
"`default`: `brie`",
"},",
"{",
"`name`: `Medium-hard cheese`,",
"`default`: `Emmental`",
"}",
"]",
"}",
"}"
).replace("`", "\"");
Config config = new JsonConfig(new StringReader(raw));

assertThat(config.get("cheeses", "default")).isEqualTo(Optional.of("manchego"));

List<String> expected =
Arrays.asList(
"default=\"brie\"", "name=\"soft cheese\"",
"default=\"Emmental\"", "name=\"Medium-hard cheese\"");
assertThat(config.getAll("cheeses", "type").orElse(Collections.emptyList()))
.isEqualTo(expected);
assertThat(config.getAll("cheeses", "type").orElse(Collections.emptyList()).subList(0, 2))
.isEqualTo(expected.subList(0, 2));
}

@Test
void ensureCanReadListOfMaps() {
String raw = String.join("", "",
"{",
"`node`: {",
"`detect-drivers`: false,",
"`driver-configuration`: [",
"{",
"`display-name`: `htmlunit`,",
"`stereotype`: {",
"`browserName`: `htmlunit`,",
"`browserVersion`: `chrome`",
"}",
"}",
"]",
"}",
"}"
).replace("`", "\"");
Config config = new JsonConfig(new StringReader(raw));
List<String> expected = Arrays.asList(
"display-name=\"htmlunit\"",
"stereotype={\"browserName\": \"htmlunit\",\"browserVersion\": \"chrome\"}"
);
Optional<List<String>> content = config.getAll("node", "driver-configuration");
assertThat(content).isEqualTo(Optional.of(expected));
}
}
Loading

0 comments on commit 1c2aac1

Please sign in to comment.