Run E2E tests on EAS Build

Edit this page

Learn how to set up and run E2E tests on EAS Build with Maestro.


This guide will evolve over time as support for E2E testing in EAS Build improves. If you are looking for an archived guide on how to run E2E tests on EAS Build using Detox, you can see it in the archive section.

In this guide, you will learn how to create and run E2E tests on EAS Build using Maestro, which is one of the most popular tools for running E2E tests in mobile apps.

The example demonstrates how to configure your EAS Build Maestro E2E tests workflow using the default Expo template. For your own app, you will need to adjust the flows to match your app's UI.

Watch: How to run E2E tests on EAS Build
Watch: How to run E2E tests on EAS Build

1

Initialize a new project

You can skip this step if you already have an existing Expo project.

Create a new project using the following commands:

Terminal
# Initialize a new project
npx create-expo-app@latest eas-tests-example

# Move into the project directory
cd eas-tests-example

2

Configure EAS Build

You can skip this step if you already have EAS Build configured for your project.

The following command creates a new project on Expo servers for your app and creates eas.json in the project's root directory:

Terminal
eas init

eas build:configure

3

Disable New Android Builds Infrastructure

Go to Project settings and disable New Android Builds Infrastructure.

Unfortunately, the new build infrastructure is incompatible with E2E tests due to the lack of virtualization support required to start Android Emulator. We are working on better solutions for running various tests on EAS.

4

Add example Maestro test cases

This is what the UI of the app created from the default Expo template looks like:

Let's create two simple Maestro flows for the example app. Start by creating a directory called maestro in the root of your project directory. This directory will contain the flows that you will configure and should be at the same level as eas.json.

Inside, create a new file called home.yaml. This flow will launch the app and assert that the text "Welcome!" is visible on the home screen.

maestro/home.yaml
appId: dev.expo.eastestsexample # This is an example app id. Replace it with your app id.
---
- launchApp
- assertVisible: 'Welcome!'

Next, create a new flow called expand_test.yaml. This flow will open the "Explore" screen in the example app, click on the "File-based routing" collapsible, and assert that the text "This app has two screens" is visible on the screen.

maestro/expand_test.yaml
appId: dev.expo.eastestsexample # This is an example app id. Replace it with your app id.
---
- launchApp
- tapOn: 'Explore.*'
- tapOn: '.*File-based routing'
- assertVisible: 'This app has two screens.*'

If you want to run these flows locally to verify that they work as expected, you need to install your app on your local simulator/emulator and run maestro test maestro/expand_test.yaml or maestro test maestro/home.yaml commands in the terminal to use Maestro CLI to start the tests.

5

Create a custom build workflow for running Maestro E2E tests

The easiest way to run Maestro E2E tests on EAS Build is to create a custom build workflow. This workflow will build your app and run the Maestro tests on it.

Start by adding a custom build config file to your project. Create a directory .eas/build at the same level as eas.json in the project. The path and the name of both directories are important for EAS Build to identify that a project contains a custom build config.

Inside, create a new config file called build-and-maestro-test.yml. This file defines the custom build workflow config that you want to run. Workflow contains steps that are executed during the custom build process. This custom build config will execute the eas/build custom function group to create a build and then the eas/maestro_test which is an all-in-one custom function group that installs Maestro, prepares a testing environment (Android Emulator or iOS Simulator) and tests the app using flows specified by the flow_path input.

.eas/build/build-and-maestro-test.yml
build:
  name: Create a build and run Maestro tests on it
  steps:
    - eas/build
    - eas/maestro_test:
        inputs:
          flow_path: |
            maestro/home.yaml
            maestro/expand_test.yaml

Now modify the eas.json by adding a new build profile called build-and-maestro-test. It will be used to run the custom build config from the build-and-maestro-test.yml file. This configuration will build the emulator/simulator version of your app and run the Maestro tests on it.

We have observed that Maestro tests often time out if run on images with Xcode 15.0 or 15.2. Use the latest image to avoid any issues.
eas.json
{
  "build": {
    %%placeholder-start%%... %%placeholder-end%%
    "build-and-maestro-test": {
      "withoutCredentials": true,
      "config": "build-and-maestro-test.yml",
      "android": {
        "buildType": "apk",
        "image": "latest"
      },
      "ios": {
        "simulator": true,
        "image": "latest"
      }
    }
  }
  %%placeholder-start%%... %%placeholder-end%%
}

6

Build your app and run E2E tests on EAS Build

To execute a custom build using the build-and-maestro-test profile that will build your app and run the Maestro E2E tests afterward, run the following command:

Terminal
eas build --profile build-and-maestro-test

When the flow fails, any Maestro artifacts are automatically uploaded as build artifacts. This includes screenshots saved at ~/.maestro/tests (the default destination). You can download them from the build page.

More

If you want to build more advanced custom builds workflows, see the custom build schema reference for more information.

To learn more about Maestro flows and how to write them, see the Maestro documentation.

Troubleshooting

If you encounter the following error message when starting an Android Emulator for E2E tests on EAS Build:

Failed to configure emulator: emulator with required ID not found.

This is likely because the New Build Infrastructure is enabled for your project. Go to Project Settings and disable New Android Builds Infrastructure.