Java tutorial
/******************************************************************************* * Copyright 2016 Rahul Verma (Web: www.AutoCognite.com, Email: RV@autocognite.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * 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 com.autocognite.appium.lib.base; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.openqa.selenium.Alert; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.OutputType; import org.openqa.selenium.Proxy; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.Augmenter; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.UnreachableBrowserException; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.Select; import org.openqa.selenium.support.ui.WebDriverWait; import com.autocognite.appium.AppiumAutomator; import com.autocognite.appium.api.AppiumMediator; import com.autocognite.appium.api.AppiumUiDriver; import com.autocognite.appium.api.enums.AppiumMobilePlatformType; import com.autocognite.batteries.api.enums.Browser; import com.autocognite.batteries.lib.exceptions.Problem; import com.autocognite.batteries.lib.utils.FileSystemBatteries; import com.autocognite.configurator.Configurator; import com.autocognite.configurator.api.RunConfiguration; import com.autocognite.uiautomator.UiAutomator; import com.autocognite.uiautomator.api.ElementMetaData; import com.autocognite.uiautomator.api.Identifier; import com.autocognite.uiautomator.api.UiElement; import com.autocognite.uiautomator.api.enums.AutomationContext; import com.autocognite.uiautomator.api.enums.ElementLoaderType; import com.autocognite.uiautomator.api.enums.UiDriverEngine; import com.autocognite.uiautomator.api.enums.UiElementType; import com.autocognite.uiautomator.api.identify.enums.MobileWebIdentifyBy; import com.autocognite.uiautomator.lib.DefaultUiDriver; import com.autocognite.uiautomator.lib.DefaultUiElement; import io.appium.java_client.AppiumDriver; import io.appium.java_client.MobileElement; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.ios.IOSDriver; import io.appium.java_client.remote.MobileCapabilityType; public abstract class AbstractAppiumUiDriver extends DefaultUiDriver implements AppiumUiDriver { private AppiumDriver<MobileElement> driver = null; private WebDriverWait waiter = null; private Browser browser = null; private int waitTime = -1; private String appPath = null; AutomationContext context = null; public AbstractAppiumUiDriver(RunConfiguration runConfig) throws Exception { super(runConfig, AutomationContext.MOBILE_WEB, ElementLoaderType.AUTOMATOR); init(runConfig, AutomationContext.MOBILE_WEB, null); } public AbstractAppiumUiDriver(RunConfiguration runConfig, String appPath, AutomationContext context, ElementLoaderType loaderType) throws Exception { super(runConfig, context, loaderType); if (appPath == null) { throw new Exception("Null value supplied for appPath"); } init(runConfig, context, appPath); } public AbstractAppiumUiDriver(RunConfiguration runConfig, String appPath) throws Exception { this(runConfig, appPath, AutomationContext.MOBILE_NATIVE, ElementLoaderType.AUTOMATOR); } public AbstractAppiumUiDriver(RunConfiguration runConfig, AutomationContext context, ElementLoaderType loaderType) throws Exception { super(runConfig, context, loaderType); init(runConfig, context, null); } public AppiumMediator createMediatorSkeleton(UiElement element) throws Exception { return new DefaultAppiumMediator(this, element); } public UiElement createDefaultElementSkeleton(ElementMetaData elementMetaData) throws Exception { return new DefaultUiElement(elementMetaData); } private void NOTEXPOSED_startService() { // AppiumDriverLocalService service; // String nodeLoc ="/Applications/Appium.app/Contents/Resources/node/bin/node"; // String appiumLoc ="/Applications/Appium.app/Contents/Resources/node_modules/appium/bin/appium.js"; // service = AppiumDriverLocalService // .buildService // ( // new AppiumServiceBuilder() // .usingDriverExecutable(new File(nodeLoc)) // .withAppiumJS(new File(appiumLoc)) // ); // service.start(); } protected void init(RunConfiguration runConfig, AutomationContext context, String appPath) throws Exception { this.context = context; this.setAppPath(appPath); switch (context) { case MOBILE_WEB: this.setWaitTime(Integer.parseInt(runConfig.get(UiAutomator.MOBILE_WEB_WAIT_TIME))); case MOBILE_NATIVE: this.setWaitTime(Integer.parseInt(runConfig.get(UiAutomator.MOBILE_NATIVE_WAIT_TIME))); default: this.setWaitTime(Integer.parseInt(runConfig.get(UiAutomator.MOBILE_WAIT_TIME))); } this.setUiTestEngineName(UiDriverEngine.APPIUM); DesiredCapabilities capabilities = new DesiredCapabilities(); URL hubUrl = new URL(String.format(runConfig.get(AppiumAutomator.APPIUM_HUB_URL), runConfig.get(AppiumAutomator.APPIUM_HUB_HOST), runConfig.get(AppiumAutomator.APPIUM_HUB_PORT))); String platform = runConfig.get(UiAutomator.MOBILE_PLATFORM_NAME); if (!AppiumAutomator.isAllowedAppiumPlatform(platform)) { throwUnsupportedPlatformException("constructor", platform); } AppiumMobilePlatformType platformType = AppiumMobilePlatformType.valueOf(platform.toUpperCase()); setCapabilities(platformType, capabilities); try { switch (platformType) { case ANDROID: driver = new AndroidDriver<MobileElement>(hubUrl, capabilities); break; case IOS: driver = new IOSDriver<MobileElement>(hubUrl, capabilities); break; } } catch (UnreachableBrowserException e) { throwUnreachableBrowserException(platformType, e); } this.setWaiter(new WebDriverWait(this.getDriver(), this.getWaitTime())); } public void setMobileNativeCapabilities(AppiumMobilePlatformType platform, DesiredCapabilities capabilities) throws Exception { RunConfiguration config = getRunConfig(); capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, AppiumAutomator.getAppiumPlatformString(platform)); capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, config.get(UiAutomator.MOBILE_PLATFORM_VERSION)); capabilities.setCapability(MobileCapabilityType.APP, this.getAppPath()); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, config.get(UiAutomator.MOBILE_DEVICE_NAME)); if (!config.get(UiAutomator.MOBILE_DEVICE_UDID).toUpperCase().equals("NOT_SET")) { capabilities.setCapability(MobileCapabilityType.UDID, config.get(UiAutomator.MOBILE_DEVICE_UDID)); } } public void setMobileWebCapabilities(AppiumMobilePlatformType platform, DesiredCapabilities capabilities) throws Exception { RunConfiguration config = getRunConfig(); String browser = config.get(UiAutomator.MOBILE_BROWSER); if (!AppiumAutomator.isAllowedAppiumBrowser(platform, browser)) { throwUnsupportedBrowserException("setMobileCapabilities", platform, browser); } capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, AppiumAutomator.getAppiumPlatformString(platform)); capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, config.get(UiAutomator.MOBILE_PLATFORM_VERSION)); capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, AppiumAutomator.getAppiumBrowserString(browser)); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, config.get(UiAutomator.MOBILE_DEVICE_NAME)); if (!config.get(UiAutomator.MOBILE_DEVICE_UDID).toUpperCase().equals("NOT_SET")) { capabilities.setCapability(MobileCapabilityType.UDID, config.get(UiAutomator.MOBILE_DEVICE_UDID)); } } public void setCapabilities(AppiumMobilePlatformType platform, DesiredCapabilities capabilities) throws Exception { RunConfiguration config = getRunConfig(); if (config.get(UiAutomator.MOBILE_PROXY).toLowerCase().equals("true")) { Proxy proxy = new Proxy(); String p = config.get(UiAutomator.MOBILE_PROXY_HOST) + ":" + config.get(UiAutomator.MOBILE_PROXY_PORT); setHttpProxy(proxy, p); setSslProxy(proxy, p); capabilities.setCapability("proxy", proxy); } switch (this.getContext()) { case MOBILE_WEB: setMobileWebCapabilities(platform, capabilities); break; case MOBILE_NATIVE: setMobileNativeCapabilities(platform, capabilities); break; default: throw new Exception("Unsupported automation context for Appium. Allowed: MOBILE_WEB/MOBILE_NATIVE"); } } public void setHttpProxy(Proxy proxy, String proxyString) { proxy.setHttpProxy(proxyString); } public void setSslProxy(Proxy proxy, String proxyString) { proxy.setSslProxy(proxyString); } public AppiumDriver<MobileElement> getDriver() { return driver; } public void setDriver(AppiumDriver<MobileElement> driver) { this.driver = driver; } public String getAppPath() { return appPath; } public void setAppPath(String appPath) { this.appPath = appPath; } public WebDriverWait getWaiter() { return this.waiter; } public void setWaiter(WebDriverWait waiter) { this.waiter = waiter; } public int getWaitTime() { return this.waitTime; } public void setWaitTime(int waitTime) { this.waitTime = waitTime; } public void setBrowser(Browser browser) { this.browser = browser; } public Browser getBrowser() { return this.browser; } @Override public Object getUiDriverEngine() { return this.getDriver(); } public Object getUnderlyingEngine() { return getDriver(); } /**********************************************************************************/ @Override public UiElement declareElement(ElementMetaData elementMetaData) throws Exception { UiElement uiElement = createDefaultElementSkeleton(elementMetaData); ArrayList<By> finderQueue = new ArrayList<By>(); for (Identifier id : elementMetaData.getIdentifiers()) { finderQueue.add(getFinderType(id.NAME, id.VALUE)); } AppiumMediator mediator = createMediatorSkeleton(uiElement); uiElement.setMediator(mediator); uiElement.setLoaderType(this.getElementLoaderType()); mediator.setFindersQueue(finderQueue); mediator.setAutomatorName(this.getName()); return uiElement; } public By getFinderType(String identifier, String idValue) throws Exception { By findBy = null; MobileWebIdentifyBy idType = null; try { idType = MobileWebIdentifyBy.valueOf(identifier.toUpperCase()); } catch (Throwable e) { throwUnsupportedIndentifierException(this.getName(), "getFinderType", identifier); } switch (identifier.toUpperCase()) { case "ID": findBy = By.id(idValue); break; case "NAME": findBy = By.name(idValue); break; case "CLASS": findBy = By.className(idValue); break; case "LINK_TEXT": findBy = By.linkText(idValue); break; case "PARTIAL_LINK_TEXT": findBy = By.partialLinkText(idValue); break; case "XPATH": findBy = By.xpath(idValue); break; case "CSS": findBy = By.cssSelector(idValue); break; case "TAG": findBy = By.tagName(idValue); break; } return findBy; } public UiElementType getElementType(MobileElement wdElement) { String tagName = wdElement.getTagName().toLowerCase(); if (tagName.equals("select")) { return UiElementType.DROPDOWN; } else if (tagName.equals("input") && wdElement.getAttribute("type").toLowerCase().equals("radio")) { return UiElementType.RADIO; } else { return UiElementType.GENERIC; } } /********************************************************************************** /** EXCEPTIONS *********************************************************************************/ protected void throwAppiumAutomatorException(String action, String code, String message) throws Exception { throw new Problem(Configurator.getConfiguredName("COMPONENT_NAMES", "APPIUM_AUTOMATOR"), this.getClass().getSimpleName(), action, code, message); } protected void throwUnsupportedPlatformException(String methodName, String platform) throws Exception { throwAppiumAutomatorException(methodName, AppiumAutomator.problem.APPIUM_UNSUPPORTED_PLATFORM, Configurator.getProblemText(AppiumAutomator.problem.APPIUM_UNSUPPORTED_PLATFORM, platform)); } protected void throwUnsupportedBrowserException(String methodName, AppiumMobilePlatformType platform, String browser) throws Exception { throwAppiumAutomatorException(methodName, AppiumAutomator.problem.APPIUM_UNSUPPORTED_BROWSER, Configurator.getProblemText(AppiumAutomator.problem.APPIUM_UNSUPPORTED_BROWSER, browser, AppiumAutomator.getAppiumPlatformString(platform))); } private void throwUnreachableBrowserException(AppiumMobilePlatformType platformType, Throwable e) throws Exception { throw new Problem(Configurator.getComponentName("UI_AUTOMATOR"), this.getName(), "Constructor", AppiumAutomator.problem.APPIUM_UNREACHABLE_BROWSER, Configurator.getProblemText(AppiumAutomator.problem.APPIUM_UNREACHABLE_BROWSER, AppiumAutomator.getAppiumPlatformString(platformType)), e); } /**********************************************************************************/ /* AUTOMATOR API */ /**********************************************************************************/ public void goTo(String url) throws Exception { getDriver().get(url); waitForBody(); } public void refresh() throws Exception { getDriver().navigate().refresh(); } public void back() throws Exception { getDriver().navigate().back(); } public void forward() throws Exception { getDriver().navigate().forward(); } public void close() { getDriver().quit(); } public void waitForBody() throws Exception { waitForElementPresence(By.tagName("body")); } public void confirmAlertIfPresent() { AppiumDriver<MobileElement> d = getDriver(); try { Alert alert = d.switchTo().alert(); alert.accept(); d.switchTo().defaultContent(); } catch (Exception e) { // ignore } } // Windows related public String getCurrentWindow() { return getDriver().getWindowHandle(); } public void switchToWindow(String windowHandle) { getDriver().switchTo().window(windowHandle); } public void switchToNewWindow() { AppiumDriver driver = getDriver(); String parentHandle = getCurrentWindow(); for (String winHandle : driver.getWindowHandles()) { if (!winHandle.equals(parentHandle)) { switchToWindow(winHandle); // switch focus of WebDriver to the next found window handle (that's your newly opened window) } } } public void closeCurrentWindow() { getDriver().close(); } public void switchToFrame(int index) throws Exception { this.getDriver().switchTo().frame(index); } public void switchToFrame(String name) throws Exception { this.getDriver().switchTo().frame(name); } @Override public void switchToFrame(MobileElement appiumElement) throws Exception { this.getDriver().switchTo().frame(appiumElement); } public void switchToDefaultFrame() throws Exception { this.getDriver().switchTo().defaultContent(); } public TakesScreenshot getScreenshotAugmentedDriver() { return (TakesScreenshot) (new Augmenter().augment(getDriver())); } @Override public File takeScreenshot() throws Exception { TakesScreenshot augDriver = getScreenshotAugmentedDriver(); File srcFile = augDriver.getScreenshotAs(OutputType.FILE); return FileSystemBatteries.moveFiletoDir(srcFile, this.getRunConfig().get(Configurator.TEMP_SCREENSHOTS_DIR)); } public void focusOnApp() throws Exception { } /**********************************************************************************/ /* ELEMENT API */ /**********************************************************************************/ public MobileElement findElement(By findBy) throws Exception { waitForElementPresence(findBy); MobileElement element = getDriver().findElement(findBy); return element; } public List<MobileElement> findElements(By findBy) throws Exception { waitForElementPresence(findBy); List<MobileElement> elements = getDriver().findElements(findBy); return elements; } @Override public void waitForElementPresence(By findBy) throws Exception { getWaiter().until(ExpectedConditions.presenceOfElementLocated(findBy)); } @Override public void waitForElementAbsence(By findBy) throws Exception { try { getWaiter().until(ExpectedConditions.presenceOfElementLocated(findBy)); throw new Exception("Not able to establish absence of element after polling for same."); } catch (Exception e) { // Do nothing. } } public void waitForElementClickability(By findBy) throws Exception { getWaiter().until(ExpectedConditions.elementToBeClickable(findBy)); } public void waitForElementClickability(WebElement element) throws Exception { getWaiter().until(ExpectedConditions.elementToBeClickable(element)); } @Override public void waitForElementVisibility(By findBy) throws Exception { getWaiter().until(ExpectedConditions.visibilityOfElementLocated(findBy)); } @Override public void waitForElementInvisibility(By findBy) throws Exception { getWaiter().until(ExpectedConditions.invisibilityOfElementLocated(findBy)); } @Override public boolean isElementPresent(By findBy) { try { waitForElementPresence(findBy); return true; } catch (Exception e) { return false; } } @Override public boolean isElementAbsent(By findBy) { try { waitForElementAbsence(findBy); return true; } catch (Exception e) { return false; } } @Override public boolean isElementVisible(By findBy) { try { waitForElementVisibility(findBy); return true; } catch (Exception e) { return false; } } @Override public boolean isElementInvisible(By findBy) { try { waitForElementInvisibility(findBy); return true; } catch (Exception e) { return false; } } /* Element Basic Actions */ public void focus(MobileElement wdElement) throws Exception { wdElement.sendKeys(""); } public boolean isSelected(MobileElement wdElement) { return wdElement.isSelected(); } public void click(MobileElement wdElement) throws Exception { waitForElementClickability(wdElement); try { wdElement.click(); } catch (Exception f) { focus(wdElement); wdElement.sendKeys(Keys.ENTER); } } public MobileElement click(By findBy) throws Exception { MobileElement wdElement = findElement(findBy); click(wdElement); return wdElement; } public MobileElement clickIfPresent(By findBy) { try { return click(findBy); } catch (Exception e) { //pass } return null; } public void clickIfNotSelected(MobileElement wdElement) { if ((wdElement != null) && (!isSelected(wdElement))) { wdElement.click(); } } public void enterText(MobileElement wdElement, String value) throws Exception { waitForElementClickability(wdElement); wdElement.click(); wdElement.sendKeys(value); } public void setText(MobileElement wdElement, String text) throws Exception { this.waitForElementClickability(wdElement); wdElement.click(); wdElement.clear(); wdElement.sendKeys(text); } public void clearText(MobileElement wdElement) throws Exception { wdElement.clear(); } public boolean isChecked(MobileElement wdElement) { return isSelected(wdElement); } public void check(MobileElement wdElement) { if (!isChecked(wdElement)) { wdElement.click(); } } public void uncheck(MobileElement wdElement) throws Exception { if (isChecked(wdElement)) { wdElement.click(); } } public void toggle(MobileElement wdElement) throws Exception { wdElement.click(); } /* * Drop Down API */ public void selectDropDownLabel(Select selectElement, String text) { selectElement.selectByVisibleText(text); } public void selectDropDownValue(Select selectElement, String value) { selectElement.selectByValue(value); } public void selectDropDownOptionAtIndex(Select selectElement, int index) { selectElement.selectByIndex(index); } public boolean isDropDownSelectedText(Select selectElement, String text) { List<WebElement> selectedOptions = selectElement.getAllSelectedOptions(); for (WebElement option : selectedOptions) { if (option.getText().equals(text)) return true; } return false; } public boolean isDropDownSelectedValue(Select selectElement, String value) { List<WebElement> selectedOptions = selectElement.getAllSelectedOptions(); for (WebElement option : selectedOptions) { if (option.getAttribute("value").equals(value)) return true; } return false; } public boolean isDropDownSelectedIndex(Select selectElement, int index) { List<WebElement> options = selectElement.getOptions(); return options.get(index).isSelected(); } public ArrayList<String> getDropDownOptionLabels(Select selectControl) { ArrayList<String> texts = new ArrayList<String>(); for (WebElement option : selectControl.getOptions()) { texts.add(option.getText()); } return texts; } public ArrayList<String> getDropDownOptionValues(Select selectControl) { ArrayList<String> texts = new ArrayList<String>(); for (WebElement option : selectControl.getOptions()) { texts.add(option.getAttribute("value")); } return texts; } public int getDropDownOptionCount(Select selectControl) { return selectControl.getOptions().size(); } public Select convertToSelectElement(MobileElement element) throws Exception { return new Select(element); } /* * Radio Button API */ public MobileElement chooseElementBasedOnText(List<MobileElement> wdElements, String text) { for (MobileElement wdElement : wdElements) { if (getText(wdElement).equals(text)) { return wdElement; } } return null; } public MobileElement chooseElementBasedOnValue(List<MobileElement> wdElements, String value) throws Exception { for (MobileElement wdElement : wdElements) { if (getValue(wdElement).equals(value)) { return wdElement; } } return null; } public MobileElement getParent(MobileElement wdElement) { return wdElement.findElement(By.xpath("parent::*")); } public MobileElement chooseElementBasedOnParentText(List<MobileElement> wdElements, String text) { for (MobileElement wdElement : wdElements) { MobileElement parent = getParent(wdElement); if (getText(parent).equals(text)) { return wdElement; } } return null; } public boolean isSelectedText(List<MobileElement> wdElements, String text) { for (MobileElement wdElement : wdElements) { if (getText(wdElement).equals(text)) { return true; } } return false; } public boolean isSelectedValue(List<MobileElement> wdElements, String value) throws Exception { for (MobileElement wdElement : wdElements) { if (getValue(wdElement).equals(value)) { return true; } } return false; } public boolean isSelectedIndex(List<MobileElement> elements, int index) { return elements.get(index).isSelected(); } public boolean isSelectedElementParentText(List<MobileElement> wdElements, String text) { for (MobileElement wdElement : wdElements) { MobileElement parent = getParent(wdElement); if (getText(parent).equals(text)) { return true; } } return false; } public ArrayList<String> getRadioButtonLabels(List<MobileElement> wdElements) { ArrayList<String> texts = new ArrayList<String>(); for (MobileElement option : wdElements) { texts.add(getText(option)); } return texts; } public ArrayList<String> getRadioButtonValues(List<MobileElement> wdElements) throws Exception { ArrayList<String> texts = new ArrayList<String>(); for (MobileElement option : wdElements) { texts.add(getValue(option)); } return texts; } // Property API public String getText(MobileElement wdElement) { return wdElement.getText(); } public String getValue(MobileElement wdElement) throws Exception { return wdElement.getAttribute("value"); } public String getAttribute(MobileElement wdElement, String attr) throws Exception { return wdElement.getAttribute(attr); } }