...25import io.appium.java_client.service.local.AppiumDriverLocalService;26import io.appium.java_client.service.local.AppiumServiceBuilder;27import org.openqa.selenium.By;28import org.openqa.selenium.Capabilities;29import org.openqa.selenium.DeviceRotation;30import org.openqa.selenium.ScreenOrientation;31import org.openqa.selenium.WebDriver;32import org.openqa.selenium.WebDriverException;33import org.openqa.selenium.WebElement;34import org.openqa.selenium.html5.Location;35import org.openqa.selenium.remote.DesiredCapabilities;36import org.openqa.selenium.remote.DriverCommand;37import org.openqa.selenium.remote.ErrorHandler;38import org.openqa.selenium.remote.ExecuteMethod;39import org.openqa.selenium.remote.Response;40import org.openqa.selenium.remote.html5.RemoteLocationContext;41import org.openqa.selenium.remote.http.HttpClient;42import java.net.URL;43import java.util.LinkedHashSet;44import java.util.List;45import java.util.Map;46import java.util.Set;47/**48* @param <T> the required type of class which implement {@link org.openqa.selenium.WebElement}.49 * Instances of the defined type will be returned via findElement* and findElements*50 * Warning (!!!). Allowed types:51 * {@link org.openqa.selenium.WebElement}52 * {@link org.openqa.selenium.remote.RemoteWebElement}53 * {@link io.appium.java_client.MobileElement} and its subclasses that designed54 * specifically55 * for each target mobile OS (still Android and iOS)56*/57@SuppressWarnings("unchecked")58public class AppiumDriver<T extends WebElement>59 extends DefaultGenericMobileDriver<T> {60 private static final ErrorHandler errorHandler = new ErrorHandler(new ErrorCodesMobile(), true);61 // frequently used command parameters62 private URL remoteAddress;63 private RemoteLocationContext locationContext;64 private ExecuteMethod executeMethod;65 private final String platformName;66 private final String automationName;67 /**68 * @param executor is an instance of {@link org.openqa.selenium.remote.HttpCommandExecutor}69 * or class that extends it. Default commands or another vendor-specific70 * commands may be specified there.71 * @param capabilities take a look72 * at {@link org.openqa.selenium.Capabilities}73 */74 public AppiumDriver(AppiumCommandExecutor executor, Capabilities capabilities) {75 super(executor, capabilities);76 this.executeMethod = new AppiumExecutionMethod(this);77 locationContext = new RemoteLocationContext(executeMethod);78 super.setErrorHandler(errorHandler);79 this.remoteAddress = executor.getAddressOfRemoteServer();80 Object capabilityPlatform1 = getCapabilities().getCapability(PLATFORM_NAME);81 Object capabilityAutomation1 = getCapabilities().getCapability(AUTOMATION_NAME);82 Object capabilityPlatform2 = capabilities.getCapability(PLATFORM_NAME);83 Object capabilityAutomation2 = capabilities.getCapability(AUTOMATION_NAME);84 platformName = ofNullable(ofNullable(super.getPlatformName())85 .orElse(capabilityPlatform1 != null ? String.valueOf(capabilityPlatform1) : null))86 .orElse(capabilityPlatform2 != null ? String.valueOf(capabilityPlatform2) : null);87 automationName = ofNullable(ofNullable(super.getAutomationName())88 .orElse(capabilityAutomation1 != null ? String.valueOf(capabilityAutomation1) : null))89 .orElse(capabilityAutomation2 != null ? String.valueOf(capabilityAutomation2) : null);90 this.setElementConverter(new JsonToMobileElementConverter(this, this));91 }92 public AppiumDriver(URL remoteAddress, Capabilities desiredCapabilities) {93 this(new AppiumCommandExecutor(MobileCommand.commandRepository, remoteAddress),94 desiredCapabilities);95 }96 public AppiumDriver(URL remoteAddress, HttpClient.Factory httpClientFactory,97 Capabilities desiredCapabilities) {98 this(new AppiumCommandExecutor(MobileCommand.commandRepository, remoteAddress,99 httpClientFactory), desiredCapabilities);100 }101 public AppiumDriver(AppiumDriverLocalService service, Capabilities desiredCapabilities) {102 this(new AppiumCommandExecutor(MobileCommand.commandRepository, service),103 desiredCapabilities);104 }105 public AppiumDriver(AppiumDriverLocalService service, HttpClient.Factory httpClientFactory,106 Capabilities desiredCapabilities) {107 this(new AppiumCommandExecutor(MobileCommand.commandRepository, service, httpClientFactory),108 desiredCapabilities);109 }110 public AppiumDriver(AppiumServiceBuilder builder, Capabilities desiredCapabilities) {111 this(builder.build(), desiredCapabilities);112 }113 public AppiumDriver(AppiumServiceBuilder builder, HttpClient.Factory httpClientFactory,114 Capabilities desiredCapabilities) {115 this(builder.build(), httpClientFactory, desiredCapabilities);116 }117 public AppiumDriver(HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities) {118 this(AppiumDriverLocalService.buildDefaultService(), httpClientFactory,119 desiredCapabilities);120 }121 public AppiumDriver(Capabilities desiredCapabilities) {122 this(AppiumDriverLocalService.buildDefaultService(), desiredCapabilities);123 }124 /**125 * @param originalCapabilities the given {@link Capabilities}.126 * @param newPlatform a {@link MobileCapabilityType#PLATFORM_NAME} value which has127 * to be set up128 * @return {@link Capabilities} with changed mobile platform value129 */130 protected static Capabilities substituteMobilePlatform(Capabilities originalCapabilities,131 String newPlatform) {132 DesiredCapabilities dc = new DesiredCapabilities(originalCapabilities);133 dc.setCapability(PLATFORM_NAME, newPlatform);134 return dc;135 }136 @Override public List<T> findElements(By by) {137 return super.findElements(by);138 }139 @Override public List<T> findElements(String by, String using) {140 return super.findElements(by, using);141 }142 @Override public List<T> findElementsById(String id) {143 return super.findElementsById(id);144 }145 public List<T> findElementsByLinkText(String using) {146 return super.findElementsByLinkText(using);147 }148 public List<T> findElementsByPartialLinkText(String using) {149 return super.findElementsByPartialLinkText(using);150 }151 public List<T> findElementsByTagName(String using) {152 return super.findElementsByTagName(using);153 }154 public List<T> findElementsByName(String using) {155 return super.findElementsByName(using);156 }157 public List<T> findElementsByClassName(String using) {158 return super.findElementsByClassName(using);159 }160 public List<T> findElementsByCssSelector(String using) {161 return super.findElementsByCssSelector(using);162 }163 public List<T> findElementsByXPath(String using) {164 return super.findElementsByXPath(using);165 }166 @Override public List<T> findElementsByAccessibilityId(String using) {167 return super.findElementsByAccessibilityId(using);168 }169 @Override public ExecuteMethod getExecuteMethod() {170 return executeMethod;171 }172 @Override public WebDriver context(String name) {173 checkNotNull(name, "Must supply a context name");174 execute(DriverCommand.SWITCH_TO_CONTEXT, ImmutableMap.of("name", name));175 return this;176 }177 @Override public Set<String> getContextHandles() {178 Response response = execute(DriverCommand.GET_CONTEXT_HANDLES);179 Object value = response.getValue();180 try {181 List<String> returnedValues = (List<String>) value;182 return new LinkedHashSet<>(returnedValues);183 } catch (ClassCastException ex) {184 throw new WebDriverException(185 "Returned value cannot be converted to List<String>: " + value, ex);186 }187 }188 @Override public String getContext() {189 String contextName =190 String.valueOf(execute(DriverCommand.GET_CURRENT_CONTEXT_HANDLE).getValue());191 if ("null".equalsIgnoreCase(contextName)) {192 return null;193 }194 return contextName;195 }196 @Override public DeviceRotation rotation() {197 Response response = execute(DriverCommand.GET_SCREEN_ROTATION);198 DeviceRotation deviceRotation =199 new DeviceRotation((Map<String, Number>) response.getValue());200 if (deviceRotation.getX() < 0 || deviceRotation.getY() < 0 || deviceRotation.getZ() < 0) {201 throw new WebDriverException("Unexpected orientation returned: " + deviceRotation);202 }203 return deviceRotation;204 }205 @Override public void rotate(DeviceRotation rotation) {206 execute(DriverCommand.SET_SCREEN_ROTATION, rotation.parameters());207 }208 @Override public void rotate(ScreenOrientation orientation) {209 execute(DriverCommand.SET_SCREEN_ORIENTATION,210 ImmutableMap.of("orientation", orientation.value().toUpperCase()));211 }212 @Override public ScreenOrientation getOrientation() {213 Response response = execute(DriverCommand.GET_SCREEN_ORIENTATION);214 String orientation = response.getValue().toString().toLowerCase();215 if (orientation.equals(ScreenOrientation.LANDSCAPE.value())) {216 return ScreenOrientation.LANDSCAPE;217 } else if (orientation.equals(ScreenOrientation.PORTRAIT.value())) {218 return ScreenOrientation.PORTRAIT;219 } else {...