Appium Desired Capabilities for Android Emulator
โก Smart Summary
Desired capabilities are the key-value pairs an Appium client sends when it opens a session, telling the server which platform, device, driver and application the automated test should run against.
What is Desired Capabilities
โDesired Capabilitiesโ help us modify the behaviour of the server during automation. In Appium it is a hashmap, or key-value pair, used to send a command to the Appium server, where every client command runs in the context of a session.
For example, a client sends a POST /session request containing a JSON object to the Appium server.
So, to send a request or maintain a session with the server, a set of key and value pairs is used. This is known as โDesired Capabilitiesโ.
import io.appium.java_client.AppiumDriver; import org.openqa.selenium.remote.DesiredCapabilities; { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability("deviceName","Android Emulator"); capabilities.setCapability("platformVersion", "4.4"); }
Important Role of Desired Capability
- โDesiredCapabilitiesโ help the user control the session request with the server. For example, for an iOS session we set the capability platformName = iOS, and for an Android session platformName = Android.
- โDesiredCapabilitiesโ are used to set up the WebDriver instance, for example FirefoxDriver, ChromeDriver or InternetExplorerDriver.
- DesiredCapability is very useful for Selenium Grid. For example, it is used to run different test cases on a different browser and a different operating system. Based on the stated capability, the Grid hub points to the corresponding node. Nodes are defined using the โsetโ property methods:
DesiredCapabilities obj = new DesiredCapabilities(); obj.setBrowserName("firefox"); obj.setVersion("18.0.1"); obj.setPlatform(org.openqa.selenium.Platform.WINDOWS);
- A desired capability is a library-defined package. Before using โDesiredCapabilitiesโ, it should be imported from the library below.
Org.openqa.selenium.remote.DesiredCapabilities
Appium supports both Android and iOS, so there is a separate set of Appium server capabilities for each platform.
The table below shows some commonly used Android capabilities and the values to use.
| Capabilities | Description | Values/Uses |
|---|---|---|
| appPackage | Call the desired Java package in Android that the user wants to run |
Value= com.example.myapp/ Obj.setCapability(โappPackageโ, โcom.whatsappโ); |
| appActivity | Application activity that the user wants to launch from the package. |
Value= MainActivity, .Settings Obj.setCapability(โappActivityโ, โcom.whatsapp.Mainโ); |
| appWaitPackage | Package that the application needs to wait for | Value=com.example.android.myapp |
| appWaitActivity | Any Android activity that the user needs to wait for |
Value= SplashActivity capabilities.setCapability(โappWaitActivityโ, โcom.example.game.SplashActivityโ) |
NOTE: refer to the Appium documentation to view more Android capabilities.
The table below shows some commonly used iOS capabilities and the values to use.
| Capabilities | Description | Values |
|---|---|---|
| LaunchTimeout | Total time (in ms) to wait for instrumentation. | 2000 |
| UDID | To identify the unique device number of a connected physical device | 166aestu4 |
NOTE: refer to the Appium capabilities guide to view more iOS capabilities.
How Desired Capabilities Changed in Appium 2
The examples above come from the Appium 1 era and still show the shape of a capability set, but two rules changed and both will stop a modern session from starting.
First, the W3C WebDriver specification defines only a small set of standard capabilities, of which platformName and browserName matter here. Every other capability is a vendor extension and must carry a namespace prefix ending in a colon. Appiumโs prefix is appium:. So deviceName becomes appium:deviceName and platformVersion becomes appium:platformVersion. Appium 2 also requires appium:automationName, because drivers are installed separately rather than bundled with the server.
Second, repeating the prefix gets tedious, so Appium accepts a single appium:options capability whose value is an object. Capabilities inside that object need no prefix, and where a name appears both inside and outside the object, the inner value wins.
{
"platformName": "iOS",
"appium:options": {
"automationName": "XCUITest",
"platformVersion": "16.0",
"app": "/path/to/your.app",
"deviceName": "iPhone 12",
"noReset": true
}
}
โ ๏ธ Version note: on the Java side, Selenium 4 and Appium Java client 8 deprecated the DesiredCapabilities class shown earlier. Driver-specific builders inherited from BaseOptions replace it โ UiAutomator2Options for Android and XCUITestOptions for iOS โ with a one-to-one mapping from each old setCapability call. The original code above is kept here as the historical example.
Extracting Packages & Activities information
Packages are bundled files or classes. They give an organised structure to modular programming. In Java, different packages are stored in a single JAR file, and the user can call that JAR for full execution. A similar concept is followed in mobile application development.
In the Android operating system, all applications are installed in the form of Java packages. So, to extract package path information, the Android PackageManager class is used.
It retrieves package and activity information for pre-installed and post-installed applications on the device.
You can get an instance of the PackageManager class by calling getPackageManager(). This method can access and manipulate the packages and related permissions of the installed applications.
For example:
PackageManager pManager = getPackageManager();
List<ApplicationInfo> list = pManager.getInstalledApplications(PackageManager.GET_META_DATA)
How to Find appPackage and appActivity with adb
The PackageManager route above works from inside an application. As a tester you usually have only the installed build, so the quicker path is a query over adb against a connected device or emulator.
Open the application on the device by hand, then run one of the commands below from a terminal in the platform-tools folder. The command prints the window that currently has focus, and the value is formatted as package/activity.
adb shell dumpsys window | find "mCurrentFocus" adb shell dumpsys window windows | grep -i "mCurrentFocus"
Use the first form in the Windows command prompt and the second in a Unix shell or Git Bash. Read the result as two halves: everything before the slash is the value for appPackage, and everything after it is the value for appActivity.
Two cautions apply. The focused activity is whatever is on screen at that moment, which is not always the activity the application starts with โ if a session fails during driver initialisation, launch the app fresh and read the value again. And if a splash screen appears first, the entry activity will differ from the one you eventually want to assert against, which is exactly the case appWaitActivity exists for.
A visual alternative is uiautomatorviewer, which captures the current screen hierarchy and shows the package and class of every node.
Common Desired Capabilities Errors and How to Fix Them
Most failed Appium sessions end before a single test step runs, and the cause is almost always in the capability set rather than in the test. The table below maps each message to its usual fix.
| Message | Likely cause | Fix |
| Invalid or unsupported WebDriver capability | A non-standard capability was sent without the vendor prefix | Add appium: to it, or move it inside appium:options |
| The desired capabilities must include either an automationName or a platformName | Appium 2 cannot pick a driver | Set platformName and appium:automationName explicitly |
| Cannot start the app. Original error: activity used to start the app does not exist | appActivity does not match the manifest | Re-read the value with the dumpsys command above |
| Session did not start: no devices found | No emulator or handset is attached | Confirm the device with adb devices before launching |
| A new session could not be created after the timeout | A splash screen delays the entry activity | Set appWaitActivity and raise appWaitDuration |
| Application state is not reset between runs | Default reset behaviour was overridden | Review appium:noReset and appium:fullReset for the run you want |
When a session refuses to start, read the Appium server log rather than the client stack trace. The server states which capability it could not satisfy, and that line names the fix.
