All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.axway.ats.uiengine.engine.MobileEngine Maven / Gradle / Ivy

/*
 * Copyright 2017 Axway Software
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.axway.ats.uiengine.engine;

import com.axway.ats.common.PublicAtsApi;
import com.axway.ats.uiengine.MobileDriver;
import com.axway.ats.uiengine.UiDriver;
import com.axway.ats.uiengine.elements.AbstractElementsFactory;
import com.axway.ats.uiengine.elements.UiElement;
import com.axway.ats.uiengine.elements.UiElementProperties;
import com.axway.ats.uiengine.elements.mobile.MobileButton;
import com.axway.ats.uiengine.elements.mobile.MobileCheckBox;
import com.axway.ats.uiengine.elements.mobile.MobileElement;
import com.axway.ats.uiengine.elements.mobile.MobileElementFinder;
import com.axway.ats.uiengine.elements.mobile.MobileElementsFactory;
import com.axway.ats.uiengine.elements.mobile.MobileLabel;
import com.axway.ats.uiengine.elements.mobile.MobileLink;
import com.axway.ats.uiengine.elements.mobile.MobileTextBox;
import com.axway.ats.uiengine.exceptions.NotSupportedOperationException;
import com.axway.ats.uiengine.internal.driver.InternalObjectsEnum;
import com.axway.ats.uiengine.internal.engine.AbstractEngine;
import com.axway.ats.uiengine.utilities.UiEngineUtilities;
import com.axway.ats.uiengine.utilities.mobile.FileInfo;
import com.axway.ats.uiengine.utilities.mobile.MobileDeviceUtils;
import com.axway.ats.uiengine.utilities.mobile.MobileElementState;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidKeyCode;

/**
 * Engine operating with mobile application/device
 */
@PublicAtsApi
public class MobileEngine extends AbstractEngine {

    private AppiumDriver       appiumDriver;

    private MobileElementsFactory mobileElementsFactory;

    private MobileDeviceUtils     mobileDeviceUtils;

    private Device                device;

    public MobileEngine( UiDriver uiDriver,
                         MobileDeviceUtils mobileDeviceUtils ) {

        this( uiDriver, MobileElementsFactory.getInstance() );
        this.mobileElementsFactory = ( MobileElementsFactory ) elementsFactory;
        this.mobileDeviceUtils = mobileDeviceUtils;
        this.device = new Device();
    }

    public MobileEngine( UiDriver uiDriver,
                         AbstractElementsFactory elementsFactory ) {

        super( uiDriver, elementsFactory );

        MobileDriver mobileDriver = ( MobileDriver ) uiDriver;
        appiumDriver = ( AppiumDriver ) mobileDriver.getInternalObject( InternalObjectsEnum.WebDriver.name() );
    }

    /**
     * Get current application as String
     */
    @PublicAtsApi
    public String getApplicationName() {

        if( appiumDriver instanceof AndroidDriver ) {
            return ( ( AndroidDriver ) appiumDriver ).currentActivity();
        }
        return ""; //TODO: return the current activity/bundleId for IOSDriver too
    }

    /**
     * Get access to button element (native/or HTML one)
     * @param mapId the element's map id
     * @return a new {@link MobileButton} instance
     */
    @PublicAtsApi
    public MobileButton getButton(
                                   String mapId ) {

        return this.mobileElementsFactory.getMobileButton( mapId, uiDriver );
    }

    /**
     * Get access to button element (native/or HTML one)
     * @param properties properties describing this element
     * @return a new {@link MobileButton} instance
     */
    @PublicAtsApi
    public MobileButton getButton(
                                   UiElementProperties properties ) {

        return this.mobileElementsFactory.getMobileButton( properties, uiDriver );
    }

    /**
     * Get access to text box element (native/or HTML one where text edit is accepted)
     * @param mapId the element's map id
     * @return a new {@link MobileTextBox} instance
     */
    @PublicAtsApi
    public MobileTextBox getTextBox(
                                     String mapId ) {

        return mobileElementsFactory.getMobileTextBox( mapId, uiDriver );
    }

    /**
     * Get access to text box element (native/or HTML one where text edit is accepted)
     * @param properties properties describing this element
     * @return a new {@link MobileTextBox} instance
     */
    @PublicAtsApi
    public MobileTextBox getTextBox(
                                     UiElementProperties properties ) {

        return mobileElementsFactory.getMobileTextBox( properties, uiDriver );
    }

    /**
     * Get access to text label element (native/or HTML one where text edit is not accepted)
     * @param mapId the element's map id
     * @return a new {@link MobileLabel} instance
     */
    @PublicAtsApi
    public MobileLabel getLabel(
                                 String mapId ) {

        return mobileElementsFactory.getMobileLabel( mapId, uiDriver );
    }

    /**
     * Get access to text box element (native/or HTML one where text edit is not accepted)
     * @param properties properties describing this element
     * @return a new {@link MobileLabel} instance
     */
    @PublicAtsApi
    public MobileLabel getLabel(
                                 UiElementProperties properties ) {

        return mobileElementsFactory.getMobileLabel( properties, uiDriver );
    }

    /**
     * Get access to check box element (native/or HTML one)
     * @param mapId the element's map id
     * @return a new {@link MobileCheckBox} instance
     */
    @PublicAtsApi
    public MobileCheckBox getCheckBox(
                                       String mapId ) {

        return mobileElementsFactory.getMobileCheckBox( mapId, uiDriver );
    }

    /**
     * Get access to check box element (native/or HTML one)
     * @param properties properties describing this element
     * @return a new {@link MobileCheckBox} instance
     */
    @PublicAtsApi
    public MobileCheckBox getCheckBox(
                                       UiElementProperties properties ) {

        return mobileElementsFactory.getMobileCheckBox( properties, uiDriver );
    }

    /**
     * Get access to link( href) element
     * @param mapId the element's map id
     * @return a new {@link MobileLink} instance
     */
    @PublicAtsApi
    public MobileLink getLink(
                               String mapId ) {

        return mobileElementsFactory.getMobileLink( mapId, uiDriver );
    }

    /**
     * Get access to link element
     * @param properties properties describing this element
     * @return a new {@link MobileLink} instance
     */
    @PublicAtsApi
    public MobileLink getLink(
                               UiElementProperties properties ) {

        return mobileElementsFactory.getMobileLink( properties, uiDriver );
    }

    /**
     * Get access to generic UI element (could be used for div/span or other UI type element)
     * @param mapId the element's map id
     * @return a new {@link MobileElement} instance
     */
    @PublicAtsApi
    public MobileElement getElement(
                                        String mapId ) {

        return mobileElementsFactory.getMobileElement( mapId, uiDriver );
    }

    /**
     * Get access to generic UI element (could be used for div/span or other UI type element)
     * @param properties properties describing this element
     * @return a new {@link MobileElement} instance
     */
    @PublicAtsApi
    public MobileElement getElement(
                                        UiElementProperties properties ) {

        return mobileElementsFactory.getMobileElement( properties, uiDriver );
    }

    /**
     * Check element state
     * @param uiElement the element to work with
     * @return a utility class for checking the state of element
     */
    @PublicAtsApi
    public MobileElementState getUtilsElementState(
                                                    UiElement uiElement ) {

        return new MobileElementState( uiElement );
    }

    @PublicAtsApi
    public String executeScriptAndReturn(
                                          String method,
                                          Object... args ) {

        return ( String ) this.appiumDriver.executeScript( method, args );
    }

    @PublicAtsApi
    public void executeScript(
                               String method,
                               Object... args ) {

        this.appiumDriver.executeAsyncScript( method, args );
    }

    /**
     * Get page source as String
     *
     * @return page source
     */
    @PublicAtsApi
    public String getPageSource() {

        return this.appiumDriver.getPageSource();
    }

    @PublicAtsApi
    public String getContext() {

        return MobileElementFinder.defaultContext;
    }

    @PublicAtsApi
    public void setContext(
                            String context ) {

        MobileElementFinder.defaultContext = context;
    }

    @PublicAtsApi
    public String[] getAvailableContexts() {

        return ( String[] ) this.appiumDriver.getContextHandles()
                                             .toArray( new String[this.appiumDriver.getContextHandles()
                                                                                   .size()] );
    }

    @PublicAtsApi
    public Device getDevice() {

        return this.device;
    }

    @PublicAtsApi
    public class Device {

        /**
         * @param appPath application absolute path
         *
         * NOTE: 'adb' executable must be in the $PATH variable in the environment of the Appium server
* Example: export PATH=/opt/android/android-sdk_r24.0.2/platform-tools/:$PATH */ @PublicAtsApi public void installApp( String appPath ) { appiumDriver.installApp( appPath ); } /** * * @param appName /. for Android (e.g. com.axway.st.mobile/.SecureTransportMobile) * or bundle ID for iOS * @return if the application is installed or if it is not */ @PublicAtsApi public boolean isAppInstalled( String appName ) { return appiumDriver.isAppInstalled( appName ); } /** * * @param appName /. for Android (e.g. com.axway.st.mobile/.SecureTransportMobile) * or bundle ID for iOS */ @PublicAtsApi public void removeApp( String appName ) { appiumDriver.removeApp( appName ); } @PublicAtsApi public void resetApp() { appiumDriver.resetApp(); } @PublicAtsApi public void pressHWButtonBack() { appiumDriver.navigate().back(); } @PublicAtsApi public void pressHWButtonHome() { if( appiumDriver instanceof AndroidDriver ) { ( ( AndroidDriver ) appiumDriver ).sendKeyEvent( AndroidKeyCode.HOME ); } else { // The automation API that Appium uses (Apple's UIAutomation JS library) limits to only automating a single application at a time throw new NotSupportedOperationException( "Currently, Appium cannot press the home button for iOS" ); } } /** * Runs the current app as a background app for the number of seconds * requested. This is a synchronous method, it returns after the back has * been returned to the foreground. * * @param seconds number of seconds to run App in background */ @PublicAtsApi public void runAppInBackground( int seconds ) { appiumDriver.runAppInBackground( seconds ); } /** * Runs the current app as a background app for the number of seconds * requested. This is a synchronous method, it returns after the back has * been returned to the foreground. * * @param seconds number of seconds to run App in background * @param appName /. for Android (e.g. com.axway.st.mobile/.SecureTransportMobile) * or bundle ID for iOS * */ @PublicAtsApi public void runAppInBackground( int seconds, String appName ) { if( appiumDriver instanceof AndroidDriver ) { // we can get the current activity, but not its package //String currentActivity = ( ( AndroidDriver ) appiumDriver ).currentActivity(); pressHWButtonHome(); UiEngineUtilities.sleep( seconds * 1000 ); // bring application to foreground mobileDeviceUtils.executeAdbCommand( new String[]{ "shell", "am", "start", "-n", appName }, true ); } else { appiumDriver.runAppInBackground( seconds ); } } /** * Calculate file MD5 sum directly on the mobile device * * @param filePath file absolute path *
* Note for iOS: You can specify relative path too, by skipping the root slash '/' at the beginning * and pass the path relative to the application data folder
* For example: "Documents/MyAppFiles/IMG_0001.PNG"
* and we'll internally search for: * "/Users/<username>/Library/Developer/CoreSimulator/Devices/<device_id>/data/Containers/Data/Application/<app_id>/Documents/MyAppFiles/IMG_0001.PNG"
* which is the iOS Simulator application data folder path * * @return the MD5 sum of the specified file */ @PublicAtsApi public String getMD5Sum( String filePath ) { return mobileDeviceUtils.getMD5Sum( filePath ); } /** * List files and directories on the mobile device * * @param path a path on the mobile device. It can be a directory or file (if you want to check * for specific file existence) *
* Note for iOS: You have to specify a relative path to the application data folder
* For example: "Documents/MyAppFiles"
* and we'll internally search for files in: * "/Users/<username>/Library/Developer/CoreSimulator/Devices/<device_id>/data/Containers/Data/Application/<app_id>/Documents/MyAppFiles/"
* which is the iOS Simulator application data folder path * * @return {@link FileInfo} array with all the files and folders from the target path */ @PublicAtsApi public FileInfo[] listFiles( String path ) { return mobileDeviceUtils.listFiles( path ); } /** * Deletes a directory from the mobile device * * @param directoryPath the directory for deletion * @param recursively whether to delete the internal directories recursively * * Note for iOS: You can specify relative directory path too, by skipping the root slash '/' at the beginning * and pass the path relative to the application data folder
* For example: "Documents/MyAppFiles"
* and we'll internally search for: * "/Users/<username>/Library/Developer/CoreSimulator/Devices/<device_id>/data/Containers/Data/Application/<app_id>/Documents/MyAppFiles/"
* which is the iOS Simulator application data folder path */ @PublicAtsApi public void deleteDirectory( String directoryPath, boolean recursively ) { mobileDeviceUtils.deleteDirectory( directoryPath, recursively ); } /** * Deletes a file from the mobile device * * @param filePath the file for deletion * * Note for iOS: You can specify relative file path too, by skipping the root slash '/' at the beginning * and pass the path relative to the application data folder
* For example: "Documents/MyAppFiles/fileToDelete"
* and we'll internally search for: * "/Users/<username>/Library/Developer/CoreSimulator/Devices/<device_id>/data/Containers/Data/Application/<app_id>/Documents/MyAppFiles/fileToDelete"
* which is the iOS Simulator application data folder path */ @PublicAtsApi public void deleteFile( String filePath ) { mobileDeviceUtils.deleteFile( filePath ); } /** * Creates directory on mobile device * * @param directoryPath the directory for creation */ @PublicAtsApi public void createDirectory( String directoryPath ) { mobileDeviceUtils.createDirectory( directoryPath ); } /** * Copies file to device * * @param localFilePath local file path * @param deviceFilePath file path on the device */ @PublicAtsApi public void copyFileTo( String localFilePath, String deviceFilePath ) { mobileDeviceUtils.copyFileTo( localFilePath, deviceFilePath ); } /** * Copies file from device to local machine * * @param deviceFilePath file path on the device * @param localFilePath local file path */ @PublicAtsApi public void copyFileFrom( String deviceFilePath, String localFilePath ) { mobileDeviceUtils.copyFileFrom( deviceFilePath, localFilePath ); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy