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