Skip to content

Commit

Permalink
Merge pull request #597 from TikhomirovSergey/master
Browse files Browse the repository at this point in the history
#594 FIX
  • Loading branch information
TikhomirovSergey authored Mar 21, 2017
2 parents b8bd6a3 + b8bc1f0 commit 065d1a9
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 43 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ compileJava {
}

dependencies {
compile('org.seleniumhq.selenium:selenium-java:3.2.0'){
compile('org.seleniumhq.selenium:selenium-java:3.3.1'){
exclude module: 'cglib'
exclude group: 'com.google.code.gson'
}
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/io/appium/java_client/AppiumCommandInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.appium.java_client;

import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.http.HttpMethod;

public class AppiumCommandInfo extends CommandInfo {
private final String url;
private final HttpMethod method;

/**
* It conntains method and URL of the command.
*
* @param url command URL
* @param method is http-method
*/
public AppiumCommandInfo(String url, HttpMethod method) {
super(url, method);
this.url = url;
this.method = method;
}

public String getUrl() {
return url;
}

public HttpMethod getMethod() {
return method;
}
}
3 changes: 1 addition & 2 deletions src/main/java/io/appium/java_client/AppiumDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import org.openqa.selenium.remote.DriverCommand;
import org.openqa.selenium.remote.ErrorHandler;
import org.openqa.selenium.remote.ExecuteMethod;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.html5.RemoteLocationContext;
import org.openqa.selenium.remote.http.HttpClient;
Expand Down Expand Up @@ -85,7 +84,7 @@ public class AppiumDriver<T extends WebElement>
* @param capabilities take a look
* at {@link org.openqa.selenium.Capabilities}
*/
public AppiumDriver(HttpCommandExecutor executor, Capabilities capabilities) {
public AppiumDriver(AppiumCommandExecutor executor, Capabilities capabilities) {
super(executor, capabilities);
this.executeMethod = new AppiumExecutionMethod(this);
locationContext = new RemoteLocationContext(executeMethod);
Expand Down
15 changes: 7 additions & 8 deletions src/main/java/io/appium/java_client/MobileCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableMap;

import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.http.HttpMethod;

import java.util.AbstractMap;
Expand Down Expand Up @@ -77,7 +76,7 @@ public class MobileCommand {
protected static final String GET_SETTINGS;
protected static final String SET_SETTINGS;

public static final Map<String, CommandInfo> commandRepository;
public static final Map<String, AppiumCommandInfo> commandRepository;

static {
RESET = "reset";
Expand Down Expand Up @@ -184,8 +183,8 @@ public class MobileCommand {
* @param url is the command URL
* @return an instance of {@link org.openqa.selenium.remote.CommandInfo}
*/
public static CommandInfo getC(String url) {
return new CommandInfo(url, HttpMethod.GET);
public static AppiumCommandInfo getC(String url) {
return new AppiumCommandInfo(url, HttpMethod.GET);
}

/**
Expand All @@ -194,8 +193,8 @@ public static CommandInfo getC(String url) {
* @param url is the command URL
* @return an instance of {@link org.openqa.selenium.remote.CommandInfo}
*/
public static CommandInfo postC(String url) {
return new CommandInfo(url, HttpMethod.POST);
public static AppiumCommandInfo postC(String url) {
return new AppiumCommandInfo(url, HttpMethod.POST);
}

/**
Expand All @@ -204,8 +203,8 @@ public static CommandInfo postC(String url) {
* @param url is the command URL
* @return an instance of {@link org.openqa.selenium.remote.CommandInfo}
*/
public static CommandInfo deleteC(String url) {
return new CommandInfo(url, HttpMethod.DELETE);
public static AppiumCommandInfo deleteC(String url) {
return new AppiumCommandInfo(url, HttpMethod.DELETE);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
import io.appium.java_client.FindsByAndroidUIAutomator;
import io.appium.java_client.PressesKeyCode;
import io.appium.java_client.TouchAction;
import io.appium.java_client.remote.AppiumCommandExecutor;
import io.appium.java_client.remote.MobilePlatform;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.http.HttpClient;

import java.net.URL;
Expand Down Expand Up @@ -59,7 +59,7 @@ public class AndroidDriver<T extends WebElement>
* @param capabilities take a look
* at {@link org.openqa.selenium.Capabilities}
*/
public AndroidDriver(HttpCommandExecutor executor, Capabilities capabilities) {
public AndroidDriver(AppiumCommandExecutor executor, Capabilities capabilities) {
super(executor, substituteMobilePlatform(capabilities, ANDROID_PLATFORM));
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/appium/java_client/ios/IOSDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
import io.appium.java_client.FindsByIosUIAutomation;
import io.appium.java_client.HidesKeyboardWithKeyName;
import io.appium.java_client.TouchAction;
import io.appium.java_client.remote.AppiumCommandExecutor;
import io.appium.java_client.remote.MobilePlatform;
import io.appium.java_client.service.local.AppiumDriverLocalService;
import io.appium.java_client.service.local.AppiumServiceBuilder;
import org.openqa.selenium.Alert;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DriverCommand;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.security.Credentials;
Expand Down Expand Up @@ -62,7 +62,7 @@ public class IOSDriver<T extends WebElement>
* @param capabilities take a look
* at {@link org.openqa.selenium.Capabilities}
*/
public IOSDriver(HttpCommandExecutor executor, Capabilities capabilities) {
public IOSDriver(AppiumCommandExecutor executor, Capabilities capabilities) {
super(executor, substituteMobilePlatform(capabilities, IOS_PLATFORM));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public interface AndroidMobileCapabilityType extends CapabilityType {
String SELENDROID_PORT = "selendroidPort";

/**
* The port number, which being used by UIAutomator2
* The port number, which being used by UIAutomator2.
*/
String SYSTEM_PORT = "systemPort";
}
125 changes: 109 additions & 16 deletions src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,29 @@

package io.appium.java_client.remote;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.getRootCause;
import static com.google.common.base.Throwables.throwIfUnchecked;
import static org.openqa.selenium.remote.DriverCommand.GET_ALL_SESSIONS;
import static org.openqa.selenium.remote.DriverCommand.NEW_SESSION;
import static org.openqa.selenium.remote.DriverCommand.QUIT;

import com.google.common.base.Throwables;

import io.appium.java_client.AppiumCommandInfo;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.SessionNotCreatedException;
import org.openqa.selenium.UnsupportedCommandException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandInfo;
import org.openqa.selenium.remote.CommandCodec;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.Dialect;
import org.openqa.selenium.remote.DriverCommand;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.HttpSessionId;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.ResponseCodec;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.internal.ApacheHttpClient;
import org.openqa.selenium.remote.service.DriverService;

Expand All @@ -34,41 +47,121 @@
import java.net.URL;
import java.util.Map;

public class AppiumCommandExecutor extends HttpCommandExecutor {
public class AppiumCommandExecutor implements CommandExecutor {

private final DriverService service;
private final URL remoteServer;
private final HttpClient client;
private final Map<String, AppiumCommandInfo> additionalCommands;
private CommandCodec<HttpRequest> commandCodec;
private ResponseCodec<HttpResponse> responseCodec;
private DriverService service;

public AppiumCommandExecutor(Map<String, CommandInfo> additionalCommands,
/**
* Cretes an instance that sends requests and receives responses.
*
* @param additionalCommands is the mapped command repository
* @param addressOfRemoteServer is the url to connect to the Appium remote/local server
* @param httpClientFactory is the http client factory
*/
public AppiumCommandExecutor(Map<String, AppiumCommandInfo> additionalCommands,
URL addressOfRemoteServer, HttpClient.Factory httpClientFactory) {
super(additionalCommands, addressOfRemoteServer, httpClientFactory);
service = null;
checkNotNull(addressOfRemoteServer);
remoteServer = addressOfRemoteServer;
this.additionalCommands = additionalCommands;
this.client = httpClientFactory.createClient(remoteServer);
}

public AppiumCommandExecutor(Map<String, CommandInfo> additionalCommands, DriverService service,
public AppiumCommandExecutor(Map<String, AppiumCommandInfo> additionalCommands, DriverService service,
HttpClient.Factory httpClientFactory) {
super(additionalCommands, service.getUrl(), httpClientFactory);
this(additionalCommands, service.getUrl(), httpClientFactory);
this.service = service;
}

public AppiumCommandExecutor(Map<String, CommandInfo> additionalCommands,
public AppiumCommandExecutor(Map<String, AppiumCommandInfo> additionalCommands,
URL addressOfRemoteServer) {
this(additionalCommands, addressOfRemoteServer, new ApacheHttpClient.Factory());
}

public AppiumCommandExecutor(Map<String, CommandInfo> additionalCommands,
public AppiumCommandExecutor(Map<String, AppiumCommandInfo> additionalCommands,
DriverService service) {
this(additionalCommands, service, new ApacheHttpClient.Factory());
}

public URL getAddressOfRemoteServer() {
return remoteServer;
}

private Response doExecute(Command command) throws IOException, WebDriverException {
if (command.getSessionId() == null) {
if (QUIT.equals(command.getName())) {
return new Response();
}
if (!GET_ALL_SESSIONS.equals(command.getName())
&& !NEW_SESSION.equals(command.getName())) {
throw new NoSuchSessionException(
"Session ID is null. Using WebDriver after calling quit()?");
}
}

if (NEW_SESSION.equals(command.getName())) {
if (commandCodec != null) {
throw new SessionNotCreatedException("Session already exists");
}
AppiumProtocolHandShake handshake = new AppiumProtocolHandShake();
AppiumProtocolHandShake.Result result = handshake.createSession(client, command);
Dialect dialect = result.getDialect();
commandCodec = dialect.getCommandCodec();

additionalCommands.forEach((key, value) -> {
checkNotNull(key);
checkNotNull(value);
commandCodec.defineCommand(key, value.getMethod(), value.getUrl());
} );

responseCodec = dialect.getResponseCodec();
return result.createResponse();
}

if (commandCodec == null || responseCodec == null) {
throw new WebDriverException(
"No command or response codec has been defined. Unable to proceed");
}

HttpRequest httpRequest = commandCodec.encode(command);
try {
HttpResponse httpResponse = client.execute(httpRequest, true);

Response response = responseCodec.decode(httpResponse);
if (response.getSessionId() == null) {
if (httpResponse.getTargetHost() != null) {
response.setSessionId(HttpSessionId.getSessionId(httpResponse.getTargetHost()));
} else {
response.setSessionId(command.getSessionId().toString());
}
}
if (QUIT.equals(command.getName())) {
client.close();
}
return response;
} catch (UnsupportedCommandException e) {
if (e.getMessage() == null || "".equals(e.getMessage())) {
throw new UnsupportedOperationException(
"No information from server. Command name was: " + command.getName(),
e.getCause());
}
throw e;
}
}

@Override public Response execute(Command command) throws IOException, WebDriverException {
if (DriverCommand.NEW_SESSION.equals(command.getName()) && service != null) {
service.start();
}

try {
return super.execute(command);
return doExecute(command);
} catch (Throwable t) {
Throwable rootCause = Throwables.getRootCause(t);
Throwable rootCause = getRootCause(t);
if (rootCause instanceof ConnectException
&& rootCause.getMessage().contains("Connection refused")
&& service != null) {
Expand All @@ -80,7 +173,7 @@ public AppiumCommandExecutor(Map<String, CommandInfo> additionalCommands,
throw new WebDriverException("The appium server has accidentally died!", t);
}
}
Throwables.propagateIfPossible(t);
throwIfUnchecked(t);
throw new WebDriverException(t);
} finally {
if (DriverCommand.QUIT.equals(command.getName()) && service != null) {
Expand Down
Loading

0 comments on commit 065d1a9

Please sign in to comment.