Android WebDriver
Introduction
This page is a reference for the available commands, execute methods, and key mappings for the Android WebDriver integration, which covers Android TV, Google TV, and Fire TV devices.
The Android WebDriver integration is written by TV Labs for Android TV devices. It is an Appium compatible WebDriver that follows appium-uiautomator2-driver, so it can be driven from any Appium or WebDriver client. It drives the device through a UiAutomator2 server running on it, and drives web views through ChromeDriver.
Starting a Session
Select a build with the tvlabs:build capability and it is installed onto the device and launched when the session starts. To launch an app that is already installed, name it with appium:appPackage instead.
const capabilities = {
'tvlabs:constraints': { platform_key: 'android_tv' },
'tvlabs:build': 'YOUR_BUILD_ID',
};
A session started without an app is still a valid session, and starts on whatever is on screen.
Capabilities
| Capability | Description |
|---|---|
appium:appPackage | The package of the app to launch. Set for you from tvlabs:build when a build is selected |
appium:appActivity | The activity to launch. Set for you from tvlabs:build, and can be overridden |
appium:autoLaunch | When false, the app is not launched when the session starts |
appium:disableIdLocatorAutocompletion | When true, id locators are not prefixed with <appPackage>:id/. Needed for Jetpack Compose test tags |
appium:newCommandTimeout | Seconds without a command before the session is ended. Default: 60 |
goog:chromeOptions | Passed through to ChromeDriver when switching into a web view |
The other UiAutomator2 settings can also be given as appium: capabilities, and are applied when the session starts.
Contexts
getContexts returns NATIVE_APP followed by a WEBVIEW_<package> entry for each debuggable web view, and CHROMIUM when a browser is open. Switch to a web view to drive its page with web commands and run JavaScript. mobile: methods always run against the native context.
A web view only appears once the app enables WebView debugging.
const contexts = await driver.getContexts();
// ['NATIVE_APP', 'WEBVIEW_com.example.myapp']
// mobile: getContexts adds the DevTools socket and the process that owns it
const details = await driver.executeScript('mobile: getContexts', []);
// [
// { id: 'NATIVE_APP' },
// {
// id: 'WEBVIEW_com.example.myapp',
// socket: 'webview_devtools_remote_4821',
// pid: 4821,
// packageName: 'com.example.myapp',
// },
// ]
await driver.switchContext('WEBVIEW_com.example.myapp');
Available Commands
The standard WebDriver commands for finding elements, element state, interaction, W3C Actions, alerts, page source, timeouts, and orientation are handled by the UiAutomator2 server. In a web context, the web commands for elements, navigation, cookies, and script execution run against the page instead.
The id, xpath, class name, accessibility id, name, and -android uiautomator locator strategies are supported in the native context. CSS, link text, and tag name locators are only available in a web context.
The following behave differently on Android:
| Command | Behavior |
|---|---|
takeScreenshot | Captured on the device, so its coordinates match element rects |
execute | In the native context, only mobile: and tvlabs: methods. Raw JavaScript needs a web context |
back | Presses the Back key |
navigateTo | Opens the URL as a deep link |
minimizeWindow | Presses Home |
getLogs | The logcat log type only |
| Cookies | Only in a web context |
W3C Actions pointerMove steps must include a duration.
Execute Methods
In addition to the standard WebDriver commands, the following execute methods are available for device interaction. They take the same arguments as the appium-uiautomator2-driver methods of the same name.
| Command | Required Arguments | Description |
|---|---|---|
mobile: pressKey | keycode | Press a key. See the key map. Optional isLongPress holds it |
mobile: pressButton | name | The same as mobile: pressKey, with the key given as name |
mobile: type, keys | text / keys | Type text into the focused element |
mobile: hideKeyboard, isKeyboardShown | - | Hide the on-screen keyboard, or check whether it is shown |
mobile: launchApp, activateApp | appPackage | Launch an app. Optional appActivity picks the activity |
mobile: terminateApp | appPackage | Force-stop an app. Returns false if it wasn't running |
mobile: queryAppState | appPackage | The app's state, from 0 (not installed) to 4 (running in the foreground) |
mobile: isAppInstalled, removeApp, clearApp | appPackage | Check, uninstall, or clear the data of an app |
mobile: listApps | - | The installed apps |
mobile: backgroundApp | - | Press Home |
mobile: getCurrentPackage, getCurrentActivity | - | The foreground app's package or activity |
mobile: startActivity | intent | Start an activity, given as package/.Activity. Optional extras, wait, and stop |
mobile: deepLink | url | Open a URL, optionally in the app named by package |
mobile: clickGesture, longClickGesture, doubleClickGesture | x, y or elementId | Tap at a point or on an element |
mobile: dragGesture, flingGesture, swipeGesture, scrollGesture | See description | Drag, fling, swipe, or scroll within an area or element |
mobile: pinchOpenGesture, pinchCloseGesture | See description | Pinch within an area or element |
mobile: scroll | strategy, selector | Scroll until an element is found |
mobile: deviceInfo | - | See mobile: deviceInfo |
mobile: deviceScreenInfo, getDisplayDensity, getSystemBars | - | Details of the screen |
mobile: getDeviceTime | - | The device's time. Optional format |
mobile: getOrientation, setOrientation, getRotation, setRotation | See description | Get or set the screen orientation or rotation |
mobile: viewportRect, viewportElementRect, viewportScreenshot | - | The app's viewport, an element's position in it, or a screenshot of it |
mobile: screenshots, listDisplays, listWindows | - | Screenshots and details of each display and window |
mobile: source | - | The page source as XML |
mobile: getContexts | - | The available contexts, including web view details |
mobile: lock, unlock, isLocked | - | Sleep or wake the device, or check whether it is locked |
mobile: setClipboard | content or text | Write the clipboard. Reading it isn't available on Android 10 and newer |
mobile: acceptAlert, dismissAlert | - | Accept or dismiss the current alert. Optional buttonLabel picks the button |
Any other mobile: method returns an unknown method or unsupported operation error. Installing apps, file transfer, screen recording, and shell access (mobile: shell) are not available through WebDriver; select a build with tvlabs:build to install an app. To run adb commands against a device, connect to its session with tvlabs connect.
mobile: pressKey
await driver.executeScript('mobile: pressKey', [{ keycode: 22 }]);
// Key names work too
await driver.executeScript('mobile: pressKey', [{ keycode: 'DPAD_CENTER' }]);
Key Map
mobile: pressKey and mobile: pressButton accept any Android KeyEvent code, either as a number or as its name, with or without the KEYCODE_ prefix. Names are case-sensitive. The keys most used on a TV are:
| Key | Code | Description |
|---|---|---|
DPAD_UP | 19 | Up |
DPAD_DOWN | 20 | Down |
DPAD_LEFT | 21 | Left |
DPAD_RIGHT | 22 | Right |
DPAD_CENTER | 23 | Select |
BACK | 4 | Back |
HOME | 3 | Home |
MENU | 82 | Menu |
ENTER | 66 | Enter |
SEARCH | 84 | Search |
SETTINGS | 176 | Settings |
GUIDE | 172 | Guide |
INFO | 165 | Info |
CAPTIONS | 175 | Captions |
MEDIA_PLAY_PAUSE | 85 | Play / Pause |
MEDIA_PLAY | 126 | Play |
MEDIA_PAUSE | 127 | Pause |
MEDIA_FAST_FORWARD | 90 | Fast forward |
MEDIA_REWIND | 89 | Rewind |
VOLUME_UP | 24 | Volume Up |
VOLUME_DOWN | 25 | Volume Down |
VOLUME_MUTE | 164 | Mute |
CHANNEL_UP | 166 | Channel Up |
CHANNEL_DOWN | 167 | Channel Down |
PROG_RED | 183 | Red |
PROG_GREEN | 184 | Green |
PROG_YELLOW | 185 | Yellow |
PROG_BLUE | 186 | Blue |
POWER | 26 | Power |
WAKEUP | 224 | Wake |