HeadSpin Documentation

Using Espresso


Espresso is an Android UI Test Framework that allows users to create automated UI tests for Android applications. Espresso tests run within Android Studio and, to execute on a real Android device, the test device must be connected via USB. This document will show you how to easily execute an Espresso test on a HeadSpin Android device, as well as briefly reviewing how to initiate sessions on a device as well as how to attach sessions to a User Flow using the HeadSpin UI and/or API.


You will need to download and install our proprietary CLI in order to use HeadSpin devices with Espresso testing.

1. Click on your name in the upper right-hand corner of the Headspin UI.


2. Click on Settings.


3. Scroll down to the 'Downloads' section and then select the appropriate CLI installation package for your system. Supported platforms are Mac, Linux, and Windows. Download and install.

Connect Your Android Device

Once you have successfully installed the CLI, you can connect a HeadSpin device to your computer using the HeadSpin CLI command 'hs connect'.

1. Go to the Remote Control page from the Nav Bar. Start the device that you would like to connect from the HeadSpin UI’s Devices list.

select device

2. Once the device has opened its live Remote Control view, click on 'Tools' from within the interactive window to the right of the live device view.

remote control panel

3. On the Tools page, In the Remote Debug section, click on the clipboard icon to copy the hs connect command for this device.


4. Open a terminal window, paste the command, and hit 'Enter'.

hs connect use

5. Verify that the connection has been made between your machine and the device by executing 'adb devices', as demonstrated below.

adb device

Execute Your Espresso Test from Android Studio

In Android Studio, you will see the connected device in the 'Device' dropdown. Make sure your connected device is selected and hit “Play”. Your Espresso test will then execute on the device.

android studio

You can watch the execution on the device in real time from the HeadSpin UI. In the Remote-Control Devices list, click on the blue button beside your selected device. This will pull up the view of the device within HeadSpin as your test runs on it.


Capturing a Session - UI and API

A session, to clarify, represents a single touchpoint between a user and your application. It is a recording of this touchpoint’s actions taken on a device as part of an automated or manual test. You can use the UI to start or stop a session, but it may be more convenient or reliable for you to use API to do this while you are using Espresso for your testing framework. You can use API to gather data on the sessions your organization performs, as well as starting or stopping a session.

Within the UI, to start a session, you must first go to the Remote Control page and begin viewing the device on which you intend to test. Within the device’s Remote window view, click on the blue camera icon in the upper-right area of the Remote view controls. This will create a session and begin recording on the device.

create session

To stop recording, click that same button, which will now be colored green.

End session

When you finish recording a session, the HeadSpin UI will prompt you to view your session’s data in either waterfall or Issue UI, and provide links to those pages.

cue data

API - Create a session

Route Method
/v0/sessions POST

To start a session on a device, you must first lock that device. Lock the device through the HeadSpin UI or using the Android Device API. Browsers require starting and stopping a capture session using the HeadSpin Selenium capture capabilities. Please refer to Selenium Capabilities and Chrome DevTools.

Request Body

The request body must contain a JSON object with a minimum of:

    "session_type": "capture",
    "device_address": "<device_address>"

For optional session configuration parameters, please review our Session API documentation.


curl -X POST https://<your_api_token>@api-dev.headspin.io/v0/sessions -d '{"session_type": "capture","device_address": "{android-device-serial}@{hostname}"}'


If the request is successful, the response is a JSON object with details of the created session, including <code class="dcode">session_id</code>.

    "companion_id": null,
    "session_type": "capture",
    "start_time": 1571175936.264,
    "endpoints": [],
    "state": "active",
    "session_id": "<session_id>",
    "device_id": "<device_id>"

If the request fails, you may get:

  • <code class="dcode">{"status": "Device is currently in use by someone else.", "status_code": 403}</code>: Someone else is currently using the device. Choose another device to create a session, or wait until this device is free.
  • <code class="dcode">{"status": "Invalid device ID.", "status_code": 404}</code>: The device ID specified doesn't exist. Double check that the device ID is correct.
  • <code class="dcode">{"status": "Device must be locked before capture.", "status_code": 403}</code>: The device must be locked by you before a session can be created. Lock the device through the UI or an API call.

Stop a session

Route Method
/v0/sessions/{session_id} PATCH

Browsers require starting and stopping a capture session using the HeadSpin Selenium capture capabilities. Please refer to Selenium Capabilities and Chrome DevTools.

Request Body

The request body must be this JSON object:

{ "active": false }


curl -X PATCH -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/sessions/{session_id} -d '{"active": false}'


  • A <code class="dcode">HTTP 200 OK</code> response with <code class="dcode">{"msg": "Video uploaded to https://api-dev.headspin.io/v0/sessions/{session_id}.mp4"}</code> is returned. This message contains a link to the captured video. The name of the video is the session ID.
  • A <code class="dcode">HTTP 500</code> response if the request fails. Check that you have the right JSON object in the request body.
  • A <code class="dcode">HTTP 404</code> Not Found response if the request fails. Make sure that the session id in your request is valid.

Optional Parameters

  • <code class="dcode">?include_all={true|false}</code>: If <code>true</code>, this will return both live (active) sessions and ended (inactive sessions). If this value is <code class="dcode">false</code>, only live sessions will be included. The default value is <code class="dcode">false</code>.
  • <code class="dcode">?num_sessions={n}</code>: The number of sessions you want the API request to return, sorted by most recent. The default value is 10 and will return up to 10 sessions.
  • <code class="dcode">?tag={key}:{value}</code>: Select sessions that contain the tag defined by tag key <code class="dcode">key</code> and tag value <code class="dcode">value</code>. Spaces in either the tag key or value may be represented using <code class="dcode">+</code>. For example, sessions containing the tag <code class="dcode">my example: this is an example tag</code> could be selected using the query argument <code class="dcode">?tag=my+example:this+is+an+example+tag</code>. This query argument may be provided multiple times to select sessions containing at least one of the tags provided.


To get a list of the most recent 20 sessions, both active and inactive:

curl 'https://<your_api_token>@api-dev.headspin.io/v0/sessions?include_all=true&num_sessions=20'

To get sessions containing at least one of the tags <code class="dcode">my:tag</code> or <code class="dcode">my other</code>:<code class="dcode">example tag</code>:

curl 'https://<your_api_token>@api-dev.headspin.io/v0/sessions?include_all=true&num_sessions=20&tag=my:tag&tag=my+other:example+tag'


The response is a JSON object with the <code>sessions</code> key, and it contains a list of sessions in your org matching the optional parameters <code class="dcode">include_all</code> and <code class="dcode">num_sessions</code>.

            "companion_id": null,
            "session_type": "capture",
            "start_time": 1565291652.17,
            "state": "ended",
            "session_id": "<session_id>",
            "device_id": "<device_id>"
          "companion_id": null,
          "session_type": "capture",
          "start_time": 1539154924.161,
          "state": "ended",
          "session_id": "<session_id>",
          "device_id": "<device_id>"

Adding a Session to a User Flow - UI and API

User Flows are a grouping tool HeadSpin uses to give you powerful data analysis options by comparing any number of sessions across any time scale. A User Flow is really just a collection of sessions, typically grouped according to a user intention. As an example, you could create a "Checkout" User Flow and add sessions that test out the various steps of your application's checkout experience.

Again, you can explore the creation of User Flows in our UI within the Performance Sessions and Performance Monitoring tabs, but it may be more convenient for you to use API to add a session to a User Flow.

Within the UI, to add a session to a User Flow, go to the Performance Sessions tab to view a list of sessions. You can search for a specific session in the search bar at the top of the page if you do not see the session you want to add to a User Flow. Click on either the Waterfall or Issue UI icons beside your selected session to view that session’s info.

performance session

On the session’s information page, in either Waterfall or Issue UI, you will see a button in the upper-left corner of the screen labeled "Add to User Flow". Clicking this button will bring up the 'Add Session to a User Flow' modal.

HeadSpin waterfall UI
HeadSpin Burst UI
Userflow Modal

Within this modal you can select a previously created User Flow from the dropdown list or create a new one if desired. You can also write out a description for the session that will be attached to it within the assigned User Flow, and you can select a status (passed, failed, excluded) for the session’s outcome. Note that a User Flow and status assignment are mandatory.

API - Attaching a Session to a User Flow

Route Method
/v0/userflows/{user_flow_id}/sessions POST


  "session_id": "..." // Session UUID ID, required
  "status": "..." // One of "Passed", "Failed", "Excluded", optional
  "status_message": "..." // Optional status message


● <code>200</code>: Updated session info.

  • <code class="dcode">user_flow_id</code>
  • <code class="dcode">perf_event_id</code>
  • <code class="dcode">status</code>
  • <code class="dcode">status_message</code>
  • <code class="dcode">host</code>
  • <code class="dcode">device_id</code>
  • <code class="dcode">event_time</code>: ISO format timestamp.

● <code class="dcode">400</code>:

  • Missing argument (<code class="dcode">session_id</code>).
  • Invalid arguments (bad <code class="dcode">session_id</code>).
  • Invalid status (Must be one of "Passed", "Failed", "Excluded").
  • Session already belongs to another user flow.

● <code class="dcode">404</code>: Session or user flow does not exist.


curl -X POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/userflows/{user_flow_id}/sessions \
     --data '{"session_id": "{session_id}"}'
# Output
  "user_flow_id": "f24cbec7-b04c-11ec-97a0-06c4c57ba6cd",
  "perf_event_id": "f527cb02-d8ce-471d-9660-689bff371b02",
  "session_id": "9f527e3f-daa1-11ec-ac12-06c4c57ba6cd",
  "status": "Not Set",
  "status_message": null,
  "host": "proxy-us-mvo-6.headspin.io",
  "device_id": "00008030-000559D902F0C02E",
  "event_time": "2022-05-23 10:07:04"

For more information on interacting with User Flows through the API, check out our documentation here.