Guide 13 · templates: mobile-test / android / android-headless · requires a KVM node (Pro plan+)
Mobile E2E testing on a cloud Android emulator
A device farm without the farm: each sandbox boots a KVM-accelerated
Android 14 emulator with adb and Appium inside. Run your suite with one
command and get a session page — live progress while it runs, then the full report
with a screen recording — or drive the device by hand.
The one-command way: pilldrops test
The mobile-test template injects a session harness: your script runs
automatically with the emulator screen recorded, and the sandbox URL serves
live progress → final report (video, screenshot, log, artifacts). Exit code 0
= GREEN, anything else = RED. Anything your
script writes to /test/artifacts/ lands in the report.
$ pilldrops test ./suite.sh sandbox: sb_m1 session: https://8765-sb_m1.pilldrops.app/ ← open now: live progress · later: report ✓ Wait for Android boot ✓ Run test script (screen recording on) ✓ Collect artifacts: video · screenshot · log verdict: GREEN # suite.sh is any script — adb, Appium (localhost:4723 inside), Maestro… # push a new version of the script and the session re-runs automatically.
Manual mode: boot the emulator sandbox
The template asks for 4 vCPU / 8 GB — Android boots in ~1–2 minutes. The
app_url is the live device screen (noVNC) — open it in a tab.
$ pilldrops sandbox create --template android --timeout 3600 sb_droid1 running android 4 vCPU · 8 GB app_url: https://6080-sb_droid1.pilldrops.app/ ← the device screen
Wait for Android, then install your APK
$ pilldrops exec sb_droid1 -- bash -c \ 'until [ "$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d "\r")" = "1" ]; do sleep 5; done; echo booted' $ pilldrops cp ./app-release.apk sb_droid1:/tmp/app.apk $ pilldrops exec sb_droid1 -- adb install /tmp/app.apk Success
Run the E2E suite
Appium runs inside the sandbox on port 4723 — point your test runner at it locally, or exec the whole suite in-sandbox and pull the report out.
$ pilldrops cp ./e2e sb_droid1:/tests $ pilldrops exec sb_droid1 -- bash -c 'cd /tests && npm ci && npx wdio run wdio.conf.js' $ pilldrops cp sb_droid1:/tests/report ./report # junit/allure output
Or let an agent drive the phone
The same loop as computer use, but for mobile: screenshot via adb, feed the frame to a vision model, tap via input events.
sb.run("adb exec-out screencap -p > /tmp/screen.png") frame = sb.files.read("/tmp/screen.png") # → model decides sb.run(f"adb shell input tap {x} {y}") # act
Headless mode for CI — no screen, Appium as the URL
Tests don't need a screen. The android-headless template skips the
VNC/streaming stack entirely (lower CPU/RAM, same ~45 s warm boot) and publishes
Appium as the preview URL — so CI drives the device remotely, exactly like a
Playwright grid endpoint.
$ pilldrops sandbox create --template android-headless --timeout 1800 app_url: https://4723-sb_ci42.pilldrops.app/ ← remote WebDriver endpoint # wdio.conf.js / Appium client in CI: # hostname: "4723-sb_ci42.pilldrops.app", port: 443, protocol: "https" $ npx wdio run wdio.conf.js # runs from CI against the cloud device
android to watch the device in a browser tab,
android-headless for CI. Always create with idle_timeout:-1 —
emulators don't survive auto-pause.