Repeato CI/CD Integration: Running Mobile Tests in Your Pipeline

Repeato CI/CD Integration: Running Mobile Tests in Your Pipeline

Recording tests in Repeato's desktop app is one thing — getting them running automatically on every commit is another. Repeato provides a CLI tool that runs tests headlessly, which means you can wire it into GitHub Actions, Jenkins, GitLab CI, or any other pipeline that can run shell commands.

The main requirement: your CI runner needs access to a running Android emulator or iOS Simulator. This is the part that takes the most setup effort.

The Repeato CLI

Install the Repeato CLI via npm:

npm install -g @repeato/cli

Verify the installation:

repeato --version

The CLI operates on a Repeato project directory (the folder you created in the desktop app). All your recorded tests, suites, and configuration live there.

Basic CLI Commands

Run all tests in a project:

repeato run --workspace /path/to/repeato-project

Run a specific suite:

repeato run --workspace /path/to/repeato-project --suite "Smoke Tests"

Run a single test by name:

repeato run --workspace /path/to/repeato-project --test "Login flow"

Run with a specific device/emulator:

repeato run --workspace /path/to/repeato-project --device emulator-5554

Output results in JUnit XML format (for CI test reporting):

repeato run --workspace /path/to/repeato-project --output-format junit --output-file results.xml

Setting Up Android Emulator in CI

The most common CI target for Repeato is Android, since Android emulators run on Linux (the standard CI OS) without needing macOS licenses.

GitHub Actions Example

name: Mobile Tests

on:
  push:
    branches: [main, develop]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Setup Android SDK
        uses: android-actions/setup-android@v3

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Repeato CLI
        run: npm install -g @repeato/cli

      - name: Enable KVM for emulator acceleration
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      - name: Create AVD
        run: |
          echo "no" | avdmanager create avd \
            --name test_device \
            --package "system-images;android-33;google_apis;x86_64" \
            --device "pixel_4"

      - name: Start emulator
        run: |
          $ANDROID_HOME/emulator/emulator \
            -avd test_device \
            -no-audio \
            -no-window \
            -gpu swiftshader_indirect \
            -no-snapshot \
            -no-boot-anim &
          adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'

      - name: Run Repeato tests
        run: |
          repeato run \
            --workspace ${{ github.workspace }}/tests/repeato \
            --suite "Smoke Tests" \
            --output-format junit \
            --output-file test-results.xml

      - name: Upload test results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-results
          path: test-results.xml

      - name: Publish test report
        uses: dorny/test-reporter@v1
        if: always()
        with:
          name: Repeato Mobile Tests
          path: test-results.xml
          reporter: java-junit

Key Points for Android in CI

KVM acceleration: GitHub Actions' ubuntu-latest runners support KVM, which makes Android emulator performance acceptable. The udev rules in the example above enable it. Without KVM, emulator startup can take 5-10 minutes and be unreliable.

System image: Use google_apis system images rather than plain AOSP — they include more complete API support. The x86_64 ABI is required for KVM acceleration.

Wait for boot: The adb wait-for-device loop waits for sys.boot_completed=1. Don't skip this — trying to run tests before the emulator has fully booted produces unreliable failures.

-no-window: Required for headless execution. The emulator won't show a window but still processes interactions normally.

iOS in CI

iOS CI is harder because:

  • It requires macOS runners
  • macOS runners on GitHub Actions cost more (10× the price of Linux)
  • Real device testing requires additional provisioning setup

A minimal iOS CI configuration using GitHub Actions' macOS runners:

jobs:
  test-ios:
    runs-on: macos-14

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Repeato CLI
        run: npm install -g @repeato/cli

      - name: Boot iOS Simulator
        run: |
          UDID=$(xcrun simctl create TestDevice \
            "iPhone 15" \
            "com.apple.CoreSimulator.SimRuntime.iOS-17-0")
          xcrun simctl boot $UDID
          echo "SIMULATOR_UDID=$UDID" >> $GITHUB_ENV

      - name: Run Repeato tests
        run: |
          repeato run \
            --workspace ${{ github.workspace }}/tests/repeato-ios \
            --device ${{ env.SIMULATOR_UDID }} \
            --output-format junit \
            --output-file ios-results.xml

      - name: Shutdown Simulator
        if: always()
        run: xcrun simctl shutdown ${{ env.SIMULATOR_UDID }}

For most teams running mobile tests in CI, Android is the practical choice unless you're specifically testing iOS-only features.

Jenkins Integration

For Jenkins, the approach is the same — start an emulator, run the CLI, collect results:

pipeline {
    agent { label 'linux-android' }
    
    stages {
        stage('Start Emulator') {
            steps {
                sh '''
                    $ANDROID_HOME/emulator/emulator \
                        -avd ci_device \
                        -no-audio -no-window -gpu swiftshader_indirect &
                    adb wait-for-device shell \
                        'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'
                '''
            }
        }
        
        stage('Run Tests') {
            steps {
                sh '''
                    repeato run \
                        --workspace ${WORKSPACE}/tests/repeato \
                        --suite "Regression" \
                        --output-format junit \
                        --output-file results.xml
                '''
            }
        }
    }
    
    post {
        always {
            junit 'results.xml'
            sh 'adb emu kill || true'
        }
    }
}

Ensure your Jenkins agent has Android SDK, ADB, and Node.js pre-installed. Configuring this as a dedicated "Android testing" label keeps it separate from your standard build agents.

Storing the Repeato Project in Git

Keep your Repeato project directory in the same repository as your app code:

my-app/
├── src/
├── android/
├── ios/
└── tests/
    └── repeato/
        ├── tests/
        ├── suites/
        └── config.json

This ensures tests are versioned alongside the app. When a PR changes app behavior, the test updates ship in the same commit.

Parallelizing Tests

Repeato's CLI supports running multiple instances in parallel against different emulators. Create multiple AVDs and split your suite across them:

# Start two emulators
$ANDROID_HOME/emulator/emulator -avd device_1 -no-window -no-audio &
$ANDROID_HOME/emulator/emulator -avd device_2 -no-window -no-audio &

# Run different suites in parallel
repeato run --workspace ./tests/repeato --suite "Login" --device emulator-5554 &
repeato run --workspace ./tests/repeato --suite "Checkout" --device emulator-5556 &
wait

For large test suites, this can cut overall execution time significantly — though you're limited by the number of emulators your CI runner can handle concurrently.

Read more

Start now free