Unless you are building from source, running the hub does not require any additional dependencies except a running MongoDB instance.
This is only hub/UI, to actually have devices available you need to have at least one provider instance running on the same host (or another host on the same network) that will actually set up and provision devices.
Follow the setup steps to create and run a provider instance.
You can have multiple provider instances on different hosts providing devices.
Run ./GADS hub with the following flags:
--host-address=- local IP address of the host machine, e.g.192.168.1.6(default islocalhost, I would advise against using the default value)--port=- port on which the UI and backend service will be served--auth=- enable/disable authentication. When disabled you can access any UI page/hub endpoint without login token validation, note that this is highly insecure and should be used only for development -true/false--mongo-db=- IP address and port of the MongoDB instance, e.g192.168.1.6:27017(default islocalhost:27017) - tested only on local network--files-dir=- directory where the UI static files will be unpacked and served from. By default the app tries to use a temporary folder available on the host automatically. NB Use this flag only if you have issues with the default behaviour.
Then access the hub UI and API on http://{host-address}:{port}
If you want to work on the React UI with hot reload you need to add a proxy in package.json to point to the Go backend
- Open the
hub/gads-uifolder. - Open the
package-jsonfile. - Add a new field
"proxy": "http://192.168.1.28:10000/"providing the host and port of the Go backend service. - Run
npm start
You can add/delete users and change their roles/passwords via the Admin panel.
There are no limitations on usernames and passwords - only the default admin user cannot be deleted and its role changed(you can change its password though)
For each provider instance you need to create a provider configuration via the Admin panel.
All fields have tooltips to help you with the required information.
Device configurations are added via the Admin panel.
You have to provide all the required information and assign each device to a provider.
Changes to the device configuration require the respective provider instance restarted.
All fields have tooltips to help you with the required information.
Android emulators are the exception - providers with Provide Android emulators? enabled discover and report running emulators automatically as ephemeral devices. They never appear in Admin > Devices (there is nothing to configure), show up in the device selection list with an emulator badge while running, and are removed within ~15 seconds after the emulator or its provider stops. See the provider documentation for details.
Using Selenium Grid 4 is a bit of a hassle and some versions do not work properly with Appium relay nodes.
For this reason the hub embeds its own grid implementation - no Selenium Grid required. Point your Appium/Selenium driver URL at the hub, e.g. http://192.168.1.6:10000/grid, and create sessions as you usually would with any Appium language client.
Session requests
- Requests must use the W3C
capabilitiesformat (alwaysMatch/firstMatch). LegacydesiredCapabilities-only requests are rejected with400 invalid argument- Appium 2+ does not accept them either - Every session request must carry the
gads:clientSecretcapability for authentication - see Appium client credentials. Allgads:*capabilities are stripped before the request is forwarded, so the secret never appears in Appium logs
Device targeting
- By UDID via
appium:udid - By
platformName(iOS or Android) orappium:automationName(XCUITest or UiAutomator2)- Additionally the grid allows filtering by
appium:platformVersioncapability which supports exact version e.g.17.5.1or a major version e.g.17,11etc
- Additionally the grid allows filtering by
- Devices whose usage is set to
ControlorDisabled, and devices on a provider configured without Appium servers, are never dispatched - requests pinned to one by UDID fail immediately with the reason instead of queueing
Queueing
- When no matching device is free the request waits in a FIFO queue - first come, first served
- The default wait is 10 seconds; the
gads:queueTimeoutcapability (seconds, clamped to 300) sets it per request, and0means fail immediately when nothing is free
Session behavior
appium:newCommandTimeoutis honored by the hub as well (default 60 seconds); an explicit0disables idle expiry entirely- Only the exact
DELETE /grid/session/{id}ends a session - DELETEs on subpaths (/window,/cookie,/actions) are proxied as ordinary commands - BiDi is not supported: sessions requesting
webSocketUrl: truestill create fine, but thewebSocketUrlcapability is always removed from the response
Response enrichment - a successful session response includes extra gads:* capabilities telling you which device you actually got:
gads:deviceUdid,gads:deviceName,gads:providergads:controlUrl- a direct link to the hub's remote control UI for the device serving your test; the session owner can also attach from the device list via theUsebutton (after confirming) and watch the test live
Observability
GET /grid/statusreports overall grid readiness; without credentials that is all it reports. Send your client secret asAuthorization: Bearer <secret>to also get the per-device availability list and a readiness flag scoped to your tenant's workspacesGET /automation-sessions(authenticated) lists the currently active automation sessions
GADS allows you to create an adb tunnel to a remotely controlled Android device for local development and debugging - find more information on usage here