In addition to the standard Appium capabilities^1 (including each driver specific capabilities) and the W3C WebDriver spec^2, the Appium server running on each HeadSpin host supports a number of custom capabilities below. In addition, the HeadSpin Appium load balancer running in the cloud supports additional capabilities that control device selection and redundancy.
Unless otherwise stated, these capabilities work for any Android, iOS, or TV device in the pool.
Supported drivers
HeadSpin supports
Host capabilities
Note, that HeadSpin allows <code class="dcode">deviceName</code> to be blank in the capabilities and will automatically use the device <code class="dcode">udid</code> instead.
Appium session
Capability |
Description |
Values |
headspin:appiumVersion |
Appium version to be used for the test. Defaults to the latest stable version installed on the host. See Setting the Appium Version below. |
e.g. 1.20.2 , 1.17.0 , 2.0.0-beta.53 |
headspin:appiumPlugins |
Appium plugins to enable in an Appium session. It is available only in Appium 2.0 session. Defaults to an empty list. |
e.g. ['relaxed-caps', 'images'] |
headspin:appiumOptions |
Appium options to include Appium server configuration for an Appium session. It is available only in Appium 2.0 sessions. See Setting Appium options for Appium 2.0 |
|
headspin:autoDownloadChromedriver |
Enable downloading chromedriver automatically from the official Google storage as Appium standard feature. Default true . |
true or false |
headspin:controlLock |
Starting the session with this set to true allows interaction with the device via the remote control UI during the session. This should be used with tools such as Appium Inspector, with which you may manually interact with the device during a session. If this is false , the device will be in view-only mode during the session. If the device is already locked by the user (by accessing it in remote control UI or via API), then an automation session cannot be started unless this is set to true . Default false . |
true , false |
headspin:enableAdbShell |
Allow Appium server to invoke mobile: shell command in On-Premise environment. For cloud environment, please refer to Android Device API to use adb commands. Default false . |
true or false |
headspin:enableBatch |
Allow Appium server to invoke execute-driver command. Default false . |
true or false |
headspin:newCommandTimeout |
Set request timeout to be the same as the newCommandTimeout in the standard Appium capabilities. If the standard capability is given, the standard value will take priority over the HeadSpin capability. |
e.g. 120 |
headspin:preferSystemUnzip |
Set APPIUM_PREFER_SYSTEM_UNZIP as false in starting an appium process when this capability is false . This prevents possible iOS application installation failure since Appium 1.22.1. Please read the official description for more details about APPIUM_PREFER_SYSTEM_UNZIP . Default false . |
true or false |
headspin:quitOnDisconnect |
Quit the session when client disconnects |
true , false |
headspin:restartDeviceOnSessionStart |
Restarts the device before starting the test. Default false . |
true , false |
headspin:screenshotSource |
Configure the screenshot source. The available values are default and camera . camera means taking a screenshot via the camera device instead of Appium. It does not affect taking an element screenshot command. Please read A/V Box API about the camera device. It returns an error response if it failed to take a screenshot via the camera device. The value will be default if the device under test does not have a camera device. Default default . |
default , camera |
headspin:useAppiumUnlock |
Unlock the device using Appium's built-in mechanism when set to true . In all cases, HeadSpin's software+hardware "pintap" system will activate if the device is still locked, which will handle MDM and other hard lock cases. Default false . |
true , false |
headspin:useMjpegScreenshotUrl |
Use HeadSpin MJPEG server to capture device screen. Defaults to false |
true , false |
headspin:waitForAvailableTimeout |
Set the timeout to wait for a locked device to be available. Defaults to 0 seconds or newCommandTimeout in the Appium capabilities, if provided. |
e.g. 90 |
headspin:assistiveTouch |
Configure iOS Assistive Touch. The assistive touch configuration will remain after the session. enable will enable the assistive touch in a session. disable will disable it. none respects the current device configuration. If this capability is left out or a value other than disable , enable , or none is used then the capability will behave as if disable was used. Defaults to disable . |
enable ,disable none |
HeadSpin session and capture
Capability |
Description |
Values |
headspin:audio.device |
If the device resides inside of an "A/V box", specify a screen device to be used for injecting/capturing audio |
front , back |
headspin:autoLabel |
Set rules to add custom session labels in session capture. See Applying labels automatically section in Selenium Capabilities for details. The rule is the same, but Appium can have wd/hub prefix in its endpoint . |
e.g. 'open headspin url': {'commands': [{'method': 'POST', 'endpoint': '/session/:sessionId/url', 'body': 'headspin.io'}], 'category': 'open url time'} |
headspin:capture |
Enable video, network, and function call capture. Default false . These capture components can be overriden individually by headspin:capture.video , headspin:capture.network , or headspin:capture.functionCall . If set, the individual settings take precedence. |
true , false |
headspin:capture.autoStart |
Force HeadSpin capture to start when setting the Appium appium:autoLaunch capability to false . Please read the table below to understand how this capability can help. Default false . |
true , false |
headspin:capture.disableHttp2 |
Prevent the device from using HTTP/2 during network capture. Default false . |
true , false |
headspin:capture.disableServerCertCheck |
Do not verify server TLS certificates during network capture. This is useful when the client makes TLS connections without SNI, because without SNI we don't know what name to expect the server certificate to contain. Default false . |
true , false |
headspin:capture.functionCall |
Enable function call capture. When set, this takes precedence over headspin:capture . Also, headspin:capture does not need to be set for this to take effect. |
true , false |
headspin:capture.ignoreHosts |
A list of ignored host:port regex patterns. These hosts are ignored from the network capture session. The pattern can be just a host name also, in which case all ports are matched. |
e.g. ['abc\.example\.com:443', '.*\.mydomain.com'] |
headspin:capture.network |
Enable network capture. When set, this takes precedence over headspin:capture . Also, headspin:capture does not need to be set for this to take effect. |
true , false |
headspin:capture.networkConfig |
Configures the network used by the device during the capture session. |
Allowed keys are shaping , redirectRules , spoofRules , headerRules . See Network Config below for details of each. |
headspin:capture.networkKeepInSessionPatterns |
Controls whether a destination host:port (or ip:port ) is kept in the session after an error. By default any destination with an error (e.g. TLS exception) will be excluded from the session, to allow the app to perform as well as possible going forward. Add glob patterns here to keep a destination with an error in the session, to continue to try to parse the network protocol for that destination. This is a list of globs that must fully match host:port or ip:port . |
e.g. ['headspin.io:443', '*.headspin.io:443'] |
headspin:capture.video |
Enable video capture. When set, this takes precedence over headspin:capture . Also, headspin:capture does not need to be set for this to take effect. |
true , false |
headspin:frameSettings |
Dictionary containing frame settings for the session. Supported settings are,
quality : JPEG compression quality in a range of 1 to 100 where 1 being the worst quality and 100 being the highest
maxWidth , maxHeight : Bounding box that the real screen frame is fit into, maintaining the aspect ratio maxFps : Maximum number frames captured in a second. This is dependant on the quality . Having a lower quality will allow higher FPS
NOTE: Currently only quality is supported across all platforms |
e.g. |
headspin:network.regionalRouting |
Sets the gateway through which network traffic will be routed, for the duration of the capture session. When the session ends, the network tunnel is removed. This capability is available for devices that support capture sessions. Note: network capture while routing through a gateway is currently unsupported, and will be disabled. |
string denoting the egress gateway, e.g. "us-nyc" , "gb-lhr" |
headspin:session.description |
Set the description of the HeadSpin session. For existing sessions, the description can be updated in the Waterfall UI or via the Session Annotation API. |
string |
headspin:session.name |
Set the name of the HeadSpin session. For existing sessions, the name can be updated in the Waterfall UI or via the Session Annotation API. |
string |
headspin:sessionTags |
Tag the session with an array of key, value tags. Tags will only be applied to sessions that have performance capture enabled. e.g. [{"demo": "tag"}, {"hello": "world"}] |
|
headspin:testData |
Add custom measurements to the session. This data will be inserted into the performance test, for this session ID |
e.g. [{"key":"App Load Time", "value":20, "title": "Custom Metrics", "units": "seconds"}] |
headspin:testName |
Sets the User Flow name of this capture session for Performance Monitoring, where all sessions with the same User Flow name are grouped together. To use this, at least one of the following capture components must be active for the session: video, network, or function call capture. For details on adding passed/failed/excluded status on the session, see User Flow Status below. |
e.g. app_load_test |
Apps
Capability |
Description |
Values |
headspin:app.id |
Specify the app ID of an APK or IPA that was uploaded using the App Management API to be installed on the device. This takes precedence over the headspin:appId and the Appium app capabilities. |
e.g. "be06ca64-712a-4695-9430-2e6937144a3e" |
headspin:app.resign |
Resign the app, specified by the app.id capability, with HeadSpin's provisioning profile. This setting currently applies only to IPA files. Default true |
true or false |
headspin:app.resignTimeout |
Set the timeout to resign the app in seconds. The resigned file is cached in the host machine in order to re-use it without resigning every session. The value can be either string or integer. This setting currently applies only to IPA files. Default 600 |
900 (string) or 900 (int) |
headspin:appId |
Specify the app ID of an APK or IPA that was uploaded using the app upload API to be installed on the device. If the Appium app capability is also defined then headspin:appId would take priority. Note: this capability is for the older v0 app API. Users are encouraged to use the App Management API and the headspin:app.id capability. |
e.g. "be06ca64-712a-4695-9430-2e6937144a3e" |
headspin:appId.resignIpa |
Resign the IPA, specified by the appId capability, with HeadSpin's provisioning profile. Default true |
true or false |
headspin:appId.resignIpaTimeout |
Set the timeout to resign the IPA in seconds. The resigned IPA file is cached in the host machine in order to re-use it without resigning every session. The value can be either string or integer. Default 600 |
900 (string) or 900 (int) |
headspin:removeAppPackages |
Provide a list of package globs to uninstall before starting the test |
e.g. ['com.example.app', 'com.xyz.app', 'com.foo.*'] |
headspin:resetUiAutomator2 |
Uninstall io.appium.uiautomator2.server and io.appium.uiautomator2.server.test packages before starting the test. Default false . |
true , false |
If <code class="dcode">appium:app</code> capability has http/https scheme, and the URL has <code class="dcode">.ipa</code> extension name, HeadSpin's provisioning profile will be applied by default to avoid possible installation failure. <code class="dcode">headspin:app.resign</code>, <code class="dcode">headspin:app.resignTimeout</code>, <code class="dcode">headspin:appId.resignIpa</code> and <code class="dcode">headspin:appId.resignIpaTimeout</code> capabilities can handle the resigning as same.
TV devices
TV devices support limited capabilities as below.
- Capture
- Video capture is available via A/V Box
- Network capture is not available
- Supported capabilities
headspin:waitForAvailableTimeout
headspin:screenshotSource
headspin:newCommandTimeout
HeadSpin commands
These HeadSpin commands are designed to be run by the Execute Mobile Command interface.
Command Name |
Description |
Arguments |
headspin:quitSession |
End the session and optionally set the session's user flow status at the same time. See User Flow Status below. |
{"status": "[passed|failed|excluded|not_set]"} |
<code class="dcode">app</code> standard Appium capability
HeadSpin drops the <code class="dcode">app</code> capability when <code class="dcode">*</code> is provided as the value.
The value <code class="dcode">*</code> is invalid for standard Appium, but some Appium client tools require the app capability even when it is not necessary. In these cases you can set * as the value to establish an Appium session using another capability.
<code class="dcode">appium:autoLaunch</code> and <code class="dcode">headspin:capture.autoStart</code>
Appium uses an <code class="dcode">appium:autoLaunch</code> capability to control if Appium launches the application under test. This is documented in the Appium documentation for creating a new session. The application under test launches when the capability is <code class="dcode">true</code>. The default is <code class="dcode">true</code>.
When <code class="dcode">appium:autoLaunch</code> is false, Appium does not launch the application under test automatically in creating a new session. Then, you are responsible for launching the application under test manually with one of Launch App, Activate App, Reset App or a few mobile commands. HeadSpin session capture starts when Appium receives one of these commands.
If you have a scenario where you need to launch the application under test without the standard application launch commands, for example, when you test a Progressive Web Application (PWA) on iOS, then HeadSpin session capture does not start automatically as described above. Instead, you can combine the <code class="dcode">"appium:autoLaunch"</code>: false capability with the <code class="dcode">"headspin:capture.autoStart"</code>: <code class="dcode">true</code> capability to start HeadSpin capture anyway. Then you may launch the application under test in any available manner, for example, by tapping the PWA application icon on the home screen.
Setting the Appium Version
New Appium versions are made available to customers as soon as they are certified on the platform. HeadSpin works with the Appium team to test and provide new versions ^3. A few select versions are available on every host by default. You can always confirm what versions are available in a host via the version API below. Please contact us if you need a specific version that is not in the result.
You should always set <code class="dcode">headspin:appiumVersion</code> to the version you are using, to avoid changes related to system updates in the future.
Appium 2.0 support
HeadSpin supports Appium 2.0 and drivers, which are available over Appium 2.0. The session needs to specify Appium 2.0 with <code class="dcode">headspin:appiumVersion</code> right now, such as <code class="dcode">"headspin:appiumVersion": "2.0.0-beta.53"</code>. The available Appium versions and driver versions are listed in the result of Check available Appium versions below. The default keys/values in the drivers are the default driver version for each <code class="dcode">appium:automationName</code> session.
Check available Appium versions
HeadSpin host provides the list of available Appium versions as API. It helps to confirm which Appium versions can run on the host machine. Please contact us if you want to use a particular Appium version which is not available on the host machine.
The minimum supported version is <code class="dcode">1.11.0</code>.
Route |
Method |
https://{headspin-host}:{headspin-port}/v0/{your-api-token}/wd/hub/versions |
GET |
Example
curl -X GET https://proxy-jp-tyo-1.headspin.io:7001/v0/{your-api-token}/wd/hub/versions
Response
{
"status": 0,
"session_id": null,
"value": {
"default": "1.22.3",
"available": ["1.21.0", "2.0.0-beta.53", "1.22.3"],
"drivers": {
"default": {
"xcuitest": "4.12.1"
}
},
"plugins": {
"default": {}
}
}
}
The <code class="dcode">available</code> is available Appium versions. You can specify them as <code class="dcode">headspin:appiumVersion</code>. The <code class="dcode">default</code> is chosen if a create session capabilities has no <code class="dcode">headspin:appiumVersion</code>.
The <code class="dcode">default</code> in the <code class="dcode">drivers</code> is the pairs of <code class="dcode">appium:automationName</code> and the available version on the host. The pair will be used when you create a new session with the Appium 2.0 as <code class="dcode">appiumVersion</code>.
Please contact us if you would like to use a version which is not in the list.
Setting <code class="dcode">appiumOptions</code> for Appium 2
<code class="dcode">headspin:appiumOptions</code> capability is available to configure the Appium server in a session, using the capabilities suggested by the Appium team for providers supporting Appium 2.0*.
Available keys
Capabilities |
Description |
Values |
version |
Appium version to be used for the session. |
e.g. 2.0.0 |
plugins |
The list of plugin names to be used for the session. |
e.g. ['images', 'relaxed-caps'] |
Example
{
"headspin:appiumOptions": {
"version": "2.0.0",
"plugins": ["images", "relaxed-caps"]
}
}
Without <code class="dcode">headspin:appiumOptions</code>, you also can specify them as individual HeadSpin Appium capabilities.
- <code class="dcode">version</code> works as same as <code class="dcode">headspin:appiumVersion</code>
- <code class="dcode">plugins</code> works as same as <code class="dcode">headspin:appiumPlugins</code>
The individual capabilities will take priority over those inside <code class="dcode">headspin:appiumOptions</code>. For example, if a capabilities set has both <code class="dcode">"headspin:appiumOptions": { "version": "2.0.0" }</code> and <code class="dcode">"headspin:appiumVersion": "1.22.3"</code>, the session will use Appium 1.22.3 provided as <code class="dcode">headspin:appiumVersion</code>.
Network Config
Key Name |
Description |
Values |
shaping |
For Android devices only, this specifies network conditioning targets. All values must be zero or positive. up and down set upper bounds for the upload and download rate in megabits per second (Mbps), respectively. rtt is the additional delay in seconds on top of the native link round-trip time. loss applies a further packet loss fraction between 0 and 1 to the native link conditions (received packets fraction = (1 − native link loss) * (1 − simulated loss)). |
e.g. {"down": 5.1, "up": 1.2, "rtt": 10, "loss": 0.1} |
redirectRules |
A list of rules host_regex=destination_host . If the host regex matches a host, the request will be rewritten as if the client sent it to destination_host instead. Backtick back references are allowed in the destination host. |
e.g. ["foo\.com=bar.com", "(.*)headspin\.io=\1headspin.com"] |
spoofRules |
A list of rules host_regex=destination_host . If the host regex matches a host, the request IP will be changed to the IP resolved by destination host, as if the DNS record for the original host were changed to the destination host's. |
e.g. ["foo\.com=13.33.148.190", ".*\.headspin.io=13.33.148.51"] |
headerRules |
A list of rules host_regex=header:value . If the host regex matches, the header will be injected into the request. Multiple headers of the same name will be comma separated in the final request. Backtick back references are allowed in the header and value. |
e.g. [".*=X-Custom:MyApp"] |
User Flow Status
To mark sessions passed, failed, or in some error state, you can either use a HeadSpin Appium command to end the session, or use the Performance Monitoring API at any time. In either case, the session must be attached to a user flow by specifying <code class="dcode">headspin:testName</code> (this in turn requires that capture is turned on for the session, see description in the Appium capabilities section).
Valid user flow status strings are: <code class="dcode">passed</code>, <code class="dcode">failed</code>, <code class="dcode">excluded</code>, and <code class="dcode">not_set</code>.
Set user flow status using the <code class="dcode">headspin:quitSession</code> command
- Set <code class="dcode">headspin:testName</code> when starting the session. This is required for the next step to work.
- End the session by sending the command <code class="dcode">headspin:quitSession</code> with the argument <code class="dcode">{"status": <user flow status>}</code>.
For example, the Python script below sets the session's status to <code class="dcode">excluded</code>:
from appium import webdriver
caps = {
... # Other capabilities
"headspin:testName": "test user flow", # Required to link session to user flow
"headspin:capture": True # Required to have a capture session
}
driver = webdriver.Remote('<Web Driver URL>', caps)
# Perform tests
...
response = driver.execute_script('headspin:quitSession', {'status': 'excluded'})
This will end the session and set its user flow status at the same time. It can be used in place of the <code class="dcode">driver.quit()</code> command to end the session. When called without any argument, it has the same effect as <code class="dcode">driver.quit()</code>.
If the command is successful, there will be no return value (<code class="dcode">response is None</code> is <code class="dcode">True</code>). However, if an argument is given but it could not be processed into a valid user flow status, then a string containing information about the problem will be returned. The session will still end, but no user flow status will be set.
Set user flow status using Performance Monitoring API
- Set headspin:testName when starting the session, or link the session to a user flow after it has started using the Performance Monitoring API.
- POST to the Performance Monitoring API to set the status of the session, using the session ID from the driver.
For example, the Python script below sets the session's status to <code class="dcode">passed</code> using <code class="dcode">requests</code> to post to the API:
from appium import webdriver
import requests
# Start a session with capture
driver = webdriver.Remote(...)
# Set api_token in the header
headers = {
'Authorization': 'Bearer <your_api_token>'
}
perf_data = {
'session_id': driver.session_id,
'status': 'passed'
}
requests.post('https://api-dev.headspin.io/v0/perftests/upload', headers=headers, json=perf_data)
BYOD and <code class="dcode">appInstallStrategy</code>
Bring Your Own Device allows you to add your own devices to HeadSpin platform. You can run appium sessions against the devices, but the application installation might fail in iOS for some reason. You can try the Appium capability <code class="dcode">"appium:appInstallStrategy": "ios-deploy"</code> to help complete the installation successfully.
Resolving Errors
HeadSpin Appium sessions return errors directly from the underlying Appium driver without modification. Additionally, the HeadSpin platform may return the following extra errors:
HTTP status code |
Error (error ) |
Note |
How to Resolve |
400 |
invalid argument |
Request body is invalid or API token in the request is invalid. |
Make sure the API token is valid or Appium commands and correct. |
403 |
unknown command |
The command is not allowed. |
Please check the error message. For example, Execute Driver Script Appium command needs headspin:enableBatch capability. |
404 |
invalid argument |
The device was not found. |
Run your tests with correct capabilities. |
404 |
invalid session id |
Cannot find active session id on the host. |
Run your tests from session that was created. |
500 |
session not created |
Failed to create a new session. This error includes when a device is unavailable by some reason like the device was locked by someone or the device was disconnected. |
Please check the error message. |
500 |
unknown error |
An unknown error occurred, or the session was terminated. |
Please contact support if this continues to happen. |