下面列出了怎么用org.openqa.selenium.remote.Command的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Sends the {@code command} to the driver server for execution. The server will be started
* if requesting a new session. Likewise, if terminating a session, the server will be shutdown
* once a response is received.
*
* @param command The command to execute.
* @return The command response.
* @throws IOException If an I/O error occurs while sending the command.
*/
@Override
public Response execute(Command command) throws IOException {
if (DriverCommand.NEW_SESSION.equals(command.getName())) {
service.start();
}
try {
return super.execute(command);
} catch (Throwable t) {
Throwable rootCause = Throwables.getRootCause(t);
if (rootCause instanceof ConnectException &&
"Connection refused".equals(rootCause.getMessage()) &&
!service.isRunning()) {
throw new WebDriverException("The driver server has unexpectedly died!", t);
}
Throwables.throwIfUnchecked(t);
throw new WebDriverException(t);
} finally {
if (DriverCommand.QUIT.equals(command.getName())) {
service.stop();
}
}
}
@Test
public void shouldGetMeaningfulExceptionOnBrowserDeath() throws Exception {
FirefoxDriver driver2 = new FirefoxDriver();
driver2.get(pages.formPage);
// Grab the command executor
CommandExecutor keptExecutor = driver2.getCommandExecutor();
SessionId sessionId = driver2.getSessionId();
try {
Field field = RemoteWebDriver.class.getDeclaredField("executor");
field.setAccessible(true);
CommandExecutor spoof = mock(CommandExecutor.class);
doThrow(new IOException("The remote server died"))
.when(spoof).execute(ArgumentMatchers.any());
field.set(driver2, spoof);
driver2.get(pages.formPage);
fail("Should have thrown.");
} catch (UnreachableBrowserException e) {
assertThat(e.getMessage()).contains("Error communicating with the remote browser");
} finally {
keptExecutor.execute(new Command(sessionId, DriverCommand.QUIT));
}
}
@Test
public void shouldBeAbleToConvertACommand() {
SessionId sessionId = new SessionId("session id");
Command original = new Command(
sessionId,
DriverCommand.NEW_SESSION,
ImmutableMap.of("food", "cheese"));
String raw = new Json().toJson(original);
Command converted = new Json().toType(raw, Command.class);
assertThat(converted.getSessionId().toString()).isEqualTo(sessionId.toString());
assertThat(converted.getName()).isEqualTo(original.getName());
assertThat(converted.getParameters().keySet()).hasSize(1);
assertThat(converted.getParameters().get("food")).isEqualTo("cheese");
}
@Test
public void shouldConvertAProxyCorrectly() {
Proxy proxy = new Proxy();
proxy.setHttpProxy("localhost:4444");
MutableCapabilities caps = new DesiredCapabilities("foo", "1", Platform.LINUX);
caps.setCapability(CapabilityType.PROXY, proxy);
Map<String, ?> asMap = ImmutableMap.of("desiredCapabilities", caps);
Command command = new Command(new SessionId("empty"), DriverCommand.NEW_SESSION, asMap);
String json = convert(command.getParameters());
JsonObject converted = new JsonParser().parse(json).getAsJsonObject();
JsonObject capsAsMap = converted.get("desiredCapabilities").getAsJsonObject();
assertThat(capsAsMap.get(CapabilityType.PROXY).getAsJsonObject().get("httpProxy").getAsString())
.isEqualTo(proxy.getHttpProxy());
}
@Test
public void shouldBeAbleToConvertACommand() {
SessionId sessionId = new SessionId("some id");
String commandName = "some command";
Map<String, Object> parameters = new HashMap<>();
parameters.put("param1", "value1");
parameters.put("param2", "value2");
Command command = new Command(sessionId, commandName, parameters);
String json = convert(command);
JsonObject converted = new JsonParser().parse(json).getAsJsonObject();
assertThat(converted.has("sessionId")).isTrue();
JsonPrimitive sid = converted.get("sessionId").getAsJsonPrimitive();
assertThat(sid.getAsString()).isEqualTo(sessionId.toString());
assertThat(commandName).isEqualTo(converted.get("name").getAsString());
assertThat(converted.has("parameters")).isTrue();
JsonObject pars = converted.get("parameters").getAsJsonObject();
assertThat(pars.entrySet()).hasSize(2);
assertThat(pars.get("param1").getAsString()).isEqualTo(parameters.get("param1"));
assertThat(pars.get("param2").getAsString()).isEqualTo(parameters.get("param2"));
}
@Test
public void shouldIncludeRemoteInfoForWrappedDriverTimeout() throws IOException {
Capabilities caps = new MutableCapabilities();
Response response = new Response(new SessionId("foo"));
response.setValue(caps.asMap());
CommandExecutor executor = mock(CommandExecutor.class);
when(executor.execute(any(Command.class))).thenReturn(response);
RemoteWebDriver driver = new RemoteWebDriver(executor, caps);
WebDriver testDriver = mock(WebDriver.class, withSettings().extraInterfaces(WrapsDriver.class));
when(((WrapsDriver) testDriver).getWrappedDriver()).thenReturn(driver);
TickingClock clock = new TickingClock();
WebDriverWait wait =
new WebDriverWait(testDriver, Duration.ofSeconds(1), Duration.ofMillis(200), clock, clock);
assertThatExceptionOfType(TimeoutException.class)
.isThrownBy(() -> wait.until(d -> false))
.withMessageContaining("Capabilities {javascriptEnabled: true, platform: ANY, platformName: ANY}")
.withMessageContaining("Session ID: foo");
}
@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 whenDecodingAnHttpRequestDoesNotRecreateWebElements() {
Command command = new Command(
new SessionId("1234567"),
DriverCommand.EXECUTE_SCRIPT,
ImmutableMap.of(
"script", "",
"args", Arrays.asList(ImmutableMap.of(OSS.getEncodedElementKey(), "67890"))));
HttpRequest request = codec.encode(command);
Command decoded = codec.decode(request);
List<?> args = (List<?>) decoded.getParameters().get("args");
Map<? ,?> element = (Map<?, ?>) args.get(0);
assertThat(element.get(OSS.getEncodedElementKey())).isEqualTo("67890");
}
@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 void afterEvent(Command command) {
if (!recording && command.getSessionId() != null) {
try {
recording = true;
videoArtifact.setLink(String.format(videoArtifact.getLink(), command.getSessionId().toString()));
commandExecutor.execute(new Command(command.getSessionId(), MobileCommand.START_RECORDING_SCREEN,
MobileCommand.startRecordingScreenCommand((BaseStartScreenRecordingOptions) startRecordingOpt)
.getValue()));
} catch (Exception e) {
LOGGER.error("Unable to start screen recording: " + e.getMessage(), e);
}
}
}
@Override
public Response execute(Command command) throws IOException {
if (!this.started) {
start();
this.started = true;
}
if (QUIT.equals(command.getName())) {
stop();
}
return super.execute(command);
}
@Override
public HttpRequest encode(Command command) {
String name = aliases.getOrDefault(command.getName(), command.getName());
CommandSpec spec = nameToSpec.get(name);
if (spec == null) {
throw new UnsupportedCommandException(command.getName());
}
Map<String, ?> parameters = amendParameters(command.getName(), command.getParameters());
String uri = buildUri(name, command.getSessionId(), parameters, spec);
HttpRequest request = new HttpRequest(spec.method, uri);
if (HttpMethod.POST == spec.method) {
String content = json.toJson(parameters);
byte[] data = content.getBytes(UTF_8);
request.setHeader(CONTENT_LENGTH, String.valueOf(data.length));
request.setHeader(CONTENT_TYPE, JSON_UTF_8.toString());
request.setContent(bytes(data));
}
if (HttpMethod.GET == spec.method) {
request.setHeader(CACHE_CONTROL, "no-cache");
}
return request;
}
@Test
public void shouldBeAbleToConvertASelenium3CommandToASelenium2Command() {
SessionId expectedId = new SessionId("thisisakey");
// In selenium 2, the sessionId is an object. In selenium 3, it's a straight string.
String raw = "{\"sessionId\": \"" + expectedId.toString() + "\", " +
"\"name\": \"some command\"," +
"\"parameters\": {}}";
Command converted = new Json().toType(raw, Command.class);
assertThat(converted.getSessionId()).isEqualTo(expectedId);
}
@Test
public void throwsIfCommandNameIsNotRecognized() {
Command command = new Command(null, "garbage-command-name");
assertThatExceptionOfType(UnsupportedCommandException.class)
.isThrownBy(() -> codec.encode(command))
.withMessageStartingWith(command.getName() + "\n");
}
@Test
public void throwsIfCommandHasNullSessionId() {
codec.defineCommand("foo", DELETE, "/foo/:sessionId");
Command command = new Command(null, "foo");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> codec.encode(command))
.withMessageContaining("Session ID");
}
@Test
public void throwsIfCommandIsMissingUriParameter() {
codec.defineCommand("foo", DELETE, "/foo/:bar");
Command command = new Command(new SessionId("id"), "foo");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> codec.encode(command))
.withMessageContaining("bar");
}
@Test
public void encodingAPostWithNoParameters() {
codec.defineCommand("foo", POST, "/foo/bar");
Command command = new Command(null, "foo");
HttpRequest request = codec.encode(command);
assertThat(request.getMethod()).isEqualTo(POST);
assertThat(request.getHeader(CONTENT_TYPE)).isEqualTo(JSON_UTF_8.toString());
assertThat(request.getHeader(CONTENT_LENGTH)).isEqualTo("3");
assertThat(request.getUri()).isEqualTo("/foo/bar");
assertThat(string(request)).isEqualTo("{\n}");
}
@Test
public void encodingAPostWithUrlParameters() {
codec.defineCommand("foo", POST, "/foo/:bar/baz");
Command command = new Command(null, "foo", ImmutableMap.of("bar", "apples123"));
String encoding = "{\n \"bar\": \"apples123\"\n}";
HttpRequest request = codec.encode(command);
assertThat(request.getMethod()).isEqualTo(POST);
assertThat(request.getHeader(CONTENT_TYPE)).isEqualTo(JSON_UTF_8.toString());
assertThat(request.getHeader(CONTENT_LENGTH)).isEqualTo(String.valueOf(encoding.length()));
assertThat(request.getUri()).isEqualTo("/foo/apples123/baz");
assertThat(string(request)).isEqualTo(encoding);
}
@Test
public void encodingANonPostWithNoParameters() {
codec.defineCommand("foo", DELETE, "/foo/bar/baz");
HttpRequest request = codec.encode(new Command(null, "foo"));
assertThat(request.getMethod()).isEqualTo(DELETE);
assertThat(request.getHeader(CONTENT_TYPE)).isNull();
assertThat(request.getHeader(CONTENT_LENGTH)).isNull();
assertThat(bytes(request.getContent()).length).isEqualTo(0);
assertThat(request.getUri()).isEqualTo("/foo/bar/baz");
}
@Test
public void encodingANonPostWithParameters() {
codec.defineCommand("eat", GET, "/fruit/:fruit/:size");
HttpRequest request = codec.encode(new Command(null, "eat", ImmutableMap.of(
"fruit", "apple", "size", "large")));
assertThat(request.getHeader(CONTENT_TYPE)).isNull();
assertThat(request.getHeader(CONTENT_LENGTH)).isNull();
assertThat(bytes(request.getContent()).length).isEqualTo(0);
assertThat(request.getUri()).isEqualTo("/fruit/apple/large");
}
@Test
public void preventsCachingGetRequests() {
codec.defineCommand("foo", GET, "/foo");
HttpRequest request = codec.encode(new Command(null, "foo"));
assertThat(request.getMethod()).isEqualTo(GET);
assertThat(request.getHeader(CACHE_CONTROL)).isEqualTo("no-cache");
}
@Test
public void canDecodeCommandWithNoParameters() {
HttpRequest request = new HttpRequest(GET, "/foo/bar/baz");
codec.defineCommand("foo", GET, "/foo/bar/baz");
Command decoded = codec.decode(request);
assertThat(decoded.getName()).isEqualTo("foo");
assertThat(decoded.getSessionId()).isNull();
assertThat(decoded.getParameters()).isEmpty();
}
@Test
public void canExtractSessionIdFromPathParameters() {
HttpRequest request = new HttpRequest(GET, "/foo/bar/baz");
codec.defineCommand("foo", GET, "/foo/:sessionId/baz");
Command decoded = codec.decode(request);
assertThat(decoded.getSessionId()).isEqualTo(new SessionId("bar"));
}
@Test
public void removesSessionIdFromParameterMap() {
HttpRequest request = new HttpRequest(GET, "/foo/bar/baz");
codec.defineCommand("foo", GET, "/foo/:sessionId/baz");
Command decoded = codec.decode(request);
assertThat(decoded.getSessionId()).isEqualTo(new SessionId("bar"));
assertThat(decoded.getParameters()).isEmpty();
}
@Test
public void canExtractSessionIdFromRequestBody() {
String data = new Json().toJson(ImmutableMap.of("sessionId", "sessionX"));
HttpRequest request = new HttpRequest(POST, "/foo/bar/baz");
request.setContent(utf8String(data));
codec.defineCommand("foo", POST, "/foo/bar/baz");
Command decoded = codec.decode(request);
assertThat(decoded.getSessionId()).isEqualTo(new SessionId("sessionX"));
}
@Test
public void extractsAllParametersFromUrl() {
HttpRequest request = new HttpRequest(GET, "/fruit/apple/size/large");
codec.defineCommand("pick", GET, "/fruit/:fruit/size/:size");
Command decoded = codec.decode(request);
assertThat(decoded.getParameters()).isEqualTo((Map<String, String>) ImmutableMap.of(
"fruit", "apple",
"size", "large"));
}
@Test
public void extractsAllParameters() {
String data = new Json().toJson(ImmutableMap.of("sessionId", "sessionX",
"fruit", "apple",
"color", "red",
"size", "large"));
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()).isEqualTo(new SessionId("sessionX"));
assertThat(decoded.getParameters()).isEqualTo((Map<String, String>) ImmutableMap.of(
"fruit", "apple", "size", "large", "color", "red"));
}
@Test
public void decodeRequestWithUtf16Encoding() {
codec.defineCommand("num", POST, "/one");
byte[] data = "{\"char\":\"水\"}".getBytes(UTF_16);
HttpRequest request = new HttpRequest(POST, "/one");
request.setHeader(CONTENT_TYPE, JSON_UTF_8.withCharset(UTF_16).toString());
request.setHeader(CONTENT_LENGTH, String.valueOf(data.length));
request.setContent(bytes(data));
Command command = codec.decode(request);
assertThat((String) command.getParameters().get("char")).isEqualTo("水");
}
@Test
public void decodingUsesUtf8IfNoEncodingSpecified() {
codec.defineCommand("num", POST, "/one");
byte[] data = "{\"char\":\"水\"}".getBytes(UTF_8);
HttpRequest request = new HttpRequest(POST, "/one");
request.setHeader(CONTENT_TYPE, JSON_UTF_8.withoutParameters().toString());
request.setHeader(CONTENT_LENGTH, String.valueOf(data.length));
request.setContent(bytes(data));
Command command = codec.decode(request);
assertThat((String) command.getParameters().get("char")).isEqualTo("水");
}
@Test
public void codecRoundTrip() {
codec.defineCommand("buy", POST, "/:sessionId/fruit/:fruit/size/:size");
Command original = new Command(new SessionId("session123"), "buy", ImmutableMap.of(
"fruit", "apple", "size", "large", "color", "red", "rotten", "false"));
HttpRequest request = codec.encode(original);
Command decoded = codec.decode(request);
assertThat(decoded.getName()).isEqualTo(original.getName());
assertThat(decoded.getSessionId()).isEqualTo(original.getSessionId());
assertThat(decoded.getParameters()).isEqualTo((Map<?, ?>) original.getParameters());
}