下面列出了怎么用org.openqa.selenium.remote.http.HttpResponse的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public Response execute(Command command) throws IOException {
if (DriverCommand.NEW_SESSION.equals(command.getName())) {
if (active) {
throw new WebDriverException("Cannot start session twice! " + session);
}
active = true;
// We already have a running session.
Response response = new Response(session.getId());
response.setValue(session.getCapabilities());
return response;
}
// The command is about to be sent to the session, which expects it to be
// encoded as if it has come from the downstream end, not the upstream end.
HttpRequest request = session.getDownstreamDialect().getCommandCodec().encode(command);
HttpResponse httpResponse = session.execute(request);
return session.getDownstreamDialect().getResponseCodec().decode(httpResponse);
}
@Override
public HttpResponse executeWebDriverCommand(HttpRequest req) {
LOG.info("Executing " + req);
HttpResponse res = client.execute(req);
if (DELETE.equals(req.getMethod()) && req.getUri().equals("/session/" + sessionId)) {
// Ensure the response is sent before we viciously kill the node
new Thread(
() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
LOG.info("Stopping session: " + sessionId);
stop(sessionId);
},
"Node clean up: " + getId())
.start();
}
return res;
}
@Override
public HttpResponse executeWebDriverCommand(HttpRequest req) {
// True enough to be good enough
SessionId id = getSessionId(req.getUri()).map(SessionId::new)
.orElseThrow(() -> new NoSuchSessionException("Cannot find session: " + req));
SessionSlot slot = currentSessions.getIfPresent(id);
if (slot == null) {
throw new NoSuchSessionException("Cannot find session with id: " + id);
}
HttpResponse toReturn = slot.execute(req);
if (req.getMethod() == DELETE && req.getUri().equals("/session/" + id)) {
stop(id);
}
return toReturn;
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
// We're not using ImmutableMap for the outer map because it disallows null values.
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("sessionId", sessionId.toString());
responseMap.put("status", NO_SUCH_SESSION);
responseMap.put("value", ImmutableMap.of(
"error", "invalid session id",
"message", String.format("No active session with ID %s", sessionId),
"stacktrace", ""));
responseMap = Collections.unmodifiableMap(responseMap);
byte[] payload = json.toJson(responseMap).getBytes(UTF_8);
return new HttpResponse().setStatus(HTTP_NOT_FOUND)
.setHeader("Content-Type", JSON_UTF_8.toString())
.setContent(bytes(payload));
}
@Test
public void shouldAllowPassthroughForW3CMode() {
HttpRequest request = new HttpRequest(POST, "/session");
request.setContent(asJson(
ImmutableMap.of(
"capabilities", ImmutableMap.of(
"alwaysMatch", ImmutableMap.of("browserName", "cheese")))));
HttpClient client = clientFactory.createClient(server.getUrl());
HttpResponse response = client.execute(request);
assertEquals(200, response.getStatus());
Map<String, Object> topLevel = json.toType(string(response), MAP_TYPE);
// There should not be a numeric status field
assertFalse(string(request), topLevel.containsKey("status"));
// And the value should have all the good stuff in it: the session id and the capabilities
Map<?, ?> value = (Map<?, ?>) topLevel.get("value");
assertThat(value.get("sessionId")).isInstanceOf(String.class);
Map<?, ?> caps = (Map<?, ?>) value.get("capabilities");
assertEquals("cheese", caps.get("browserName"));
}
@Override
protected void execute(Config config) {
SessionMapOptions sessionMapOptions = new SessionMapOptions(config);
SessionMap sessions = sessionMapOptions.getSessionMap();
BaseServerOptions serverOptions = new BaseServerOptions(config);
Server<?> server = new NettyServer(serverOptions, Route.combine(
sessions,
get("/status").to(() -> req ->
new HttpResponse()
.addHeader("Content-Type", JSON_UTF_8)
.setContent(asJson(
ImmutableMap.of("value", ImmutableMap.of(
"ready", true,
"message", "Session map is ready."))))),
get("/readyz").to(() -> req -> new HttpResponse().setStatus(HTTP_NO_CONTENT))));
server.start();
BuildInfo info = new BuildInfo();
LOG.info(String.format(
"Started Selenium session map %s (revision %s): %s",
info.getReleaseLabel(),
info.getBuildRevision(),
server.getUrl()));
}
@Test
public void webSocketHandlersShouldBeAbleToFireMoreThanOneMessage() {
server = new NettyServer(
defaultOptions(),
req -> new HttpResponse(),
(uri, sink) -> Optional.of(msg -> {
sink.accept(new TextMessage("beyaz peynir"));
sink.accept(new TextMessage("cheddar"));
})).start();
HttpClient client = HttpClient.Factory.createDefault().createClient(server.getUrl());
List<String> messages = new LinkedList<>();
WebSocket socket = client.openSocket(new HttpRequest(GET, "/cheese"), new WebSocket.Listener() {
@Override
public void onText(CharSequence data) {
messages.add(data.toString());
}
});
socket.send(new TextMessage("Hello"));
new FluentWait<>(messages).until(msgs -> msgs.size() == 2);
}
@Override
protected HttpClient.Factory createFactory() {
return config -> {
ReactorHandler reactorHandler = new ReactorHandler(config, httpClient);
return new HttpClient() {
@Override
public WebSocket openSocket(HttpRequest request, WebSocket.Listener listener) {
throw new UnsupportedOperationException("openSocket");
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
return reactorHandler.execute(req);
}
};
};
}
@Test
public void shouldIncludeAUserAgentHeader() throws Exception {
HttpResponse response = executeWithinServer(
new HttpRequest(GET, "/foo"),
new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
try (Writer writer = resp.getWriter()) {
writer.write(req.getHeader("user-agent"));
}
}
});
String label = new BuildInfo().getReleaseLabel();
Platform platform = Platform.getCurrent();
Platform family = platform.family() == null ? platform : platform.family();
assertThat(string(response)).isEqualTo(String.format(
"selenium/%s (java %s)",
label,
family.toString().toLowerCase()));
}
private HttpResponse getQueryParameterResponse(HttpRequest request) throws Exception {
return executeWithinServer(
request,
new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
try (Writer writer = resp.getWriter()) {
JsonOutput json = new Json().newOutput(writer);
json.beginObject();
req.getParameterMap()
.forEach((key, value) -> {
json.name(key);
json.beginArray();
Stream.of(value).forEach(json::write);
json.endArray();
});
json.endObject();
}
}
});
}
@Test
public void requestShouldIncludeJsonWireProtocolCapabilities() throws IOException {
Map<String, Object> params = singletonMap("desiredCapabilities", new ImmutableCapabilities());
Command command = new Command(null, DriverCommand.NEW_SESSION, params);
HttpResponse response = new HttpResponse();
response.setStatus(HTTP_OK);
response.setContent(utf8String(
"{\"value\": {\"sessionId\": \"23456789\", \"capabilities\": {}}}"));
RecordingHttpClient client = new RecordingHttpClient(response);
new ProtocolHandshake().createSession(client, command);
Map<String, Object> json = getRequestPayloadAsMap(client);
assertThat(json.get("desiredCapabilities")).isEqualTo(EMPTY_MAP);
}
@Test
public void shouldStillBeAbleToServeHttpTraffic() {
server = new NettyServer(
defaultOptions(),
req -> new HttpResponse().setContent(utf8String("Brie!")),
(uri, sink) -> {
if ("/foo".equals(uri)) {
return Optional.of(msg -> sink.accept(new TextMessage("Peas!")));
}
return Optional.empty();
}).start();
HttpClient client = HttpClient.Factory.createDefault().createClient(server.getUrl());
HttpResponse res = client.execute(new HttpRequest(GET, "/cheese"));
assertThat(Contents.string(res)).isEqualTo("Brie!");
}
@Test
public void decodingAnErrorWithoutAStacktraceIsDecodedProperlyForNonCompliantImplementations() {
Map<String, Object> error = new HashMap<>();
error.put("error", "unsupported operation"); // 500
error.put("message", "I like peas");
error.put("stacktrace", "");
HttpResponse response = createValidResponse(HTTP_INTERNAL_ERROR, error);
Response decoded = new W3CHttpResponseCodec().decode(response);
assertThat(decoded.getState()).isEqualTo("unsupported operation");
assertThat(decoded.getStatus().intValue()).isEqualTo(METHOD_NOT_ALLOWED);
assertThat(decoded.getValue()).isInstanceOf(UnsupportedCommandException.class);
assertThat(((WebDriverException) decoded.getValue()).getMessage()).contains("I like peas");
}
@Test
public void convertsResponses_success() {
Response response = new Response();
response.setStatus(ErrorCodes.SUCCESS);
response.setValue(ImmutableMap.of("color", "red"));
HttpResponse converted = codec.encode(HttpResponse::new, response);
assertThat(converted.getStatus()).isEqualTo(HTTP_OK);
assertThat(converted.getHeader(CONTENT_TYPE)).isEqualTo(JSON_UTF_8.toString());
Response rebuilt = new Json().toType(string(converted), Response.class);
assertThat(rebuilt.getStatus()).isEqualTo(response.getStatus());
assertThat(rebuilt.getState()).isEqualTo(new ErrorCodes().toState(response.getStatus()));
assertThat(rebuilt.getSessionId()).isEqualTo(response.getSessionId());
assertThat(rebuilt.getValue()).isEqualTo(response.getValue());
}
@Test
public void convertsResponses_failure() {
Response response = new Response();
response.setStatus(ErrorCodes.NO_SUCH_ELEMENT);
response.setValue(ImmutableMap.of("color", "red"));
HttpResponse converted = codec.encode(HttpResponse::new, response);
assertThat(converted.getStatus()).isEqualTo(HTTP_INTERNAL_ERROR);
assertThat(converted.getHeader(CONTENT_TYPE)).isEqualTo(JSON_UTF_8.toString());
Response rebuilt = new Json().toType(string(converted), Response.class);
assertThat(rebuilt.getStatus()).isEqualTo(response.getStatus());
assertThat(rebuilt.getState()).isEqualTo(new ErrorCodes().toState(response.getStatus()));
assertThat(rebuilt.getSessionId()).isEqualTo(response.getSessionId());
assertThat(rebuilt.getValue()).isEqualTo(response.getValue());
}
boolean apply(ContainerId id) {
Require.nonNull("Container id", id);
Map<String, Object> filters = ImmutableMap.of("id", ImmutableSet.of(id));
HttpResponse res = throwIfNecessary(
client.execute(
new HttpRequest(GET, "/v1.40/containers/json")
.addHeader("Content-Length", "0")
.addHeader("Content-Type", JSON_UTF_8)
.addQueryParameter("filters", JSON.toJson(filters))
),
"Unable to list container %s",
id);
List<?> allContainers = JSON.toType(Contents.string(res), List.class);
return !allContainers.isEmpty();
}
@Test
public void shouldInstantiateSessionIfEverythingIsOK() throws IOException {
HttpClient httpClient = mock(HttpClient.class);
when(httpClient.execute(any(HttpRequest.class))).thenReturn(
new HttpResponse().setStatus(200).setContent(() -> new ByteArrayInputStream(
"{ \"value\": { \"sessionId\": \"1\", \"capabilities\": {} } }".getBytes())));
when(clientFactory.createClient(any(URL.class))).thenReturn(httpClient);
DriverServiceSessionFactory factory = factoryFor("chrome", builder);
Optional<ActiveSession> session = factory.apply(new CreateSessionRequest(
ImmutableSet.of(Dialect.W3C), toPayload("chrome"), ImmutableMap.of()));
assertThat(session).isNotEmpty();
verify(builder, times(1)).build();
verifyNoMoreInteractions(builder);
verify(driverService, times(1)).start();
verify(driverService, atLeastOnce()).getUrl();
verifyNoMoreInteractions(driverService);
}
@Test
public void exceptionsThrownByHandlersAreConvertedToAProperPayload() {
Server<?> server = new JettyServer(
emptyOptions,
req -> {
throw new UnableToSetCookieException("Yowza");
});
server.start();
URL url = server.getUrl();
HttpClient client = HttpClient.Factory.createDefault().createClient(url);
HttpResponse response = client.execute(new HttpRequest(GET, "/status"));
assertThat(response.getStatus()).isEqualTo(HTTP_INTERNAL_ERROR);
Throwable thrown = null;
try {
thrown = ErrorCodec.createDefault().decode(new Json().toType(string(response), MAP_TYPE));
} catch (IllegalArgumentException ignored) {
fail("Apparently the command succeeded" + string(response));
}
assertThat(thrown).isInstanceOf(UnableToSetCookieException.class);
assertThat(thrown.getMessage()).startsWith("Yowza");
}
@Override
public Optional<ActiveSession> apply(CreateSessionRequest sessionRequest) {
SessionId id = new SessionId(UUID.randomUUID());
Session session = sessionGenerator.apply(id, sessionRequest.getCapabilities());
URL url = null;
try {
url = session.getUri().toURL();
} catch (MalformedURLException e) {
throw new UncheckedIOException(e);
}
Dialect downstream = sessionRequest.getDownstreamDialects().contains(W3C) ?
W3C :
sessionRequest.getDownstreamDialects().iterator().next();
BaseActiveSession activeSession = new BaseActiveSession(
session.getId(),
url,
downstream,
W3C,
session.getCapabilities()) {
@Override
public void stop() {
// Do nothing
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
if (session instanceof HttpHandler) {
return ((HttpHandler) session).execute(req);
} else {
// Do nothing.
return new HttpResponse().setStatus(HTTP_NOT_FOUND).setContent(utf8String("No handler found for " + req));
}
}
};
return Optional.of(activeSession);
}
public static Optional<URI> getCdpEndPoint(
HttpClient.Factory clientFactory,
URI reportedUri) {
Require.nonNull("HTTP client factory", clientFactory);
Require.nonNull("DevTools URI", reportedUri);
ClientConfig config = ClientConfig.defaultConfig().baseUri(reportedUri);
HttpClient client = clientFactory.createClient(config);
HttpResponse res = client.execute(new HttpRequest(GET, "/json/version"));
if (res.getStatus() != HTTP_OK) {
return Optional.empty();
}
Map<String, Object> versionData = JSON.toType(string(res), MAP_TYPE);
Object raw = versionData.get("webSocketDebuggerUrl");
if (!(raw instanceof String)) {
return Optional.empty();
}
String debuggerUrl = (String) raw;
try {
return Optional.of(new URI(debuggerUrl));
} catch (URISyntaxException e) {
LOG.warning("Invalid URI for endpoint " + raw);
return Optional.empty();
}
}
private Optional<Result> createSession(HttpClient client, InputStream newSessionBlob, long size) {
// Create the http request and send it
HttpRequest request = new HttpRequest(HttpMethod.POST, "/session");
HttpResponse response;
long start = System.currentTimeMillis();
request.setHeader(CONTENT_LENGTH, String.valueOf(size));
request.setHeader(CONTENT_TYPE, JSON_UTF_8.toString());
request.setContent(() -> newSessionBlob);
response = client.execute(request);
long time = System.currentTimeMillis() - start;
// Ignore the content type. It may not have been set. Strictly speaking we're not following the
// W3C spec properly. Oh well.
Map<?, ?> blob;
try {
blob = new Json().toType(string(response), Map.class);
} catch (JsonException e) {
throw new WebDriverException(
"Unable to parse remote response: " + string(response), e);
}
InitialHandshakeResponse initialResponse = new InitialHandshakeResponse(
time,
response.getStatus(),
blob);
return Stream.of(
new W3CHandshakeResponse().getResponseFunction(),
new JsonWireProtocolResponse().getResponseFunction())
.map(func -> func.apply(initialResponse))
.filter(Objects::nonNull)
.findFirst();
}
public static HttpResponse toSeleniumResponse(Response response) {
HttpResponse toReturn = new HttpResponse();
toReturn.setStatus(response.getStatusCode());
toReturn.setContent(! response.hasResponseBody()
? empty()
: memoize(response::getResponseBodyAsStream));
response.getHeaders().names().forEach(
name -> response.getHeaders(name).forEach(value -> toReturn.addHeader(name, value)));
return toReturn;
}
public static HttpResponse toSeleniumResponse(Response response) {
HttpResponse toReturn = new HttpResponse();
toReturn.setStatus(response.getStatusCode());
toReturn.setContent(! response.hasResponseBody()
? empty()
: memoize(response::getResponseBodyAsStream));
response.getHeaders().names().forEach(
name -> response.getHeaders(name).forEach(value -> toReturn.addHeader(name, value)));
return toReturn;
}
@Test
public void baseServerStartsAndDoesNothing() {
Server<?> server = new JettyServer(emptyOptions, req -> new HttpResponse()).start();
URL url = server.getUrl();
HttpClient client = HttpClient.Factory.createDefault().createClient(url);
HttpResponse response = client.execute(new HttpRequest(GET, "/status"));
// Although we don't expect the server to be ready, we do expect the request to succeed.
assertEquals(HTTP_OK, response.getStatus());
// And we expect the content to be UTF-8 encoded JSON.
assertEquals(MediaType.JSON_UTF_8, MediaType.parse(response.getHeader("Content-Type")));
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
Map<String, Object> args = json.toType(string(req), Json.MAP_TYPE);
String file = (String) args.get("file");
File tempDir = session.getFileSystem().createTempDir("upload", "file");
try {
Zip.unzip(file, tempDir);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
// Select the first file
File[] allFiles = tempDir.listFiles();
Response response = new Response(session.getId());
if (allFiles == null || allFiles.length != 1) {
response.setStatus(ErrorCodes.UNHANDLED_ERROR);
response.setValue(new WebDriverException(
"Expected there to be only 1 file. There were: " +
(allFiles == null ? 0 : allFiles.length)));
} else {
response.setStatus(ErrorCodes.SUCCESS);
response.setValue(allFiles[0].getAbsolutePath());
}
HttpResponse resp = new HttpResponse();
session.getDownstreamDialect().getResponseCodec().encode(() -> resp, response);
return resp;
}
@Before
public void setup() {
appServer = new JreAppServer(req -> new HttpResponse()
.setStatus(200)
.addHeader("Content-Type", MediaType.XHTML_UTF_8.toString())
.setContent(utf8String("<html><head><title>Hello, World!</title></head><body/></html>")));
appServer.start();
driver = new WebDriverBuilder().get();
assumeThat(driver).isInstanceOf(HasDevTools.class);
}
@Override
public void stop(SessionId id) throws NoSuchSessionException {
Require.nonNull("Session ID", id);
HttpRequest req = new HttpRequest(DELETE, "/se/grid/node/session/" + id);
HttpTracing.inject(tracer, tracer.getCurrentContext(), req);
HttpResponse res = client.execute(req);
Values.get(res, Void.class);
}
@Override
public HttpResponse execute(HttpRequest req) {
NodeStatus status = json.toType(string(req), NodeStatus.class);
Node node = new RemoteNode(
tracer,
httpFactory,
status.getNodeId(),
status.getUri(),
status.getStereotypes().keySet());
distributor.add(node);
return new HttpResponse();
}
@Test
public void manifestHasCorrectMimeType() throws IOException {
String url = server.whereIs("html5/test.appcache");
HttpClient.Factory factory = HttpClient.Factory.createDefault();
HttpClient client = factory.createClient(new URL(url));
HttpResponse response = client.execute(new HttpRequest(HttpMethod.GET, url));
System.out.printf("Content for %s was %s\n", url, string(response));
assertTrue(StreamSupport.stream(response.getHeaders("Content-Type").spliterator(), false)
.anyMatch(header -> header.contains(APPCACHE_MIME_TYPE)));
}
@Before
public void setUp() throws URISyntaxException {
tracer = DefaultTestTracer.createTracer();
bus = new GuavaEventBus();
caps = new ImmutableCapabilities("browserName", "cheese");
uri = new URI("http://localhost:1234");
class Handler extends Session implements HttpHandler {
private Handler(Capabilities capabilities) {
super(new SessionId(UUID.randomUUID()), uri, capabilities);
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
return new HttpResponse();
}
}
local = LocalNode.builder(tracer, bus, uri, uri, null)
.add(caps, new TestSessionFactory((id, c) -> new Handler(c)))
.add(caps, new TestSessionFactory((id, c) -> new Handler(c)))
.add(caps, new TestSessionFactory((id, c) -> new Handler(c)))
.maximumConcurrentSessions(2)
.build();
node = new RemoteNode(
tracer,
new PassthroughHttpClient.Factory(local),
UUID.randomUUID(),
uri,
ImmutableSet.of(caps));
}