Local Emulator Setup
Tier 1 — runs Appium on the developer's macOS machine against a local Android Emulator. Zero cost, instant feedback, single-developer use.
This is the easiest path to a working mobile test, and what every demo uses.
Why "native macOS, not Docker"
Docker Desktop on macOS can't run Android Emulators — no KVM / nested virtualization on the macOS hypervisor. The platform's backend services run in Docker, but Appium and the emulator must run natively on the host.
The mobile-test-agent also runs natively on macOS (as a JAR) so it can talk to local Appium without crossing the Docker NAT.
┌──────────────────────────── Docker (backend) ─────────────────────────┐
│ proofarc-backend │ proofarc-postgres │ proofarc-ui │ proofarc-minio │
└──────────────────────────────────┬─────────────────────────────────────┘
│ HTTP / WebSocket
▼
┌──────────────────────────── macOS host ───────────────────────────────┐
│ mobile-test-agent (Java JAR) │
│ │ │
│ ▼ WebDriver to localhost:4723 │
│ Appium server ────► Android Emulator (Pixel_7_API_34) │
└────────────────────────────────────────────────────────────────────────┘
Prerequisites
| Tool | Install |
|---|---|
| Java 17+ | brew install openjdk@17 |
| Node.js | brew install node |
| Docker Desktop | from docker.com (for backend services) |
| Android SDK | Android Studio, OR run ./scripts/install-android-sdk.sh |
The script installs adb, emulator, an API 34 system image, and creates a Pixel_7_API_34 AVD without needing Android Studio.
One-shot setup
From the repo root:
./scripts/start-mobile-env.sh local
This runs the full stack:
- Verifies prerequisites (Java, Node, Android SDK)
- Installs Appium + the uiautomator2 driver if missing
- Boots the Android Emulator (
Pixel_7_API_34) - Starts the Appium server on port 4723
- Starts the Docker backend services
- Builds and runs the
mobile-test-agentJAR locally
When it's done, visit http://localhost:3000 to see the platform.
Verifying the setup
./scripts/start-mobile-env.sh status
Expected output:
- Android emulator: running
- Appium server: listening on 4723
- mobile-test-agent: process running, polling for jobs
- Backend services: all healthy
Configuring a mobile app for T1
In the UI Configuration → Mobile Apps:
| Field | Value |
|---|---|
| Name | anything readable, e.g. "SauceLabs Demo App" |
| Platform | ANDROID |
| App package | com.swaglabsmobileapp (or your app's package) |
| Cloud provider | NONE ← the key bit |
Upload your APK using Upload Binary. The agent will pull it from MinIO at job time.
Writing your first mobile test
Same YAML shape as UI tests, different action set:
steps:
- action: tap
selector: accessibility:test-Username
- action: type
selector: accessibility:test-Username
value: standard_user
- action: tap
selector: accessibility:test-Password
- action: type
selector: accessibility:test-Password
value: secret_sauce
- action: tap
selector: accessibility:test-LOGIN
- action: assert_visible
selector: accessibility:test-PRODUCTS
See yaml-format for the full action reference.
Troubleshooting
Emulator doesn't start
- Check
adb devices— should show oneemulator-5554line. If empty, the emulator's still booting (takes 30-60s on first run) or the AVD is corrupt. - Recreate the AVD:
./scripts/install-android-sdk.sh recreate-avd
Appium says "no device"
- Restart Appium:
pkill -f appium && appium & - Verify Appium can see the device:
appium driver listshould showuiautomator2
Agent isn't picking up jobs
- Check the JWT token isn't expired —
./scripts/start-mobile-env.sh statuschecks this - Tail the agent log:
tail -f /tmp/mobile-test-agent.log
"Docker daemon not running"
- Docker Desktop must be open.
open -a Docker, wait ~30s.
Switching to a different tier
The same mobile app + test can run on T2 (self-hosted) or T4 (vendor) by changing the cloud_provider field:
- → T4 (BrowserStack / Sauce Labs): see Device farms
- → T2 (your K8s emulator pods): see Self-hosted
The YAML doesn't change. Same selectors, same assertions.
What's next
- Device farms — graduate to BrowserStack / Sauce Labs for iOS or real devices
- YAML format — full mobile action reference
- Credentials — store login credentials so tests aren't littered with secrets