Testing on Emulators and Devices
AbsoluteJS installs the emulators, boots them, and tests your app inside its real WebView on Android emulators, iOS simulators and iPhones. It can install the exact signed build you are about to ship, launch it with the network off, and hand you a report that becomes release evidence.
#Toolchain in one command
You do not need Android Studio. mobile doctor checks everything native development needs, and --fix installs what is missing. bun dev offers the same install the first time it finds the toolchain missing.
bunx absolute mobile doctor # every check, both platforms
bunx absolute mobile doctor android --fix # install the SDK, emulator and Java 21
bunx absolute mobile doctor ios --fix # on a Mac: download an iOS Simulator runtime
bunx absolute mobile doctor ios --remote studio-mac # check a paired Mac| What --fix sets up | Details |
|---|---|
| Android SDK location | ANDROID_HOME or ANDROID_SDK_ROOT when set; otherwise ~/.absolutejs/android-sdk, or %LOCALAPPDATA%\AbsoluteJS\Android\Sdk on Windows and WSL |
| Command-line tools | Google’s pinned release, downloaded and checked against its SHA-256 before it is unpacked |
| SDK packages | platform-tools, emulator, Android API 36 and build-tools 36.0.0, after you review the SDK licenses |
| Emulator | An AVD named AbsoluteJS_API_36 built from the Google APIs system image for your CPU |
| Java | Java 21: Temurin through winget on Windows and WSL or Homebrew on macOS, OpenJDK through apt, dnf or pacman on Linux |
| iOS Simulator | On a Mac with Xcode, --fix downloads the current iOS Simulator runtime |
#Emulators and simulators
With mobile configured, bun dev starts your app on an Android emulator and, on a Mac or through a paired one, an iOS simulator, next to the web server. Every target goes through the same steps:
Physical devices use the same loop with --android-device and --ios-device. Development covers them and the Remote Mac.
#Three ways to test
The browser preview is the fastest loop for layout, routes, offline states and Back. It runs your real page in an iOS- or Android-shaped frame, but it is not a WebView, so plugins, permissions, OAuth callbacks and secure storage need a real target. Use all three: the preview while you build, mobile test on the running app, and --release before you ship.
| Feature | Browser preview | Running app | Release |
|---|---|---|---|
| What it runs against | Your page in a browser frame | The debug app on the emulator, simulator or device | The signed AAB or IPA you will ship |
| Native WebView, plugins and permissions | |||
| Offline launch proven | |||
| Produces certification evidence | |||
| How | /__absolute/mobile-preview | mobile test android|ios | mobile test android|ios --release |
#Test the running app
With bun dev running, mobile test android drives the app on the emulator through the same debugging protocol Chrome uses. List the routes that matter; each one is opened inside the app and checked.
# Terminal 1: web plus the app on the emulator
bun dev
# Terminal 2: open each route in the app's real WebView
bunx absolute mobile test android --route / --route /account --route /orders/42On iOS, mobile test ios launches the installed app on the booted simulator, waits for it to connect to your dev server and takes a screenshot. The simulator opens mobile.entry, so iOS does not take --route. --wait-for-hmr works on both:
bunx absolute mobile test android --wait-for-hmr
bunx absolute mobile test ios --wait-for-hmrTo test a physical iPhone, start bun dev on it and pass the same device to the test. It relaunches the app and confirms it reconnects to your HTTPS dev server.
bunx absolute dev --ios-device "Test iPhone"
bunx absolute mobile test ios --device "Test iPhone" --reportmobile.entry is a web route. Expo has the rest.#Test the exact release
--release tests the signed App Bundle that mobile build android produced, not a debug build. It proves the app installs and starts from what is inside it, with no network.
bunx absolute mobile build android
bunx absolute mobile test android \
--release .absolutejs/mobile/releases/android/<release-id> \
--report$ bunx absolute mobile test android --release <release-dir>✓ Installed immutable capacitor release <release-id> with Bundletool in <time>. ✓ Embedded web content booted offline in <time> and relaunched in <time>.
#iOS: simulator, iPhone, TestFlight
iOS release testing runs at three levels, each closer to what your users install. Each launches the app twice and checks it renders its embedded content. On an iPhone, the test asks you to turn on Airplane Mode and turn off Wi-Fi first; --yes confirms you have. From Windows or Linux, add --remote and the run happens on your paired Mac.
# Simulator, on this Mac or a paired one
bunx absolute mobile test ios --release <release-dir> --report
# A registered iPhone, from the same archive
bunx absolute mobile build ios --registered-device-artifact
bunx absolute mobile test ios --release <release-dir> --device <udid> --report
# The TestFlight build Apple delivered to that iPhone
bunx absolute mobile test ios --release <release-dir> --device <udid> --testflight --report| Level | What is installed | Evidence |
|---|---|---|
| Simulator | A Release build from the same project and version, run in the iOS Simulator | simulator |
| Registered iPhone (--device) | The IPA exported from the same archive with --registered-device-artifact | device |
| TestFlight (--device --testflight) | The build Apple processed and TestFlight installed on the iPhone | store |
#Reports and artifacts
Every test prints its result and exits non-zero on failure. Add --report to keep a record:
#From report to certification
A release report is evidence for mobile certify, which binds it to that exact release. An Android release report counts as installed; iOS reports count as simulator, device or store, by the level above. Publishing checks the certification your release policy requires.
bunx absolute mobile certify <release-dir> \
--evidence .absolutejs/mobile/test-reports/android-<timestamp> \
--require installedRelease covers certification policies and publishing.
#In CI
Release tests run unattended: --yes approves the Bundletool download, --json prints a machine-readable result, and the exit code fails the job. absolute mobile ci github generates a workflow that builds, tests and certifies for you; Release walks through it.
bunx absolute mobile test android --release <release-dir> --yes --json --report#Flags
| Flag | Applies to | What it does |
|---|---|---|
| --route <path> | Android, development | A route to check; repeat it for more. Defaults to mobile.entry. |
| --wait-for-hmr | Android and iOS, development | Wait for a saved edit to reach the app and report how long it took |
| --port <n> [--https] | Development | The dev server to use when more than one is running for the project |
| --timeout <ms> | Development | How long each check may take. Default 30000. |
| --serial <id> | Android | The adb target. Defaults to the first ready emulator. |
| --udid <id> | iOS | The booted simulator to use |
| --device <id> | iOS | A physical iPhone: the one running bun dev --ios-device, or the one to install a release on |
| --testflight | iOS release | Test the TestFlight build installed on --device |
| --remote <name> | iOS | Run on a paired Mac: release runs, or a device session started through it |
| --release <dir> | Android and iOS | Test an installed release: its directory or its release.json |
| --report [dir] | Android and iOS | Write report.json, report.md and a screenshot |
| --artifacts <dir> | Android and iOS | Where failure diagnostics go; must be inside the project |
| --yes | Release runs | Approve the Bundletool download, or confirm an iPhone is offline |
| --json | Android and iOS | Print the result as JSON; progress goes to stderr |
Every absolute mobile command is in the CLI reference.