diff --git a/docs/jsonrpc_README.md b/docs/jsonrpc_README.md deleted file mode 100644 index e64c233..0000000 --- a/docs/jsonrpc_README.md +++ /dev/null @@ -1,309 +0,0 @@ -# mobilecli JSON-RPC API - -This document describes the JSON-RPC methods exposed by the mobilecli HTTP server at the `/rpc` endpoint. - -Base URL: `http://:/rpc` - -All requests must be JSON-RPC 2.0 objects with `jsonrpc` set to "2.0", a `method` string, an `id`, and optionally `params`. - -Common response format: - -```json -{ - "jsonrpc": "2.0", - "result": ... , - "error": { "code": ..., "message": ..., "data": ... }, - "id": -} -``` - -Errors use standard JSON-RPC error codes and include a `data` field with additional context. - -## BREAKING CHANGE: Method Names Updated - -**All JSON-RPC methods now use a `device.*` naming scheme. Old method names are no longer supported.** - -### Migration Table - -| Old Method Name | New Method Name | -|-----------------|-----------------| -| devices | devices.list | -| screenshot | device.screenshot | -| screencapture | device.screencapture | -| io_tap | device.io.tap | -| io_longpress | device.io.longpress | -| io_text | device.io.text | -| io_button | device.io.button | -| io_swipe | device.io.swipe | -| io_gesture | device.io.gesture | -| url | device.url | -| device_info | device.info | -| io_orientation_get | device.io.orientation.get | -| io_orientation_set | device.io.orientation.set | -| device_boot | device.boot | -| device_shutdown | device.shutdown | -| device_reboot | device.reboot | -| dump_ui | device.dump.ui | -| apps_launch | device.apps.launch | -| apps_terminate | device.apps.terminate | -| apps_list | device.apps.list | -| apps_foreground | device.apps.foreground | - -## Methods - -This section documents the JSON-RPC methods registered by the server and shows example `params` and curl requests. - -- `devices.list` - - Description: List devices. - - Params: object (optional) - - `includeOffline` (bool) - - `platform` (string) - - `type` (string) - - Example: - -```json -{"jsonrpc":"2.0","method":"devices.list","params":{"includeOffline":true},"id":1} -``` - -- `device.screenshot` - - Description: Take a screenshot and return base64 data. - - Params: object - - `deviceId` (string) - - `format` (string) - `png` or `jpeg` - - `quality` (int) - JPEG quality 1-100 - - Example: - -```json -{"jsonrpc":"2.0","method":"device.screenshot","params":{"deviceId":"","format":"png"},"id":2} -``` - -- `device.screencapture` (streaming) - - Description: Start a screen capture stream (MJPEG or AVC). This writes a streaming response; use the HTTP `/rpc` POST to initiate streaming. - - Params: object - - `deviceId` (string) - - `format` (string) - `mjpeg` or `avc` - - `quality` (int) - - `scale` (float) - - Note: Progress notifications are sent inside the stream for `mjpeg`. - -- `device.io.tap` - - Description: Tap at coordinates. - - Params: object - - `deviceId` (string) - - `x` (int) - - `y` (int) - - Example: - -```json -{"jsonrpc":"2.0","method":"device.io.tap","params":{"deviceId":"","x":100,"y":200},"id":3} -``` - -- `device.io.longpress` - - Description: Long-press at coordinates. - - Params: object - - `deviceId` (string) - - `x` (int) - - `y` (int) - - `duration` (int, ms) - -- `device.io.text` - - Description: Send text input. - - Params: object - - `deviceId` (string) - - `text` (string) - -- `device.io.button` - - Description: Press a hardware button (HOME, VOLUME_UP, etc.). - - Params: object - - `deviceId` (string) - - `button` (string) - -- `device.io.swipe` - - Description: Swipe from one point to another. - - Params: object - - `deviceId` (string) - - `x1`,`y1`,`x2`,`y2` (ints) - -- `device.io.gesture` - - Description: Perform a gesture composed of actions (tap, move, wait, etc.). - - Params: object - - `deviceId` (string) - - `actions` (array of action objects) — see `devices/wda` types in code for schema. - -- `device.url` - - Description: Open a URL or deep link on device. - - Params: object - - `deviceId` (string) - - `url` (string) - -- `device.info` - - Description: Retrieve detailed device info (screen size, OS, etc.). - - Params: object - - `deviceId` (string) - - Example: - -```json -{"jsonrpc":"2.0","method":"device_info","params":{"deviceId":""},"id":21} -``` - -- `device.io.orientation.get` - - Description: Get device orientation. - - Params: object - - `deviceId` (string) - -- `device.io.orientation.set` - - Description: Set device orientation. - - Params: object - - `deviceId` (string) - - `orientation` (string) - -- `device.boot`, `device.shutdown`, `device.reboot` - - Description: Control device power state (boot, shutdown, reboot). - - Params: object - - `deviceId` (string) - -- `device.dump.ui` - - Description: Dump the UI tree from the device. - - Params: object - - `deviceId` (string) - - `format` (string) - `json` (default) or `raw` - -- `device.apps.launch` - - Description: Launch an app on a device. - - Params: object - - `deviceId` (string) - - `bundleId` (string) - required - -- `device.apps.terminate` - - Description: Terminate a running app on a device. - - Params: object - - `deviceId` (string) - - `bundleId` (string) - required - -- `device.apps.list` - - Description: List installed apps on a device. - - Params: object (optional) - - `deviceId` (string) - -- `device.apps.foreground` - - Description: Get the currently foreground (active) app on a device. - - Params: object (optional) - - `deviceId` (string) - -Common notes: -- For most methods `deviceId` is optional; when omitted the server auto-selects a single online device or returns an error when multiple devices are available. -- Methods that interact with the UI/agent (`device.io.*`, `device.dump.ui`, `device.apps.launch`, `device.info`, etc.) call `StartAgent` which may start/forward WDA for iOS devices. If WDA is unresponsive the server will attempt to relaunch it. - -## Curl examples - -- List devices: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"devices.list","params":{},"id":10}' -``` - -- Take a screenshot: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"device.screenshot","params":{"deviceId":"","format":"png"},"id":11}' -``` - -- Start MJPEG screen capture (streaming): - -```bash -curl -v -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"screencapture","params":{"deviceId":"","format":"mjpeg"},"id":12}' -``` - -- Tap coordinates: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"device.io.tap","params":{"deviceId":"","x":195,"y":422},"id":13}' -``` - -- Long press: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"io_longpress","params":{"deviceId":"","x":100,"y":200,"duration":750},"id":14}' -``` - -- Send text: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"io_text","params":{"deviceId":"","text":"Hello"},"id":15}' -``` - -- Press button: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"io_button","params":{"deviceId":"","button":"HOME"},"id":16}' -``` - -- Swipe: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"io_swipe","params":{"deviceId":"","x1":100,"y1":200,"x2":300,"y2":400},"id":17}' -``` - -- Open URL: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"url","params":{"deviceId":"","url":"https://example.com"},"id":18}' -``` - -- Get device info: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"device_info","params":{"deviceId":""},"id":21}' -``` - -- Dump UI (json): - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"dump_ui","params":{"deviceId":"","format":"json"},"id":19}' -``` - -- Launch app: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"apps_launch","params":{"deviceId":"","bundleId":"com.example.app"},"id":20}' -``` - -- Terminate app: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"apps_terminate","params":{"deviceId":"","bundleId":"com.example.app"},"id":21}' -``` - -- List apps: - -```bash -curl -s -X POST http://localhost:12000/rpc \ - -H 'Content-Type: application/json' \ - -d '{"jsonrpc":"2.0","method":"apps_list","params":{"deviceId":""},"id":22}' -``` diff --git a/docs/openrpc.json b/docs/openrpc.json new file mode 100644 index 0000000..51cf674 --- /dev/null +++ b/docs/openrpc.json @@ -0,0 +1,1855 @@ +{ + "openrpc": "1.3.2", + "info": { + "title": "Mobile CLI Server API", + "description": "JSON-RPC API for mobile device automation and control", + "version": "0.0.1" + }, + "methods": [ + { + "name": "devices.list", + "summary": "List all connected devices", + "description": "Returns a list of all connected mobile devices (iOS and Android)", + "params": [ + { + "name": "includeOffline", + "description": "Include offline devices in the list", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "platform", + "description": "Filter devices by platform (ios or android)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "ios", + "android" + ] + } + }, + { + "name": "type", + "description": "Filter devices by type (device or simulator)", + "required": false, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "devices", + "description": "List of connected devices", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Device" + } + } + } + }, + { + "name": "device.screenshot", + "summary": "Take a screenshot of a device", + "description": "Captures a screenshot from the specified device and returns it as base64 data", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "format", + "description": "Image format (png or jpeg)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "png", + "jpeg" + ], + "default": "png" + } + }, + { + "name": "quality", + "description": "Image quality (1-100, only used for JPEG)", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100 + } + }, + { + "name": "clip", + "description": "Optional rectangle to crop the screenshot to, in screen coordinates", + "required": false, + "schema": { + "$ref": "#/components/schemas/Rect" + } + } + ], + "result": { + "name": "screenshot", + "description": "Screenshot data", + "schema": { + "$ref": "#/components/schemas/ScreenshotResult" + } + } + }, + { + "name": "device.screencapture", + "summary": "Start screen capture streaming", + "description": "Starts screen capture streaming for the specified device. Supports MJPEG (iOS and Android) and AVC/H.264 (Android only) formats.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "format", + "description": "Video format - 'mjpeg' for MJPEG stream (iOS and Android) or 'avc' for H.264 stream (Android only)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "mjpeg", + "avc" + ], + "default": "mjpeg" + } + }, + { + "name": "quality", + "description": "Video quality (only used for MJPEG format)", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "scale", + "description": "Video scale factor", + "required": false, + "schema": { + "type": "number" + } + } + ], + "result": { + "name": "stream", + "description": "Video stream - multipart/x-mixed-replace for MJPEG or video/h264 for AVC", + "schema": { + "type": "string" + } + } + }, + { + "name": "device.io.tap", + "summary": "Perform tap gesture", + "description": "Performs a tap gesture at the specified coordinates on the device screen", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "x", + "description": "X coordinate for the tap", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "y", + "description": "Y coordinate for the tap", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.io.longpress", + "summary": "Perform long press gesture", + "description": "Performs a long press gesture at the specified coordinates on the device screen", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "x", + "description": "X coordinate for the long press", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "y", + "description": "Y coordinate for the long press", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "duration", + "description": "Duration of the long press in milliseconds", + "required": false, + "schema": { + "type": "integer", + "default": 500 + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.io.text", + "summary": "Input text", + "description": "Inputs the specified text on the device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "text", + "description": "Text to input", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.io.button", + "summary": "Press device button", + "description": "Presses a physical or virtual button on the device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "button", + "description": "Button to press", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.io.gesture", + "summary": "Perform custom gesture", + "description": "Performs a custom gesture with multiple actions on the device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "actions", + "description": "List of gesture actions to perform", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "object" + } + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.url", + "summary": "Open URL", + "description": "Opens the specified URL on the device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "url", + "description": "URL to open", + "required": true, + "schema": { + "type": "string", + "format": "uri" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.io.swipe", + "summary": "Perform swipe gesture", + "description": "Performs a swipe gesture from one coordinate to another on the device screen", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "x1", + "description": "Starting X coordinate", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "y1", + "description": "Starting Y coordinate", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "x2", + "description": "Ending X coordinate", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "y2", + "description": "Ending Y coordinate", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.info", + "summary": "Get device information", + "description": "Returns detailed information about the specified device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "deviceInfo", + "description": "Device information", + "schema": { + "$ref": "#/components/schemas/DeviceInfo" + } + } + }, + { + "name": "device.io.orientation.get", + "summary": "Get device orientation", + "description": "Returns the current orientation of the device screen", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "orientation", + "description": "Current device orientation", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.io.orientation.set", + "summary": "Set device orientation", + "description": "Sets the orientation of the device screen", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "orientation", + "description": "Desired orientation", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.boot", + "summary": "Boot a device", + "description": "Boots the specified device (simulators/emulators only)", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "bootResult", + "description": "Boot operation result", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.shutdown", + "summary": "Shutdown a device", + "description": "Shuts down the specified device (simulators/emulators only)", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "shutdownResult", + "description": "Shutdown operation result", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.reboot", + "summary": "Reboot a device", + "description": "Reboots the specified device (simulators/emulators only)", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "rebootResult", + "description": "Reboot operation result", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.dump.ui", + "summary": "Dump UI hierarchy", + "description": "Dumps the UI hierarchy of the device screen", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "format", + "description": "Output format (json or raw)", + "required": false, + "schema": { + "type": "string", + "enum": [ + "json", + "raw" + ], + "default": "json" + } + } + ], + "result": { + "name": "uiHierarchy", + "description": "UI hierarchy data", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.apps.launch", + "summary": "Launch an application", + "description": "Launches an application by bundle ID on the specified device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "bundleId", + "description": "Bundle ID of the application to launch", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "locales", + "description": "BCP 47 locale tags to set for the app (e.g. [\"fr-FR\", \"en-GB\"]). On iOS this is a per-launch argument. On Android 13+ this is persistent.", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$" + } + } + } + ], + "result": { + "name": "launchResult", + "description": "Launch operation result", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.apps.terminate", + "summary": "Terminate an application", + "description": "Terminates a running application by bundle ID on the specified device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "bundleId", + "description": "Bundle ID of the application to terminate", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "terminateResult", + "description": "Terminate operation result", + "schema": { + "type": "object", + "properties": { + "terminated": { + "type": "boolean", + "description": "True if the app was running and got terminated, false if it was not running" + } + }, + "required": [ + "terminated" + ] + } + } + }, + { + "name": "device.apps.list", + "summary": "List installed applications", + "description": "Returns a list of installed applications on the specified device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "apps", + "description": "List of installed applications", + "schema": { + "type": "array", + "items": { + "type": "object" + } + } + } + }, + { + "name": "device.apps.foreground", + "summary": "Get foreground application", + "description": "Returns the currently foreground (active) application on the specified device", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "foregroundApp", + "description": "Foreground application information", + "schema": { + "type": "object" + } + } + }, + { + "name": "device.apps.install", + "summary": "Install an application", + "description": "Installs an application on the specified device from a local file path. Supports optional IPA re-signing for real iOS devices.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "description": "Local file path to the application package (.apk, .ipa, or .app)", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "forceResign", + "description": "Re-sign the IPA with a local provisioning profile before installing (only for .ipa files on real iOS devices)", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "provisioningProfile", + "description": "Path to a .mobileprovision file to use for re-signing. If not provided, a matching profile is auto-detected.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "signingIdentity", + "description": "Signing identity name or SHA-1 hash to use for re-signing. If not provided, a matching identity is auto-detected.", + "required": false, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.apps.uninstall", + "summary": "Uninstall an application", + "description": "Uninstalls an application from the specified device by its bundle/package ID", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "bundleId", + "description": "Bundle identifier (iOS) or package name (Android) of the application to uninstall", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.apps.clear", + "summary": "Clear application data", + "description": "Clears all data (cache, preferences, databases) for an application without uninstalling it. Supported on Android and iOS Simulator. Not supported on real iOS devices.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "bundleId", + "description": "Bundle identifier (iOS) or package name (Android) of the application to clear", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.apps.path", + "summary": "Get app data container path", + "description": "Returns the on-device path to an app's data container. Currently supported on Android and iOS real devices.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "bundleId", + "description": "Bundle identifier (iOS) or package name (Android) of the application", + "required": true, + "schema": { "type": "string" } + } + ], + "result": { + "name": "containerPath", + "description": "Data container path", + "schema": { + "type": "object", + "properties": { + "path": { "type": "string", "description": "Absolute path to the app's data container on the device" } + }, + "required": ["path"] + } + } + }, + { + "name": "device.fs.ls", + "summary": "List files on device", + "description": "Lists files and directories at a given path on the device, or in an app's container. Defaults to the device root if no path is given. Supported on Android and iOS Simulator.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "bundleId", + "description": "Bundle identifier to list files inside an app's container", + "required": false, + "schema": { "type": "string" } + }, + { + "name": "remotePath", + "description": "Absolute path on the device to list. Defaults to device root if omitted.", + "required": false, + "schema": { "type": "string" } + } + ], + "result": { + "name": "entries", + "description": "List of file entries", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "type": "string", "description": "File or directory name" }, + "path": { "type": "string", "description": "Full path on the device" }, + "size": { "type": "integer", "description": "File size in bytes (0 for directories)" }, + "modTime": { "type": "string", "format": "date-time", "description": "Last modification time" }, + "isDir": { "type": "boolean", "description": "True if this entry is a directory" } + }, + "required": ["name", "path", "size", "isDir"] + } + } + } + }, + { + "name": "device.fs.pull", + "summary": "Pull a file from the device", + "description": "Downloads a file from the device and returns its contents as base64. Maximum file size is 1 MB. Supports arbitrary paths on Android and iOS Simulator.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "remotePath", + "description": "Absolute path of the file on the device", + "required": true, + "schema": { "type": "string" } + } + ], + "result": { + "name": "fileContent", + "description": "File contents", + "schema": { + "type": "object", + "properties": { + "content": { "type": "string", "description": "Base64-encoded file contents" }, + "size": { "type": "integer", "description": "File size in bytes" } + }, + "required": ["content", "size"] + } + } + }, + { + "name": "device.fs.push", + "summary": "Push a file to the device", + "description": "Uploads a file to the device from base64-encoded content. Maximum file size is 1 MB. For /data/user/ paths on Android, the file is staged via /data/local/tmp and copied with run-as.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "remotePath", + "description": "Absolute destination path on the device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "content", + "description": "Base64-encoded file contents to write. Maximum decoded size is 1 MB.", + "required": true, + "schema": { "type": "string", "format": "byte" } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { "$ref": "#/components/schemas/SuccessResult" } + } + }, + { + "name": "device.fs.mkdir", + "summary": "Create a directory on the device", + "description": "Creates a directory at the specified path on the device or in an app's container.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "bundleId", + "description": "Bundle identifier to create directory inside an app's container", + "required": false, + "schema": { "type": "string" } + }, + { + "name": "remotePath", + "description": "Absolute path of the directory to create", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "parents", + "description": "Create parent directories as needed (like mkdir -p)", + "required": false, + "schema": { "type": "boolean", "default": false } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { "$ref": "#/components/schemas/SuccessResult" } + } + }, + { + "name": "device.fs.rm", + "summary": "Remove a file or directory on the device", + "description": "Removes a file or directory at the specified path on the device or in an app's container.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "bundleId", + "description": "Bundle identifier to remove files inside an app's container", + "required": false, + "schema": { "type": "string" } + }, + { + "name": "remotePath", + "description": "Absolute path of the file or directory to remove", + "required": true, + "schema": { "type": "string" } + }, + { + "name": "recursive", + "description": "Remove directories and their contents recursively (like rm -rf)", + "required": false, + "schema": { "type": "boolean", "default": false } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { "$ref": "#/components/schemas/SuccessResult" } + } + }, + { + "name": "device.crashes.list", + "summary": "List crash reports", + "description": "Returns a list of crash reports from the specified device. Supports iOS real devices (via crashreport service), iOS simulators (reads from DiagnosticReports), and Android devices (parses adb logcat crash buffer).", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "crashes", + "description": "List of crash reports", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "processName": { + "type": "string", + "description": "Name of the process that crashed" + }, + "timestamp": { + "type": "string", + "description": "Timestamp of the crash" + }, + "id": { + "type": "string", + "description": "Unique identifier for the crash report, used with device.crashes.get" + } + }, + "required": [ + "processName", + "timestamp", + "id" + ] + } + } + } + }, + { + "name": "device.crashes.get", + "summary": "Get a crash report", + "description": "Returns the full content of a specific crash report by ID. The ID is obtained from device.crashes.list.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "Crash report ID (from device.crashes.list)", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "crashReport", + "description": "Crash report content", + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Crash report ID" + }, + "content": { + "type": "string", + "description": "Full crash report text" + } + }, + "required": [ + "id", + "content" + ] + } + } + }, + { + "name": "device.webview.list", + "summary": "List webviews", + "description": "Returns all embedded webviews currently visible in the foreground app on the device. Browser apps (Safari, Chrome) are not included.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "webviews", + "description": "List of embedded webviews", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebView" + } + } + } + }, + { + "name": "device.webview.content", + "summary": "Get webview HTML content", + "description": "Returns the full outer HTML of the page currently loaded in the attached webview.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "content", + "description": "Full outer HTML of the page", + "schema": { + "type": "string" + } + } + }, + { + "name": "device.webview.goto", + "summary": "Navigate webview to URL", + "description": "Navigates the attached webview to the given URL and optionally waits for a load state.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "url", + "description": "URL to navigate to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "waitUntil", + "description": "Load state to wait for after navigation", + "required": false, + "schema": { + "type": "string", + "enum": [ + "load", + "domcontentloaded" + ], + "default": "load" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.webview.reload", + "summary": "Reload webview", + "description": "Reloads the current page in the attached webview.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "waitUntil", + "description": "Load state to wait for after reload", + "required": false, + "schema": { + "type": "string", + "enum": [ + "load", + "domcontentloaded" + ], + "default": "load" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.webview.goBack", + "summary": "Navigate back in webview history", + "description": "Navigates one step back in the attached webview's session history.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.webview.goForward", + "summary": "Navigate forward in webview history", + "description": "Navigates one step forward in the attached webview's session history.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "device.webview.url", + "summary": "Get webview URL", + "description": "Returns the current top-level URL (location.href) of the attached webview.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "url", + "description": "Current top-level URL", + "schema": { + "type": "string" + } + } + }, + { + "name": "device.webview.title", + "summary": "Get webview title", + "description": "Returns the document title (document.title) of the page currently loaded in the attached webview.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "title", + "description": "Document title", + "schema": { + "type": "string" + } + } + }, + { + "name": "device.webview.query", + "summary": "Query DOM elements in webview", + "description": "Finds elements matching a CSS selector and returns their tag, text, id, class, value, and href.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "selector", + "description": "CSS selector to match elements against", + "required": true, + "schema": { + "type": "string" + } + } + ], + "result": { + "name": "elements", + "description": "Matched DOM elements", + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tag": { + "type": "string", + "description": "Lowercase tag name" + }, + "text": { + "type": "string", + "description": "Trimmed text content, truncated to 200 characters" + }, + "id": { + "type": "string", + "description": "Element id attribute, or null" + }, + "class": { + "type": "string", + "description": "Element class attribute, or null" + }, + "value": { + "type": "string", + "description": "Element value, or null" + }, + "href": { + "type": "string", + "description": "Element href, or null" + } + }, + "required": [ + "tag", + "text" + ] + } + } + } + }, + { + "name": "device.webview.evaluate", + "summary": "Evaluate JavaScript in webview", + "description": "Evaluates a JavaScript expression in the attached webview and returns the JSON-serialized result. Throws WebViewEvaluateError if the script throws.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "expression", + "description": "JavaScript expression to evaluate. May be a function body invoked with args.", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "args", + "description": "Arguments passed to the expression when it is a function body", + "required": false, + "schema": { + "type": "array" + } + } + ], + "result": { + "name": "evaluateResult", + "description": "Serialized return value", + "schema": { + "type": "object", + "properties": { + "result": {} + } + } + } + }, + { + "name": "device.webview.waitForLoadState", + "summary": "Wait for webview load state", + "description": "Polls the attached webview server-side until the requested load state is reached or the timeout elapses.", + "params": [ + { + "name": "deviceId", + "description": "ID of the target device", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "id", + "description": "WebView ID from device.webview.list", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "state", + "description": "Load state to wait for", + "required": false, + "schema": { + "type": "string", + "enum": [ + "load", + "domcontentloaded" + ], + "default": "load" + } + }, + { + "name": "timeout", + "description": "Timeout in milliseconds", + "required": false, + "schema": { + "type": "integer", + "minimum": 0, + "default": 30000 + } + } + ], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + }, + { + "name": "server.info", + "summary": "Get server information", + "description": "Returns the server name and version", + "params": [], + "result": { + "name": "serverInfo", + "description": "Server information", + "schema": { + "$ref": "#/components/schemas/ServerInfo" + } + } + }, + { + "name": "server.shutdown", + "summary": "Shutdown the server", + "description": "Initiates a graceful server shutdown", + "params": [], + "result": { + "name": "success", + "description": "Operation result", + "schema": { + "$ref": "#/components/schemas/SuccessResult" + } + } + } + ], + "components": { + "errors": { + "ParseError": { + "code": -32700, + "message": "Parse error", + "data": "Invalid JSON was received by the server" + }, + "InvalidRequest": { + "code": -32600, + "message": "Invalid Request", + "data": "The JSON sent is not a valid Request object" + }, + "MethodNotFound": { + "code": -32601, + "message": "Method not found", + "data": "The method does not exist or is not available" + }, + "InvalidParams": { + "code": -32602, + "message": "Invalid params", + "data": "Invalid method parameters" + }, + "InternalError": { + "code": -32603, + "message": "Internal error", + "data": "Internal JSON-RPC error" + }, + "ServerError": { + "code": -32000, + "message": "Server error", + "data": "Unexpected internal server error" + }, + "DeviceNotFound": { + "code": -32010, + "message": "Device not found", + "data": "The specified device does not exist" + }, + "DeviceTimeout": { + "code": -32050, + "message": "Device timeout", + "data": "The device did not respond in time" + }, + "WebViewNotFound": { + "code": -32100, + "message": "Webview not found", + "data": "The supplied webview id does not match any currently-attached webview" + }, + "WebViewSessionExpired": { + "code": -32101, + "message": "Webview session expired", + "data": "The session is no longer valid; the client must re-attach to the webview" + }, + "WebViewNodeNotFound": { + "code": -32102, + "message": "Webview node not found", + "data": "The supplied node id is stale because the DOM has mutated; the client must re-query" + }, + "WebViewNavigationFailed": { + "code": -32103, + "message": "Webview navigation failed", + "data": "The webview did not reach the requested load state in time" + }, + "WebViewEvaluateError": { + "code": -32104, + "message": "Webview evaluate error", + "data": "The script passed to device.webview.evaluate threw an exception" + } + }, + "schemas": { + "Device": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique device identifier" + }, + "name": { + "type": "string", + "description": "Device name" + }, + "platform": { + "type": "string", + "enum": [ + "ios", + "android" + ], + "description": "Device platform" + }, + "status": { + "type": "string", + "description": "Device connection status" + }, + "model": { + "type": "string", + "description": "Device model" + }, + "provider": { + "$ref": "#/components/schemas/DeviceProvider", + "description": "Provider information for this device" + } + }, + "required": [ + "id", + "name", + "platform", + "status", + "model" + ] + }, + "DeviceProvider": { + "type": "object", + "description": "Describes where the device is provided from", + "properties": { + "type": { + "type": "string", + "description": "Provider type (e.g. 'mobilefleet', 'local')" + }, + "sessionId": { + "type": "string", + "description": "Session identifier for this device allocation" + } + }, + "required": [ + "type" + ] + }, + "ScreenshotResult": { + "type": "object", + "properties": { + "format": { + "type": "string", + "enum": [ + "png", + "jpeg" + ], + "description": "Image format" + }, + "data": { + "type": "string", + "description": "Base64 encoded image data with data URI prefix" + } + }, + "required": [ + "format", + "data" + ] + }, + "SuccessResult": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "ok" + ], + "description": "Operation status" + } + }, + "required": [ + "status" + ] + }, + "DeviceInfo": { + "type": "object", + "description": "Detailed device information", + "additionalProperties": true + }, + "ServerInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Server name" + }, + "version": { + "type": "string", + "description": "Server version" + } + }, + "required": [ + "name", + "version" + ] + }, + "Rect": { + "type": "object", + "description": "Rectangle in pixels", + "properties": { + "x": { + "type": "integer" + }, + "y": { + "type": "integer" + }, + "width": { + "type": "integer" + }, + "height": { + "type": "integer" + } + }, + "required": [ + "x", + "y", + "width", + "height" + ] + }, + "WebView": { + "type": "object", + "description": "An embedded webview attached to the foreground app", + "properties": { + "id": { + "type": "string", + "description": "Stable handle for this webview within the device session" + }, + "url": { + "type": "string", + "description": "Current top-level URL" + }, + "title": { + "type": "string", + "description": "document.title" + }, + "bundleId": { + "type": "string", + "description": "Bundle ID (iOS) or package name (Android) of the host app" + }, + "processName": { + "type": "string", + "description": "Host process name or identifier" + }, + "bounds": { + "$ref": "#/components/schemas/Rect", + "description": "Webview position on screen, in screen coordinates" + }, + "isVisible": { + "type": "boolean", + "description": "True when the webview has non-zero on-screen bounds" + } + }, + "required": [ + "id", + "url", + "title", + "bundleId", + "bounds", + "isVisible" + ] + } + } + } +} diff --git a/docs/openrpc.md b/docs/openrpc.md new file mode 100644 index 0000000..4d7c898 --- /dev/null +++ b/docs/openrpc.md @@ -0,0 +1,1707 @@ +# Mobile CLI Server API + +JSON-RPC API for mobile device automation and control + +**Version:** 0.0.1 + +## Table of Contents + +- [device.apps.clear](#deviceappsclear) +- [device.apps.foreground](#deviceappsforeground) +- [device.apps.install](#deviceappsinstall) +- [device.apps.launch](#deviceappslaunch) +- [device.apps.list](#deviceappslist) +- [device.apps.path](#deviceappspath) +- [device.apps.terminate](#deviceappsterminate) +- [device.apps.uninstall](#deviceappsuninstall) +- [device.boot](#deviceboot) +- [device.crashes.get](#devicecrashesget) +- [device.crashes.list](#devicecrasheslist) +- [device.dump.ui](#devicedumpui) +- [device.fs.ls](#devicefsls) +- [device.fs.mkdir](#devicefsmkdir) +- [device.fs.pull](#devicefspull) +- [device.fs.push](#devicefspush) +- [device.fs.rm](#devicefsrm) +- [device.info](#deviceinfo) +- [device.io.button](#deviceiobutton) +- [device.io.gesture](#deviceiogesture) +- [device.io.longpress](#deviceiolongpress) +- [device.io.orientation.get](#deviceioorientationget) +- [device.io.orientation.set](#deviceioorientationset) +- [device.io.swipe](#deviceioswipe) +- [device.io.tap](#deviceiotap) +- [device.io.text](#deviceiotext) +- [device.reboot](#devicereboot) +- [device.screencapture](#devicescreencapture) +- [device.screenshot](#devicescreenshot) +- [device.shutdown](#deviceshutdown) +- [device.url](#deviceurl) +- [device.webview.content](#devicewebviewcontent) +- [device.webview.evaluate](#devicewebviewevaluate) +- [device.webview.goBack](#devicewebviewgoback) +- [device.webview.goForward](#devicewebviewgoforward) +- [device.webview.goto](#devicewebviewgoto) +- [device.webview.list](#devicewebviewlist) +- [device.webview.query](#devicewebviewquery) +- [device.webview.reload](#devicewebviewreload) +- [device.webview.title](#devicewebviewtitle) +- [device.webview.url](#devicewebviewurl) +- [device.webview.waitForLoadState](#devicewebviewwaitforloadstate) +- [devices.list](#deviceslist) +- [server.info](#serverinfo) +- [server.shutdown](#servershutdown) +- [Error Codes](#error-codes) +- [Schemas](#schemas) + +## Methods + +### device.apps.clear + +**Clear application data** + +Clears all data (cache, preferences, databases) for an application without uninstalling it. Supported on Android and iOS Simulator. Not supported on real iOS devices. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | ✓ | Bundle identifier (iOS) or package name (Android) of the application to clear | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.clear", + "params": { + "deviceId": "string", + "bundleId": "string" + }, + "id": 1 +} +``` + + +### device.apps.foreground + +**Get foreground application** + +Returns the currently foreground (active) application on the specified device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** `object` + +Foreground application information + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.foreground", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.apps.install + +**Install an application** + +Installs an application on the specified device from a local file path. Supports optional IPA re-signing for real iOS devices. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `path` | `string` | ✓ | Local file path to the application package (.apk, .ipa, or .app) | +| `forceResign` | `boolean` | | Re-sign the IPA with a local provisioning profile before installing (only for .ipa files on real iOS devices) | +| `provisioningProfile` | `string` | | Path to a .mobileprovision file to use for re-signing. If not provided, a matching profile is auto-detected. | +| `signingIdentity` | `string` | | Signing identity name or SHA-1 hash to use for re-signing. If not provided, a matching identity is auto-detected. | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.install", + "params": { + "deviceId": "string", + "path": "string", + "forceResign": false, + "provisioningProfile": "string", + "signingIdentity": "string" + }, + "id": 1 +} +``` + + +### device.apps.launch + +**Launch an application** + +Launches an application by bundle ID on the specified device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | ✓ | Bundle ID of the application to launch | +| `locales` | Array<`string`> | | BCP 47 locale tags to set for the app (e.g. ["fr-FR", "en-GB"]). On iOS this is a per-launch argument. On Android 13+ this is persistent. | + +#### Response + +**Type:** `object` + +Launch operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.launch", + "params": { + "deviceId": "string", + "bundleId": "string", + "locales": [ + "string" + ] + }, + "id": 1 +} +``` + + +### device.apps.list + +**List installed applications** + +Returns a list of installed applications on the specified device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** Array<`object`> + +List of installed applications + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.list", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.apps.path + +**Get app data container path** + +Returns the on-device path to an app's data container. Currently supported on Android and iOS real devices. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | ✓ | Bundle identifier (iOS) or package name (Android) of the application | + +#### Response + +**Type:** `object` + +Data container path + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.path", + "params": { + "deviceId": "string", + "bundleId": "string" + }, + "id": 1 +} +``` + + +### device.apps.terminate + +**Terminate an application** + +Terminates a running application by bundle ID on the specified device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | ✓ | Bundle ID of the application to terminate | + +#### Response + +**Type:** `object` + +Terminate operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.terminate", + "params": { + "deviceId": "string", + "bundleId": "string" + }, + "id": 1 +} +``` + + +### device.apps.uninstall + +**Uninstall an application** + +Uninstalls an application from the specified device by its bundle/package ID + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | ✓ | Bundle identifier (iOS) or package name (Android) of the application to uninstall | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.apps.uninstall", + "params": { + "deviceId": "string", + "bundleId": "string" + }, + "id": 1 +} +``` + + +### device.boot + +**Boot a device** + +Boots the specified device (simulators/emulators only) + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** `object` + +Boot operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.boot", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.crashes.get + +**Get a crash report** + +Returns the full content of a specific crash report by ID. The ID is obtained from device.crashes.list. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | Crash report ID (from device.crashes.list) | + +#### Response + +**Type:** `object` + +Crash report content + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.crashes.get", + "params": { + "deviceId": "string", + "id": "string" + }, + "id": 1 +} +``` + + +### device.crashes.list + +**List crash reports** + +Returns a list of crash reports from the specified device. Supports iOS real devices (via crashreport service), iOS simulators (reads from DiagnosticReports), and Android devices (parses adb logcat crash buffer). + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** Array<`object`> + +List of crash reports + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.crashes.list", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.dump.ui + +**Dump UI hierarchy** + +Dumps the UI hierarchy of the device screen + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `format` | enum: `json, raw` | | Output format (json or raw) | + +#### Response + +**Type:** `object` + +UI hierarchy data + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.dump.ui", + "params": { + "deviceId": "string", + "format": "json" + }, + "id": 1 +} +``` + + +### device.fs.ls + +**List files on device** + +Lists files and directories at a given path on the device, or in an app's container. Defaults to the device root if no path is given. Supported on Android and iOS Simulator. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | | Bundle identifier to list files inside an app's container | +| `remotePath` | `string` | | Absolute path on the device to list. Defaults to device root if omitted. | + +#### Response + +**Type:** Array<`object`> + +List of file entries + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.fs.ls", + "params": { + "deviceId": "string", + "bundleId": "string", + "remotePath": "string" + }, + "id": 1 +} +``` + + +### device.fs.mkdir + +**Create a directory on the device** + +Creates a directory at the specified path on the device or in an app's container. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | | Bundle identifier to create directory inside an app's container | +| `remotePath` | `string` | ✓ | Absolute path of the directory to create | +| `parents` | `boolean` | | Create parent directories as needed (like mkdir -p) | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.fs.mkdir", + "params": { + "deviceId": "string", + "bundleId": "string", + "remotePath": "string", + "parents": false + }, + "id": 1 +} +``` + + +### device.fs.pull + +**Pull a file from the device** + +Downloads a file from the device and returns its contents as base64. Maximum file size is 1 MB. Supports arbitrary paths on Android and iOS Simulator. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `remotePath` | `string` | ✓ | Absolute path of the file on the device | + +#### Response + +**Type:** `object` + +File contents + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.fs.pull", + "params": { + "deviceId": "string", + "remotePath": "string" + }, + "id": 1 +} +``` + + +### device.fs.push + +**Push a file to the device** + +Uploads a file to the device from base64-encoded content. Maximum file size is 1 MB. For /data/user/ paths on Android, the file is staged via /data/local/tmp and copied with run-as. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `remotePath` | `string` | ✓ | Absolute destination path on the device | +| `content` | `string` | ✓ | Base64-encoded file contents to write. Maximum decoded size is 1 MB. | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.fs.push", + "params": { + "deviceId": "string", + "remotePath": "string", + "content": "string" + }, + "id": 1 +} +``` + + +### device.fs.rm + +**Remove a file or directory on the device** + +Removes a file or directory at the specified path on the device or in an app's container. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `bundleId` | `string` | | Bundle identifier to remove files inside an app's container | +| `remotePath` | `string` | ✓ | Absolute path of the file or directory to remove | +| `recursive` | `boolean` | | Remove directories and their contents recursively (like rm -rf) | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.fs.rm", + "params": { + "deviceId": "string", + "bundleId": "string", + "remotePath": "string", + "recursive": false + }, + "id": 1 +} +``` + + +### device.info + +**Get device information** + +Returns detailed information about the specified device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** [`DeviceInfo`](#deviceinfo) + +Device information + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.info", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.io.button + +**Press device button** + +Presses a physical or virtual button on the device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `button` | `string` | ✓ | Button to press | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.button", + "params": { + "deviceId": "string", + "button": "string" + }, + "id": 1 +} +``` + + +### device.io.gesture + +**Perform custom gesture** + +Performs a custom gesture with multiple actions on the device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `actions` | Array<`object`> | ✓ | List of gesture actions to perform | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.gesture", + "params": { + "deviceId": "string", + "actions": [ + {} + ] + }, + "id": 1 +} +``` + + +### device.io.longpress + +**Perform long press gesture** + +Performs a long press gesture at the specified coordinates on the device screen + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `x` | `integer` | ✓ | X coordinate for the long press | +| `y` | `integer` | ✓ | Y coordinate for the long press | +| `duration` | `integer` | | Duration of the long press in milliseconds | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.longpress", + "params": { + "deviceId": "string", + "x": 0, + "y": 0, + "duration": 500 + }, + "id": 1 +} +``` + + +### device.io.orientation.get + +**Get device orientation** + +Returns the current orientation of the device screen + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** `object` + +Current device orientation + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.orientation.get", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.io.orientation.set + +**Set device orientation** + +Sets the orientation of the device screen + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `orientation` | `string` | ✓ | Desired orientation | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.orientation.set", + "params": { + "deviceId": "string", + "orientation": "string" + }, + "id": 1 +} +``` + + +### device.io.swipe + +**Perform swipe gesture** + +Performs a swipe gesture from one coordinate to another on the device screen + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `x1` | `integer` | ✓ | Starting X coordinate | +| `y1` | `integer` | ✓ | Starting Y coordinate | +| `x2` | `integer` | ✓ | Ending X coordinate | +| `y2` | `integer` | ✓ | Ending Y coordinate | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.swipe", + "params": { + "deviceId": "string", + "x1": 0, + "y1": 0, + "x2": 0, + "y2": 0 + }, + "id": 1 +} +``` + + +### device.io.tap + +**Perform tap gesture** + +Performs a tap gesture at the specified coordinates on the device screen + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `x` | `integer` | ✓ | X coordinate for the tap | +| `y` | `integer` | ✓ | Y coordinate for the tap | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.tap", + "params": { + "deviceId": "string", + "x": 0, + "y": 0 + }, + "id": 1 +} +``` + + +### device.io.text + +**Input text** + +Inputs the specified text on the device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `text` | `string` | ✓ | Text to input | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.io.text", + "params": { + "deviceId": "string", + "text": "string" + }, + "id": 1 +} +``` + + +### device.reboot + +**Reboot a device** + +Reboots the specified device (simulators/emulators only) + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** `object` + +Reboot operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.reboot", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.screencapture + +**Start screen capture streaming** + +Starts screen capture streaming for the specified device. Supports MJPEG (iOS and Android) and AVC/H.264 (Android only) formats. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `format` | enum: `mjpeg, avc` | | Video format - 'mjpeg' for MJPEG stream (iOS and Android) or 'avc' for H.264 stream (Android only) | +| `quality` | `integer` | | Video quality (only used for MJPEG format) | +| `scale` | `number` | | Video scale factor | + +#### Response + +**Type:** `string` + +Video stream - multipart/x-mixed-replace for MJPEG or video/h264 for AVC + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.screencapture", + "params": { + "deviceId": "string", + "format": "mjpeg", + "quality": 0, + "scale": 0 + }, + "id": 1 +} +``` + + +### device.screenshot + +**Take a screenshot of a device** + +Captures a screenshot from the specified device and returns it as base64 data + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `format` | enum: `png, jpeg` | | Image format (png or jpeg) | +| `quality` | `integer` | | Image quality (1-100, only used for JPEG) | +| `clip` | [`Rect`](#rect) | | Optional rectangle to crop the screenshot to, in screen coordinates | + +#### Response + +**Type:** [`ScreenshotResult`](#screenshotresult) + +Screenshot data + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.screenshot", + "params": { + "deviceId": "string", + "format": "png", + "quality": 1, + "clip": { + "x": 0, + "y": 0, + "width": 0, + "height": 0 + } + }, + "id": 1 +} +``` + + +### device.shutdown + +**Shutdown a device** + +Shuts down the specified device (simulators/emulators only) + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** `object` + +Shutdown operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.shutdown", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.url + +**Open URL** + +Opens the specified URL on the device + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `url` | `string` | ✓ | URL to open | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.url", + "params": { + "deviceId": "string", + "url": "string" + }, + "id": 1 +} +``` + + +### device.webview.content + +**Get webview HTML content** + +Returns the full outer HTML of the page currently loaded in the attached webview. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | + +#### Response + +**Type:** `string` + +Full outer HTML of the page + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.content", + "params": { + "deviceId": "string", + "id": "string" + }, + "id": 1 +} +``` + + +### device.webview.evaluate + +**Evaluate JavaScript in webview** + +Evaluates a JavaScript expression in the attached webview and returns the JSON-serialized result. Throws WebViewEvaluateError if the script throws. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | +| `expression` | `string` | ✓ | JavaScript expression to evaluate. May be a function body invoked with args. | +| `args` | `array` | | Arguments passed to the expression when it is a function body | + +#### Response + +**Type:** `object` + +Serialized return value + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.evaluate", + "params": { + "deviceId": "string", + "id": "string", + "expression": "string", + "args": [] + }, + "id": 1 +} +``` + + +### device.webview.goBack + +**Navigate back in webview history** + +Navigates one step back in the attached webview's session history. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.goBack", + "params": { + "deviceId": "string", + "id": "string" + }, + "id": 1 +} +``` + + +### device.webview.goForward + +**Navigate forward in webview history** + +Navigates one step forward in the attached webview's session history. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.goForward", + "params": { + "deviceId": "string", + "id": "string" + }, + "id": 1 +} +``` + + +### device.webview.goto + +**Navigate webview to URL** + +Navigates the attached webview to the given URL and optionally waits for a load state. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | +| `url` | `string` | ✓ | URL to navigate to | +| `waitUntil` | enum: `load, domcontentloaded` | | Load state to wait for after navigation | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.goto", + "params": { + "deviceId": "string", + "id": "string", + "url": "string", + "waitUntil": "load" + }, + "id": 1 +} +``` + + +### device.webview.list + +**List webviews** + +Returns all embedded webviews currently visible in the foreground app on the device. Browser apps (Safari, Chrome) are not included. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | + +#### Response + +**Type:** Array<[`WebView`](#webview)> + +List of embedded webviews + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.list", + "params": { + "deviceId": "string" + }, + "id": 1 +} +``` + + +### device.webview.query + +**Query DOM elements in webview** + +Finds elements matching a CSS selector and returns their tag, text, id, class, value, and href. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | +| `selector` | `string` | ✓ | CSS selector to match elements against | + +#### Response + +**Type:** Array<`object`> + +Matched DOM elements + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.query", + "params": { + "deviceId": "string", + "id": "string", + "selector": "string" + }, + "id": 1 +} +``` + + +### device.webview.reload + +**Reload webview** + +Reloads the current page in the attached webview. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | +| `waitUntil` | enum: `load, domcontentloaded` | | Load state to wait for after reload | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.reload", + "params": { + "deviceId": "string", + "id": "string", + "waitUntil": "load" + }, + "id": 1 +} +``` + + +### device.webview.title + +**Get webview title** + +Returns the document title (document.title) of the page currently loaded in the attached webview. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | + +#### Response + +**Type:** `string` + +Document title + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.title", + "params": { + "deviceId": "string", + "id": "string" + }, + "id": 1 +} +``` + + +### device.webview.url + +**Get webview URL** + +Returns the current top-level URL (location.href) of the attached webview. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | + +#### Response + +**Type:** `string` + +Current top-level URL + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.url", + "params": { + "deviceId": "string", + "id": "string" + }, + "id": 1 +} +``` + + +### device.webview.waitForLoadState + +**Wait for webview load state** + +Polls the attached webview server-side until the requested load state is reached or the timeout elapses. + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `deviceId` | `string` | ✓ | ID of the target device | +| `id` | `string` | ✓ | WebView ID from device.webview.list | +| `state` | enum: `load, domcontentloaded` | | Load state to wait for | +| `timeout` | `integer` | | Timeout in milliseconds | + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "device.webview.waitForLoadState", + "params": { + "deviceId": "string", + "id": "string", + "state": "load", + "timeout": 30000 + }, + "id": 1 +} +``` + + +### devices.list + +**List all connected devices** + +Returns a list of all connected mobile devices (iOS and Android) + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `includeOffline` | `boolean` | | Include offline devices in the list | +| `platform` | enum: `ios, android` | | Filter devices by platform (ios or android) | +| `type` | `string` | | Filter devices by type (device or simulator) | + +#### Response + +**Type:** Array<[`Device`](#device)> + +List of connected devices + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "devices.list", + "params": { + "includeOffline": false, + "platform": "ios", + "type": "string" + }, + "id": 1 +} +``` + + +### server.info + +**Get server information** + +Returns the server name and version + +#### Response + +**Type:** [`ServerInfo`](#serverinfo) + +Server information + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "server.info", + "params": {}, + "id": 1 +} +``` + + +### server.shutdown + +**Shutdown the server** + +Initiates a graceful server shutdown + +#### Response + +**Type:** [`SuccessResult`](#successresult) + +Operation result + +#### Example Request + +```json +{ + "jsonrpc": "2.0", + "method": "server.shutdown", + "params": {}, + "id": 1 +} +``` + + +## Error Codes + +| Code | Name | Message | Description | +|------|------|---------|-------------| +| `-32700` | **ParseError** | Parse error | Invalid JSON was received by the server | +| `-32600` | **InvalidRequest** | Invalid Request | The JSON sent is not a valid Request object | +| `-32601` | **MethodNotFound** | Method not found | The method does not exist or is not available | +| `-32602` | **InvalidParams** | Invalid params | Invalid method parameters | +| `-32603` | **InternalError** | Internal error | Internal JSON-RPC error | +| `-32000` | **ServerError** | Server error | Unexpected internal server error | +| `-32010` | **DeviceNotFound** | Device not found | The specified device does not exist | +| `-32050` | **DeviceTimeout** | Device timeout | The device did not respond in time | +| `-32100` | **WebViewNotFound** | Webview not found | The supplied webview id does not match any currently-attached webview | +| `-32101` | **WebViewSessionExpired** | Webview session expired | The session is no longer valid; the client must re-attach to the webview | +| `-32102` | **WebViewNodeNotFound** | Webview node not found | The supplied node id is stale because the DOM has mutated; the client must re-query | +| `-32103` | **WebViewNavigationFailed** | Webview navigation failed | The webview did not reach the requested load state in time | +| `-32104` | **WebViewEvaluateError** | Webview evaluate error | The script passed to device.webview.evaluate threw an exception | + +## Schemas + +### Device + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `id` | `string` | ✓ | Unique device identifier | +| `name` | `string` | ✓ | Device name | +| `platform` | enum: `ios, android` | ✓ | Device platform | +| `status` | `string` | ✓ | Device connection status | +| `model` | `string` | ✓ | Device model | +| `provider` | [`DeviceProvider`](#deviceprovider) | | Provider information for this device | + +### DeviceInfo + +Detailed device information + +`object` + +### DeviceProvider + +Describes where the device is provided from + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `type` | `string` | ✓ | Provider type (e.g. 'mobilefleet', 'local') | +| `sessionId` | `string` | | Session identifier for this device allocation | + +### Rect + +Rectangle in pixels + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `x` | `integer` | ✓ | | +| `y` | `integer` | ✓ | | +| `width` | `integer` | ✓ | | +| `height` | `integer` | ✓ | | + +### ScreenshotResult + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `format` | enum: `png, jpeg` | ✓ | Image format | +| `data` | `string` | ✓ | Base64 encoded image data with data URI prefix | + +### ServerInfo + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `name` | `string` | ✓ | Server name | +| `version` | `string` | ✓ | Server version | + +### SuccessResult + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `status` | enum: `ok` | ✓ | Operation status | + +### WebView + +An embedded webview attached to the foreground app + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `id` | `string` | ✓ | Stable handle for this webview within the device session | +| `url` | `string` | ✓ | Current top-level URL | +| `title` | `string` | ✓ | document.title | +| `bundleId` | `string` | ✓ | Bundle ID (iOS) or package name (Android) of the host app | +| `processName` | `string` | | Host process name or identifier | +| `bounds` | [`Rect`](#rect) | ✓ | Webview position on screen, in screen coordinates | +| `isVisible` | `boolean` | ✓ | True when the webview has non-zero on-screen bounds |