package functional.tests.core.mobile.basetest; import functional.tests.core.exceptions.AppiumException; import functional.tests.core.exceptions.DeviceException; import functional.tests.core.exceptions.MobileAppException; import functional.tests.core.image.ImageUtils; import functional.tests.core.log.Log; import functional.tests.core.log.LoggerBase; import functional.tests.core.mobile.app.App; import functional.tests.core.mobile.appium.Client; import functional.tests.core.mobile.appium.Server; import functional.tests.core.mobile.device.Device; import functional.tests.core.mobile.find.Find; import functional.tests.core.mobile.find.Locators; import functional.tests.core.mobile.find.UIElementClass; import functional.tests.core.mobile.find.Wait; import functional.tests.core.mobile.gestures.Gestures; import functional.tests.core.mobile.settings.MobileSettings; import functional.tests.core.utils.FileSystem; import org.testng.ITestResult; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeoutException; /** * TODO(svetli): Add docs. */ public class MobileSetupManager { private static final LoggerBase LOGGER_BASE = LoggerBase.getLogger("MobileSetupManager"); protected static Map<String, MobileSetupManager> initSettings; private MobileContext context; private MobileSettings settings; private Log log; private Locators locators; private Server server; private Client client; private Device device; private ImageUtils imageUtils; private App app; private Find find; private Wait wait; private Gestures gestures; private UIElementClass uiElements; private MobileSetupManager() { } /** * Init only once per configuration. * * @return Instance of MobileSetupManager. */ public static MobileSetupManager initTestSetupBasic(boolean shouldStartLog4j) { MobileSetupManager mobileSetupManager; if (MobileSetupManager.initSettings == null) { if (shouldStartLog4j) { LoggerBase.initLog4j(); } MobileSetupManager.initSettings = new HashMap<>(); } if (!MobileSetupManager.initSettings.containsKey(getAppConfig())) { mobileSetupManager = new MobileSetupManager(); mobileSetupManager.settings = new MobileSettings(); mobileSetupManager.log = new Log(); mobileSetupManager.uiElements = new UIElementClass(mobileSetupManager.settings); mobileSetupManager.locators = new Locators(mobileSetupManager.settings); mobileSetupManager.server = new Server(mobileSetupManager.settings); mobileSetupManager.client = new Client(mobileSetupManager.server, mobileSetupManager.settings); mobileSetupManager.device = new Device(mobileSetupManager.client, mobileSetupManager.settings); mobileSetupManager.imageUtils = new ImageUtils(mobileSetupManager.settings, mobileSetupManager.client, mobileSetupManager.device); mobileSetupManager.log = new Log(mobileSetupManager.client, mobileSetupManager.settings); mobileSetupManager.app = new App(mobileSetupManager.device, mobileSetupManager.settings); mobileSetupManager.find = new Find(mobileSetupManager.client, mobileSetupManager.locators, mobileSetupManager.settings); mobileSetupManager.wait = new Wait(mobileSetupManager.client, mobileSetupManager.find, mobileSetupManager.settings); mobileSetupManager.gestures = new Gestures( mobileSetupManager.client, mobileSetupManager.wait, mobileSetupManager.device, mobileSetupManager.locators, mobileSetupManager.settings); mobileSetupManager.context = new MobileContext( mobileSetupManager.settings, mobileSetupManager.log, mobileSetupManager.client, mobileSetupManager.server, mobileSetupManager.device, mobileSetupManager.app, mobileSetupManager.find, mobileSetupManager.gestures, mobileSetupManager.imageUtils, mobileSetupManager.locators, mobileSetupManager.wait, mobileSetupManager.uiElements); mobileSetupManager.context.lastTestResult = ITestResult.SUCCESS; MobileSetupManager.initSettings.put(getAppConfig(), mobileSetupManager); } else { mobileSetupManager = MobileSetupManager.initSettings.get(getAppConfig()); } return mobileSetupManager; } /** * Get the MobileSetupManager for the current instance according to app config. * * @return */ public static MobileSetupManager getTestSetupManager() { return MobileSetupManager.initSettings.get(MobileSetupManager.getAppConfig()); } /** * Get current app configuration. * * @return */ public static String getAppConfig() { return System.getProperty("appConfig"); } public MobileContext getContext() { return this.context; } /** * Init Appium Server. */ public void initServer() throws IOException, AppiumException { this.context.server.initServer(); } /** * Stop app under test, appium client and server. */ public void stopSession() throws DeviceException { this.context.app.close(); this.context.client.stopDriver(); this.context.server.stopServer(); } public void restartSession() throws MobileAppException, DeviceException, TimeoutException, IOException, AppiumException { this.stopSession(); this.initServer(); this.initDevice(); } /** * Init device - ensure it is up and running and test app is deployed. * This will also start Appium client session. * * @throws MobileAppException When app can not be deployed or started. * @throws DeviceException When device is not attached or emulator can not start. * @throws TimeoutException When device can not be started in appropriate time. */ public void initDevice() throws MobileAppException, DeviceException, TimeoutException { try { this.context.device.start(); } catch (Exception ex) { Log.logScreenOfHost(this.settings, "onStartDevice"); throw ex; } } /** * Log test results. * * @param previousTestStatus Outcome of the test. * @param testCase Test name. */ public void logTestResult(int previousTestStatus, String testCase) { if (previousTestStatus == ITestResult.SUCCESS) { if (this.context.settings.takeScreenShotAfterTest) { this.context.log.logScreen(testCase + "_pass", "Screenshot after " + testCase); } this.log.info("=> Test " + testCase + " passed!"); } else if (previousTestStatus == ITestResult.FAILURE) { if (this.context.device == null) { LOGGER_BASE.error("The device is null"); } else { try { this.context.device.writeConsoleLogToFile(testCase); } catch (IOException e) { e.printStackTrace(); } } this.context.log.logScreen(testCase + "_fail", "Screenshot after " + testCase); this.context.log.saveXmlTree(testCase + "_VisualTree.xml"); this.log.error("=> Test " + testCase + " failed!"); } else if (this.context.lastTestResult == ITestResult.SKIP) { this.context.log.logScreen(testCase + "_skip", "Screenshot after " + testCase); this.log.error("=> Test " + testCase + " skipped!"); } } /** * Check Appium server log iOS crashes. * Note: Implemented only for iOS. */ private void checkAppiumServerLogs() { try { String appiumLog = FileSystem.readFile(this.context.settings.appiumLogFile); String[] lines = appiumLog.split("\\r?\\n"); for (String line : lines) { if (line.contains("IOS_SYSLOG_ROW") && line.contains("crashed.")) { LOGGER_BASE.fatal("App crashes at startup. Please see appium logs."); } } } catch (IOException e) { LOGGER_BASE.info("Failed to check appium log files."); } } }