diff --git a/java/client/src/org/openqa/selenium/remote/NewSessionPayload.java b/java/client/src/org/openqa/selenium/remote/NewSessionPayload.java index ff43dc1a420a4..d034327cafaef 100644 --- a/java/client/src/org/openqa/selenium/remote/NewSessionPayload.java +++ b/java/client/src/org/openqa/selenium/remote/NewSessionPayload.java @@ -219,8 +219,7 @@ public void writeTo(Appendable appendable) throws IOException { Map first = getOss(); if (first == null) { - //noinspection unchecked - first = (Map) stream().findFirst() + first = stream().findFirst() .orElse(new ImmutableCapabilities()) .asMap(); } @@ -246,10 +245,36 @@ public void writeTo(Appendable appendable) throws IOException { json.endArray(); json.endObject(); // Close "capabilities" object + + writeMetaData(json); + json.endObject(); } } + private void writeMetaData(JsonOutput out) throws IOException { + CharSource charSource = backingStore.asByteSource().asCharSource(UTF_8); + try (Reader reader = charSource.openBufferedStream(); + JsonInput input = json.newInput(reader)) { + input.beginObject(); + while (input.hasNext()) { + String name = input.nextName(); + switch (name) { + case "capabilities": + case "desiredCapabilities": + case "requiredCapabilities": + input.skipValue(); + break; + + default: + out.name(name); + out.write(input.read(Object.class), Object.class); + break; + } + } + } + } + private void streamW3CProtocolParameters(JsonOutput out, Map des) { // Technically we should be building up a combination of "alwaysMatch" and "firstMatch" options. // We're going to do a little processing to figure out what we might be able to do, and assume diff --git a/java/server/test/org/openqa/selenium/remote/server/NewSessionPayloadTest.java b/java/server/test/org/openqa/selenium/remote/server/NewSessionPayloadTest.java index 0033ce93f1eb6..157ae9de4ecdd 100644 --- a/java/server/test/org/openqa/selenium/remote/server/NewSessionPayloadTest.java +++ b/java/server/test/org/openqa/selenium/remote/server/NewSessionPayloadTest.java @@ -19,7 +19,9 @@ import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import static org.openqa.selenium.json.Json.MAP_TYPE; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -211,6 +213,34 @@ public void convertEverythingToFirstMatchOnlyifPayloadContainsAlwaysMatchSection capabilities); } + @Test + public void forwardsMetaDataAssociatedWithARequest() throws IOException { + try (NewSessionPayload payload = NewSessionPayload.create( ImmutableMap.of( + "desiredCapabilities", ImmutableMap.of(), + "cloud:user", "bob", + "cloud:key", "there is no cake"))) { + StringBuilder toParse = new StringBuilder(); + payload.writeTo(toParse); + Map seen = new Json().toType(toParse.toString(), MAP_TYPE); + + assertEquals("bob", seen.get("cloud:user")); + assertEquals("there is no cake", seen.get("cloud:key")); + } + } + + @Test + public void doesNotForwardRequiredCapabilitiesAsTheseAreVeryLegacy() throws IOException { + try (NewSessionPayload payload = NewSessionPayload.create( ImmutableMap.of( + "capabilities", ImmutableMap.of(), + "requiredCapabilities", ImmutableMap.of("key", "so it's not empty")))) { + StringBuilder toParse = new StringBuilder(); + payload.writeTo(toParse); + Map seen = new Json().toType(toParse.toString(), MAP_TYPE); + + assertNull(seen.get("requiredCapabilities")); + } + } + private List create(Map source) throws IOException { List presumablyFromMemory; List fromDisk;