Best Carina code snippet using com.qaprosoft.carina.core.foundation.utils.android.IAndroidUtils.changePermissions
Source:IAndroidUtils.java  
...63    static final String LANGUAGE_CHANGE_APP_PATH = "app/ADB_Change_Language.apk";64    static final String SHELL_INIT_CONSOLE = "mobile: shell";65    static final String SHELL_INIT_DEEPLINK_CONSOLE = "mobile:deepLink";66    static final String SHELL_INIT_GET_PERMISSION_CONSOLE = "mobile:getPermissions";67    static final String SHELL_INIT_CHANGE_PERMISSION_CONSOLE = "mobile:changePermissions";68    static final String SHELL_GPS_STATUS_CMD = "settings get secure location_providers_allowed";69    static final String SHELL_CLOSE_STATUS_BAR_CMD = "cmd statusbar collapse";70    static final String SHELL_OPEN_STATUS_BAR_CMD = "cmd statusbar expand-notifications";71    static final String SHELL_INPUT_TXT_CMD = "input text ";72    static final String SHELL_OPEN_URL_CMD = "am start -a android.intent.action.VIEW";73    static final String SHELL_CLEAR_CACHE_CMD = "pm clear";74    static final String SHELL_OPEN_DEVICE_SETTINGS_CMD = "am start -a android.settings.SETTINGS";75    static final String SHELL_TAKE_SCREENSHOT_CMD = "screencap -p";76    static final String SHELL_DISABLE_GPS_CMD = "settings put secure location_providers_allowed -gps";77    static final String SHELL_ENABLE_GPS_CMD = "settings put secure location_providers_allowed +gps";78    static final String SHELL_PRESS_HOME_CMD = "input keyevent 3";79    static final String SHELL_RECENT_APPS_CMD = "input keyevent KEYCODE_APP_SWITCH";80    default public void pressKeyboardKey(AndroidKey key) {81        ((AndroidDriver<?>) castDriver()).pressKey(new KeyEvent(key).withFlag(KeyEventFlag.SOFT_KEYBOARD)82                .withFlag(KeyEventFlag.KEEP_TOUCH_MODE).withFlag(KeyEventFlag.EDITOR_ACTION));83    }84    default public void pressBack() {85        ((AndroidDriver<?>) castDriver()).pressKey(new KeyEvent(AndroidKey.BACK));86    }87    /**88     * Pressing "search" key of Android keyboard by coordinates.89     * <p>90     * Tested at Nexus 6P Android 8.0.0 standard keyboard. Coefficients of91     * coordinates for other devices and custom keyboards could be different.92     * <p>93     * Following options are not working: 1.94     * AndroidDriver.pressKeyCode(AndroidKeyCode.KEYCODE_SEARCH); 2.95     * searchEditText.sendKeys("textToSearch" + "\n")96     */97    default public void pressSearchKey() {98        pressBottomRightKey();99    }100    default public void pressNextKey() {101        pressBottomRightKey();102    }103    // Change Device Language section104    /**105     * change Android Device Language106     * <p>107     * Url: <a href=108     * "http://play.google.com/store/apps/details?id=net.sanapeli.adbchangelanguage">109     * ADBChangeLanguage apk </a> Change locale (language) of your device via ADB110     * (on Android OS version 6.0, 5.0, 4.4, 4.3, 4.2 and older). No need to root111     * your device! With ADB (Android Debug Bridge) on your computer, you can fast112     * switch the device locale to see how your application UI looks on different113     * languages. Usage: - install this app - setup adb connection to your device114     * (http://developer.android.com/tools/help/adb.html) - Android OS 4.2 onwards115     * (tip: you can copy the command here and paste it to your command console):116     * adb shell pm grant net.sanapeli.adbchangelanguage117     * android.permission.CHANGE_CONFIGURATION118     * <p>119     * English: adb shell am start -n120     * net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e language en Russian: adb121     * shell am start -n net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e122     * language ru Spanish: adb shell am start -n123     * net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e language es124     *125     * @param language126     *            to set. Can be es, en, etc.127     * @return boolean128     */129    default public boolean setDeviceLanguage(String language) {130        boolean status = setDeviceLanguage(language, 20);131        return status;132    }133    /**134     * change Android Device Language135     * <p>136     * Url: <a href=137     * "http://play.google.com/store/apps/details?id=net.sanapeli.adbchangelanguage">138     * ADBChangeLanguage apk </a> Change locale (language) of your device via ADB139     * (on Android OS version 6.0, 5.0, 4.4, 4.3, 4.2 and older). No need to root140     * your device! With ADB (Android Debug Bridge) on your computer, you can fast141     * switch the device locale to see how your application UI looks on different142     * languages. Usage: - install this app - setup adb connection to your device143     * (http://developer.android.com/tools/help/adb.html) - Android OS 4.2 onwards144     * (tip: you can copy the command here and paste it to your command console):145     * adb shell pm grant net.sanapeli.adbchangelanguage146     * android.permission.CHANGE_CONFIGURATION147     * <p>148     * English: adb shell am start -n149     * net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e language en Russian: adb150     * shell am start -n net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e151     * language ru Spanish: adb shell am start -n152     * net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e language es153     *154     * @param language155     *            to set. Can be es, en, etc.156     * @param waitTime157     *            int wait in seconds before device refresh.158     * @return boolean159     */160    default public boolean setDeviceLanguage(String language, int waitTime) {161        boolean status = false;162        UTILS_LOGGER.info("Do not concat language for Android. Keep: " + language);163        language = language.replace("_", "-");164        UTILS_LOGGER.info("Refactor language to : " + language);165        String actualDeviceLanguage = getDeviceLanguage();166        if (language.contains(actualDeviceLanguage.toLowerCase())167                || actualDeviceLanguage.toLowerCase().contains(language)) {168            UTILS_LOGGER.info("Device already have expected language: " + actualDeviceLanguage);169            return true;170        }171        String setLocalizationChangePermissionCmd = "shell pm grant net.sanapeli.adbchangelanguage android.permission.CHANGE_CONFIGURATION";172        String setLocalizationCmd = "shell am start -n net.sanapeli.adbchangelanguage/.AdbChangeLanguage -e language "173                + language;174        UTILS_LOGGER.info("Try set localization change permission with following cmd:" + setLocalizationChangePermissionCmd);175        String expandOutput = executeAdbCommand(setLocalizationChangePermissionCmd);176        String pathToInstalledAppCmd = "shell pm path net.sanapeli.adbchangelanguage";177        String pathToInstalledApp = executeAdbCommand(pathToInstalledAppCmd);178        if (expandOutput.contains("Unknown package: net.sanapeli.adbchangelanguage") || pathToInstalledApp.isEmpty()) {179            UTILS_LOGGER.info("Looks like 'ADB Change Language apk' is not installed. Install it and try again.");180            installApk(LANGUAGE_CHANGE_APP_PATH, true);181            expandOutput = executeAdbCommand(setLocalizationChangePermissionCmd);182        }183        UTILS_LOGGER.info("Output after set localization change permission using 'ADB Change Language apk': " + expandOutput);184        UTILS_LOGGER.info("Try set localization to '" + language + "' with following cmd: " + setLocalizationCmd);185        String changeLocaleOutput = executeAdbCommand(setLocalizationCmd);186        UTILS_LOGGER.info("Output after set localization to '" + language + "' using 'ADB Change Language apk' : "187                + changeLocaleOutput);188        if (waitTime > 0) {189            UTILS_LOGGER.info("Wait for at least '" + waitTime + "' seconds before device refresh.");190            CommonUtils.pause(waitTime);191        }192        actualDeviceLanguage = getDeviceLanguage();193        UTILS_LOGGER.info("Actual Device Language: " + actualDeviceLanguage);194        if (language.contains(actualDeviceLanguage.toLowerCase())195                || actualDeviceLanguage.toLowerCase().contains(language)) {196            status = true;197        } else {198            if (getDeviceLanguage().isEmpty()) {199                UTILS_LOGGER.info("Adb return empty response without errors.");200                status = true;201            } else {202                String currentAndroidVersion = IDriverPool.getDefaultDevice().getOsVersion();203                UTILS_LOGGER.info("currentAndroidVersion=" + currentAndroidVersion);204                if (currentAndroidVersion.contains("7.")) {205                    UTILS_LOGGER.info("Adb return language command do not work on some Android 7+ devices."206                            + " Check that there are no error.");207                    status = !getDeviceLanguage().toLowerCase().contains("error");208                }209            }210        }211        return status;212    }213    /**214     * getDeviceLanguage215     *216     * @return String217     */218    default public String getDeviceLanguage() {219        String locale = executeAdbCommand("shell getprop persist.sys.language");220        if (locale.isEmpty()) {221            locale = executeAdbCommand("shell getprop persist.sys.locale");222        }223        return locale;224    }225    // End Language Change section226    /**227     * install android Apk by path to apk file.228     *229     * @param apkPath230     *            String231     */232    default public void installApk(final String apkPath) {233        installApk(apkPath, false);234    }235    /**236     * install android Apk by path to apk or by name in classpath.237     *238     * @param apkPath239     *            String240     * @param inClasspath241     *            boolean242     */243    default public void installApk(final String apkPath, boolean inClasspath) {244        String filePath = apkPath;245        if (inClasspath) {246            URL baseResource = ClassLoader.getSystemResource(apkPath);247            if (baseResource == null) {248                throw new RuntimeException("Unable to get resource from classpath: " + apkPath);249            } else {250                UTILS_LOGGER.debug("Resource was found: " + baseResource.getPath());251            }252            String fileName = FilenameUtils.getBaseName(baseResource.getPath()) + "."253                    + FilenameUtils.getExtension(baseResource.getPath());254            // make temporary copy of resource in artifacts folder255            filePath = ReportContext.getArtifactsFolder().getAbsolutePath() + File.separator + fileName;256            File file = new File(filePath);257            if (!file.exists()) {258                InputStream link = (ClassLoader.getSystemResourceAsStream(apkPath));259                try {260                    Files.copy(link, file.getAbsoluteFile().toPath());261                } catch (IOException e) {262                    UTILS_LOGGER.error("Unable to extract resource from ClassLoader!", e);263                }264            }265        }266        executeAdbCommand("install " + filePath);267    }268    public enum SelectorType {269        TEXT,270        TEXT_CONTAINS,271        TEXT_STARTS_WITH,272        ID,273        DESCRIPTION,274        DESCRIPTION_CONTAINS,275        CLASS_NAME276    }277    /**278     * Scrolls into view in specified container by text only and return boolean279     *280     * @param container281     *            ExtendedWebElement - defaults to id Selector Type282     * @param scrollToElement283     *            String defaults to text Selector Type284     * @return ExtendedWebElement285     *         <p>286     *         example of usage: ExtendedWebElement res =287     *         AndroidUtils.scroll("News", newsListContainer);288     **/289    default public ExtendedWebElement scroll(String scrollToElement, ExtendedWebElement container) {290        return scroll(scrollToElement, container, SelectorType.ID, SelectorType.TEXT);291    }292    /**293     * Scrolls into view in a container specified by it's instance (index)294     * 295     * @param scrollToEle296     *            - has to be id, text, contentDesc or className297     * @param scrollableContainer298     *            - ExtendedWebElement type299     * @param containerSelectorType300     *            - has to be id, text, textContains, textStartsWith, Description,301     *            DescriptionContains or className302     * @param containerInstance303     *            - has to an instance number of desired container304     * @param eleSelectorType305     *            - has to be id, text, textContains, textStartsWith, Description,306     *            DescriptionContains or className307     * @return ExtendedWebElement308     *         <p>309     *         example of usage: ExtendedWebElement res =310     *         AndroidUtils.scroll("News", newsListContainer,311     *         AndroidUtils.SelectorType.CLASS_NAME, 1,312     *         AndroidUtils.SelectorType.TEXT);313     **/314    default public ExtendedWebElement scroll(String scrollToEle, ExtendedWebElement scrollableContainer,315            SelectorType containerSelectorType, int containerInstance, SelectorType eleSelectorType) {316        ExtendedWebElement extendedWebElement = null;317        long startTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());318        // TODO: support multi threaded WebDriver's removing DriverPool usage319        WebDriver drv = castDriver();320        // workaorund for appium issue: https://github.com/appium/appium/issues/10159321        if (scrollToEle.contains(",")) {322            scrollToEle = StringUtils.join(StringUtils.split(scrollToEle, ","), ",", 0, 2);323            if (eleSelectorType.equals(SelectorType.TEXT)) {324                eleSelectorType = SelectorType.TEXT_CONTAINS;325            }326        }327        for (int i = 0; i < SCROLL_MAX_SEARCH_SWIPES; i++) {328            try {329                By scrollBy = MobileBy.AndroidUIAutomator("new UiScrollable("330                        + getScrollContainerSelector(scrollableContainer, containerSelectorType) + ".instance("331                        + containerInstance + "))" + ".setMaxSearchSwipes(" + SCROLL_MAX_SEARCH_SWIPES + ")"332                        + ".scrollIntoView(" + getScrollToElementSelector(scrollToEle, eleSelectorType) + ")");333                WebElement ele = drv.findElement(scrollBy);334                if (ele.isDisplayed()) {335                    UTILS_LOGGER.info("Element found!!!");336                    // initializing with driver context because scrollBy consists from container and element selectors337                    extendedWebElement = new ExtendedWebElement(scrollBy, scrollToEle, drv, drv);338                    break;339                }340            } catch (NoSuchElementException noSuchElement) {341                UTILS_LOGGER.error(String.format("%s %s:%s", SpecialKeywords.NO_SUCH_ELEMENT_ERROR, eleSelectorType, scrollToEle),342                        noSuchElement);343            }344            for (int j = 0; j < i; j++) {345                checkTimeout(startTime);346                MobileBy.AndroidUIAutomator(347                        "new UiScrollable(" + getScrollContainerSelector(scrollableContainer, containerSelectorType)348                                + ".instance(" + containerInstance + ")).scrollForward()");349                UTILS_LOGGER.info("Scroller got stuck on a page, scrolling forward to next page of elements..");350            }351        }352        return extendedWebElement;353    }354    /**355     * Scrolls into view in specified container356     * 357     * @param scrollToEle358     *            - has to be id, text, contentDesc or className359     * @param scrollableContainer360     *            - ExtendedWebElement type361     * @param containerSelectorType362     *            - has to be id, text, textContains, textStartsWith, Description,363     *            DescriptionContains or className364     * @param containerInstance365     *            - has to an instance number of desired container366     * @param eleSelectorType367     *            - has to be id, text, textContains, textStartsWith, Description,368     *            DescriptionContains or className369     * @param eleSelectorInstance370     *            - has to an instance number of desired container371     * @return ExtendedWebElement372     *         <p>373     *         example of usage: ExtendedWebElement res =374     *         AndroidUtils.scroll("News", newsListContainer,375     *         AndroidUtils.SelectorType.CLASS_NAME, 1,376     *         AndroidUtils.SelectorType.TEXT, 2);377     **/378    default public ExtendedWebElement scroll(String scrollToEle, ExtendedWebElement scrollableContainer,379            SelectorType containerSelectorType, int containerInstance, SelectorType eleSelectorType,380            int eleSelectorInstance) {381        ExtendedWebElement extendedWebElement = null;382        long startTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());383        // TODO: support multi threaded WebDriver's removing DriverPool usage384        WebDriver drv = castDriver();385        // workaorund for appium issue: https://github.com/appium/appium/issues/10159386        if (scrollToEle.contains(",")) {387            scrollToEle = StringUtils.join(StringUtils.split(scrollToEle, ","), ",", 0, 2);388            if (eleSelectorType.equals(SelectorType.TEXT)) {389                eleSelectorType = SelectorType.TEXT_CONTAINS;390            }391        }392        for (int i = 0; i < SCROLL_MAX_SEARCH_SWIPES; i++) {393            try {394                By scrollBy = MobileBy.AndroidUIAutomator("new UiScrollable("395                        + getScrollContainerSelector(scrollableContainer, containerSelectorType) + ".instance("396                        + containerInstance + "))" + ".setMaxSearchSwipes(" + SCROLL_MAX_SEARCH_SWIPES + ")"397                        + ".scrollIntoView(" + getScrollToElementSelector(scrollToEle, eleSelectorType) + ".instance("398                        + eleSelectorInstance + "))");399                WebElement ele = drv.findElement(scrollBy);400                if (ele.isDisplayed()) {401                    UTILS_LOGGER.info("Element found!!!");402                    // initializing with driver context because scrollBy consists from container and element selectors403                    extendedWebElement = new ExtendedWebElement(scrollBy, scrollToEle, drv, drv);404                    break;405                }406            } catch (NoSuchElementException noSuchElement) {407                UTILS_LOGGER.error(String.format("%s%s:%s", SpecialKeywords.NO_SUCH_ELEMENT_ERROR, eleSelectorType, scrollToEle),408                        noSuchElement);409            }410            for (int j = 0; j < i; j++) {411                checkTimeout(startTime);412                MobileBy.AndroidUIAutomator(413                        "new UiScrollable(" + getScrollContainerSelector(scrollableContainer, containerSelectorType)414                                + ".instance(" + containerInstance + ")).scrollForward()");415                UTILS_LOGGER.info("Scroller got stuck on a page, scrolling forward to next page of elements..");416            }417        }418        return extendedWebElement;419    }420    /**421     * Scrolls into view in specified container422     * 423     * @param scrollToEle424     *            - has to be id, text, contentDesc or className425     * @param scrollableContainer426     *            - ExtendedWebElement type427     * @param containerSelectorType428     *            - container Selector type: has to be id, text, textContains,429     *            textStartsWith, Description, DescriptionContains or className430     * @param eleSelectorType431     *            - scrollToEle Selector type: has to be id, text, textContains,432     *            textStartsWith, Description, DescriptionContains or className433     * @return ExtendedWebElement434     *         <p>435     *         example of usage: ExtendedWebElement res =436     *         AndroidUtils.scroll("News", newsListContainer,437     *         AndroidUtils.SelectorType.CLASS_NAME,438     *         AndroidUtils.SelectorType.TEXT);439     **/440    default public ExtendedWebElement scroll(String scrollToEle, ExtendedWebElement scrollableContainer,441            SelectorType containerSelectorType, SelectorType eleSelectorType) {442        ExtendedWebElement extendedWebElement = null;443        long startTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());444        // TODO: support multi threaded WebDriver's removing DriverPool usage445        WebDriver drv = castDriver();446        // workaorund for appium issue: https://github.com/appium/appium/issues/10159447        if (scrollToEle.contains(",")) {448            scrollToEle = StringUtils.join(StringUtils.split(scrollToEle, ","), ",", 0, 2);449            if (eleSelectorType.equals(SelectorType.TEXT)) {450                eleSelectorType = SelectorType.TEXT_CONTAINS;451            }452        }453        for (int i = 0; i < SCROLL_MAX_SEARCH_SWIPES; i++) {454            try {455                By scrollBy = MobileBy.AndroidUIAutomator(456                        "new UiScrollable(" + getScrollContainerSelector(scrollableContainer, containerSelectorType)457                                + ")" + ".setMaxSearchSwipes(" + SCROLL_MAX_SEARCH_SWIPES + ")" + ".scrollIntoView("458                                + getScrollToElementSelector(scrollToEle, eleSelectorType) + ")");459                WebElement ele = drv.findElement(scrollBy);460                if (ele.isDisplayed()) {461                    UTILS_LOGGER.info("Element found!!!");462                    // initializing with driver context because scrollBy consists from container and element selectors463                    extendedWebElement = new ExtendedWebElement(scrollBy, scrollToEle, drv, drv);464                    break;465                }466            } catch (NoSuchElementException noSuchElement) {467                UTILS_LOGGER.error(String.format("%s%s:%s", SpecialKeywords.NO_SUCH_ELEMENT_ERROR, eleSelectorType, scrollToEle),468                        noSuchElement);469            }470            for (int j = 0; j < i; j++) {471                checkTimeout(startTime);472                MobileBy.AndroidUIAutomator("new UiScrollable("473                        + getScrollContainerSelector(scrollableContainer, containerSelectorType) + ").scrollForward()");474                UTILS_LOGGER.info("Scroller got stuck on a page, scrolling forward to next page of elements..");475            }476        }477        return extendedWebElement;478    }479    /**480     * Scrolls into view in specified container481     * 482     * @param scrollableContainer483     *            - ExtendedWebElement type484     * @param containerSelectorType485     *            - Selector type: has to be id, text, contentDesc or className486     * @return scrollViewContainerFinder String487     *488     **/489    default String getScrollContainerSelector(ExtendedWebElement scrollableContainer,490            SelectorType containerSelectorType) {491        UTILS_LOGGER.debug(scrollableContainer.getBy().toString());492        String scrollableContainerBy;493        String scrollViewContainerFinder = "";494        switch (containerSelectorType) {495        case TEXT:496            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.text:", "").trim();497            scrollViewContainerFinder = "new UiSelector().text(\"" + scrollableContainerBy + "\")";498            break;499        case TEXT_CONTAINS:500            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.textContains:", "").trim();501            scrollViewContainerFinder = "new UiSelector().textContains(\"" + scrollableContainerBy + "\")";502            break;503        case TEXT_STARTS_WITH:504            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.textStartsWith:", "").trim();505            scrollViewContainerFinder = "new UiSelector().textStartsWith(\"" + scrollableContainerBy + "\")";506            break;507        case ID:508            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.id:", "").trim();509            scrollViewContainerFinder = "new UiSelector().resourceId(\"" + scrollableContainerBy + "\")";510            break;511        case DESCRIPTION:512            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.description:", "").trim();513            scrollViewContainerFinder = "new UiSelector().description(\"" + scrollableContainerBy + "\")";514            break;515        case DESCRIPTION_CONTAINS:516            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.descriptionContains:", "")517                    .trim();518            scrollViewContainerFinder = "new UiSelector().descriptionContains(\"" + scrollableContainerBy + "\")";519            break;520        case CLASS_NAME:521            scrollableContainerBy = scrollableContainer.getBy().toString().replace("By.className:", "").trim();522            scrollViewContainerFinder = "new UiSelector().className(\"" + scrollableContainerBy + "\")";523            break;524        default:525            UTILS_LOGGER.info("Please provide valid selectorType for element to be found...");526            break;527        }528        return scrollViewContainerFinder;529    }530    /**531     * Scrolls into view in specified container532     * 533     * @param scrollToEle534     *            - String type535     * @param eleSelectorType536     *            - Selector type: has to be id, text, contentDesc or className537     * @return String538     **/539    default String getScrollToElementSelector(String scrollToEle, SelectorType eleSelectorType) {540        String neededElementFinder = "";541        String scrollToEleTrimmed;542        switch (eleSelectorType) {543        case TEXT:544            neededElementFinder = "new UiSelector().text(\"" + scrollToEle + "\")";545            break;546        case TEXT_CONTAINS:547            neededElementFinder = "new UiSelector().textContains(\"" + scrollToEle + "\")";548            break;549        case TEXT_STARTS_WITH:550            neededElementFinder = "new UiSelector().textStartsWith(\"" + scrollToEle + "\")";551            break;552        case ID:553            scrollToEleTrimmed = scrollToEle.replace("By.id:", "").trim();554            neededElementFinder = "new UiSelector().resourceId(\"" + scrollToEleTrimmed + "\")";555            break;556        case DESCRIPTION:557            neededElementFinder = "new UiSelector().description(\"" + scrollToEle + "\")";558            break;559        case DESCRIPTION_CONTAINS:560            neededElementFinder = "new UiSelector().descriptionContains(\"" + scrollToEle + "\")";561            break;562        case CLASS_NAME:563            scrollToEleTrimmed = scrollToEle.replace("By.className:", "").trim();564            neededElementFinder = "new UiSelector().className(\"" + scrollToEleTrimmed + "\")";565            break;566        default:567            UTILS_LOGGER.info("Please provide valid selectorType for element to be found...");568            break;569        }570        return neededElementFinder;571    }572    /**573     * Scroll Timeout check574     * 575     * @param startTime576     *            - Long initial time for timeout count down577     **/578    default public void checkTimeout(long startTime) {579        long elapsed = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - startTime;580        if (elapsed > SCROLL_TIMEOUT) {581            throw new NoSuchElementException("Scroll timeout has been reached..");582        }583    }584    /**585     * getCurrentDeviceFocus - get actual device apk in focus.586     *587     * @return String588     */589    default public String getCurrentDeviceFocus() {590        String result = executeAdbCommand("shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'");591        return result;592    }593    /**594     * executeAbdCommand595     *596     * @param command597     *            String598     * @return String command output in one line599     */600    default public String executeAdbCommand(String command) {601        String deviceName = getDevice().getAdbName();602        if (!deviceName.isEmpty()) {603            // add remoteURL/udid reference604            command = "-s " + deviceName + " " + command;605        } else {606            UTILS_LOGGER.warn("nullDevice detected fot current thread!");607        }608        String result = "";609        UTILS_LOGGER.info("Command: " + command);610        String[] listOfCommands = command.split(" ");611        String[] execCmd = CmdLine.insertCommandsAfter(baseInitCmd, listOfCommands);612        try {613            UTILS_LOGGER.info("Try to execute following cmd: " + CmdLine.arrayToString(execCmd));614            List<String> execOutput = executor.execute(execCmd);615            UTILS_LOGGER.info("Output after execution ADB command: " + execOutput);616            result = execOutput.toString().replaceAll("\\[|\\]", "").replaceAll(", ", " ").trim();617            UTILS_LOGGER.info("Returning Output: " + result);618        } catch (Exception e) {619            UTILS_LOGGER.error("Error while executing adb command: " + command, e);620        }621        return result;622    }623    /**624     * 625     * @param command626     * 627     *            - ADB shell command represented as single String where 1st literal628     *            is a command itself. Everything that follow is treated as629     *            arguments.630     *631     *            NOTE: "adb -s {UDID} shell" - should be omitted.632     *            Example: "adb -s {UDID} shell list packages" - list packages633     * 634     *            NOTE: shell arguments with space symbols are unsupported!635     * 636     * @return String - response (might be empty)637     */638    default public String executeShell(String command) {639        UTILS_LOGGER.info("ADB command to be executed: adb shell ".concat(command.trim()));640        List<String> literals = Arrays.asList(command.split(" "));641        return executeShell(literals);642    }643    /**644     * 645     * @param commands list of string commands646     * 647     *            - ADB shell command represented as single String where 1st literal648     *            is a command itself. Everything that follow is treated as649     *            arguments.650     *651     *            NOTE: "adb -s {UDID} shell" - should be omitted.652     *            Example: "adb -s {UDID} shell list packages" - list packages653     * 654     * @return String - response (might be empty)655     */656    default public String executeShell(List<String> commands) {657        String commadKeyWord = commands.get(0);658        List<String> args = commands.subList(1, commands.size());659        Map<String, Object> preparedCommand = ImmutableMap.of("command", commadKeyWord, "args", args);660        String output = (String) ((AppiumDriver<?>) castDriver()).executeScript(SHELL_INIT_CONSOLE, preparedCommand);661        if (!StringUtils.isEmpty(output)) {662            UTILS_LOGGER.debug("ADB command output: " + output);663        }664        return output;665    }666    /**667     * This method performs an action corresponding to press Android device's native668     * button to show all recent applications.669     * 670     * NOTE: method could be used to get a list of running in background671     * applications with respect to particular device.672     */673    default public void displayRecentApps() {674        executeShell(SHELL_RECENT_APPS_CMD);675    }676    /**677     * Tapping at native 'Home' button will be emulated. All applications will be678     * closed to background.679     */680    default public void pressHome() {681        executeShell(SHELL_PRESS_HOME_CMD);682    }683    /**684     * Is used to get GPS service status.685     * 686     * Response reflects which services are used for obtaining location:687     * 688     * - "gps" - GPS only (device only);689     * 690     * - "gps,network" - GPS + Wi-Fi + Bluetooth or cellular networks (High accuracy691     * mode);692     * 693     * - "network" - Using Wi-Fi, Bluetooth or cellular networks (Battery saving694     * mode);695     * 696     * @return boolean697     */698    default public boolean isGPSEnabled() {699        String response = executeShell(SHELL_GPS_STATUS_CMD);700        return response.contains("gps");701    }702    default public void enableGPS() {703        executeShell(SHELL_ENABLE_GPS_CMD);704    }705    /**706     * Works if ONLY DEVICE (GPS sensor) is user for obtaining location707     */708    default public void disableGPS() {709        executeShell(SHELL_DISABLE_GPS_CMD);710    }711    /**712     * This command will save screenshot to specified folder on device's OS using713     * provided path.714     * 715     * @param filepath716     *            - path to save screenshot to device's OS (/storage/emulated/0/Download/scr.png).717     */718    default public void takeScreenShot(String filepath) {719        UTILS_LOGGER.info("Screenshot will be saved to: " + filepath);720        String command = String.format(SHELL_TAKE_SCREENSHOT_CMD.concat(" %s"), filepath);721        executeShell(command);722    }723    /**724     * This method provides app's version for the app that is already installed to725     * devices, based on its package name.726     * In order to do that we search for "versionCode" parameter in system dump.727     * 728     * @param packageName String729     * 730     * @return appVersion String731     */732    default public String getAppVersion(String packageName) {733        String command = "dumpsys package ".concat(packageName);734        String output = executeShell(command);735        String versionCode = StringUtils.substringBetween(output, "versionCode=", " ");736        UTILS_LOGGER.info(String.format("Version code for '%s' package name is %s", packageName, versionCode));737        return versionCode;738    }739    /**740     * This method provides app's version name for the app that is already installed to741     * devices, based on its package name.742     * In order to do that we search for "versionName" parameter in system dump.743     * Ex. "versionCode" returns 11200050, "versionName" returns 11.2.0744     * 745     * @param packageName String746     * @return appVersion String747     */748    default public String getAppVersionName(String packageName) {749        String command = "dumpsys package ".concat(packageName);750        String output = this.executeShell(command);751        String versionName = StringUtils.substringBetween(output, "versionName=", "\n");752        UTILS_LOGGER.info(String.format("Version name for '%s' package name is %s", packageName, versionName));753        return versionName;754    }755    /**756     * To open Android device native settings757     */758    default public void openDeviceSettings() {759        executeShell(SHELL_OPEN_DEVICE_SETTINGS_CMD);760    }761    /**762     * Method to reset test specific application by package name763     * 764     * App's settings will be reset. User will be logged out. Application will be765     * closed to background.766     * 767     * @param packageName String768     */769    default public void clearAppCache(String packageName) {770        UTILS_LOGGER.info("Will clear data for the following app: " + packageName);771        String command = String.format(SHELL_CLEAR_CACHE_CMD.concat(" %s"), packageName);772        String response = executeShell(command);773        UTILS_LOGGER.info(774                String.format("Output after resetting custom application by package (%s): ", packageName) + response);775        if (!response.contains("Success")) {776            UTILS_LOGGER.warn(String.format("App data was not cleared for %s app", packageName));777        }778    }779    /**780     * With this method user is able to trigger a deeplink (link to specific place781     * within the application) or event open URL in mobile browser.782     * 783     * NOTE, that to open URL in browser, URL should starts with "https://www.{place784     * your link here}".785     * 786     * NOTE that not all deeplinks require package name.787     * 788     * @param link789     *            - URL to trigger790     */791    default public void openURL(String link) {792        // TODO: #1380 make openURL call from this mobile interface in DriverHelper793        UTILS_LOGGER.info("Following link will be triggered via ADB: " + link);794        String command = String.format(SHELL_OPEN_URL_CMD.concat(" %s"), link);795        executeShell(command);796    }797    /**798     * With this method user is able to trigger a deeplink (link to specific place799     * within the application)800     * 801     * @param link String802     * @param packageName String803     */804    default public void triggerDeeplink(String link, String packageName) {805        Map<String, Object> preparedCommand = ImmutableMap.of("url", link, "package", packageName);806        try {807            ((AppiumDriver<?>) castDriver()).executeScript(SHELL_INIT_DEEPLINK_CONSOLE, preparedCommand);808        } catch (WebDriverException wde) {809            // TODO: need to pay attention810            UTILS_LOGGER.warn("org.openqa.selenium.WebDriverException is caught and ignored.", wde);811        }812    }813    /**814     * To get list of granted/denied/requested permission for specified application815     * 816     * @param packageName String817     * @param type PermissionType818     * @return ArrayList String819     */820    @SuppressWarnings("unchecked")821    default public ArrayList<String> getAppPermissions(String packageName, PermissionType type) {822        Map<String, Object> preparedCommand = ImmutableMap.of("type", type.getType(), "package", packageName);823        return (ArrayList<String>) ((AppiumDriver<?>) castDriver()).executeScript(SHELL_INIT_GET_PERMISSION_CONSOLE,824                preparedCommand);825    }826    /**827     * To change (grant or revoke) application permissions.828     * 829     * @param packageName String830     * @param action PermissionAction831     * @param permissions Permission832     */833    default public void changePermissions(String packageName, PermissionAction action, Permission... permissions) {834        ArrayList<String> permissionsStr = new ArrayList<>();835        Arrays.asList(permissions).forEach(p -> permissionsStr.add(p.getPermission()));836        Map<String, Object> preparedCommand = ImmutableMap.of("action", action.getAction(), "appPackage", packageName,837                "permissions", permissionsStr);838        ((AppiumDriver<?>) castDriver()).executeScript(SHELL_INIT_CHANGE_PERMISSION_CONSOLE, preparedCommand);839    }840    /**841     * Method to enter text to ACTIVATED input field.842     * 843     * NOTE: that it might be necessary to escape some special characters.844     * Space-symbol is already escaped.845     * 846     * NOTE2: input field should be cleared previously.847     * ...changePermissions
Using AI Code Generation
1import com.qaprosoft.carina.core.foundation.utils.android.IAndroidUtils;2public class MyAndroidTest {3    public void testAndroidPermissions() {4        IAndroidUtils.changePermissions("android.permission.READ_CONTACTS");5    }6}7import com.qaprosoft.carina.core.foundation.utils.ios.IOSUtils;8public class MyIOSTest {9    public void testIOSPermissions() {10        IOSUtils.changePermissions("ios.permission.READ_CONTACTS");11    }12}13import com.qaprosoft.carina.core.foundation.utils.desktop.IDesktopUtils;14public class MyDesktopTest {15    public void testDesktopPermissions() {16        IDesktopUtils.changePermissions("desktop.permission.READ_CONTACTS");17    }18}19import com.qaprosoft.carina.core.foundation.utils.web.IWebUtils;20public class MyWebTest {21    public void testWebPermissions() {22        IWebUtils.changePermissions("web.permission.READ_CONTACTS");23    }24}25import com.qaprosoft.carina.core.foundation.utils.mobile.IMobileUtils;26public class MyMobileTest {27    public void testMobilePermissions() {28        IMobileUtils.changePermissions("mobile.permission.READ_CONTACTS");29    }30}31import com.qaprosoft.carina.core.foundation.utils.automation.IAutomationUtils;32public class MyAutomationTest {33    public void testAutomationPermissions() {34        IAutomationUtils.changePermissions("automation.permission.READ_CONTACTS");35    }36}37import com.qaprosoft.carina.core.foundation.utils.mobile.IOSUtils;38public class MyMobileTest {39    public void testMobilePermissions() {40        IOSUtils.changePermissions("mobile.permission.READ_CONTACTS");41    }42}changePermissions
Using AI Code Generation
1IAndroidUtils.changePermissions("com.example.app", "android.permission.READ_CONTACTS");2IAndroidUtils.changePermissions("com.example.app", "android.permission.READ_CONTACTS", false);3IIOSUtils.changePermissions("com.example.app", "NSContactsUsageDescription");4IIOSUtils.changePermissions("com.example.app", "NSContactsUsageDescription", false);5IMobileUtils.changePermissions("com.example.app", "android.permission.READ_CONTACTS");6IMobileUtils.changePermissions("com.example.app", "android.permission.READ_CONTACTS", false);7IMobileUtils.changePermissions("com.example.app", "NSContactsUsageDescription");8IMobileUtils.changePermissions("com.example.app", "NSContactsUsageDescription", false);9IAndroidUtils.changePermissions("com.example.app", "android.permission.READ_CONTACTS");10IAndroidUtils.changePermissions("com.example.app", "android.permission.READ_CONTACTS", false);11IIOSUtils.changePermissions("com.example.app", "NSContactsUsageDescription");12IIOSUtils.changePermissions("com.example.app", "NSContactsUsageDescription", false);changePermissions
Using AI Code Generation
1IAndroidUtils.changePermissions("allow");2IAndroidUtils.changePermissions("deny");3IAndroidUtils.changePermissions("allow", "android.permission.ACCESS_FINE_LOCATION");4IAndroidUtils.changePermissions("deny", "android.permission.ACCESS_FINE_LOCATION");5IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");6IAndroidUtils.changePermissions("deny", "android.permission-group.CONTACTS");7IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");8IAndroidUtils.changePermissions("deny", "android.permission-group.CONTACTS");9IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");10IAndroidUtils.changePermissions("deny", "android.permission-group.CONTACTS");11IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");12IAndroidUtils.changePermissions("deny", "android.permission-group.CONTACTS");13IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");14IAndroidUtils.changePermissions("deny", "android.permission-group.CONTACTS");15IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");16IAndroidUtils.changePermissions("deny", "android.permission-group.CONTACTS");17IAndroidUtils.changePermissions("allow", "android.permission-group.CONTACTS");Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
