...41import java.util.Optional;42import java.util.Set;43import java.util.stream.Collectors;44@SuppressWarnings("unchecked")45public class ProtocolHandshakeTest {46 @Test47 public void requestShouldIncludeJsonWireProtocolCapabilities() throws IOException {48 Map<String, Object> params = singletonMap("desiredCapabilities", new ImmutableCapabilities());49 Command command = new Command(null, DriverCommand.NEW_SESSION, params);50 HttpResponse response = new HttpResponse();51 response.setStatus(HTTP_OK);52 response.setContent(utf8String(53 "{\"value\": {\"sessionId\": \"23456789\", \"capabilities\": {}}}"));54 RecordingHttpClient client = new RecordingHttpClient(response);55 new ProtocolHandshake().createSession(client, command);56 Map<String, Object> json = getRequestPayloadAsMap(client);57 assertThat(json.get("desiredCapabilities")).isEqualTo(EMPTY_MAP);58 }59 @Test60 public void requestShouldIncludeSpecCompliantW3CCapabilities() throws IOException {61 Map<String, Object> params = singletonMap("desiredCapabilities", new ImmutableCapabilities());62 Command command = new Command(null, DriverCommand.NEW_SESSION, params);63 HttpResponse response = new HttpResponse();64 response.setStatus(HTTP_OK);65 response.setContent(utf8String(66 "{\"value\": {\"sessionId\": \"23456789\", \"capabilities\": {}}}"));67 RecordingHttpClient client = new RecordingHttpClient(response);68 new ProtocolHandshake().createSession(client, command);69 Map<String, Object> json = getRequestPayloadAsMap(client);70 List<Map<String, Object>> caps = mergeW3C(json);71 assertThat(caps).isNotEmpty();72 }73 @Test74 public void shouldParseW3CNewSessionResponse() throws IOException {75 Map<String, Object> params = singletonMap("desiredCapabilities", new ImmutableCapabilities());76 Command command = new Command(null, DriverCommand.NEW_SESSION, params);77 HttpResponse response = new HttpResponse();78 response.setStatus(HTTP_OK);79 response.setContent(utf8String(80 "{\"value\": {\"sessionId\": \"23456789\", \"capabilities\": {}}}"));81 RecordingHttpClient client = new RecordingHttpClient(response);82 ProtocolHandshake.Result result = new ProtocolHandshake().createSession(client, command);83 assertThat(result.getDialect()).isEqualTo(Dialect.W3C);84 }85 @Test86 public void shouldParseWireProtocolNewSessionResponse() throws IOException {87 Map<String, Object> params = singletonMap("desiredCapabilities", new ImmutableCapabilities());88 Command command = new Command(null, DriverCommand.NEW_SESSION, params);89 HttpResponse response = new HttpResponse();90 response.setStatus(HTTP_OK);91 response.setContent(utf8String(92 "{\"sessionId\": \"23456789\", \"status\": 0, \"value\": {}}"));93 RecordingHttpClient client = new RecordingHttpClient(response);94 ProtocolHandshake.Result result = new ProtocolHandshake().createSession(client, command);95 assertThat(result.getDialect()).isEqualTo(Dialect.OSS);96 }97 @Test98 public void shouldNotIncludeNonProtocolExtensionKeys() throws IOException {99 Capabilities caps = new ImmutableCapabilities(100 "se:option", "cheese",101 "option", "I like sausages",102 "browserName", "amazing cake browser");103 Map<String, Object> params = singletonMap("desiredCapabilities", caps);104 Command command = new Command(null, DriverCommand.NEW_SESSION, params);105 HttpResponse response = new HttpResponse();106 response.setStatus(HTTP_OK);107 response.setContent(utf8String(108 "{\"sessionId\": \"23456789\", \"status\": 0, \"value\": {}}"));109 RecordingHttpClient client = new RecordingHttpClient(response);110 new ProtocolHandshake().createSession(client, command);111 Map<String, Object> handshakeRequest = getRequestPayloadAsMap(client);112 Object rawCaps = handshakeRequest.get("capabilities");113 assertThat(rawCaps).isInstanceOf(Map.class);114 Map<?, ?> capabilities = (Map<?, ?>) rawCaps;115 assertThat(capabilities.get("alwaysMatch")).isNull();116 List<Map<?, ?>> first = (List<Map<?, ?>>) capabilities.get("firstMatch");117 // We don't care where they are, but we want to see "se:option" and not "option"118 Set<String> keys = first.stream()119 .map(Map::keySet)120 .flatMap(Collection::stream)121 .map(String::valueOf).collect(Collectors.toSet());122 assertThat(keys)123 .contains("browserName", "se:option")124 .doesNotContain("options");125 }126 @Test127 public void firstMatchSeparatesCapsForDifferentBrowsers() throws IOException {128 Capabilities caps = new ImmutableCapabilities(129 "moz:firefoxOptions", EMPTY_MAP,130 "browserName", "chrome");131 Map<String, Object> params = singletonMap("desiredCapabilities", caps);132 Command command = new Command(null, DriverCommand.NEW_SESSION, params);133 HttpResponse response = new HttpResponse();134 response.setStatus(HTTP_OK);135 response.setContent(utf8String(136 "{\"sessionId\": \"23456789\", \"status\": 0, \"value\": {}}"));137 RecordingHttpClient client = new RecordingHttpClient(response);138 new ProtocolHandshake().createSession(client, command);139 Map<String, Object> handshakeRequest = getRequestPayloadAsMap(client);140 List<Map<String, Object>> capabilities = mergeW3C(handshakeRequest);141 assertThat(capabilities).contains(142 singletonMap("moz:firefoxOptions", EMPTY_MAP),143 singletonMap("browserName", "chrome"));144 }145 @Test146 public void doesNotCreateFirstMatchForNonW3CCaps() throws IOException {147 Capabilities caps = new ImmutableCapabilities(148 "cheese", EMPTY_MAP,149 "moz:firefoxOptions", EMPTY_MAP,150 "browserName", "firefox");151 Map<String, Object> params = singletonMap("desiredCapabilities", caps);152 Command command = new Command(null, DriverCommand.NEW_SESSION, params);153 HttpResponse response = new HttpResponse();154 response.setStatus(HTTP_OK);155 response.setContent(utf8String(156 "{\"sessionId\": \"23456789\", \"status\": 0, \"value\": {}}"));157 RecordingHttpClient client = new RecordingHttpClient(response);158 new ProtocolHandshake().createSession(client, command);159 Map<String, Object> handshakeRequest = getRequestPayloadAsMap(client);160 List<Map<String, Object>> w3c = mergeW3C(handshakeRequest);161 assertThat(w3c).hasSize(1);162 // firstMatch should not contain an object for Chrome-specific capabilities. Because163 // "chromeOptions" is not a W3C capability name, it is stripped from any firstMatch objects.164 // The resulting empty object should be omitted from firstMatch; if it is present, then the165 // Firefox-specific capabilities might be ignored.166 assertThat(w3c.get(0))167 .containsKey("moz:firefoxOptions")168 .containsEntry("browserName", "firefox");169 }170 @Test171 public void shouldLowerCaseProxyTypeForW3CRequest() throws IOException {172 Proxy proxy = new Proxy();173 proxy.setProxyType(AUTODETECT);174 Capabilities caps = new ImmutableCapabilities(CapabilityType.PROXY, proxy);175 Map<String, Object> params = singletonMap("desiredCapabilities", caps);176 Command command = new Command(null, DriverCommand.NEW_SESSION, params);177 HttpResponse response = new HttpResponse();178 response.setStatus(HTTP_OK);179 response.setContent(utf8String(180 "{\"sessionId\": \"23456789\", \"status\": 0, \"value\": {}}"));181 RecordingHttpClient client = new RecordingHttpClient(response);182 new ProtocolHandshake().createSession(client, command);183 Map<String, Object> handshakeRequest = getRequestPayloadAsMap(client);184 mergeW3C(handshakeRequest).forEach(always -> {185 Map<String, ?> seenProxy = (Map<String, ?>) always.get("proxy");186 assertThat(seenProxy.get("proxyType")).isEqualTo("autodetect");187 });188 Map<String, ?> jsonCaps = (Map<String, ?>) handshakeRequest.get("desiredCapabilities");189 Map<String, ?> seenProxy = (Map<String, ?>) jsonCaps.get("proxy");190 assertThat(seenProxy.get("proxyType")).isEqualTo("AUTODETECT");191 }192 @Test193 public void shouldNotIncludeMappingOfANYPlatform() throws IOException {194 Capabilities caps = new ImmutableCapabilities(195 "platform", "ANY",196 "platformName", "ANY",197 "browserName", "cake");198 Map<String, Object> params = singletonMap("desiredCapabilities", caps);199 Command command = new Command(null, DriverCommand.NEW_SESSION, params);200 HttpResponse response = new HttpResponse();201 response.setStatus(HTTP_OK);202 response.setContent(utf8String(203 "{\"sessionId\": \"23456789\", \"status\": 0, \"value\": {}}"));204 RecordingHttpClient client = new RecordingHttpClient(response);205 new ProtocolHandshake().createSession(client, command);206 Map<String, Object> handshakeRequest = getRequestPayloadAsMap(client);207 mergeW3C(handshakeRequest)208 .forEach(capabilities -> {209 assertThat(capabilities.get("browserName")).isEqualTo("cake");210 assertThat(capabilities.get("platformName")).isNull();211 assertThat(capabilities.get("platform")).isNull();212 });213 }214 private List<Map<String, Object>> mergeW3C(Map<String, Object> caps) {215 Map<String, Object> capabilities = (Map<String, Object>) caps.get("capabilities");216 if (capabilities == null) {217 return null;218 }219 Map<String, Object> always = Optional.ofNullable(...