Teaching Claude to QA a mobile app
TL;DR Highlight
A solo dev filled the automated testing gap for their Capacitor-based mobile app using Claude + CDP + adb — now 25 screens are auto-tested every morning in 90 seconds with auto-generated bug reports.
Who Should Read
Solo developers or small teams building WebView-based hybrid apps with Capacitor or React Native who haven't been able to tackle mobile automation testing.
Core Mechanics
- Capacitor wraps a React web app into Android (WebView) and iOS (WKWebView), creating a 'testing no-man's-land' where neither web testing tools like Playwright nor native tools like XCTest/Espresso work properly. Too native for web tools, too web for native tools.
- The Android solution exploits the fact that WebView exposes a Chrome DevTools Protocol (CDP) socket. Forward that socket to a local port via adb, and you can control the app programmatically using the same protocol Playwright/Puppeteer use.
- Android localhost connectivity was fixed with 'adb reverse tcp:3000 tcp:3000'. The emulator's localhost points to itself, not the host Mac, so this command must be re-run after every emulator restart.
- A Python script runs daily at 8:47 AM, cycling through 25 screens (landing, login, 4 feed types, post detail, profile, badges, content creation forms, etc.) in about 90 seconds, taking screenshots at each. Claude analyzes each screenshot for layout breaks, error messages, missing images, blank screens, status bar overlaps, etc.
- When bugs are found, Claude authenticates as zabriskie_bot, uploads screenshots to S3, and auto-files bug reports to the production forum in '[Android QA] Shows Hub: RSVP button overlaps venue text' format. The title immediately identifies it as coming from automation.
- Claude was also taught 'expected normal states.' A non-member seeing 'Forbidden' on a crew detail page, empty avatar circles, or 'Preview' text in profile settings are not bugs. Without this context, screenshot analysis produces too many false positives.
- iOS took 6+ hours vs Android's setup — over 6x longer. Apple's security policies block external access to WKWebView's CDP socket. A stark demonstration of the 2026 maturity gap in mobile automation tooling.
- Claude accidentally committed to the wrong repository after misidentifying a git worktree. In interactive mode this is caught immediately, but during scheduled unattended runs, it wasn't discovered until the next morning. A case study in why isolation boundary enforcement matters for autonomous AI agents.
Evidence
- Someone pointed out that WebdriverIO + Appium already solves this, citing Ionic (Capacitor's parent company) officially recommending this combo for E2E testing. Meaning existing open-source tools should have been evaluated before reaching for Claude.
- The git worktree isolation failure was highlighted as the most interesting part. The key insight: 'worktree doesn't physically prevent an agent from running cd ../main-repo.' Narrow, well-defined tasks (25-screen screenshot cycling) work fine, but judgment-heavy tasks ('fix the failing test') can lead to worktree escape. A developer building tooling for this (openhelm.ai) chimed in.
- Skepticism about whether Claude analyzing screenshots constitutes meaningful QA. Visual anomaly detection-level analysis can't replace real functional verification — a criticism directly pointing at the approach's limitations.
- Someone shared their experience with hardware-layer approaches for mobile app reverse engineering and smart home device automation — connecting external controllers to device mainboards as an alternative when software-layer automation hits walls.
How to Apply
- To automate Capacitor app testing on Android, forward the WebView's CDP socket to a local port via adb, then attach existing CDP clients (like Puppeteer libraries) directly. Remember to re-run 'adb reverse tcp:port tcp:port' after emulator restarts to maintain connectivity.
- When building screenshot-based visual regression testing with Claude (or other LLMs), explicitly include an 'expected normal states' list in the prompt to reduce false positives. For example: Forbidden screen for non-member access, empty circles for unset avatars, etc.
- When running AI agents on a schedule unattended, scope tasks as narrowly as possible, and use physical enforcement (filesystem permission restrictions, separate containers) rather than soft boundaries like git worktree isolation. Agents will cross boundaries unless explicitly prevented.
- If you're first introducing mobile E2E automation for a Capacitor app, evaluate the officially recommended stack of WebdriverIO + Appium before custom Claude scripts. There's a proven open-source ecosystem with robust community support.
Code Example
snippet
# 1. Android emulator network forwarding
adb reverse tcp:3000 tcp:3000
adb reverse tcp:8080 tcp:8080
# 2. Find WebView CDP socket and port forwarding
WV_SOCKET=$(adb shell "cat /proc/net/unix" | \
grep webview_devtools_remote | \
grep -oE 'webview_devtools_remote_[0-9]+' | head -1)
adb forward tcp:9223 localabstract:$WV_SOCKET
# 3. Verify CDP endpoint
curl http://localhost:9223/json
# 4. Capture screenshot (adb)
adb shell screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png ./screenshots/screen.pngTerminology
CDP (Chrome DevTools Protocol)The protocol Chrome uses to communicate with external tools. It's the same channel Playwright and Puppeteer use internally to control browsers. Android WebView also exposes this socket.
adb (Android Debug Bridge)A CLI tool connecting your dev PC to Android emulators/devices. Supports port forwarding, file transfers, shell commands, etc.
WebViewA mini browser container embedded inside an app. Hybrid app frameworks like Capacitor display HTML/JS-built UI inside it.
CapacitorIonic's open-source framework that packages web tech (React, etc.) apps into Android and iOS native apps. Unlike Flutter's custom renderer, it wraps web code in a WebView.
git worktreeA Git feature for checking out multiple branches simultaneously in different directories. Often used to give AI agents isolated workspaces, but doesn't physically prevent agents from escaping the directory.
Visual Regression TestingA testing technique that compares UI screenshots before and after deployment to detect unintended visual changes. Checks 'does the screen look wrong' rather than 'does the feature work correctly.'