Quick start
This page takes you from nothing to a test running on a device and showing up on the dashboard, on one machine. You need Node.js, Appium 3 and, for Android, the Android SDK. Installation and requirements lists everything.
You also need a device Xenon can use, connected or booted: an Android phone with USB debugging on, an Android emulator, an iPhone or an iOS simulator.
1. Install the plugin and a driver
appium plugin install --source=npm @xenon-device-management/xenon
appium driver install uiautomator2 # Android
appium driver install xcuitest # iOS (macOS only)
Install the driver for the platform you test. Appium keeps both in its home folder, ~/.appium unless APPIUM_HOME says otherwise.
2. Start Appium with Xenon and its dashboard
For Android, Xenon finds adb through ANDROID_HOME (or ANDROID_SDK_ROOT), so export it in the shell you start Appium from. On a Mac with Android Studio the SDK is usually here:
export ANDROID_HOME=~/Library/Android/sdk
Then start Appium:
appium server --use-plugins=xenon \
--plugin-xenon-platform=both \
--plugin-xenon-enable-dashboard
When Xenon is ready, the log prints its address, such as Xenon will be served at http://192.168.0.10:4723/xenon.
--plugin-xenon-enable-dashboardmakes Xenon keep a record of the sessions on this machine's own devices. Without it the dashboard still opens, but those sessions leave no record and don't appear on its Sessions page.- Without
ANDROID_HOMEthe log saysNeither ANDROID_HOME nor ANDROID_SDK_ROOT environment variable was exported, and Xenon finds no Android devices. - For iPhones, Xenon needs its own copy of go-ios, which it uses to start WebDriverAgent, for the live preview and recordings, and for logs and CPU charts. Installation and requirements shows how to get it.
3. Open the dashboard and sign in
Open http://localhost:4723/xenon/ and sign in as the first super admin. Unless you set XENON_BOOTSTRAP_ADMIN_EMAIL and XENON_BOOTSTRAP_ADMIN_PASSWORD before the first start, that is:
- Email:
admin@xenon.local - Password:
Admin@123
On any machine others can reach, change it at once: open the account menu at the top right, choose Profile, then Password & authentication. Or set your own before Xenon starts for the first time:
export XENON_BOOTSTRAP_ADMIN_EMAIL=you@example.com
export XENON_BOOTSTRAP_ADMIN_PASSWORD='a long password of your own'
Xenon reads these only when it creates its first user, so setting them later changes nothing.
4. Point a test at it
A test identifies itself with an access key and an API token. Both are under Profile, on the API tokens tab: your access key is at the top, and Generate new token makes a token. Give it a description and an expiry, and copy the token straight away, because Xenon shows it once. Then keep them in your environment:
export XENON_ACCESS_KEY=xen_...
export XENON_TOKEN=...
Connect your Appium client to http://localhost:4723 with these capabilities:
- JavaScript
- Java
- Python
import { remote } from 'webdriverio';
const capabilities = {
platformName: 'Android',
'appium:automationName': 'UiAutomator2',
'xe:options': {
accessKey: process.env.XENON_ACCESS_KEY,
token: process.env.XENON_TOKEN,
},
'xe:build': 'nightly-2026-10-04',
'xe:name': 'Checkout: pay by card',
};
const driver = await remote({ hostname: 'localhost', port: 4723, capabilities });
// ...your test...
await driver.deleteSession();
The JavaScript sample is an ES module, so save it as .mjs: it uses import and top-level await.
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import java.net.URL;
import java.util.Map;
UiAutomator2Options options = new UiAutomator2Options();
options.setCapability("xe:options", Map.of(
"accessKey", System.getenv("XENON_ACCESS_KEY"),
"token", System.getenv("XENON_TOKEN")));
options.setCapability("xe:build", "nightly-2026-10-04");
options.setCapability("xe:name", "Checkout: pay by card");
AndroidDriver driver = new AndroidDriver(new URL("http://localhost:4723"), options);
// ...your test...
driver.quit();
import os
from appium import webdriver
from appium.options.android import UiAutomator2Options
options = UiAutomator2Options()
options.set_capability("xe:options", {
"accessKey": os.environ["XENON_ACCESS_KEY"],
"token": os.environ["XENON_TOKEN"],
})
options.set_capability("xe:build", "nightly-2026-10-04")
options.set_capability("xe:name", "Checkout: pay by card")
driver = webdriver.Remote("http://localhost:4723", options=options)
# ...your test...
driver.quit()
xe:optionscarries your credentials. Xenon removes them before the driver or anything it stores sees the capabilities.- On a lab that checks every command (
XENON_REQUIRE_COMMAND_AUTH), every command must also carry your credentials, as headers: see Check every command. xe:buildgroups sessions into a build, andxe:namenames the session on the dashboard.- If you started Appium with a base path, such as
--base-path /wd/hub, add it to the URL.
A wrong or missing key or token doesn't stop a session. Xenon logs Session created without valid credentials and runs it with no owner, so only an admin can control its phone from the dashboard. To refuse such sessions, set XENON_REQUIRE_SESSION_TOKEN=true on the server. Authentication explains the options.
What you should see
Open Sessions in the dashboard's sidebar. The session is listed under the build nightly-2026-10-04, named Checkout: pay by card. Open it to see its commands and timeline, its screenshots and, once it has ended, its video.
- Video is recorded unless the session sets
xe:record_videotofalse. - Screenshots are taken after commands that change the screen, such as
click,setValueandswipe, and when a command fails. - Device logs are saved for sessions on this machine's own devices, for the whole session (on an iPhone, the lines about the app under test). A session that sets
xe:save_device_logstofalsekeeps none.
If nothing appears, open Devices: the phone you asked for should be listed and not busy. When no device matches, Xenon holds the request and the server log says Waiting for free device.
Next steps
- Capabilities: everything a test can ask for.
- Devices and allocation: how Xenon picks a device, and what to do when none is free.
- Hub and nodes: add more machines to the lab.
- Teams: decide who may use which device.
- Self-healing: what Xenon does when a selector breaks.