Introduction
This page shows how to use the ATS UI Engine in order to automate the UI testing of native, hybrid and mobile web applications. This includes applications in emulator or real mobile device.
NO device rooting, NO patching, NO instrumentation(recompiling with additional modules/libraries) of the tested application is needed!
The tests runs against the same application provided to the clients.
The current implementation uses Appium framework, but if this get changed in the future, the UI Engine needs to make the change transparent to the test cases.
There are some preparation/configuration steps in order to run tests. For more details see Configuration section.
Quick example
Here we will take a look at a simple example to see how mobile engine tests look like
// 1. initialize the driver (device connector) MobileDriver mobileDriver = UiDriver.getMobileDriver( MobileDriver.DEVICE_ANDROID_EMULATOR, "4.4", null, "localhost" ); mobileDriver.setAndroidHome( "D:\\android\\android-sdk_r24.0.2\\" ); // if not already set as an Environment Variable (ANDROID_HOME) // 2. start the driver (starts the device emulator if not already started and load the tested application) mobileDriver.start( "D:\\mobile_apps\\android\\SecureTransportMobile.apk" ); // 3. get the engine to work with MobileEngine mobileEngine = mobileDriver.getMobileEngine(); // 4. specify the file describing the UI components we want to work with mobileEngine.loadMapFile( "MyUiComponents.map", "login" ); // 5. work with some UI components mobileEngine.getTextBox( "usernameTB" ).setValue( "admin" ); mobileEngine.getTextBox( "passwordTB" ).setValue( "pass" ); mobileEngine.getButton( "loginB" ).click(); // "tap" on the button // 6. stop the driver ( close the tested application ) mobileDriver.stop();
This example basically does the following:
- Initialize the device connection:
- we specify we will be working with Android emulator. Other possibilities are Android device, iPhone/iPad simulator or a specific iPhone/iPad device (iPad 2, ...)
- for Android a path to the ANDROID_HOME is needed to be specified - Start the driver - starts the device emulator/simulator if not already started and load the tested application
- Get a reference to the later used engine, in this example this is an MobileEngine as we will be testing a mobile application.
- Specify the file describing the UI components we want to work with
- in this example we suppose we have a map file which defines the UI components of interest. We also have dedicated a section in that file called "login" which contains the components at the login page of our application. - Work with some UI components. In our case we:
- set the value of a Text Box with our user name
- set the value of a Text Box with our password
- click/tap a login Button - Stop the driver - close the tested application
Configuration
Setup environment
- Android
- Install Android SDK
> /opt/android/android-sdk_r24.0.2/tools/android & - Setup environment variables
> export PATH=/opt/android/android-sdk_r24.0.2/platform-tools/:$PATH
> export ANDROID_HOME=/opt/android/android-sdk_r24.0.2/ - Create and start AVD (Android Virtual Device)
> /opt/android/android-sdk_r24.0.2/tools/android avd &
- Install Android SDK
- iOS
- Install Xcode
- (Optional) Open and do some settings to the iOS Simulator (for example iCloud server)
> open /Applications/Xcode.app/Contents/Developer/Applications/iOS\ Simulator.app
Install and start Appium Server
- Windows
Use Appium installer (Appium-windows-nnnnn.zip) from here - Mac OS X
Use Appium installer (Appium-mac-NNN.dmg) from here - Linux
- Install node.js and npm (its packet manager)
- Install Appium server
> npm install -g appium
> npm install wd - Start Appium server
> appium --session-override
Configure Appium Server
An important option that should be used in most of the cases is --session-override, which allows next test executions to use create a new session and override the existing one. Sometimes the connection could drop or a test could miss session closing due to an error and without session overriding the next test executions would fail until the session expires and a new one could be successfully created.
Detailed information about the Appium Server start options/flags can be found here.
UiEngine Configuration
Using the UiEngineConfigurator class you can do some changes to the UI Engine behavior.
For example, the following code will change how long time to wait for an element to be found
// wait for up to 5 seconds UiEngineConfigurator.getInstance().setElementStateChangeDelay( 5000 );
Mobile Driver initialization
Mobile driver initialization happens through the UiDriver.getMobileDriver(...) method, where accepted arguments are:
- deviceName - the kind of mobile device or emulator to use. You can use one of MobileDriver driver type constants. For example: Android Emulator, iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Galaxy S4, ... On iOS, this should be one of the valid devices returned by instruments with "instruments -s devices"
- platformVersion - mobile OS version. For example: 8.1, 4.4 ... For Android it could be skipped (null)
- udid - unique device identifier of the connected physical device or null for emulator/simulator usage
- host - the host address of the Appium server. null may be passed if you want to work with localhost emulator
- port - the port number of the Appium server or null to use the default Appium server port 4723
Examples:
MobileDriver driver = UiDriver.getMobileDriver( MobileDriver.DEVICE_ANDROID_EMULATOR, null, null, "127.0.0.1" ); driver.setAndroidHome( "D:\\android\\android-sdk_r24.0.2\\" ); // if not already set as an Environment Variable (ANDROID_HOME)
MobileDriver driver = UiDriver.getMobileDriver( MobileDriver.DEVICE_IPAD_SIMULATOR, "8.1", null, "10.11.12.13" ); // or MobileDriver driver = UiDriver.getMobileDriver( "iPad 2", "8.1", "1ae203187fc012g", "10.11.12.13" );
Supported UI elements
Following is the current list with all supported UI elements. They work both for Android and iOS platform.
You can see the java classes per UI element, the list of actions you can run on each UI element and the list of attributes the needed to find the UI element.
Button
A button
class |
instantiation |
searched by |
---|---|---|
MobileButton |
mobileEngine.getButton() |
1. id |
2. name |
||
3. text |
||
4. partialText |
||
5. xpath |
methods |
description |
---|---|
click |
tap it |
clickIfExists |
tap it if exists specifying a waiting timeout |
scrollTo |
scroll to the element |
getTextContent |
get its text content |
getAttributeValue |
get element attribute value |
Text Box
A single line text box which value can be changed
class |
instantiation |
searched by |
---|---|---|
MobileTextBox |
mobileEngine.getTextBox() |
1. id |
2. name |
||
3. text |
||
4. partialText |
||
5. xpath |
methods |
description |
---|---|
getValue |
get its value |
setValue |
set its value |
verifyValue |
verify its value is as specified |
verifyNotValue |
verify its value is not as specified |
click |
tap it |
clickIfExists |
tap it if exists specifying a waiting timeout |
scrollTo |
scroll to the element |
getTextContent |
get its text content |
getAttributeValue |
get element attribute value |
Check Box
A check box
class |
instantiation |
searched by |
---|---|---|
MobileCheckBox |
mobileEngine.getCheckBox() |
1. id |
2. name |
||
3. text |
||
4. partialText |
||
5. xpath |
methods |
description |
---|---|
check |
check it |
unCheck |
un-check it |
isChecked |
tell if it is checked |
verifyChecked |
verify it is checked |
verifyNotChecked |
verify it is not checked |
click |
tap it |
clickIfExists |
tap it if exists specifying a waiting timeout |
scrollTo |
scroll to the element |
getTextContent |
get its text content |
getAttributeValue |
get element attribute value |
Link
A link
class |
instantiation |
searched by |
---|---|---|
|
mobileEngine.getLink() |
1. id |
2. name |
||
3. text |
||
4. partialText |
||
5. xpath |
methods |
description |
---|---|
click |
tap it |
clickIfExists |
tap it if exists specifying a waiting timeout |
scrollTo |
scroll to the element |
getTextContent |
get its text content |
getAttributeValue |
get element attribute value |
Generic element
Any element. This is generic case to work with any element and also container ones like views and div/span elements in HTML.
class |
instantiation |
searched by |
---|---|---|
MobileElement |
mobileEngine.getElement() |
1. id |
2. name |
||
3. text |
||
4. partialText |
||
5. xpath |
methods |
description |
---|---|
click |
tap it |
clickIfExists |
tap it if exists specifying a waiting timeout |
scrollTo |
scroll to the element |
getTextContent |
get its text content |
getAttributeValue |
get element attribute value |
Popups - Alerts, Prompts and Confirms
Elements in like Alert,Prompt are found the same way as other UI elements.
Running against real devices
Android
- Connect device to computer via USB.
- Make sure device and computer are connected to the same WiFi network.
Run this command to restart adb in TCP mode and setups connections to the adb daemon on the device on port 5555 (http://developer.android.com/tools/help/adb.html):
adb tcpip 5555
- Disconnect device from the USB cable
- Get IP address of your phone ("Settings" -> Wifi -> "Your connected network" -> "Your IP address")
Run this command to connect adb to your device over Wifi using its IP address:
adb connect <IP address>
Verify, that adb works remotely:
adb devices
- Run the tests (now over WiFi)
WebView issue on Android 4.4 or later
On Android 4.4 (KitKat/API 19) or later, in order to debug WebViews on real devices you have to enable it explicitly in the application code.
To enable WebView debugging, call the static method setWebContentsDebuggingEnabled on the WebView class (source).
import android.webkit.WebView; import android.content.pm.ApplicationInfo; import android.os.Build; ... public void onCreate(Bundle savedInstanceState) { ... if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE)) { WebView.setWebContentsDebuggingEnabled(true); } } ... }
Troubleshooting
Currently Appium shows the original/actual error in its Console only (we hope it will be fixed soon and these errors will be passed to the Appium Java client and we will have more accurate exception messages), so if you doesn't understand the reason of the failure check the Appium console for the last error message (search for text like: "Original error: ...").
Error: "We already have a chromedriver instance running"
There are more than one "chromedriver" instances running. To fix that, kill all chromedriver instances and start Appium server again
Error: "'java -version' failed. Error: spawn ENOENT"
This error appears on the Appium console even when the 'java -version' works and the PATH variable looks fine, but the problem is there. %PATH% must also contain the windows system directories (i.e. %SystemRoot%\system32;%SystemRoot%), because behind the scenes Appium uses something in those directories when launching 'java -version' (source: https://github.com/appium/appium/issues/4229)
Back to parent page
Go to Table of Contents