From 6210c200bc05ae9069a991e2db7a638191fa0a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Thu, 14 Mar 2024 17:27:09 +0100 Subject: [PATCH 01/17] Updated for using mobile web tests with Testerra 2.4 --- appium/build.gradle | 4 +- .../appium/WinAppDriverFactory.java | 27 +++---- .../mobile/driver/AppiumDeviceQuery.java | 3 +- .../mobile/driver/AppiumDriverFactory.java | 60 +++++++-------- .../mobile/driver/MobileOsChecker.java | 21 +++--- .../AppiumGuiElementCoreAdapter.java | 75 +++++++++++-------- .../CreateAppiumGuiElementAction.java | 2 +- .../tic/testframework/utils/AppiumUtils.java | 10 ++- .../webdrivermanager/AppiumDriverRequest.java | 23 +++--- .../test/apps/TesterraMobileAppTest.java | 2 +- .../test/apps/VanillaAppiumAppTest.java | 5 +- .../test/driver/TesterraAppiumDriverTest.java | 17 +++-- .../test/driver/VanillaAppiumDriverTest.java | 30 ++++---- build.gradle | 8 +- 14 files changed, 156 insertions(+), 131 deletions(-) diff --git a/appium/build.gradle b/appium/build.gradle index 3569e6d2..9b2b3d27 100644 --- a/appium/build.gradle +++ b/appium/build.gradle @@ -1,6 +1,6 @@ dependencies { compileOnly 'io.testerra:driver-ui:' + testerraCompileVersion - compileOnly 'io.appium:java-client:7.3.0' + compileOnly 'io.appium:java-client:' + appiumJavaClientVersion implementation 'com.google.code.gson:gson:2.9.0' implementation 'org.apache.commons:commons-lang3:3.12.0' @@ -11,7 +11,7 @@ dependencies { testImplementation 'io.testerra:driver-ui:' + testerraTestVersion // testImplementation 'io.testerra:driver-ui' testImplementation 'io.testerra:report-ng:' + testerraTestVersion - testImplementation 'io.appium:java-client:7.3.0' + testImplementation 'io.appium:java-client:' + appiumJavaClientVersion } test() { diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/WinAppDriverFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/WinAppDriverFactory.java index 24e4442e..6cfa7414 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/WinAppDriverFactory.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/WinAppDriverFactory.java @@ -21,8 +21,8 @@ package eu.tsystems.mms.tic.testframework.appium; -import eu.tsystems.mms.tic.testframework.core.WinAppDriverCoreAdapter; import eu.tsystems.mms.tic.testframework.common.IProperties; +import eu.tsystems.mms.tic.testframework.core.WinAppDriverCoreAdapter; import eu.tsystems.mms.tic.testframework.logging.Loggable; import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementCore; import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementData; @@ -33,16 +33,15 @@ import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverRequest; import eu.tsystems.mms.tic.testframework.webdrivermanager.WinAppDriverRequest; import io.appium.java_client.windows.WindowsDriver; -import io.appium.java_client.windows.WindowsElement; -import java.net.URL; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; +import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; +import java.net.URL; +import java.util.Arrays; +import java.util.List; + public class WinAppDriverFactory implements WebDriverFactory, Loggable, TestControllerProvider, Sleepy { public enum Properties implements IProperties { @@ -68,7 +67,7 @@ public Object getDefault() { } } - private WindowsDriver startNewWindowsDriver(WinAppDriverRequest appDriverRequest, SessionContext sessionContext) { + private WindowsDriver startNewWindowsDriver(WinAppDriverRequest appDriverRequest, SessionContext sessionContext) { final URL finalWinAppServerUrl = appDriverRequest.getServerUrl().get(); sessionContext.setNodeUrl(finalWinAppServerUrl); @@ -80,7 +79,7 @@ private WindowsDriver startNewWindowsDriver(WinAppDriverRequest desiredCapabilities.setCapability(WinAppDriverRequest.APP_ID, appId); }); - WindowsDriver windowsDriver = new WindowsDriver<>(finalWinAppServerUrl, desiredCapabilities); + WindowsDriver windowsDriver = new WindowsDriver(finalWinAppServerUrl, desiredCapabilities); //CONTROL.retryFor(appDriverRequest.getStartupTimeoutSeconds(), windowsDriver::getTitle, this::sleep); return windowsDriver; } @@ -94,8 +93,8 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques } @Override - public WebDriver createWebDriver(WebDriverRequest webDriverRequest, SessionContext sessionContext) { - WinAppDriverRequest appDriverRequest = (WinAppDriverRequest)webDriverRequest; + public WebDriver createWebDriver(WebDriverRequest webDriverRequest, SessionContext sessionContext) { + WinAppDriverRequest appDriverRequest = (WinAppDriverRequest) webDriverRequest; /** * Try to reuse an already opened application @@ -113,11 +112,13 @@ public WebDriver createWebDriver(WebDriverRequest webDriverRequest, SessionConte appDriverRequest.getServerUrl().ifPresent(desktopDriverRequest::setServerUrl); } - WindowsDriver desktopDriver = startNewWindowsDriver(desktopDriverRequest, sessionContext); + WindowsDriver desktopDriver = startNewWindowsDriver(desktopDriverRequest, sessionContext); log().info(String.format("Try to create driver on running application by window title \"%s\"", reuseableWindowTitle)); CONTROL.waitFor(appDriverRequest.getReuseTimeoutSeconds(), () -> { - WebElement elementByName = desktopDriver.findElementByName(reuseableWindowTitle); + // TODO: Verify migration + // WebElement elementByName = desktopDriver.findElementByName(reuseableWindowTitle); --> migrate to Appium 8.x + WebElement elementByName = desktopDriver.findElement(By.name(reuseableWindowTitle)); String nativeWindowHandle = elementByName.getAttribute("NativeWindowHandle"); int nativeWindowHandleId = Integer.parseInt(nativeWindowHandle); if (nativeWindowHandleId > 0) { diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDeviceQuery.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDeviceQuery.java index 3687d88f..ca4ae64a 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDeviceQuery.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDeviceQuery.java @@ -45,7 +45,8 @@ public AppiumDeviceQuery() { } public AppiumDeviceQuery(Capabilities capabilities) { - this.setOs((String) capabilities.getCapability("platformName")); + this.setOs(capabilities.getPlatformName().toString()); +// this.setOs((String) capabilities.getCapability("platformName")); this.setVersion((String) capabilities.getCapability("platformVersion")); this.setManufacture((String) capabilities.getCapability("deviceManufacture")); this.setModel((String) capabilities.getCapability("deviceModel")); diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java index dfa46b89..712ad6f5 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java @@ -31,7 +31,6 @@ import eu.tsystems.mms.tic.testframework.report.model.context.SessionContext; import eu.tsystems.mms.tic.testframework.report.utils.IExecutionContextController; import eu.tsystems.mms.tic.testframework.utils.AppiumProperties; -import eu.tsystems.mms.tic.testframework.utils.DefaultCapabilityUtils; import eu.tsystems.mms.tic.testframework.utils.TimerUtils; import eu.tsystems.mms.tic.testframework.webdriver.WebDriverFactory; import eu.tsystems.mms.tic.testframework.webdrivermanager.AppiumDriverRequest; @@ -41,10 +40,13 @@ import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.ios.IOSDriver; import io.appium.java_client.remote.MobileBrowserType; +import io.appium.java_client.remote.options.BaseOptions; import org.apache.commons.lang3.StringUtils; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; -import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.support.events.EventFiringWebDriver; import java.net.URL; @@ -74,21 +76,21 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques finalRequest.setBrowserVersion(webDriverRequest.getBrowserVersion()); } - DesiredCapabilities requestCapabilities = finalRequest.getDesiredCapabilities(); + MutableCapabilities requestCapabilities = finalRequest.getMutableCapabilities(); + BaseOptions baseOptions = new BaseOptions<>(); - // general caps IExecutionContextController executionContext = Testerra.getInjector().getInstance(IExecutionContextController.class); - requestCapabilities.setCapability(AppiumDriverRequest.CAPABILITY_NAME_TEST_NAME, executionContext.getExecutionContext().getRunConfig().getReportName()); + baseOptions.setCapability(AppiumDriverRequest.CAPABILITY_NAME_TEST_NAME, executionContext.getExecutionContext().getRunConfig().getReportName()); if (requestCapabilities.getCapability(AppiumDriverRequest.DEVICE_QUERY) == null || StringUtils.isBlank(requestCapabilities.getCapability(AppiumDriverRequest.DEVICE_QUERY).toString())) { switch (webDriverRequest.getBrowser()) { case Browsers.mobile_safari: { - finalRequest.setDeviceQuery(AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_IOS.asString()); + baseOptions.setCapability(AppiumDriverRequest.DEVICE_QUERY, AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_IOS.asString()); break; } case Browsers.mobile_chrome: { - finalRequest.setDeviceQuery(AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_ANDROID.asString()); + baseOptions.setCapability(AppiumDriverRequest.DEVICE_QUERY, AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_ANDROID.asString()); break; } } @@ -96,15 +98,20 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques switch (webDriverRequest.getBrowser()) { case Browsers.mobile_chrome: - requestCapabilities.setBrowserName(MobileBrowserType.CHROME); + baseOptions.setCapability(CapabilityType.BROWSER_NAME, MobileBrowserType.CHROME); break; case Browsers.mobile_safari: - requestCapabilities.setBrowserName(MobileBrowserType.SAFARI); + baseOptions.setCapability(CapabilityType.BROWSER_NAME, MobileBrowserType.SAFARI); break; default: log().info("No mobile browser requested."); } + // Any additional defined desired capabilities are merged into browser options + baseOptions = baseOptions.merge(finalRequest.getDesiredCapabilities()); + baseOptions = baseOptions.merge(finalRequest.getMutableCapabilities()); + finalRequest.setCapabilities(baseOptions); + return finalRequest; } @@ -123,43 +130,32 @@ public WebDriver createWebDriver(WebDriverRequest webDriverRequest, SessionConte private WebDriver startNewAppiumSession(WebDriverRequest webDriverRequest, SessionContext sessionContext) { AppiumDriverRequest appiumDriverRequest = (AppiumDriverRequest) webDriverRequest; - DesiredCapabilities requestCapabilities = appiumDriverRequest.getDesiredCapabilities(); + Capabilities requestCapabilities = appiumDriverRequest.getCapabilities(); URL appiumUrl = appiumDriverRequest.getServerUrl().get(); - DesiredCapabilities finalCapabilities = new DesiredCapabilities(requestCapabilities); +// DesiredCapabilities finalCapabilities = new DesiredCapabilities(requestCapabilities); + +// IExecutionContextController executionContextController = Testerra.getInjector().getInstance(IExecutionContextController.class); +// DefaultCapabilityUtils utils = new DefaultCapabilityUtils(); - IExecutionContextController executionContextController = Testerra.getInjector().getInstance(IExecutionContextController.class); - DefaultCapabilityUtils utils = new DefaultCapabilityUtils(); - // TODO: Move to prepareWebDriverRequest - utils.putIfAbsent(finalCapabilities, AppiumDriverRequest.CAPABILITY_NAME_TEST_NAME, executionContextController.getExecutionContext().getRunConfig().getReportName()); +// utils.putIfAbsent(requestCapabilities, AppiumDriverRequest.CAPABILITY_NAME_TEST_NAME, executionContextController.getExecutionContext().getRunConfig().getReportName()); AppiumDriver appiumDriver = null; Platform mobilePlatform = new MobileOsChecker().getPlatform(webDriverRequest); switch (mobilePlatform) { case IOS: - appiumDriver = new IOSDriver<>(appiumUrl, finalCapabilities); + appiumDriver = new IOSDriver(appiumUrl, requestCapabilities); break; case ANDROID: - appiumDriver = new AndroidDriver<>(appiumUrl, finalCapabilities); + appiumDriver = new AndroidDriver(appiumUrl, requestCapabilities); break; } -// switch (webDriverRequest.getBrowser()) { -// case Browsers.mobile_safari: { -// finalCapabilities.setBrowserName(MobileBrowserType.SAFARI); -// appiumDriver = new IOSDriver<>(appiumUrl, finalCapabilities); -// break; -// } -// case Browsers.mobile_chrome: { -// finalCapabilities.setBrowserName(MobileBrowserType.CHROME); -// appiumDriver = new AndroidDriver<>(appiumUrl, finalCapabilities); -// break; -// } -// } if (appiumDriver != null) { AppiumDeviceQuery appiumDeviceQuery = new AppiumDeviceQuery(appiumDriver.getCapabilities()); - sessionContext.setActualBrowserName(appiumDeviceQuery.toString()); + sessionContext.setUserAgent(appiumDeviceQuery.toString()); + sessionContext.setActualBrowserName(appiumDeviceQuery.getBrowserName()); } else { - throw new RuntimeException("Cannot create new Appium session - ambiguous capabilities found:\n " + finalCapabilities.toString()); + throw new RuntimeException("Cannot create new Appium session - ambiguous capabilities found:\n " + requestCapabilities.toString()); // throw new RuntimeException("Mobile Browser not supported: " + webDriverRequest.getBrowser()); } return appiumDriver; @@ -174,7 +170,7 @@ public void setupNewWebDriverSession(EventFiringWebDriver webDriver, SessionCont .ifPresent(driver -> driverString.set(driver.getClass().toString())); // In case of app automation it es not possible to call a URL - if (StringUtils.isNotBlank(appiumDriverRequest.getDesiredCapabilities().getBrowserName())) { + if (StringUtils.isNotBlank(appiumDriverRequest.getBrowser())) { appiumDriverRequest.getBaseUrl().ifPresent(url -> { log().info("Open {} on {}", url, driverString.get()); webDriver.get(url.toString()); diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java index 52e3746d..09e92bbb 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java @@ -28,10 +28,10 @@ import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.IOSMobileCapabilityType; import io.appium.java_client.remote.MobileCapabilityType; +import org.openqa.selenium.Capabilities; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; -import java.util.Map; import java.util.Optional; /** @@ -42,20 +42,21 @@ public class MobileOsChecker { public Platform getPlatform(WebDriverRequest webDriverRequest) { - Map capabilities = webDriverRequest.getCapabilities(); + Capabilities capabilities = webDriverRequest.getCapabilities(); + if (webDriverRequest.getBrowser().equals(Browsers.mobile_chrome) - || "Espresso".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME)) - || "UiAutomator2".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME)) - || "UiAutomator".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME)) - || capabilities.containsKey(AndroidMobileCapabilityType.APP_PACKAGE) - || capabilities.containsKey(AndroidMobileCapabilityType.APP_ACTIVITY) + || "Espresso".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) + || "UiAutomator2".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) + || "UiAutomator".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) + || capabilities.getCapability(AndroidMobileCapabilityType.APP_PACKAGE) != null + || capabilities.getCapability(AndroidMobileCapabilityType.APP_ACTIVITY) != null ) { return Platform.ANDROID; } if (webDriverRequest.getBrowser().equals(Browsers.mobile_safari) - || "XCUITest".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME)) - || "UIAutomation".equals(capabilities.get(MobileCapabilityType.AUTOMATION_NAME)) - || capabilities.containsKey(IOSMobileCapabilityType.BUNDLE_ID) + || "XCUITest".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) + || "UIAutomation".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) + || capabilities.getCapability(IOSMobileCapabilityType.BUNDLE_ID) != null ) { return Platform.IOS; } diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java index f35b61e7..266f61e6 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java @@ -31,14 +31,17 @@ import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils; import io.appium.java_client.AppiumDriver; +import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; import io.appium.java_client.touch.LongPressOptions; import io.appium.java_client.touch.TapOptions; import io.appium.java_client.touch.WaitOptions; import io.appium.java_client.touch.offset.ElementOption; import io.appium.java_client.touch.offset.PointOption; +import org.apache.commons.lang3.NotImplementedException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.PointerInput; import java.time.Duration; import java.util.concurrent.atomic.AtomicBoolean; @@ -80,41 +83,47 @@ public void hover() { throw new MobileActionNotSupportedException("hover() is not supported on mobile element.s"); } - @Override - public void contextClick() { - this.findWebElement(webElement -> { - final ElementOption elementOption = new ElementOption().withElement(webElement); - final TouchAction action = new TouchAction<>(appiumDriver); - - action.longPress(new LongPressOptions().withElement(elementOption)); - action.perform(); - }); - } - - @Override - public void doubleClick() { - this.findWebElement(webElement -> { - final ElementOption elementOption = new ElementOption().withElement(webElement); - final TouchAction action = new TouchAction<>(appiumDriver); - - final TapOptions tapOptions = new TapOptions().withTapsCount(2).withElement(elementOption); - action.tap(tapOptions).perform(); - }); - } - + // TODO: Migrate to W3C actions +// @Override +// public void contextClick() { +// this.findWebElement(webElement -> { +// final ElementOption elementOption = new ElementOption().withElement(webElement); +// // new +//// PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); +// final TouchAction action = new TouchAction(appiumDriver); +// +// action.longPress(new LongPressOptions().withElement(elementOption)); +// action.perform(); +// }); +// } + + // TODO: Migrate to W3C actions +// @Override +// public void doubleClick() { +// this.findWebElement(webElement -> { +// final ElementOption elementOption = new ElementOption().withElement(webElement); +// final TouchAction action = new TouchAction<>(appiumDriver); +// +// final TapOptions tapOptions = new TapOptions().withTapsCount(2).withElement(elementOption); +// action.tap(tapOptions).perform(); +// }); +// } + + // TODO: Migrate to W3C actions @Override public void swipe(int offsetX, int offsetY) { - this.findWebElement(webElement -> { - TouchAction touchAction = new TouchAction(appiumDriver); - - final TapOptions tapOption = new TapOptions().withElement(new ElementOption().withElement(webElement)); - touchAction.tap(tapOption); - touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); - touchAction.moveTo(new PointOption().withCoordinates(offsetX, offsetY)); - touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); - touchAction.release(); - touchAction.perform(); - }); + throw new NotImplementedException("Implement me with W3C actions"); +// this.findWebElement(webElement -> { +// TouchAction touchAction = new TouchAction(appiumDriver); +// +// final TapOptions tapOption = new TapOptions().withElement(new ElementOption().withElement(webElement)); +// touchAction.tap(tapOption); +// touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); +// touchAction.moveTo(new PointOption().withCoordinates(offsetX, offsetY)); +// touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); +// touchAction.release(); +// touchAction.perform(); +// }); } @Override diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java index cb794f34..935e39ae 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java @@ -100,7 +100,7 @@ private String getAutomationEngine(WebDriver driver, Platform platform) { IWebDriverManager instance = Testerra.getInjector().getInstance(IWebDriverManager.class); Optional optional = instance.getSessionContext(driver).map(SessionContext::getWebDriverRequest); if (optional.isPresent()) { - String automationEngine = optional.get().getCapabilities().get(MobileCapabilityType.AUTOMATION_NAME).toString(); + String automationEngine = optional.get().getCapabilities().getCapability(MobileCapabilityType.AUTOMATION_NAME).toString(); if (StringUtils.isNotBlank(automationEngine)) { return automationEngine; } else { diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java index 6673048e..8f88c900 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java @@ -27,6 +27,7 @@ import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker; import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; import io.appium.java_client.AppiumDriver; +import io.appium.java_client.remote.SupportsContextSwitching; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; @@ -66,7 +67,10 @@ public void switchContext(WebDriver driver, AppiumContext desiredContext) { if (appiumDriver.isEmpty()) { throw new RuntimeException("Current Webdriver is not an Appium driver."); } - String currentContext = appiumDriver.get().getContext(); + + SupportsContextSwitching contextSwitchingDriver = (SupportsContextSwitching) appiumDriver.get(); + + String currentContext = contextSwitchingDriver.getContext(); AppiumContext parsedInitialContext = AppiumContext.parse(currentContext); log().info("Current context: {} ({})", currentContext, parsedInitialContext); @@ -75,14 +79,14 @@ public void switchContext(WebDriver driver, AppiumContext desiredContext) { return; } - Set contextHandles = appiumDriver.get().getContextHandles(); + Set contextHandles = contextSwitchingDriver.getContextHandles(); log().info("Available contexts: {}", contextHandles); contextHandles.stream() .filter(contextHandle -> AppiumContext.parse(contextHandle).equals(desiredContext)) .findFirst() .ifPresentOrElse(handle -> { log().info("Switch to context {} ({})", handle, desiredContext); - appiumDriver.get().context(handle); + contextSwitchingDriver.context(handle); }, () -> { log().error("Couldn't find a {} context in {}", desiredContext, contextHandles); throw new RuntimeException(String.format("Cannot switch in %s, because it does not exist. (%s)", desiredContext, contextHandles)); diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java index 4c5be9a8..96f6196f 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java @@ -37,8 +37,9 @@ public class AppiumDriverRequest extends SeleniumWebDriverRequest { public static final String CAPABILITY_NAME_TEST_NAME = "testName"; public AppiumDriverRequest() { + super(); setAccessKey(AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString()); - this.setBrowser(Browsers.mobile); +// this.setBrowser(Browsers.mobile); } @Override @@ -55,43 +56,43 @@ public Optional getServerUrl() { public void setDeviceQuery(String deviceQuery) { if (StringUtils.isNotBlank(deviceQuery)) { - this.getDesiredCapabilities().setCapability(DEVICE_QUERY, deviceQuery); + this.getMutableCapabilities().setCapability(DEVICE_QUERY, deviceQuery); } } public void setAccessKey(String accessKey) { - this.getDesiredCapabilities().setCapability(ACCESS_KEY, accessKey); + this.getMutableCapabilities().setCapability(ACCESS_KEY, accessKey); } public void setAppiumEngine(String engine) { - this.getDesiredCapabilities().setCapability(MobileCapabilityType.AUTOMATION_NAME, engine); + this.getMutableCapabilities().setCapability(MobileCapabilityType.AUTOMATION_NAME, engine); } public String getAppiumEngine() { - return this.getDesiredCapabilities().getCapability(MobileCapabilityType.AUTOMATION_NAME).toString(); + return this.getMutableCapabilities().getCapability(MobileCapabilityType.AUTOMATION_NAME).toString(); } public void setDeviceName(String deviceName) { - this.getDesiredCapabilities().setCapability(MobileCapabilityType.DEVICE_NAME, deviceName); + this.getMutableCapabilities().setCapability(MobileCapabilityType.DEVICE_NAME, deviceName); } public String getDeviceName() { - return this.getDesiredCapabilities().getCapability(MobileCapabilityType.DEVICE_NAME).toString(); + return this.getMutableCapabilities().getCapability(MobileCapabilityType.DEVICE_NAME).toString(); } public void setPlatformVersion(String platformVersion) { - this.getDesiredCapabilities().setCapability(MobileCapabilityType.PLATFORM_VERSION, platformVersion); + this.getMutableCapabilities().setCapability(MobileCapabilityType.PLATFORM_VERSION, platformVersion); } public String getPlatformVersion() { - return this.getDesiredCapabilities().getCapability(MobileCapabilityType.PLATFORM_VERSION).toString(); + return this.getMutableCapabilities().getCapability(MobileCapabilityType.PLATFORM_VERSION).toString(); } public void setDeviceId(String id) { - this.getDesiredCapabilities().setCapability(MobileCapabilityType.UDID, id); + this.getMutableCapabilities().setCapability(MobileCapabilityType.UDID, id); } public String getDeviceId() { - return this.getDesiredCapabilities().getCapability(MobileCapabilityType.UDID).toString(); + return this.getMutableCapabilities().getCapability(MobileCapabilityType.UDID).toString(); } } diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java index 82cdf42b..f7c84c42 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java @@ -48,7 +48,7 @@ public class TesterraMobileAppTest extends AbstractAppiumTest { public void testT01AndroidApp() { AppiumDriverRequest request = new AppiumDriverRequest(); request.setDeviceQuery("contains(@name, 'Galaxy S20')"); - request.getDesiredCapabilities().setCapability("appiumVersion", "1.22.3"); + request.getDesiredCapabilities().setCapability("appiumVersion", "2.2.2"); request.getDesiredCapabilities().setCapability(MobileCapabilityType.APP, "cloud:eu.tsystems.mms.tic.mdc.app.android/.HomeActivity"); request.getDesiredCapabilities().setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "eu.tsystems.mms.tic.mdc.app.android"); diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java index 39b5be04..3283f3de 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/VanillaAppiumAppTest.java @@ -24,7 +24,6 @@ import eu.tsystems.mms.tic.testframework.utils.AppiumProperties; import eu.tsystems.mms.tic.testframework.utils.TimerUtils; import io.appium.java_client.android.AndroidDriver; -import io.appium.java_client.android.AndroidElement; import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.MobileCapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; @@ -43,7 +42,7 @@ */ public class VanillaAppiumAppTest extends AbstractAppiumTest { - protected AndroidDriver driver = null; + protected AndroidDriver driver = null; @BeforeMethod public void setUp() throws MalformedURLException { @@ -61,7 +60,7 @@ public void setUp() throws MalformedURLException { dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UIAutomator2"); URL url = new URL(AppiumProperties.MOBILE_GRID_URL.asString()); // driver = new IOSDriver<>(new URL(PropertyManager.getProperty("tt.mobile.grid.url")), dc); - driver = new AndroidDriver<>(url, dc); + driver = new AndroidDriver(url, dc); } @Test diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java index e738f55c..10dff111 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java @@ -32,6 +32,7 @@ import eu.tsystems.mms.tic.testframework.utils.WebDriverUtils; import eu.tsystems.mms.tic.testframework.webdrivermanager.AppiumDriverRequest; import io.appium.java_client.AppiumDriver; +import io.appium.java_client.remote.SupportsRotation; import org.openqa.selenium.Rectangle; import org.openqa.selenium.ScreenOrientation; import org.openqa.selenium.WebDriver; @@ -48,12 +49,15 @@ public class TesterraAppiumDriverTest extends AbstractAppiumTest implements WebD @Test public void testT01_startDefaultSession() { + AppiumDriverRequest request = new AppiumDriverRequest(); + request.getMutableCapabilities().setCapability("appiumVersion", "2.2.2"); + final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(request); - final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(); WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class).ifPresent(appiumDriver -> { - appiumDriver.rotate(ScreenOrientation.LANDSCAPE); + ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.LANDSCAPE); }); driver.get("https://the-internet.herokuapp.com/dropdown"); + UITestUtils.takeScreenshots(); } @Test @@ -62,13 +66,13 @@ public void testT02_startMultipleSessions() { final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(); AppiumDriver appiumDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class).get(); - appiumDriver.rotate(ScreenOrientation.LANDSCAPE); + ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.LANDSCAPE); driver.get("https://the-internet.herokuapp.com/dropdown"); final WebDriver driver2 = WEB_DRIVER_MANAGER.getWebDriver("second"); AppiumDriver appiumDriver2 = WEB_DRIVER_MANAGER.unwrapWebDriver(driver2, AppiumDriver.class).get(); - appiumDriver2.rotate(ScreenOrientation.PORTRAIT); + ((SupportsRotation) appiumDriver2).rotate(ScreenOrientation.PORTRAIT); driver2.get("https://the-internet.herokuapp.com/checkboxes"); Assert.assertNotEquals(driver, driver2, "Driver equals"); @@ -80,6 +84,7 @@ public void testT03_startRequestSession() { final String device = "Apple iPhone X"; request.setBrowser(Browsers.mobile_safari); request.setDeviceQuery(String.format("contains(@name, '%s')", device)); + request.getMutableCapabilities().setCapability("appium:appiumVersion", "2.2.2"); final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(request); @@ -107,11 +112,11 @@ public void testT05_takeScreenshot() { driver.get("https://the-internet.herokuapp.com/"); - appiumDriver.rotate(ScreenOrientation.LANDSCAPE); + ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.LANDSCAPE); final Screenshot screenshotLandScape = UITestUtils.takeScreenshot(driver, true); Assert.assertNotNull(screenshotLandScape, "Screenshot created."); - appiumDriver.rotate(ScreenOrientation.PORTRAIT); + ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.PORTRAIT); final Screenshot screenshotPortrait = UITestUtils.takeScreenshot(driver, true); Assert.assertNotNull(screenshotPortrait, "Screenshot created."); } diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java index 27b54b1d..8e7ec246 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/VanillaAppiumDriverTest.java @@ -28,8 +28,8 @@ import eu.tsystems.mms.tic.testframework.report.Report; import eu.tsystems.mms.tic.testframework.report.TesterraListener; import eu.tsystems.mms.tic.testframework.utils.AppiumProperties; +import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.ios.IOSDriver; -import io.appium.java_client.ios.IOSElement; import io.appium.java_client.remote.MobileBrowserType; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; @@ -47,6 +47,7 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; +import java.time.Duration; /** * Date: 24.06.2020 @@ -56,30 +57,33 @@ */ public class VanillaAppiumDriverTest extends AbstractAppiumTest implements Loggable, PropertyManagerProvider { - protected IOSDriver driver = null; -// protected AndroidDriver driver = null; +// protected IOSDriver driver = null; + protected AndroidDriver driver = null; @BeforeMethod public void setUp() throws MalformedURLException { final String accessKey = AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString(); Assert.assertNotNull(accessKey, "No access key loaded"); + + DesiredCapabilities dc = new DesiredCapabilities(); - dc.setCapability("testName", "Demo Tests"); - dc.setCapability("accessKey", accessKey); - dc.setCapability("appiumVersion", "1.22.3"); -// dc.setCapability("deviceQuery", "contains(@name, 'Samsung Galaxy S20')"); + dc.setCapability("appium:testName", "Demo Tests"); + dc.setCapability("appium:accessKey", accessKey); +// dc.setCapability("appiumVersion", "1.22.3"); + dc.setCapability("appium:appiumVersion", "2.2.2"); // dc.setCapability("deviceQuery", "contains(@name, 'Google Pixel 6')"); // dc.setCapability("deviceQuery", AppiumProperties.MOBILE_APPIUM_DEVICE_QUERY_ANDROID); - dc.setCapability("deviceQuery", "contains(@name, 'Apple iPhone X (')"); +// dc.setCapability("appium:deviceQuery", "contains(@name, 'Apple iPhone X (')"); + dc.setCapability("appium:deviceQuery", "contains(@name, 'Samsung Galaxy S20')"); // dc.setCapability(MobileCapabilityType.UDID, "..."); - dc.setBrowserName(MobileBrowserType.SAFARI); -// dc.setBrowserName(MobileBrowserType.CHROME); +// dc.setBrowserName(MobileBrowserType.SAFARI); + dc.setBrowserName(MobileBrowserType.CHROME); URL url = new URL(AppiumProperties.MOBILE_GRID_URL.asString()); log().info(dc.toString()); - driver = new IOSDriver<>(url, dc); -// driver = new AndroidDriver<>(url, dc); +// driver = new IOSDriver(url, dc); + driver = new AndroidDriver(url, dc); } @@ -87,7 +91,7 @@ public void setUp() throws MalformedURLException { public void testT01_DoGoogleSearch() { driver.rotate(ScreenOrientation.PORTRAIT); driver.get("https://www.google.com"); - new WebDriverWait(driver, 10).until(driver1 -> { + new WebDriverWait(driver, Duration.ofSeconds(10)).until(driver1 -> { ExpectedCondition q = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@name='q']")); return q; }); diff --git a/build.gradle b/build.gradle index 1976dcdc..94a89677 100644 --- a/build.gradle +++ b/build.gradle @@ -5,10 +5,14 @@ plugins { apply plugin: 'io.codearte.nexus-staging' ext { + // Tested with + appiumJavaClientVersion = '8.5.1' + // Minimum required Testerra version - testerraCompileVersion = '2.0' + testerraCompileVersion = '2.4' // Unit tests use the latest Testerra version - testerraTestVersion = '[2,3-SNAPSHOT)' +// testerraTestVersion = '[2,3-SNAPSHOT)' + testerraTestVersion = '2.4' moduleVersion = '2-SNAPSHOT' if (System.properties.containsKey('moduleVersion')) { moduleVersion = System.getProperty('moduleVersion') From 169548ea752c47203efbacbf347b5f66682a6b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Fri, 15 Mar 2024 15:47:22 +0100 Subject: [PATCH 02/17] Updated Appium tools --- README.md | 22 ++++++++++-------- .../tic/testframework/utils/AppiumUtils.java | 8 +++++++ .../test/driver/TesterraAppiumDriverTest.java | 23 ++++++------------- appium/src/test/resources/test.properties | 2 +- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 275bc4fa..870d7b18 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,12 @@ It will register with Testerra Hooking system and uses the event bus to react on ### Requirements -| Appium connector | Testerra | -|------------------|-------------| -| `>=1.1` | `>=1.3` | -| `2.0 - 2.2` | `2.0 - 2.3` | +| Appium connector | Testerra | Notes | +|------------------|-------------|------------------------------| +| `>=1.1` | `>=1.3` | +| `2.0 - 2.2` | `2.0 - 2.3` | | +| `2.3` | `2.4` | Support of Appium Client 8.x | + ### Usage @@ -41,10 +43,10 @@ Gradle: ```groovy // Version from this module -implementation 'io.testerra:appium:2.2' +implementation 'io.testerra:appium:2.3' // Used Testerra version -implementation 'io.testerra:driver-ui:2.2' -implementation 'io.appium:java-client:7.3.0' +implementation 'io.testerra:driver-ui:2.4' +implementation 'io.appium:java-client:8.5.1' ``` Maven: @@ -54,18 +56,18 @@ Maven: io.testerra appium - 2.2 + 2.3 io.testerra driver-ui - 2.2 + 2.4 io.appium java-client - 7.3.0 + 8.5.1 diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java index 8f88c900..e9e157ca 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java @@ -28,7 +28,9 @@ import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; import io.appium.java_client.AppiumDriver; import io.appium.java_client.remote.SupportsContextSwitching; +import io.appium.java_client.remote.SupportsRotation; import org.openqa.selenium.Platform; +import org.openqa.selenium.ScreenOrientation; import org.openqa.selenium.WebDriver; import java.util.Arrays; @@ -59,6 +61,12 @@ public void launchIOSApp(WebDriver driver, String bundleId) { } } + public void rotate(WebDriver driver, ScreenOrientation screenOrientation) { + WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class).ifPresent(appiumDriver -> { + ((SupportsRotation) appiumDriver).rotate(screenOrientation); + }); + } + /** * Switch the Appium Context if available */ diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java index 10dff111..0b607232 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java @@ -27,12 +27,11 @@ import eu.tsystems.mms.tic.testframework.report.model.context.Screenshot; import eu.tsystems.mms.tic.testframework.report.model.context.SessionContext; import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; +import eu.tsystems.mms.tic.testframework.utils.AppiumUtils; import eu.tsystems.mms.tic.testframework.utils.JSUtils; import eu.tsystems.mms.tic.testframework.utils.UITestUtils; import eu.tsystems.mms.tic.testframework.utils.WebDriverUtils; import eu.tsystems.mms.tic.testframework.webdrivermanager.AppiumDriverRequest; -import io.appium.java_client.AppiumDriver; -import io.appium.java_client.remote.SupportsRotation; import org.openqa.selenium.Rectangle; import org.openqa.selenium.ScreenOrientation; import org.openqa.selenium.WebDriver; @@ -53,9 +52,8 @@ public void testT01_startDefaultSession() { request.getMutableCapabilities().setCapability("appiumVersion", "2.2.2"); final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(request); - WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class).ifPresent(appiumDriver -> { - ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.LANDSCAPE); - }); + new AppiumUtils().rotate(driver, ScreenOrientation.LANDSCAPE); + driver.get("https://the-internet.herokuapp.com/dropdown"); UITestUtils.takeScreenshots(); } @@ -64,16 +62,11 @@ public void testT01_startDefaultSession() { public void testT02_startMultipleSessions() { final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(); - AppiumDriver appiumDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class).get(); - - ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.LANDSCAPE); + new AppiumUtils().rotate(driver, ScreenOrientation.LANDSCAPE); driver.get("https://the-internet.herokuapp.com/dropdown"); final WebDriver driver2 = WEB_DRIVER_MANAGER.getWebDriver("second"); - AppiumDriver appiumDriver2 = WEB_DRIVER_MANAGER.unwrapWebDriver(driver2, AppiumDriver.class).get(); - - ((SupportsRotation) appiumDriver2).rotate(ScreenOrientation.PORTRAIT); - driver2.get("https://the-internet.herokuapp.com/checkboxes"); + new AppiumUtils().rotate(driver2, ScreenOrientation.PORTRAIT); Assert.assertNotEquals(driver, driver2, "Driver equals"); } @@ -108,15 +101,13 @@ public void testT04_startSessionTwice() { public void testT05_takeScreenshot() { final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(); - AppiumDriver appiumDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class).get(); - driver.get("https://the-internet.herokuapp.com/"); - ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.LANDSCAPE); + new AppiumUtils().rotate(driver, ScreenOrientation.LANDSCAPE); final Screenshot screenshotLandScape = UITestUtils.takeScreenshot(driver, true); Assert.assertNotNull(screenshotLandScape, "Screenshot created."); - ((SupportsRotation) appiumDriver).rotate(ScreenOrientation.PORTRAIT); + new AppiumUtils().rotate(driver, ScreenOrientation.PORTRAIT); final Screenshot screenshotPortrait = UITestUtils.takeScreenshot(driver, true); Assert.assertNotNull(screenshotPortrait, "Screenshot created."); } diff --git a/appium/src/test/resources/test.properties b/appium/src/test/resources/test.properties index c95bb1a6..8de485dd 100644 --- a/appium/src/test/resources/test.properties +++ b/appium/src/test/resources/test.properties @@ -6,7 +6,7 @@ tt.baseurl=https://the-internet.herokuapp.com/ #tt.mobile.device.query.ios=@os='ios' and @category='PHONE' tt.mobile.device.query.ios=contains(@name, 'iPhone X') #tt.mobile.device.query.android=@os='android' and @category='PHONE' and @version='10' -tt.mobile.device.query.android=contains(@name, 'Samsung Galaxy A5') +tt.mobile.device.query.android=contains(@name, 'Samsung Galaxy S20') tt.winapp.server.url= From ea1432e7661528a671f080049e75acefd01f3bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Fri, 15 Mar 2024 16:03:57 +0100 Subject: [PATCH 03/17] Updated Appium Seetest module --- appium-seetest/build.gradle | 4 ++-- .../appium/seetest/ioc}/DriverUi_AppiumSeeTest.java | 2 +- .../plugins/appium/seetest/utils/VideoLoader.java | 3 +-- .../seetest/webdriver/SeeTestAppiumDriverFactory.java | 8 +++++++- 4 files changed, 11 insertions(+), 6 deletions(-) rename appium-seetest/src/main/java/{eu/tsystems/mms/tic/testerra/plugins/appium/seetest => io/testerra/plugins/appium/seetest/ioc}/DriverUi_AppiumSeeTest.java (97%) diff --git a/appium-seetest/build.gradle b/appium-seetest/build.gradle index 3273036e..cb765553 100644 --- a/appium-seetest/build.gradle +++ b/appium-seetest/build.gradle @@ -1,6 +1,6 @@ dependencies { compileOnly 'io.testerra:driver-ui:' + testerraCompileVersion - compileOnly 'io.appium:java-client:7.3.0' + compileOnly 'io.appium:java-client:' + appiumJavaClientVersion compileOnly project(':appium') // Rest client @@ -11,7 +11,7 @@ dependencies { testImplementation 'io.testerra:driver-ui-desktop:' + testerraTestVersion testImplementation 'io.testerra:report-ng:' + testerraTestVersion testImplementation project(':appium') - testImplementation 'io.appium:java-client:7.3.0' + testImplementation 'io.appium:java-client:' + appiumJavaClientVersion } test { diff --git a/appium-seetest/src/main/java/eu/tsystems/mms/tic/testerra/plugins/appium/seetest/DriverUi_AppiumSeeTest.java b/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/ioc/DriverUi_AppiumSeeTest.java similarity index 97% rename from appium-seetest/src/main/java/eu/tsystems/mms/tic/testerra/plugins/appium/seetest/DriverUi_AppiumSeeTest.java rename to appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/ioc/DriverUi_AppiumSeeTest.java index cc843c91..03025141 100644 --- a/appium-seetest/src/main/java/eu/tsystems/mms/tic/testerra/plugins/appium/seetest/DriverUi_AppiumSeeTest.java +++ b/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/ioc/DriverUi_AppiumSeeTest.java @@ -19,7 +19,7 @@ * under the License. * */ -package eu.tsystems.mms.tic.testerra.plugins.appium.seetest; +package io.testerra.plugins.appium.seetest.ioc; import com.google.inject.AbstractModule; import com.google.inject.Scopes; diff --git a/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/utils/VideoLoader.java b/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/utils/VideoLoader.java index 60ee8c6c..6f1e3831 100644 --- a/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/utils/VideoLoader.java +++ b/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/utils/VideoLoader.java @@ -28,7 +28,6 @@ import eu.tsystems.mms.tic.testframework.utils.AppiumProperties; import eu.tsystems.mms.tic.testframework.utils.Sequence; import io.testerra.plugins.appium.seetest.request.VideoRequest; -import org.apache.http.HttpStatus; import java.io.File; import java.io.IOException; @@ -81,7 +80,7 @@ private Optional downloadVideo(VideoRequest videoRequest) { .header("Authorization", "Bearer " + AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString()) .build(); HttpResponse httpResponse = client.send(request, HttpResponse.BodyHandlers.ofFile(videoFile.toPath())); - if (httpResponse.statusCode() != HttpStatus.SC_OK) { + if (httpResponse.statusCode() != 200) { log().info("Download status code: {}", httpResponse.statusCode()); log().info("Wait for video is ready for download..."); } else { diff --git a/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/webdriver/SeeTestAppiumDriverFactory.java b/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/webdriver/SeeTestAppiumDriverFactory.java index d90e4f00..22087063 100644 --- a/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/webdriver/SeeTestAppiumDriverFactory.java +++ b/appium-seetest/src/main/java/io/testerra/plugins/appium/seetest/webdriver/SeeTestAppiumDriverFactory.java @@ -5,6 +5,7 @@ import eu.tsystems.mms.tic.testframework.webdriver.WebDriverFactory; import eu.tsystems.mms.tic.testframework.webdrivermanager.AppiumDriverRequest; import eu.tsystems.mms.tic.testframework.webdrivermanager.WebDriverRequest; +import io.appium.java_client.remote.options.BaseOptions; import io.testerra.plugins.appium.seetest.utils.SeeTestProperties; import org.apache.commons.lang3.StringUtils; @@ -19,11 +20,16 @@ public class SeeTestAppiumDriverFactory extends AppiumDriverFactory implements W public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverRequest) { AppiumDriverRequest request = (AppiumDriverRequest) super.prepareWebDriverRequest(webDriverRequest); + BaseOptions options = new BaseOptions(); + final String appiumServer = SeeTestProperties.SEETEST_APPIUM_VERSION.asString(); if (StringUtils.isNotBlank(appiumServer)) { - request.getDesiredCapabilities().setCapability("appiumVersion", appiumServer); + options.setCapability("appiumVersion", appiumServer); +// request.getDesiredCapabilities().setCapability("appiumVersion", appiumServer); } + request.setCapabilities(request.getCapabilities().merge(options)); + return request; } From 19cf73319d98fdb77c754ef8f22fe22f29b8bcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Fri, 15 Mar 2024 16:35:41 +0100 Subject: [PATCH 04/17] Updated Appium core module --- .../testframework/mobile/driver/AppiumDriverFactory.java | 2 +- .../webdrivermanager/AppiumDriverRequest.java | 9 ++++++--- .../mobile/test/apps/TesterraMobileAppTest.java | 9 +++++---- appium/src/test/resources/test.properties | 5 +++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java index 712ad6f5..38dd3103 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java @@ -73,7 +73,7 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques finalRequest = new AppiumDriverRequest(); finalRequest.setSessionKey(webDriverRequest.getSessionKey()); finalRequest.setBrowser(webDriverRequest.getBrowser()); - finalRequest.setBrowserVersion(webDriverRequest.getBrowserVersion()); +// finalRequest.setBrowserVersion(webDriverRequest.getBrowserVersion()); } MutableCapabilities requestCapabilities = finalRequest.getMutableCapabilities(); diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java index 96f6196f..01d55e6d 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java @@ -37,9 +37,12 @@ public class AppiumDriverRequest extends SeleniumWebDriverRequest { public static final String CAPABILITY_NAME_TEST_NAME = "testName"; public AppiumDriverRequest() { - super(); - setAccessKey(AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString()); -// this.setBrowser(Browsers.mobile); + this.setAccessKey(AppiumProperties.MOBILE_GRID_ACCESS_KEY.asString()); + + if (StringUtils.isBlank(this.getBrowser())) { + this.setBrowser(Browsers.mobile); + } + } @Override diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java index f7c84c42..2fb8e5d1 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/apps/TesterraMobileAppTest.java @@ -47,12 +47,13 @@ public class TesterraMobileAppTest extends AbstractAppiumTest { @Test public void testT01AndroidApp() { AppiumDriverRequest request = new AppiumDriverRequest(); + request.setBrowser("mobile"); request.setDeviceQuery("contains(@name, 'Galaxy S20')"); - request.getDesiredCapabilities().setCapability("appiumVersion", "2.2.2"); + request.getMutableCapabilities().setCapability("appiumVersion", "2.2.2"); - request.getDesiredCapabilities().setCapability(MobileCapabilityType.APP, "cloud:eu.tsystems.mms.tic.mdc.app.android/.HomeActivity"); - request.getDesiredCapabilities().setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "eu.tsystems.mms.tic.mdc.app.android"); - request.getDesiredCapabilities().setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".HomeActivity"); + request.getMutableCapabilities().setCapability(MobileCapabilityType.APP, "cloud:eu.tsystems.mms.tic.mdc.app.android/.HomeActivity"); + request.getMutableCapabilities().setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "eu.tsystems.mms.tic.mdc.app.android"); + request.getMutableCapabilities().setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".HomeActivity"); request.setAppiumEngine("UiAutomator2"); WebDriver webDriver = WEB_DRIVER_MANAGER.getWebDriver(request); diff --git a/appium/src/test/resources/test.properties b/appium/src/test/resources/test.properties index 8de485dd..d7b11907 100644 --- a/appium/src/test/resources/test.properties +++ b/appium/src/test/resources/test.properties @@ -1,8 +1,9 @@ #tt.browser=mobile_chrome #tt.browser=mobile_safari -tt.watchdog.enable=false -tt.baseurl=https://the-internet.herokuapp.com/ + +#tt.baseurl=https://the-internet.herokuapp.com/ + #tt.mobile.device.query.ios=@os='ios' and @category='PHONE' tt.mobile.device.query.ios=contains(@name, 'iPhone X') #tt.mobile.device.query.android=@os='android' and @category='PHONE' and @version='10' From 7a0e5cf86b996f17138cf43150f42d86b47909eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 13:26:40 +0200 Subject: [PATCH 05/17] Update capability handling with 'appium:' prefix --- .../appium/AppiumCapabilityHelper.java | 15 +++++++++++++++ .../mobile/driver/MobileOsChecker.java | 19 ++++++++++--------- .../webdrivermanager/AppiumDriverRequest.java | 11 ++++++----- .../test/driver/TesterraAppiumDriverTest.java | 2 +- appium/src/test/resources/test.properties | 2 +- 5 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java new file mode 100644 index 00000000..23660f18 --- /dev/null +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java @@ -0,0 +1,15 @@ +package eu.tsystems.mms.tic.testframework.appium; + +/** + * Created on 2024-06-11 + * + * The Appium client convert all Appium specific capabilities and adds the prefix 'appium:'. + * This should help to read a capability. + */ +public interface AppiumCapabilityHelper { + + default String getAppiumCap(final String capabilityName) { + return "appium:" + capabilityName; + } + +} diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java index 09e92bbb..e4071097 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java @@ -20,6 +20,7 @@ */ package eu.tsystems.mms.tic.testframework.mobile.driver; +import eu.tsystems.mms.tic.testframework.appium.AppiumCapabilityHelper; import eu.tsystems.mms.tic.testframework.appium.Browsers; import eu.tsystems.mms.tic.testframework.common.Testerra; import eu.tsystems.mms.tic.testframework.report.model.context.SessionContext; @@ -39,24 +40,24 @@ * * @author mgn */ -public class MobileOsChecker { +public class MobileOsChecker implements AppiumCapabilityHelper { public Platform getPlatform(WebDriverRequest webDriverRequest) { Capabilities capabilities = webDriverRequest.getCapabilities(); if (webDriverRequest.getBrowser().equals(Browsers.mobile_chrome) - || "Espresso".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) - || "UiAutomator2".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) - || "UiAutomator".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) - || capabilities.getCapability(AndroidMobileCapabilityType.APP_PACKAGE) != null - || capabilities.getCapability(AndroidMobileCapabilityType.APP_ACTIVITY) != null + || "Espresso".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || "UiAutomator2".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || "UiAutomator".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || capabilities.getCapability(getAppiumCap(AndroidMobileCapabilityType.APP_PACKAGE)) != null + || capabilities.getCapability(getAppiumCap(AndroidMobileCapabilityType.APP_ACTIVITY)) != null ) { return Platform.ANDROID; } if (webDriverRequest.getBrowser().equals(Browsers.mobile_safari) - || "XCUITest".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) - || "UIAutomation".equals(capabilities.getCapability(MobileCapabilityType.AUTOMATION_NAME)) - || capabilities.getCapability(IOSMobileCapabilityType.BUNDLE_ID) != null + || "XCUITest".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || "UIAutomation".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || capabilities.getCapability(getAppiumCap(IOSMobileCapabilityType.BUNDLE_ID)) != null ) { return Platform.IOS; } diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java index 01d55e6d..824f087f 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/webdrivermanager/AppiumDriverRequest.java @@ -21,6 +21,7 @@ package eu.tsystems.mms.tic.testframework.webdrivermanager; +import eu.tsystems.mms.tic.testframework.appium.AppiumCapabilityHelper; import eu.tsystems.mms.tic.testframework.appium.Browsers; import eu.tsystems.mms.tic.testframework.utils.AppiumProperties; import io.appium.java_client.remote.MobileCapabilityType; @@ -30,7 +31,7 @@ import java.net.URL; import java.util.Optional; -public class AppiumDriverRequest extends SeleniumWebDriverRequest { +public class AppiumDriverRequest extends SeleniumWebDriverRequest implements AppiumCapabilityHelper { public static final String DEVICE_QUERY = "deviceQuery"; public static final String ACCESS_KEY = "accessKey"; @@ -72,7 +73,7 @@ public void setAppiumEngine(String engine) { } public String getAppiumEngine() { - return this.getMutableCapabilities().getCapability(MobileCapabilityType.AUTOMATION_NAME).toString(); + return this.getMutableCapabilities().getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME)).toString(); } public void setDeviceName(String deviceName) { @@ -80,7 +81,7 @@ public void setDeviceName(String deviceName) { } public String getDeviceName() { - return this.getMutableCapabilities().getCapability(MobileCapabilityType.DEVICE_NAME).toString(); + return this.getMutableCapabilities().getCapability(getAppiumCap(MobileCapabilityType.DEVICE_NAME)).toString(); } public void setPlatformVersion(String platformVersion) { @@ -88,7 +89,7 @@ public void setPlatformVersion(String platformVersion) { } public String getPlatformVersion() { - return this.getMutableCapabilities().getCapability(MobileCapabilityType.PLATFORM_VERSION).toString(); + return this.getMutableCapabilities().getCapability(getAppiumCap(MobileCapabilityType.PLATFORM_VERSION)).toString(); } public void setDeviceId(String id) { @@ -96,6 +97,6 @@ public void setDeviceId(String id) { } public String getDeviceId() { - return this.getMutableCapabilities().getCapability(MobileCapabilityType.UDID).toString(); + return this.getMutableCapabilities().getCapability(getAppiumCap(MobileCapabilityType.UDID)).toString(); } } diff --git a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java index 0b607232..5cf89d9b 100644 --- a/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java +++ b/appium/src/test/java/eu/tsystems/mms/tic/testframework/mobile/test/driver/TesterraAppiumDriverTest.java @@ -77,7 +77,7 @@ public void testT03_startRequestSession() { final String device = "Apple iPhone X"; request.setBrowser(Browsers.mobile_safari); request.setDeviceQuery(String.format("contains(@name, '%s')", device)); - request.getMutableCapabilities().setCapability("appium:appiumVersion", "2.2.2"); + request.getMutableCapabilities().setCapability("appiumVersion", "2.2.2"); final WebDriver driver = WEB_DRIVER_MANAGER.getWebDriver(request); diff --git a/appium/src/test/resources/test.properties b/appium/src/test/resources/test.properties index d7b11907..4a2af29b 100644 --- a/appium/src/test/resources/test.properties +++ b/appium/src/test/resources/test.properties @@ -1,5 +1,5 @@ -#tt.browser=mobile_chrome +tt.browser=mobile_chrome #tt.browser=mobile_safari #tt.baseurl=https://the-internet.herokuapp.com/ From 6b727ac9b61376f0e05c7cc8de4e1163a7b17e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 13:56:55 +0200 Subject: [PATCH 06/17] Fix NPE getting empty cap --- .../guielement/CreateAppiumGuiElementAction.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java index 935e39ae..e179fd31 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/CreateAppiumGuiElementAction.java @@ -20,6 +20,7 @@ */ package eu.tsystems.mms.tic.testframework.mobile.guielement; +import eu.tsystems.mms.tic.testframework.appium.AppiumCapabilityHelper; import eu.tsystems.mms.tic.testframework.common.Testerra; import eu.tsystems.mms.tic.testframework.internal.NameableChild; import eu.tsystems.mms.tic.testframework.logging.Loggable; @@ -47,7 +48,10 @@ * * @author mgn */ -public class CreateAppiumGuiElementAction extends AbstractFieldAction implements UiElementFinderFactoryProvider, Loggable { +public class CreateAppiumGuiElementAction extends AbstractFieldAction implements + UiElementFinderFactoryProvider, + Loggable, + AppiumCapabilityHelper { public CreateAppiumGuiElementAction(Field field, AbstractPage declaringPage) { super(field, declaringPage); @@ -100,9 +104,9 @@ private String getAutomationEngine(WebDriver driver, Platform platform) { IWebDriverManager instance = Testerra.getInjector().getInstance(IWebDriverManager.class); Optional optional = instance.getSessionContext(driver).map(SessionContext::getWebDriverRequest); if (optional.isPresent()) { - String automationEngine = optional.get().getCapabilities().getCapability(MobileCapabilityType.AUTOMATION_NAME).toString(); - if (StringUtils.isNotBlank(automationEngine)) { - return automationEngine; + Object automationEngine = optional.get().getCapabilities().getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME)); + if (automationEngine != null && StringUtils.isNotBlank(automationEngine.toString())) { + return automationEngine.toString(); } else { // Use default values for automation engine switch (platform) { From 3c1f252a7423ebfed2fb9e7f64d858fd31ad1970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 14:53:02 +0200 Subject: [PATCH 07/17] Activated AppiumPageFactory as default --- .../eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java index 4735a69a..1dc0e865 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java @@ -26,6 +26,8 @@ import com.google.inject.multibindings.Multibinder; import eu.tsystems.mms.tic.testframework.appium.WinAppDriverFactory; import eu.tsystems.mms.tic.testframework.mobile.driver.AppiumDriverFactory; +import eu.tsystems.mms.tic.testframework.mobile.pageobject.AppiumPageFactory; +import eu.tsystems.mms.tic.testframework.pageobjects.internal.PageFactory; import eu.tsystems.mms.tic.testframework.utils.AppiumExecutionUtils; import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils; import eu.tsystems.mms.tic.testframework.webdriver.WebDriverFactory; @@ -46,5 +48,6 @@ protected void configure() { webDriverFactoryBinder.addBinding().to(AppiumDriverFactory.class).in(Scopes.SINGLETON); webDriverFactoryBinder.addBinding().to(WinAppDriverFactory.class).in(Scopes.SINGLETON); bind(ExecutionUtils.class).to(AppiumExecutionUtils.class).in(Scopes.SINGLETON); + bind(PageFactory.class).to(AppiumPageFactory.class).in(Scopes.SINGLETON); // Support for device specific pages } } From 759104ed0c79ad02bb7fa14ba9b5c803c59f49eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 15:32:55 +0200 Subject: [PATCH 08/17] Added AppiumUiElementHighlighter to prevent highlighting at app tests --- .../appium/AppiumCapabilityHelper.java | 20 ++++++++ .../testframework/ioc/DriverUi_Appium.java | 7 ++- .../AppiumUiElementHighlighter.java | 51 +++++++++++++++++++ .../mobile/pageobject/AppiumClassFinder.java | 20 ++++++++ .../mobile/pageobject/AppiumPageFactory.java | 20 ++++++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java index 23660f18..ed3d9955 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/appium/AppiumCapabilityHelper.java @@ -1,3 +1,23 @@ +/* + * Testerra + * + * (C) 2024, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG + * + * Deutsche Telekom AG and all other contributors / + * copyright owners license this file to you 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 eu.tsystems.mms.tic.testframework.appium; /** diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java index 1dc0e865..780fca9b 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/ioc/DriverUi_Appium.java @@ -26,7 +26,9 @@ import com.google.inject.multibindings.Multibinder; import eu.tsystems.mms.tic.testframework.appium.WinAppDriverFactory; import eu.tsystems.mms.tic.testframework.mobile.driver.AppiumDriverFactory; +import eu.tsystems.mms.tic.testframework.mobile.guielement.AppiumUiElementHighlighter; import eu.tsystems.mms.tic.testframework.mobile.pageobject.AppiumPageFactory; +import eu.tsystems.mms.tic.testframework.pageobjects.UiElementHighlighter; import eu.tsystems.mms.tic.testframework.pageobjects.internal.PageFactory; import eu.tsystems.mms.tic.testframework.utils.AppiumExecutionUtils; import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils; @@ -48,6 +50,9 @@ protected void configure() { webDriverFactoryBinder.addBinding().to(AppiumDriverFactory.class).in(Scopes.SINGLETON); webDriverFactoryBinder.addBinding().to(WinAppDriverFactory.class).in(Scopes.SINGLETON); bind(ExecutionUtils.class).to(AppiumExecutionUtils.class).in(Scopes.SINGLETON); - bind(PageFactory.class).to(AppiumPageFactory.class).in(Scopes.SINGLETON); // Support for device specific pages + // Support for device specific pages + bind(PageFactory.class).to(AppiumPageFactory.class).in(Scopes.SINGLETON); + // Prevent error while trying element highlighting in apps + bind(UiElementHighlighter.class).to(AppiumUiElementHighlighter.class).in(Scopes.SINGLETON); } } diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java new file mode 100644 index 00000000..1aadac6b --- /dev/null +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java @@ -0,0 +1,51 @@ +/* + * Testerra + * + * (C) 2024, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG + * + * Deutsche Telekom AG and all other contributors / + * copyright owners license this file to you 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 eu.tsystems.mms.tic.testframework.mobile.guielement; + +import eu.tsystems.mms.tic.testframework.common.Testerra; +import eu.tsystems.mms.tic.testframework.pageobjects.DefaultUiElementHighlighter; +import eu.tsystems.mms.tic.testframework.report.utils.IExecutionContextController; +import org.apache.commons.lang3.StringUtils; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import java.awt.Color; + +/** + * Created on 2024-06-11 + * + * @author mgn + */ +public class AppiumUiElementHighlighter extends DefaultUiElementHighlighter { + + @Override + public void highlight(WebDriver driver, WebElement webElement, Color color) { + IExecutionContextController instance = Testerra.getInjector().getInstance(IExecutionContextController.class); + instance.getCurrentSessionContext().ifPresent(sessionContext -> { + // Highlighting is only working in browsers but not in apps + String browser = sessionContext.getWebDriverRequest().getBrowser(); + if (StringUtils.isNotEmpty(browser)) { + super.highlight(driver, webElement, color); + } + }); + } + +} diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java index 3814e37a..5964a73e 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumClassFinder.java @@ -1,3 +1,23 @@ +/* + * Testerra + * + * (C) 2023, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG + * + * Deutsche Telekom AG and all other contributors / + * copyright owners license this file to you 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 eu.tsystems.mms.tic.testframework.mobile.pageobject; import eu.tsystems.mms.tic.testframework.logging.Loggable; diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java index 706f8b0d..1c6e0fa2 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/pageobject/AppiumPageFactory.java @@ -1,3 +1,23 @@ +/* + * Testerra + * + * (C) 2023, Martin Großmann, Deutsche Telekom MMS GmbH, Deutsche Telekom AG + * + * Deutsche Telekom AG and all other contributors / + * copyright owners license this file to you 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 eu.tsystems.mms.tic.testframework.mobile.pageobject; import eu.tsystems.mms.tic.testframework.enums.CheckRule; From 43e26d6bb36319a32e48735bab2ec38af79c8f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 16:08:12 +0200 Subject: [PATCH 09/17] Fix AppiumUiElementHighlighter and added app check --- .../mobile/driver/MobileOsChecker.java | 36 +++++++++++-------- .../AppiumUiElementHighlighter.java | 8 +++-- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java index e4071097..d1a90d2e 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/MobileOsChecker.java @@ -43,25 +43,12 @@ public class MobileOsChecker implements AppiumCapabilityHelper { public Platform getPlatform(WebDriverRequest webDriverRequest) { - Capabilities capabilities = webDriverRequest.getCapabilities(); - - if (webDriverRequest.getBrowser().equals(Browsers.mobile_chrome) - || "Espresso".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) - || "UiAutomator2".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) - || "UiAutomator".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) - || capabilities.getCapability(getAppiumCap(AndroidMobileCapabilityType.APP_PACKAGE)) != null - || capabilities.getCapability(getAppiumCap(AndroidMobileCapabilityType.APP_ACTIVITY)) != null - ) { + if (Browsers.mobile_chrome.equals(webDriverRequest.getBrowser()) || isAppTest(webDriverRequest, Platform.ANDROID)) { return Platform.ANDROID; } - if (webDriverRequest.getBrowser().equals(Browsers.mobile_safari) - || "XCUITest".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) - || "UIAutomation".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) - || capabilities.getCapability(getAppiumCap(IOSMobileCapabilityType.BUNDLE_ID)) != null - ) { + if (Browsers.mobile_safari.equals(webDriverRequest.getBrowser()) || isAppTest(webDriverRequest, Platform.IOS)) { return Platform.IOS; } - return Platform.ANY; } @@ -75,4 +62,23 @@ public Platform getPlatform(WebDriver driver) { } } + // Returns true if WebDriverRequest contains typical app capabilities + public boolean isAppTest(WebDriverRequest webDriverRequest, Platform platform) { + Capabilities capabilities = webDriverRequest.getCapabilities(); + switch (platform) { + case ANDROID: + return "Espresso".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || "UiAutomator2".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || "UiAutomator".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || capabilities.getCapability(getAppiumCap(AndroidMobileCapabilityType.APP_PACKAGE)) != null + || capabilities.getCapability(getAppiumCap(AndroidMobileCapabilityType.APP_ACTIVITY)) != null; + case IOS: + return "XCUITest".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || "UIAutomation".equals(capabilities.getCapability(getAppiumCap(MobileCapabilityType.AUTOMATION_NAME))) + || capabilities.getCapability(getAppiumCap(IOSMobileCapabilityType.BUNDLE_ID)) != null; + default: + return false; + } + } + } diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java index 1aadac6b..eb2481b1 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumUiElementHighlighter.java @@ -21,9 +21,10 @@ package eu.tsystems.mms.tic.testframework.mobile.guielement; import eu.tsystems.mms.tic.testframework.common.Testerra; +import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker; import eu.tsystems.mms.tic.testframework.pageobjects.DefaultUiElementHighlighter; import eu.tsystems.mms.tic.testframework.report.utils.IExecutionContextController; -import org.apache.commons.lang3.StringUtils; +import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -41,8 +42,9 @@ public void highlight(WebDriver driver, WebElement webElement, Color color) { IExecutionContextController instance = Testerra.getInjector().getInstance(IExecutionContextController.class); instance.getCurrentSessionContext().ifPresent(sessionContext -> { // Highlighting is only working in browsers but not in apps - String browser = sessionContext.getWebDriverRequest().getBrowser(); - if (StringUtils.isNotEmpty(browser)) { + MobileOsChecker mobileOsChecker = new MobileOsChecker(); + Platform platform = mobileOsChecker.getPlatform(driver); + if (!mobileOsChecker.isAppTest(sessionContext.getWebDriverRequest(), platform)) { super.highlight(driver, webElement, color); } }); From d6152f9af9b53c20de20235f86debbff14c5221f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 16:47:57 +0200 Subject: [PATCH 10/17] Updated README.md --- README.md | 12 ++++++++---- build.gradle | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 870d7b18..6ddcb585 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,16 @@ It will register with Testerra Hooking system and uses the event bus to react on ### Requirements -| Appium connector | Testerra | Notes | -|------------------|-------------|------------------------------| +| Appium connector | Testerra | Notes | +|------------------|-------------|--------------------------------------| | `>=1.1` | `>=1.3` | -| `2.0 - 2.2` | `2.0 - 2.3` | | -| `2.3` | `2.4` | Support of Appium Client 8.x | +| `2.0 - 2.2` | `2.0 - 2.3` | | +| `2.3` | `2.4` | Support of Appium Client 8.5.1/8.6.0 | +| `2.4` | `>=2.6` | (not released) | +Important notes: +* Please check the matrix at https://github.com/appium/java-client?tab=readme-ov-file#compatibility-matrix if Appium Java Client matches to Selenium version +* Please check the Testerra releaes at https://github.com/telekom/testerra/releases which Selenium vesion is used ### Usage diff --git a/build.gradle b/build.gradle index 94a89677..3f460977 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,8 @@ apply plugin: 'io.codearte.nexus-staging' ext { // Tested with - appiumJavaClientVersion = '8.5.1' +// appiumJavaClientVersion = '9.0.0' + appiumJavaClientVersion = '8.6.0' // Minimum required Testerra version testerraCompileVersion = '2.4' From c6616812b0477d558b895bd97e8aab423c93855c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Tue, 11 Jun 2024 16:48:51 +0200 Subject: [PATCH 11/17] Updated README.md --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6ddcb585..bce4c14b 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Gradle: implementation 'io.testerra:appium:2.3' // Used Testerra version implementation 'io.testerra:driver-ui:2.4' -implementation 'io.appium:java-client:8.5.1' +implementation 'io.appium:java-client:8.6.0' ``` Maven: @@ -71,7 +71,7 @@ Maven: io.appium java-client - 8.5.1 + 8.6.0 @@ -92,15 +92,15 @@ This module is deployed and published to Maven Central. All JAR files are signed The following properties have to be set via command line or ``~/.gradle/gradle.properties`` -| Property | Description | -| ----------------------------- | --------------------------------------------------- | -| `moduleVersion` | Version of deployed module, default is `1-SNAPSHOT` | -| `deployUrl` | Maven repository URL | -| `deployUsername` | Maven repository username | -| `deployPassword` | Maven repository password | -| `signing.keyId` | GPG private key ID (short form) | -| `signing.password` | GPG private key password | -| `signing.secretKeyRingFile` | Path to GPG private key | +| Property | Description | +|-----------------------------|-----------------------------------------------------| +| `moduleVersion` | Version of deployed module, default is `1-SNAPSHOT` | +| `deployUrl` | Maven repository URL | +| `deployUsername` | Maven repository username | +| `deployPassword` | Maven repository password | +| `signing.keyId` | GPG private key ID (short form) | +| `signing.password` | GPG private key password | +| `signing.secretKeyRingFile` | Path to GPG private key | If all properties are set, call the following to build, deploy and release this module: ```shell From 40a003b6f359ea98eddaddcdfc4bc3938017de97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Wed, 12 Jun 2024 07:52:51 +0200 Subject: [PATCH 12/17] Cleanup --- .../mobile/driver/AppiumDriverFactory.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java index 38dd3103..1ade3db5 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/driver/AppiumDriverFactory.java @@ -73,7 +73,6 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques finalRequest = new AppiumDriverRequest(); finalRequest.setSessionKey(webDriverRequest.getSessionKey()); finalRequest.setBrowser(webDriverRequest.getBrowser()); -// finalRequest.setBrowserVersion(webDriverRequest.getBrowserVersion()); } MutableCapabilities requestCapabilities = finalRequest.getMutableCapabilities(); @@ -107,7 +106,7 @@ public WebDriverRequest prepareWebDriverRequest(WebDriverRequest webDriverReques log().info("No mobile browser requested."); } - // Any additional defined desired capabilities are merged into browser options + // Any additional defined desired capabilities are merged into base options baseOptions = baseOptions.merge(finalRequest.getDesiredCapabilities()); baseOptions = baseOptions.merge(finalRequest.getMutableCapabilities()); finalRequest.setCapabilities(baseOptions); @@ -132,12 +131,6 @@ private WebDriver startNewAppiumSession(WebDriverRequest webDriverRequest, Sessi AppiumDriverRequest appiumDriverRequest = (AppiumDriverRequest) webDriverRequest; Capabilities requestCapabilities = appiumDriverRequest.getCapabilities(); URL appiumUrl = appiumDriverRequest.getServerUrl().get(); -// DesiredCapabilities finalCapabilities = new DesiredCapabilities(requestCapabilities); - -// IExecutionContextController executionContextController = Testerra.getInjector().getInstance(IExecutionContextController.class); -// DefaultCapabilityUtils utils = new DefaultCapabilityUtils(); - -// utils.putIfAbsent(requestCapabilities, AppiumDriverRequest.CAPABILITY_NAME_TEST_NAME, executionContextController.getExecutionContext().getRunConfig().getReportName()); AppiumDriver appiumDriver = null; Platform mobilePlatform = new MobileOsChecker().getPlatform(webDriverRequest); @@ -156,7 +149,6 @@ private WebDriver startNewAppiumSession(WebDriverRequest webDriverRequest, Sessi sessionContext.setActualBrowserName(appiumDeviceQuery.getBrowserName()); } else { throw new RuntimeException("Cannot create new Appium session - ambiguous capabilities found:\n " + requestCapabilities.toString()); -// throw new RuntimeException("Mobile Browser not supported: " + webDriverRequest.getBrowser()); } return appiumDriver; } From 05e4b8c2e1c7a2feadc81b9bbe2464c45bb2d6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Wed, 12 Jun 2024 11:00:48 +0200 Subject: [PATCH 13/17] Added long press gesture as context click --- .../AppiumGuiElementCoreAdapter.java | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java index 266f61e6..2e039ea1 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java @@ -31,22 +31,18 @@ import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils; import io.appium.java_client.AppiumDriver; -import io.appium.java_client.PerformsTouchActions; -import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.LongPressOptions; -import io.appium.java_client.touch.TapOptions; -import io.appium.java_client.touch.WaitOptions; -import io.appium.java_client.touch.offset.ElementOption; -import io.appium.java_client.touch.offset.PointOption; import org.apache.commons.lang3.NotImplementedException; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.Point; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Pause; import org.openqa.selenium.interactions.PointerInput; +import org.openqa.selenium.interactions.Sequence; import java.time.Duration; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; -import java.util.function.Supplier; /** * Implements {@link GuiElementCore} to fullfill Testerra {@link GuiElement} functionality. @@ -78,24 +74,32 @@ protected void switchToFrame(WebDriver webDriver, WebElement webElement) { @Override public void hover() { - // Caused by: org.openqa.selenium.WebDriverException: Not Implemented (Method 'mouseMoveTo' is not implemented) - throw new MobileActionNotSupportedException("hover() is not supported on mobile element.s"); + throw new MobileActionNotSupportedException("hover() is not supported on mobile elements."); } - // TODO: Migrate to W3C actions -// @Override -// public void contextClick() { -// this.findWebElement(webElement -> { -// final ElementOption elementOption = new ElementOption().withElement(webElement); -// // new -//// PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); -// final TouchAction action = new TouchAction(appiumDriver); -// -// action.longPress(new LongPressOptions().withElement(elementOption)); -// action.perform(); -// }); -// } + @Override + public void contextClick() { + this.findWebElement(webElement -> { + Point sourceLocation = webElement.getLocation(); + Dimension sourceSize = webElement.getSize(); + int centerX = sourceLocation.getX() + sourceSize.getWidth() / 2; + int centerY = sourceLocation.getY() + sourceSize.getHeight() / 2; + + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence tap = new Sequence(finger, 1); + tap.addAction(finger.createPointerMove(Duration.ofMillis(0), PointerInput.Origin.viewport(), centerX, centerY)); + tap.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + + // Default in iOS: 500ms + // https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_uikit_gestures/handling_long-press_gestures + // Default in Android: 1_000ms + // https://developer.android.com/develop/ui/views/touch-and-input/input-events + tap.addAction(new Pause(finger, Duration.ofMillis(1_000))); + tap.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + this.appiumDriver.perform(List.of(tap)); + }); + } // TODO: Migrate to W3C actions // @Override From 539c777f2bcbcf58ef64f25a2ee519ef3870e4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Wed, 12 Jun 2024 14:32:09 +0200 Subject: [PATCH 14/17] Added draft for swipe --- .../AppiumGuiElementCoreAdapter.java | 6 +-- .../tic/testframework/utils/AppiumUtils.java | 40 ++++++++++++++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java index 2e039ea1..bf209095 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java @@ -29,6 +29,7 @@ import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementCore; import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementData; import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; +import eu.tsystems.mms.tic.testframework.utils.AppiumUtils; import eu.tsystems.mms.tic.testframework.utils.ExecutionUtils; import io.appium.java_client.AppiumDriver; import org.apache.commons.lang3.NotImplementedException; @@ -113,11 +114,9 @@ public void contextClick() { // }); // } - // TODO: Migrate to W3C actions @Override public void swipe(int offsetX, int offsetY) { - throw new NotImplementedException("Implement me with W3C actions"); -// this.findWebElement(webElement -> { + new AppiumUtils().swipe(this.guiElementData.getGuiElement(), new Point(offsetX, offsetY)); // TouchAction touchAction = new TouchAction(appiumDriver); // // final TapOptions tapOption = new TapOptions().withElement(new ElementOption().withElement(webElement)); @@ -127,7 +126,6 @@ public void swipe(int offsetX, int offsetY) { // touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); // touchAction.release(); // touchAction.perform(); -// }); } @Override diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java index e9e157ca..9222bef6 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java @@ -25,15 +25,22 @@ import eu.tsystems.mms.tic.testframework.appium.AppiumContext; import eu.tsystems.mms.tic.testframework.logging.Loggable; import eu.tsystems.mms.tic.testframework.mobile.driver.MobileOsChecker; +import eu.tsystems.mms.tic.testframework.pageobjects.UiElement; import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider; import io.appium.java_client.AppiumDriver; import io.appium.java_client.remote.SupportsContextSwitching; import io.appium.java_client.remote.SupportsRotation; +import org.openqa.selenium.Dimension; import org.openqa.selenium.Platform; +import org.openqa.selenium.Point; import org.openqa.selenium.ScreenOrientation; import org.openqa.selenium.WebDriver; +import org.openqa.selenium.interactions.PointerInput; +import org.openqa.selenium.interactions.Sequence; +import java.time.Duration; import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -67,16 +74,34 @@ public void rotate(WebDriver driver, ScreenOrientation screenOrientation) { }); } + public void swipe(UiElement uiElement, Point offset) { + AppiumDriver appiumDriver = this.getAppiumDriver(uiElement.getWebDriver()); + uiElement.findWebElement(webElement -> { + Point sourceLocation = webElement.getLocation(); + Dimension sourceSize = webElement.getSize(); + int centerX = sourceLocation.getX() + sourceSize.getWidth() / 2; + int centerY = sourceLocation.getY() + sourceSize.getHeight() / 2; + int endX = centerX + offset.getX(); + int endY = centerY + offset.getY(); + + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + org.openqa.selenium.interactions.Sequence swipe = new Sequence(finger, 0); + + swipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), centerX, centerY)); + swipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); + swipe.addAction(finger.createPointerMove(Duration.ofMillis(600), PointerInput.Origin.viewport(), endX, endY)); + swipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); + appiumDriver.perform(List.of(swipe)); + }); + } + /** * Switch the Appium Context if available */ public void switchContext(WebDriver driver, AppiumContext desiredContext) { - Optional appiumDriver = WEB_DRIVER_MANAGER.unwrapWebDriver(driver, AppiumDriver.class); - if (appiumDriver.isEmpty()) { - throw new RuntimeException("Current Webdriver is not an Appium driver."); - } + AppiumDriver appiumDriver = this.getAppiumDriver(driver); - SupportsContextSwitching contextSwitchingDriver = (SupportsContextSwitching) appiumDriver.get(); + SupportsContextSwitching contextSwitchingDriver = (SupportsContextSwitching) appiumDriver; String currentContext = contextSwitchingDriver.getContext(); AppiumContext parsedInitialContext = AppiumContext.parse(currentContext); @@ -102,4 +127,9 @@ public void switchContext(WebDriver driver, AppiumContext desiredContext) { } + public AppiumDriver getAppiumDriver(WebDriver webDriver) { + return WEB_DRIVER_MANAGER.unwrapWebDriver(webDriver, AppiumDriver.class) + .orElseThrow(() -> new RuntimeException("Current Webdriver is not an Appium driver.")); + } + } From bf906ddd34663de2631a4b7009d931f00e100762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Thu, 20 Jun 2024 10:53:18 +0200 Subject: [PATCH 15/17] Added final implementation of swipe --- .../AppiumGuiElementCoreAdapter.java | 9 -- .../tic/testframework/utils/AppiumUtils.java | 101 ++++++++++++++++-- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java index bf209095..87dc6cf2 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java @@ -117,15 +117,6 @@ public void contextClick() { @Override public void swipe(int offsetX, int offsetY) { new AppiumUtils().swipe(this.guiElementData.getGuiElement(), new Point(offsetX, offsetY)); -// TouchAction touchAction = new TouchAction(appiumDriver); -// -// final TapOptions tapOption = new TapOptions().withElement(new ElementOption().withElement(webElement)); -// touchAction.tap(tapOption); -// touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); -// touchAction.moveTo(new PointOption().withCoordinates(offsetX, offsetY)); -// touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); -// touchAction.release(); -// touchAction.perform(); } @Override diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java index 9222bef6..d7755c60 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java @@ -41,7 +41,6 @@ import java.time.Duration; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.Set; /** @@ -51,11 +50,32 @@ */ public class AppiumUtils implements WebDriverManagerProvider, Loggable { + public enum Swipe { + LEFT, + RIGHT, + UP, + DOWN; + } + + /** + * Run a shell command, especially at Android devices + * + * @param driver + * @param command + * @param args + * @return + */ public String runCommand(WebDriver driver, String command, String... args) { log().info("Shell command (native): {}, {}", command, Arrays.toString(args)); // ImmutableList does NOT work here... return String.valueOf(JSUtils.executeScript(driver, "mobile: shell", ImmutableMap.of("command", command, "args", Lists.newArrayList(args)))); } + /** + * Helper method to start a native app from iOS system. To start installed custom apps use the default way with AppiumDriverRequest + * + * @param driver Current webdriver instance + * @param bundleId Bundle ID of native app + */ public void launchIOSApp(WebDriver driver, String bundleId) { log().info("Start application '{}'", bundleId); MobileOsChecker checker = new MobileOsChecker(); @@ -74,8 +94,12 @@ public void rotate(WebDriver driver, ScreenOrientation screenOrientation) { }); } + /** + * Perform a swipe action, start point is an element and end point is calculated based on the offset. + */ public void swipe(UiElement uiElement, Point offset) { AppiumDriver appiumDriver = this.getAppiumDriver(uiElement.getWebDriver()); + uiElement.findWebElement(webElement -> { Point sourceLocation = webElement.getLocation(); Dimension sourceSize = webElement.getSize(); @@ -84,17 +108,75 @@ public void swipe(UiElement uiElement, Point offset) { int endX = centerX + offset.getX(); int endY = centerY + offset.getY(); - PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); - org.openqa.selenium.interactions.Sequence swipe = new Sequence(finger, 0); + this.swipeAction(appiumDriver, Duration.ofMillis(500), centerX, centerY, endX, endY); + }); + } - swipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), centerX, centerY)); - swipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); - swipe.addAction(finger.createPointerMove(Duration.ofMillis(600), PointerInput.Origin.viewport(), endX, endY)); - swipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); - appiumDriver.perform(List.of(swipe)); + /** + * Perform a swipe action, start point is the center of an element. Possible directions are + * Swipe.LEFT, Swipe.RIGHT, Swipe.UP and Swipe.DOWN. + */ + public void swipe(UiElement startElement, Swipe direction) { + startElement.findWebElement(webElement -> { + Point sourceLocation = webElement.getLocation(); + Dimension sourceSize = webElement.getSize(); + int startX = sourceLocation.getX() + sourceSize.getWidth() / 2; + int startY = sourceLocation.getY() + sourceSize.getHeight() / 2; + + this.swipeAction(startElement.getWebDriver(), startX, startY, direction); }); } + /** + * Perform a swipe action. Start point is the center of the screen. Possible directions are + * Swipe.LEFT, Swipe.RIGHT, Swipe.UP and Swipe.DOWN. + */ + public void swipe(WebDriver driver, Swipe direction) { + Dimension screenDim = driver.manage().window().getSize(); + int startX = screenDim.getWidth() / 2; + int startY = screenDim.getHeight() / 2; + this.swipeAction(driver, startX, startY, direction); + } + + private void swipeAction(WebDriver driver, int startX, int startY, Swipe direction) { + AppiumDriver appiumDriver = this.getAppiumDriver(driver); + final Duration intensity = Duration.ofMillis(500); + // Length of swipe action according screen resolution + final double screenMultiplier = 0.4; + + Dimension screenDim = appiumDriver.manage().window().getSize(); + final int diffX = (int) (screenDim.getWidth() * screenMultiplier); + final int diffY = (int) (screenDim.getHeight() * screenMultiplier); + + int endX = startX; + int endY = startY; + switch (direction) { + case LEFT: + endX = Math.max(startX - diffX, 1); + break; + case RIGHT: + endX = Math.max(startX + diffX, screenDim.getWidth() - 1); + break; + case UP: + endY = Math.max(startY - diffY, 1); + break; + case DOWN: + endY = Math.max(startY + diffY, screenDim.getHeight() - 1); + } + + this.swipeAction(appiumDriver, intensity, startX, startY, endX, endY); + } + + private void swipeAction(AppiumDriver driver, Duration intensity, int startX, int startY, int endX, int endY) { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence swipe = new Sequence(finger, 1); + swipe.addAction(finger.createPointerMove(intensity, PointerInput.Origin.viewport(), startX, startY)); + swipe.addAction(finger.createPointerDown(0)); + swipe.addAction(finger.createPointerMove(intensity, PointerInput.Origin.viewport(), endX, endY)); + swipe.addAction(finger.createPointerUp(0)); + driver.perform(List.of(swipe)); + } + /** * Switch the Appium Context if available */ @@ -127,6 +209,9 @@ public void switchContext(WebDriver driver, AppiumContext desiredContext) { } + /** + * Unwrap the current WebDriver instance and returns a native AppiumDriver instance. + */ public AppiumDriver getAppiumDriver(WebDriver webDriver) { return WEB_DRIVER_MANAGER.unwrapWebDriver(webDriver, AppiumDriver.class) .orElseThrow(() -> new RuntimeException("Current Webdriver is not an Appium driver.")); From d33d0085f7489f68b0f7595f5cb8f928a5f0294c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Thu, 20 Jun 2024 10:53:18 +0200 Subject: [PATCH 16/17] Added final implementation of swipe --- .../AppiumGuiElementCoreAdapter.java | 9 -- .../tic/testframework/utils/AppiumUtils.java | 117 ++++++++++++++++-- 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java index bf209095..87dc6cf2 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/mobile/guielement/AppiumGuiElementCoreAdapter.java @@ -117,15 +117,6 @@ public void contextClick() { @Override public void swipe(int offsetX, int offsetY) { new AppiumUtils().swipe(this.guiElementData.getGuiElement(), new Point(offsetX, offsetY)); -// TouchAction touchAction = new TouchAction(appiumDriver); -// -// final TapOptions tapOption = new TapOptions().withElement(new ElementOption().withElement(webElement)); -// touchAction.tap(tapOption); -// touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); -// touchAction.moveTo(new PointOption().withCoordinates(offsetX, offsetY)); -// touchAction.waitAction(new WaitOptions().withDuration(Duration.ofMillis(1500))); -// touchAction.release(); -// touchAction.perform(); } @Override diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java index 9222bef6..2cf66dcf 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java @@ -41,7 +41,6 @@ import java.time.Duration; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.Set; /** @@ -51,11 +50,40 @@ */ public class AppiumUtils implements WebDriverManagerProvider, Loggable { + public enum Swipe { + LEFT, + RIGHT, + UP, + DOWN; + } + + // Relative positions to the screen dimension of standard swipe actions + // for example scroll down: + // - 0.2 * screenHeight -> start y + // - 0.8 * screenHeight -> end y + // - x is center of screen + private static final double SCREEN_SWIPE_START = 0.2; + private static final double SCREEN_SWIPE_END = 0.8; + + /** + * Run a shell command, especially at Android devices + * + * @param driver + * @param command + * @param args + * @return + */ public String runCommand(WebDriver driver, String command, String... args) { log().info("Shell command (native): {}, {}", command, Arrays.toString(args)); // ImmutableList does NOT work here... return String.valueOf(JSUtils.executeScript(driver, "mobile: shell", ImmutableMap.of("command", command, "args", Lists.newArrayList(args)))); } + /** + * Helper method to start a native app from iOS system. To start installed custom apps use the default way with AppiumDriverRequest + * + * @param driver Current webdriver instance + * @param bundleId Bundle ID of native app + */ public void launchIOSApp(WebDriver driver, String bundleId) { log().info("Start application '{}'", bundleId); MobileOsChecker checker = new MobileOsChecker(); @@ -74,8 +102,12 @@ public void rotate(WebDriver driver, ScreenOrientation screenOrientation) { }); } + /** + * Perform a swipe action, start point is an element and end point is calculated based on the offset. + */ public void swipe(UiElement uiElement, Point offset) { AppiumDriver appiumDriver = this.getAppiumDriver(uiElement.getWebDriver()); + uiElement.findWebElement(webElement -> { Point sourceLocation = webElement.getLocation(); Dimension sourceSize = webElement.getSize(); @@ -84,17 +116,83 @@ public void swipe(UiElement uiElement, Point offset) { int endX = centerX + offset.getX(); int endY = centerY + offset.getY(); - PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); - org.openqa.selenium.interactions.Sequence swipe = new Sequence(finger, 0); + this.swipeAction(appiumDriver, Duration.ofMillis(200), centerX, centerY, endX, endY); + }); + } - swipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), centerX, centerY)); - swipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg())); - swipe.addAction(finger.createPointerMove(Duration.ofMillis(600), PointerInput.Origin.viewport(), endX, endY)); - swipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg())); - appiumDriver.perform(List.of(swipe)); + /** + * Perform a swipe action, start point is the center of an element. Possible directions are + * Swipe.LEFT, Swipe.RIGHT, Swipe.UP and Swipe.DOWN. + */ + public void swipe(UiElement startElement, Swipe direction) { + startElement.findWebElement(webElement -> { + Point sourceLocation = webElement.getLocation(); + Dimension sourceSize = webElement.getSize(); + int startX = sourceLocation.getX() + sourceSize.getWidth() / 2; + int startY = sourceLocation.getY() + sourceSize.getHeight() / 2; + Point startPoint = new Point(startX, startY); + // TODO: change + this.swipeAction(startElement.getWebDriver(), direction, startPoint); }); } + /** + * Perform a swipe action. Start point is the center of the screen. Possible directions are + * Swipe.LEFT, Swipe.RIGHT, Swipe.UP and Swipe.DOWN. + */ + public void swipe(WebDriver driver, Swipe direction) { + Dimension screenDim = driver.manage().window().getSize(); + int startX = screenDim.getWidth() / 2; + int startY = screenDim.getHeight() / 2; + Point startPoint = new Point(startX, startY); + this.swipeAction(driver, direction, startPoint); + } + + private void swipeAction(WebDriver driver, Swipe direction, Point startPoint) { + AppiumDriver appiumDriver = this.getAppiumDriver(driver); + final Duration intensity = Duration.ofMillis(500); + // Length of swipe action according screen resolution + final double screenMultiplier = 0.5; + + Dimension screenDim = appiumDriver.manage().window().getSize(); +// final int centerX = screenDim.getWidth() / 2; +// final int centerY = screenDim.getHeight() / 2; + final int diffX = (int) (screenDim.getWidth() * screenMultiplier); + final int diffY = (int) (screenDim.getHeight() * screenMultiplier); + + int startX = startPoint.getX(); + int startY = startPoint.getY(); + int endX = startX; + int endY = startY; + switch (direction) { + case LEFT: + startX = (int) (screenDim.getWidth() * SCREEN_SWIPE_END); + endX = (int) (screenDim.getWidth() * SCREEN_SWIPE_START); +// endX = Math.max(startX - diffX, 1); + break; + case RIGHT: + endX = Math.max(startX + diffX, screenDim.getWidth() - 1); + break; + case UP: + endY = Math.max(startY - diffY, 1); + break; + case DOWN: + endY = Math.max(startY + diffY, screenDim.getHeight() - 1); + } + + this.swipeAction(appiumDriver, intensity, startX, startY, endX, endY); + } + + private void swipeAction(AppiumDriver driver, Duration intensity, int startX, int startY, int endX, int endY) { + PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger"); + Sequence swipe = new Sequence(finger, 1); + swipe.addAction(finger.createPointerMove(intensity, PointerInput.Origin.viewport(), startX, startY)); + swipe.addAction(finger.createPointerDown(0)); + swipe.addAction(finger.createPointerMove(intensity, PointerInput.Origin.viewport(), endX, endY)); + swipe.addAction(finger.createPointerUp(0)); + driver.perform(List.of(swipe)); + } + /** * Switch the Appium Context if available */ @@ -127,6 +225,9 @@ public void switchContext(WebDriver driver, AppiumContext desiredContext) { } + /** + * Unwrap the current WebDriver instance and returns a native AppiumDriver instance. + */ public AppiumDriver getAppiumDriver(WebDriver webDriver) { return WEB_DRIVER_MANAGER.unwrapWebDriver(webDriver, AppiumDriver.class) .orElseThrow(() -> new RuntimeException("Current Webdriver is not an Appium driver.")); From c457dedc55e3e37869c9783a889c388658e96045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gro=C3=9Fmann?= Date: Fri, 12 Jul 2024 15:50:21 +0200 Subject: [PATCH 17/17] Updated docs --- .../tic/testframework/utils/AppiumUtils.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java index 37c3b5c2..d6153dbd 100644 --- a/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java +++ b/appium/src/main/java/eu/tsystems/mms/tic/testframework/utils/AppiumUtils.java @@ -57,13 +57,18 @@ public enum Swipe { DOWN; } - // Relative positions to the screen dimension of standard swipe actions + // Relative start and end positions to the screen dimension of standard swipe actions // for example scroll down: - // - 0.2 * screenHeight -> start y - // - 0.8 * screenHeight -> end y - // - x is center of screen + // - 0.2 * screenHeight -> start y (SCREEN_SWIPE_START) + // - 0.5 * screenHeight -> end y (SCREEN_MULTIPLIER) + // - x is center of screen + // for example scroll left: + // - 0.8 * screenWidth -> start x (SCREEN_SWIPE_END) + // - 0.5 * screenWidth -> end x (SCREEN_MULTIPLIER) + // - y is center of screen private static final double SCREEN_SWIPE_START = 0.2; private static final double SCREEN_SWIPE_END = 0.8; + private static final double SCREEN_MULTIPLIER = 0.5; /** * Run a shell command, especially at Android devices @@ -152,13 +157,11 @@ private void swipeAction(WebDriver driver, Swipe direction, Point startPoint) { AppiumDriver appiumDriver = this.getAppiumDriver(driver); final Duration intensity = Duration.ofMillis(500); // Length of swipe action according screen resolution - final double screenMultiplier = 0.5; + Dimension screenDim = appiumDriver.manage().window().getSize(); -// final int centerX = screenDim.getWidth() / 2; -// final int centerY = screenDim.getHeight() / 2; - final int diffX = (int) (screenDim.getWidth() * screenMultiplier); - final int diffY = (int) (screenDim.getHeight() * screenMultiplier); + final int diffX = (int) (screenDim.getWidth() * SCREEN_MULTIPLIER); + final int diffY = (int) (screenDim.getHeight() * SCREEN_MULTIPLIER); int startX = startPoint.getX(); int startY = startPoint.getY();