下面列出了怎么用org.openqa.selenium.remote.http.HttpRequest的API类实例代码及写法,或者点击链接到github查看源代码。
@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
public HttpResponse execute(HttpRequest req) {
try (Span span = newSpanAsChildOf(tracer, req, "sessions.add_session")) {
HTTP_REQUEST.accept(span, req);
Session session = json.toType(string(req), Session.class);
Objects.requireNonNull(session, "Session to add must be set");
SESSION_ID.accept(span, session.getId());
CAPABILITIES.accept(span, session.getCapabilities());
span.setAttribute("session.uri", session.getUri().toString());
sessions.add(session);
return new HttpResponse().setContent(asJson(ImmutableMap.of("value", true)));
}
}
private HttpResponse readDirectory(HttpRequest req, Resource resource) {
if (!req.getUri().endsWith("/")) {
String dest = UrlPath.relativeToContext(req, req.getUri() + "/");
return new HttpResponse()
.setStatus(HTTP_MOVED_TEMP)
.addHeader("Location", dest);
}
String links = resource.list().stream()
.map(res -> String.format("<li><a href=\"%s\">%s</a>", res.name(), res.name()))
.sorted()
.collect(Collectors.joining("\n", "<ul>\n", "</ul>\n"));
String html = String.format(
"<html><title>Listing of %s</title><body><h1>%s</h1>%s",
resource.name(),
resource.name(),
links);
return new HttpResponse()
.addHeader("Content-Type", HTML_UTF_8.toString())
.setContent(utf8String(html));
}
@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 shouldAllowPassthroughForJWPMode() {
HttpRequest request = new HttpRequest(POST, "/session");
request.setContent(asJson(
ImmutableMap.of(
"desiredCapabilities", 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 be a numeric status field
assertEquals(topLevel.toString(), 0L, topLevel.get("status"));
// The session id
assertTrue(string(request), topLevel.containsKey("sessionId"));
// And the value should be the capabilities.
Map<?, ?> value = (Map<?, ?>) topLevel.get("value");
assertEquals(string(request), "cheese", value.get("browserName"));
}
@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!");
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
int lastIndex = req.getUri().lastIndexOf('/');
String pageNumber =
(lastIndex == -1 ? "Unknown" : req.getUri().substring(lastIndex + 1));
String body = String.format("<html><head><title>Page%s</title></head>" +
"<body>Page number <span id=\"pageNumber\">%s</span>" +
"<p><a href=\"../xhtmlTest.html\" target=\"_top\">top</a>" +
"</body></html>",
pageNumber, pageNumber);
return new HttpResponse()
.setHeader("Content-Type", "text/html")
.setContent(utf8String(body));
}
@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;
}
@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");
}
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();
}
}
});
}
private HttpResponse executeWithinServer(HttpRequest request, HttpServlet servlet)
throws Exception {
Server server = new Server(PortProber.findFreePort());
ServletContextHandler handler = new ServletContextHandler();
handler.setContextPath("");
ServletHolder holder = new ServletHolder(servlet);
handler.addServlet(holder, "/*");
server.setHandler(handler);
server.start();
try {
HttpClient client = createFactory().createClient(fromUri(server.getURI()));
return client.execute(request);
} finally {
server.stop();
}
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
List<Map<String, Object>> value = new ArrayList<>();
allSessions.getAllSessions().forEach(s -> value.add(
ImmutableMap.of("id", s.getId().toString(), "capabilities", s.getCapabilities())));
Map<String, Object> payloadObj = ImmutableMap.of(
"status", SUCCESS,
"value", value);
// Write out a minimal W3C status response.
byte[] payload = json.toJson(payloadObj).getBytes(UTF_8);
return new HttpResponse().setStatus(HTTP_OK)
.setHeader("Content-Type", JSON_UTF_8.toString())
.setContent(bytes(payload));
}
@Test
public void ignoresNullSessionIdInSessionBody() {
Map<String, Object> map = new HashMap<>();
map.put("sessionId", null);
map.put("fruit", "apple");
map.put("color", "red");
map.put("size", "large");
String data = new Json().toJson(map);
HttpRequest request = new HttpRequest(POST, "/fruit/apple/size/large");
request.setContent(utf8String(data));
codec.defineCommand("pick", POST, "/fruit/:fruit/size/:size");
Command decoded = codec.decode(request);
assertThat(decoded.getSessionId()).isNull();
assertThat(decoded.getParameters()).isEqualTo((Map<String, String>) ImmutableMap.of(
"fruit", "apple", "size", "large", "color", "red"));
}
@Test
public void shouldReturnValueFromHandlerIfUrlMatches() throws IOException {
String cheerfulGreeting = "Hello, world!";
HttpHandlerServlet servlet = new HttpHandlerServlet(
Route.matching(req -> true)
.to(() -> req -> new HttpResponse().setContent(utf8String(cheerfulGreeting))));
HttpServletRequest request = requestConverter.apply(new HttpRequest(GET, "/hello-world"));
FakeHttpServletResponse response = new FakeHttpServletResponse();
servlet.service(request, response);
assertThat(response.getStatus()).isEqualTo(HTTP_OK);
assertThat(response.getBody()).isEqualTo(cheerfulGreeting);
}
public Set<Image> apply(Reference reference) {
Require.nonNull("Reference to search for", reference);
String familiarName = reference.getFamiliarName();
Map<String, Object> filters = ImmutableMap.of("reference", ImmutableMap.of(familiarName, true));
// https://docs.docker.com/engine/api/v1.40/#operation/ImageList
HttpRequest req = new HttpRequest(GET, "/v1.40/images/json")
.addHeader("Content-Length", "0")
.addHeader("Content-Type", JSON_UTF_8)
.addQueryParameter("filters", JSON.toJson(filters));
HttpResponse response = DockerMessages.throwIfNecessary(
client.execute(req),
"Unable to list images for %s", reference);
Set<ImageSummary> images =
JSON.toType(string(response), SET_OF_IMAGE_SUMMARIES);
return images.stream()
.map(org.openqa.selenium.docker.Image::new)
.collect(toImmutableSet());
}
@Override
public Optional<Consumer<Message>> apply(String uri, Consumer<Message> downstream) {
Objects.requireNonNull(uri);
Objects.requireNonNull(downstream);
Optional<SessionId> sessionId = HttpSessionId.getSessionId(uri).map(SessionId::new);
if (!sessionId.isPresent()) {
return Optional.empty();
}
try {
Session session = sessions.get(sessionId.get());
HttpClient client = clientFactory.createClient(ClientConfig.defaultConfig().baseUri(session.getUri()));
WebSocket upstream = client.openSocket(new HttpRequest(GET, uri), new ForwardingListener(downstream));
return Optional.of(upstream::send);
} catch (NoSuchSessionException e) {
LOG.info("Attempt to connect to non-existant session: " + uri);
return Optional.empty();
}
}
@Test
public void shouldUseUriToChooseWhichWebSocketHandlerToUse() throws InterruptedException {
AtomicBoolean foo = new AtomicBoolean(false);
AtomicBoolean bar = new AtomicBoolean(false);
BiFunction<String, Consumer<Message>, Optional<Consumer<Message>>> factory = (str, sink) -> {
if ("/foo".equals(str)) {
return Optional.of(msg -> {
foo.set(true);
sink.accept(new TextMessage("Foo called"));
});
} else {
return Optional.of(msg -> {
bar.set(true);
sink.accept(new TextMessage("Bar called"));
});
}
};
server = new NettyServer(
defaultOptions(),
req -> new HttpResponse(),
factory
).start();
CountDownLatch latch = new CountDownLatch(1);
HttpClient client = HttpClient.Factory.createDefault().createClient(server.getUrl());
WebSocket fooSocket = client.openSocket(new HttpRequest(GET, "/foo"), new WebSocket.Listener() {
@Override
public void onText(CharSequence data) {
System.out.println("Called!");
latch.countDown();
}
});
fooSocket.sendText("Hello, World!");
latch.await(2, SECONDS);
assertThat(foo.get()).isTrue();
assertThat(bar.get()).isFalse();
}
@Override
public void stop() {
// Try and kill the running session. Both W3C and OSS use the same quit endpoint
try {
HttpRequest request = new HttpRequest(HttpMethod.DELETE, "/session/" + getId());
execute(request);
} catch (UncheckedIOException e) {
// This is fine.
}
service.stop();
}
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();
}
}
@Override
public HttpResponse execute(HttpRequest req) {
return handlers.entrySet().stream()
.filter(entry -> entry.getKey().matches(req))
.findFirst()
.map(Map.Entry::getValue)
.orElse(new NoHandler(new Json()))
.execute(req);
}
private HttpResponse readFile(HttpRequest req, Resource resource) {
Optional<byte[]> bytes = resource.read();
if (bytes.isPresent()) {
return new HttpResponse()
.addHeader("Content-Type", mediaType(req.getUri()))
.setContent(bytes(bytes.get()));
}
return get404(req);
}
@Override
public HttpResponse execute(HttpRequest req) {
try (Span span = newSpanAsChildOf(tracer, req, "httpclient.execute")) {
KIND.accept(span, Span.Kind.CLIENT);
HTTP_REQUEST.accept(span, req);
tracer.getPropagator().inject(span, req, (r, key, value) -> r.setHeader(key, value));
HttpResponse response = delegate.execute(req);
HTTP_RESPONSE.accept(span, response);
return response;
}
}
@Test
public void shouldRedirectIfDirectoryButPathDoesNotEndInASlash() throws IOException {
Path dir = base.resolve("cheese");
Files.createDirectories(dir);
HttpHandler handler = new ResourceHandler(new PathResource(base));
HttpResponse res = handler.execute(new HttpRequest(GET, "/cheese"));
assertThat(res.getStatus()).isEqualTo(HTTP_MOVED_TEMP);
assertThat(res.getHeader("Location")).endsWith("/cheese/");
}
@Override
public boolean matches(HttpRequest req) {
return handlers.keySet().stream()
.map(p -> p.matches(req))
.reduce(Boolean::logicalOr)
.orElse(false);
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
ImmutableMap.Builder<String, Object> value = ImmutableMap.builder();
// W3C spec
value.put("ready", true);
value.put("message", "Server is running");
// And now more information
BuildInfo buildInfo = new BuildInfo();
value.put("build", ImmutableMap.of(
// We need to fix the BuildInfo to properly fill out these values.
"revision", buildInfo.getBuildRevision(),
"version", buildInfo.getReleaseLabel()));
value.put("os", ImmutableMap.of(
"arch", System.getProperty("os.arch"),
"name", System.getProperty("os.name"),
"version", System.getProperty("os.version")));
value.put("java", ImmutableMap.of("version", System.getProperty("java.version")));
Map<String, Object> payloadObj = ImmutableMap.of(
"status", SUCCESS,
"value", value.build());
// Write out a minimal W3C status response.
byte[] payload = json.toJson(payloadObj).getBytes(UTF_8);
return new HttpResponse()
.setStatus(HTTP_OK)
.setHeader("Content-Type", JSON_UTF_8.toString())
.setContent(bytes(payload));
}
@Test
public void shouldAcceptAW3CPayload() throws URISyntaxException {
String payload = json.toJson(ImmutableMap.of(
"capabilities", ImmutableMap.of(
"alwaysMatch", ImmutableMap.of("cheese", "brie"))));
HttpRequest request = new HttpRequest(POST, "/session");
request.setContent(utf8String(payload));
URI uri = new URI("http://example.com");
Node node = LocalNode.builder(
DefaultTestTracer.createTracer(),
new GuavaEventBus(),
uri,
uri,
null)
.add(stereotype, new TestSessionFactory((id, caps) -> new Session(id, uri, caps)))
.build();
CreateSessionResponse sessionResponse = node.newSession(
new CreateSessionRequest(
ImmutableSet.of(W3C),
stereotype,
ImmutableMap.of()))
.orElseThrow(() -> new AssertionError("Unable to create session"));
Map<String, Object> all = json.toType(
new String(sessionResponse.getDownstreamEncodedResponse(), UTF_8),
MAP_TYPE);
// Ensure that there's no status field (as this is used by the protocol handshake to determine
// whether the session is using the JWP or the W3C dialect.
assertThat(all.containsKey("status")).isFalse();
// Now check the fields required by the spec
Map<?, ?> value = (Map<?, ?>) all.get("value");
assertThat(value.get("sessionId")).isInstanceOf(String.class);
assertThat(value.get("capabilities")).isInstanceOf(Map.class);
}
@Override
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
String duration = req.getQueryParameter("time");
long timeout = Long.parseLong(duration) * 1000;
reallySleep(timeout);
return new HttpResponse()
.setHeader("Content-Type", "text/html")
//Dont Cache Anything at the browser
.setHeader("Cache-Control","no-cache")
.setHeader("Pragma","no-cache")
.setHeader("Expires", "0")
.setContent(utf8String(String.format(RESPONSE_STRING_FORMAT, duration)));
}
private HttpRequest createRequest(io.netty.handler.codec.http.HttpRequest nettyRequest) {
HttpRequest req = new HttpRequest(
HttpMethod.valueOf(nettyRequest.method().name()),
nettyRequest.uri());
nettyRequest.headers().entries().stream()
.filter(entry -> entry.getKey() != null)
.forEach(entry -> req.addHeader(entry.getKey(), entry.getValue()));
return req;
}
@Test(expected = ConnectionFailedException.class)
public void clientShouldThrowAnExceptionIfUnableToConnectToAWebSocketEndPoint() {
server = new NettyServer(defaultOptions(), req -> new HttpResponse()).start();
HttpClient client = HttpClient.Factory.createDefault().createClient(server.getUrl());
client.openSocket(new HttpRequest(GET, "/does-not-exist"), new WebSocket.Listener() {});
}
@Test
public void shouldBeAbleToConnectToAUnixDomainSocketUrl() {
ClientConfig config = ClientConfig.defaultConfig().baseUri(socket);
HttpClient client = new NettyClient.Factory().createClient(config);
String emphaticCheeseEnjoyment = "I like cheese!";
responseText.set(emphaticCheeseEnjoyment);
HttpResponse res = client.execute(new HttpRequest(GET, "/do-you-like-cheese"));
assertThat(Contents.string(res)).isEqualTo(emphaticCheeseEnjoyment);
}