ARTICLE AD BOX
I'm building a C# WinForms application that automates login on Android devices using ADB and Playwright.
The workflow works partially:
Chrome opens successfully on the Android device using an ADB intent
Remote debugging is enabled with --remote-debugging-port=9222
Port forwarding is created with adb forward tcp:9222 tcp:9222
Playwright connects using Chromium.ConnectOverCDPAsync
The website loads correctly on the Android device, but Playwright cannot detect or interact with any DOM elements.
Selectors return null and JavaScript injection fails to find elements.
No exceptions are thrown.
Environment
Language: C#
Framework: .NET 6 / .NET Framework 4.8
Automation library: Microsoft.Playwright
ADB library: AdvancedSharpAdbClient
Target: Android devices running Chrome
Host OS: Windows 10 / 11
ADB setup and Chrome launch
await Invio_ComandoAsync("am force-stop com.android.chrome", deviceIndex, cancellationToken); string chromeCommand = "am start -n com.android.chrome/com.google.android.apps.chrome.Main " + "--es com.android.chrome.command_line \"--remote-debugging-port=9222\" " + "-a android.intent.action.VIEW -d about:blank"; await Invio_ComandoAsync(chromeCommand, deviceIndex, cancellationToken); var adbClient = new AdbClient(); var devices = await adbClient.GetDevicesAsync(); var device = devices.FirstOrDefault(d => d.Serial == deviceSerial); await adbClient.CreateForwardAsync(device, "tcp:9222", "tcp:9222", true, cancellationToken); await Invio_ComandoAsync( $"am start -a android.intent.action.VIEW -d \"{url}\"", deviceIndex, cancellationToken );Playwright connection
_playwright = await Playwright.CreateAsync(); _browser = await _playwright.Chromium.ConnectOverCDPAsync( "http://localhost:9222" ); var pages = _browser.Contexts.SelectMany(c => c.Pages).ToList(); _page = pages.LastOrDefault();The page appears in the browser and the URL is visible on the Android device.
Attempt to interact with the page
string jsCode = @" (function() { const username = document.querySelector('#username'); const password = document.querySelector('#password'); const button = document.querySelector('button[type=""submit""]'); if(username && password && button) { username.value = 'test'; password.value = 'test'; button.click(); return 'success'; } return 'elements_not_found'; })(); "; var result = await _page.EvaluateAsync(jsCode);The result returned is:
elements_not_foundHowever, the login fields are clearly visible on the Android device screen.
Expected result
Playwright should detect the DOM elements and fill the login form.
Actual result
No elements are detected and no interaction happens.
What I've tried
Waiting for page load using delays
Using different selectors
Using JavaScript injection instead of Playwright selectors
Checking _browser.Contexts and Pages
Testing with multiple Android devices
The same Playwright code works correctly with desktop Chrome, but not with Android Chrome via ADB CDP connection.
Questions
How can I ensure Playwright is connected to the correct Android Chrome tab/page?
Is there a recommended way to wait for the page to be fully interactive when connecting via CDP?
Is launching Chrome this way the correct approach for enabling remote debugging on Android?
Could this be related to Chrome contexts or DevTools targets?
