How to Automate Android Testing with Playwright on Real Devices
Connect Playwright to an Android phone or emulator through ADB, then automate Chrome for Android or an app’s debuggable WebView.
Playwright can automate Chrome for Android and Android WebView on a physical device or Android Virtual Device (AVD) emulator. It connects through authenticated Android Debug Bridge (ADB); the Android API is experimental, and it automates browser content rather than every native Android interface. For Chrome, discover the device and launch a browser context. For an app WebView, expose the WebView for debugging, find it by package name, and automate its page.
This guide uses Node.js because Playwright’s documented Android API is exposed through its Node package. The workflow requires an Android device or AVD, an authenticated ADB connection, and a compatible Chrome installation. Review the current Playwright Android guide before setting up: its requirements and API details may change.
1. Choose the Android target
Use a real phone when the result needs to reflect actual hardware, the installed Android environment, or a device-specific issue. Use an AVD when you need an Android target without a physical phone. Playwright documents both connected hardware and emulated devices as Android targets.
| Need | Use |
|---|---|
| Automate Chrome running on Android | Playwright Android API and an authenticated ADB target |
| Automate web content inside an Android app | Playwright Android API, the app’s debuggable WebView, and an authenticated ADB target |
| Check responsive layouts and browser parameters | Playwright’s regular browser device emulation |
| Automate native Android UI outside the browser or WebView | This documented Playwright Android workflow does not establish support for that task |
Playwright device emulation sets browser properties such as viewport, screen size, user agent, touch support, locale, timezone, geolocation, permissions, and color scheme. Those settings are useful for web layout tests, but they do not connect the test to an Android operating system through ADB. Use the Android API when the Android Chrome or WebView target itself matters. See Playwright’s emulation guide.
2. Prepare ADB and Chrome
- Install Android platform tools and make an Android phone available, or start an AVD emulator.
- On a phone, enable Developer options and USB debugging. Connect it to the host and accept the device’s authorization prompt. For an emulator, start the AVD.
- Check that ADB can see and authenticate the target:
adb devices
The device should appear as device. An unauthorized state means the host has not been approved on the phone. If several devices are connected, note each serial; the sample below selects the first device, so make your selection explicit for repeatable runs.
For Chrome automation, Playwright’s Android guide documents Chrome 87 or newer and the Enable command line on non-rooted devices flag in chrome://flags. These are documented prerequisites, not a promise that every Chrome or device combination works; confirm the current guide for the version you install.
3. Install Playwright and run Chrome on Android
In a Node.js project, install Playwright:
npm install playwright
Save the following as android-chrome.cjs and run node android-chrome.cjs. It connects to the first device returned by Playwright, launches Chrome on that target, navigates to a page, checks its title, and closes the context and device. The _android export is underscored because the Android support is experimental; check the API for your installed Playwright version.
const { _android: android } = require('playwright');
(async () => {
let device;
let context;
try {
const devices = await android.devices();
if (devices.length === 0) {
throw new Error('No Android devices found. Check ADB authorization and adb devices.');
}
// For multiple targets, select the intended device by its serial.
device = devices[0];
console.log(`Connected to ${device.model} (${device.serial})`);
context = await device.launchBrowser();
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'load' });
console.log('Title:', await page.title());
console.log('URL:', page.url());
await page.screenshot({ path: 'android-chrome.png', fullPage: true });
} finally {
if (context) await context.close();
if (device) await device.close();
}
})().catch(error => {
console.error(error);
process.exitCode = 1;
});
The returned context is a persistent browser context on the Android target. Use Playwright page operations such as goto, locators, assertions, and screenshots against its pages. The Android device reference also documents operations such as reading device information, running shell commands, taking device screenshots, and installing APK files; consult the AndroidDevice API reference for signatures and version-specific behavior.
Select a device when more than one is attached
Do not rely on array order in a shared or multi-device environment. Inspect the available devices and select by serial:
const devices = await android.devices();
for (const device of devices) {
console.log({ model: device.model, serial: device.serial });
}
const wantedSerial = process.env.ANDROID_SERIAL;
const device = devices.find(item => item.serial === wantedSerial);
if (!device) throw new Error(`Android device not found: ${wantedSerial}`);
Set ANDROID_SERIAL to the serial printed by ADB or Playwright before running the script. The Playwright Android guide also documents starting an Android server and connecting a client to its WebSocket endpoint, with device serial selection for multi-device use. That is infrastructure context; it does not establish compatibility with a particular hosted device service.
4. Automate an Android app WebView
WebView automation targets the web page inside an app. The app must be running with the relevant WebView open, and that WebView must be exposed for DevTools debugging. Android’s guidance says the app should call WebView.setWebContentsDebuggingEnabled(true); the android:debuggable manifest flag does not enable WebView debugging by itself. Restrict the debugging switch to development builds, as recommended by Android Developers.
A Kotlin setup can enable debugging in a development build like this:
if (BuildConfig.DEBUG) {
WebView.setWebContentsDebuggingEnabled(true)
}
Use your project’s build configuration to ensure this condition is false in production. Start the app on the Android target, then use Playwright to find the WebView by its package name and operate on its page:
const { _android: android } = require('playwright');
(async () => {
let device;
try {
const devices = await android.devices();
if (devices.length === 0) throw new Error('No Android devices found');
device = devices[0];
const webview = await device.webView({ pkg: 'com.example.app' });
const page = await webview.page();
await page.waitForLoadState('domcontentloaded');
console.log('WebView title:', await page.title());
console.log('WebView URL:', page.url());
await page.screenshot({ path: 'android-webview.png', fullPage: true });
} finally {
if (device) await device.close();
}
})().catch(error => {
console.error(error);
process.exitCode = 1;
});
Replace com.example.app with the app’s actual package name. The Playwright Android API documents retrieving a page from a WebView; check the current Android API guide for the exact method shape supported by your version. Android Developers also documents inspecting enabled WebViews through Chrome DevTools at chrome://inspect while the app runs on a physical device or emulator.
5. Make tests repeatable
- Wait for application state. Prefer a locator or a page condition tied to the result you need. Avoid fixed sleeps unless the app has a known delay that cannot be observed directly.
- Record target identity. Log the model and serial so failures can be tied to a specific device.
- Keep device selection explicit. Select by serial in CI or when multiple ADB targets are attached.
- Clean up resources. Close contexts and devices in a
finallyblock so failed assertions do not leave browser sessions open. - Separate browser checks from native UI checks. This API operates Chrome or WebView pages; it is not a general Android view automation API.
- Keep WebView inspection development-only. Enable it in a debug build and verify the production build does not enable it.
6. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
android.devices() returns no devices |
ADB is not running, the device is disconnected, or the target is not available | Run adb devices, start the AVD if applicable, reconnect the phone, and verify platform tools are available. |
ADB shows unauthorized |
The phone has not approved this host’s debugging key | Unlock the phone, accept the USB debugging prompt, then check adb devices again. |
| More than one device is listed | The script selects a different target than intended | Log serials and select the intended device explicitly instead of using the first entry. |
| Chrome does not launch | Chrome may be missing, too old, or missing the documented non-rooted command-line flag | Check the installed Chrome version, review chrome://flags, and confirm current prerequisites in Playwright’s Android guide. |
| WebView cannot be found | The app or WebView is not open, the package name is wrong, or debugging is disabled | Launch the app and its WebView, verify the package name, enable WebView debugging in a development build, and inspect chrome://inspect. |
| WebView exists but the page is not ready | The app has not navigated or rendered its content yet | Wait for a meaningful page condition or locator before reading content or taking the screenshot. |
| Screenshot is blank or unavailable | The device may be asleep; Playwright’s guide says the device must be awake to produce screenshots | Wake and unlock the target, keep it awake for the capture, and retry. |
| Test passes on emulation but fails on Android | Device emulation and an ADB-connected Android target exercise different environments | Reproduce on the target type relevant to the bug, and record browser, device, and app details. |
| Native controls cannot be located with page locators | The control is outside the browser or WebView page | Use an Android native UI automation approach for native views; Playwright’s documented Android support here is for Chrome and WebView. |
7. Performance, reliability, and cost
Startup and navigation time depend on the device, app, network, and page. Reusing a browser context for related checks can avoid repeated setup, while independent tests may need isolated state. Keep waits tied to observable page conditions and capture only the screenshots needed to diagnose failures.
Playwright labels Android automation experimental. Its guide also notes that raw USB operation is not supported directly (use ADB), the device must be awake for screenshots, and not all tests have been run against the device. Treat device coverage as something to validate for your own browser and app combinations, and keep a fallback path for critical checks. The reviewed documentation provides no reliability rate or performance benchmark, so none is claimed here.
The documented workflow uses Playwright and an Android target; the research does not establish a Playwright or device-service price. A physical phone is optional if an AVD meets the testing need. Factor in the hardware or emulator resources and CI time required by your setup rather than assuming a phone purchase is mandatory.
8. Or skip the browser setup
If your task is to capture a website rather than exercise Android Chrome or an app WebView, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns an image or PDF. It does not replace an Android device test, but it can skip installing and controlling a browser for routine page captures. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as image:
image.write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
require('node:fs').writeFileSync('shot.webp', image);
Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Plans include every feature. The API also supports full-page capture, element selection, device presets, custom CSS and JavaScript, waits, request blocking, caching, signed links, async jobs, and bulk capture.
Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Can Playwright test an Android app?
It can automate Chrome for Android and app WebViews through the documented Android API. This workflow does not imply automation of every native Android screen or control.
Do I need a physical phone?
No. Playwright documents Android devices and AVD emulators as targets. Use hardware when your test needs a real device; an emulator can cover many browser and app checks.
Can I use regular Playwright device emulation instead?
Yes, for browser parameter and responsive layout checks. It does not attach to an Android OS through ADB, so use Android automation when the actual Android Chrome or WebView environment is part of the test.
Does the app’s debuggable build automatically expose its WebView?
No. Android Developers says WebView debugging is controlled separately with WebView.setWebContentsDebuggingEnabled(true); the manifest debuggable flag does not enable it.
Is Playwright Android support stable?
The Android guide calls it experimental. Check its current requirements and validate the specific device, Chrome, and WebView combinations your project depends on.


