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/cliVerify the installation:
repeato --versionThe 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-projectRun 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-5554Output results in JUnit XML format (for CI test reporting):
repeato run --workspace /path/to/repeato-project --output-format junit --output-file results.xmlSetting 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-junitKey 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.jsonThis 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 &
waitFor 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.