/playwright-for-android
End-to-end Android debug loop on an emulator. Builds the APK with a Gradle task, boots a named AVD, installs and launches the target package, then drives a single feature via adb-injected UI actions while capturing a unified logcat-and-actions timeline plus a developer-facing
$ npx -y skills add fclab-skku/playwright_for_android --skill playwright-for-android --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/playwright-for-android
Context preview
The summary Claude sees to decide when to auto-load this skill.
End-to-end Android debug loop on an emulator. Builds the APK with a Gradle task, boots a named AVD, installs and launches the target package, then drives a single feature via adb-injected UI actions while capturing a unified logcat-and-actions timeline plus a developer-facing
SKILL.md
playwright-for-android.SKILL.mdname: playwright-for-android
description: End-to-end Android debug loop on an emulator. Builds the APK with a Gradle task, boots a named AVD, installs and launches the target package, then drives a single feature via adb-injected UI actions while capturing a unified logcat-and-actions timeline plus a developer-facing test report. Use when the user wants to debug, test, verify, or reproduce a feature or bug of an Android app by driving an emulator and reflecting on the UI.
playwright-for-android
Tools live in the `playwright-for-android` MCP server. Each tool's schema (parameters, defaults, descriptions) is authoritative — this document covers only the cross-cutting workflow, reasoning rules, and conventions that don't fit in a single tool description.
When to use
- "Debug the login flow on the emulator and tell me where it breaks."
- "Verify that the new VoiceChat screen renders correctly after I changed `MainActivity.kt`."
- "Reproduce the FCM-token-staleness logcat error and show me the exact UI step that triggers it."
- "Test the wake-word fallback path on a fresh install."
- Any time the alternative would be juggling `./gradlew`, `adb install`, `adb shell am start`, `adb logcat`, and manual UI taps to validate a single feature.
One structured task per invocation. Compose a task, start a session, loop through observations and actions, call `finish_test`. Surface the returned report to the user. Repeat for the next task.
Driving an app without building it
`start_debug_session` builds from a Gradle `project_root` by default. To drive an app this server does not build — e.g. boot the AVD and exercise an already-installed Chrome to test a website — pass `skip_build=true`. In that mode no Gradle build runs and `project_root` is not required to be a Gradle project; it only has to be an existing directory, used solely as the run-dir parent (any folder, even a tmp dir, works). `gradle_task` is ignored.
- **Drive an already-installed package**: `skip_build=true` + `skip_install=true` (no `apk_path` needed). Set `package` to the app to launch (e.g. `com.android.chrome`), or add `skip_launch=true` to attach without forcing a relaunch.
- **Install a prebuilt APK without building**: `skip_build=true` + `apk_path=/path/to/app.apk`.
Tools at a glance
- **Lifecycle**: `precheck`, `start_debug_session`, `finish_test`, `abort_session`.
- **Observation**: `observe_screen`.
- **Actions** (each writes a logcat marker, runs adb, settles, returns the new screen): `tap`, `long_press`, `type_text`, `scroll_dir`, `scroll_to_text_tool`, `press_home`, `press_back`, `wait`.
At most one debug session is active per server process. `start_debug_session` installs it; the action and observation tools operate on the current session implicitly. `finish_test` and `abort_session` clear it. There is no `session_id` parameter.
Every action and observation tool returns one text block (task metadata, step counter, last error, UI element list) and one image block (raw screenshot).
Workflow
1. **Pre-flight.** Call `precheck` and inspect the JSON. Resolve:
- **AVD** — if `default_avd` is null OR `available_avds` has more than one entry and there's no other reason to prefer one, ask the user.
- **Device serial** — if `connected_devices` contains more than one emulator (or a mix of real device + emulator and the user hasn't specified), ask. Real-device serials look like `R5CY50ANT9A`; emulator serials always start with `emulator-`.
- **Project root / package** — if not stated in the user's request, ask.
If `adb.found` or `emulator.found` is `false`, stop and tell the user to install the Android SDK / set `ANDROID_SDK_ROOT`.
2. **Start the session.** Call `start_debug_session` with the resolved values. The first observation comes back with the raw screenshot — start reasoning from there.
3. **Loop: observe → decide → act.** Look at the raw screenshot first to establish current state. Reconcile with the prior turn — if the previous action's expected outcome didn't happen, acknowledge it and adapt. Then call exactly one action tool. The response is the next observation; repeat until a verdict is reachable.
Hard cap of **20 steps**. Once the step counter hits `max_steps`, action tools refuse — call `finish_test` next.
4. **Finish.** Call `finish_test(outcome="pass"|"fail"|"inconclusive", report=...)`. Compose `report` as developer-facing markdown — include UX observations as bullets and embed screenshots inline (``). Captured frames live at `screenshots/stepNN_raw.jpg` relative to the run directory. The tool returns the full report markdown as a string — surface it directly to the user.
Information trust hierarchy
1. **Raw screenshot (GROUND TRUTH)** — the unmodified screenshot is the authoritative source for what is on screen. 2. **UI element list (SUPPLEMENTARY)** — useful for locating coordinates of interactive elements, but may include phantom elements (occluded by the keyboard, behind overlays, off-screen, or invisible accessibility nodes). Always cross-reference against the raw screenshot. 3. **Conversation history (INTENDED ACTIONS ONLY)** — records what was tried, not what actually happened. Actions can fail silently. Verify outcomes against the **current** raw screenshot, not against history.
Reasoning order at every step
1. Look at the raw screenshot first and determine the actual current state. 2. Reconcile with prior turns: if the previous action's expected outcome did not happen, acknowledge it and adapt — do not assume success. 3. Use the UI element list to find coordinates for the next action — only after confirming the target element is actually visible in the raw screenshot. 4. Pick exactly one action tool. Pass a past-tense `summary` (≤ 80 chars). Pass `ux_feedback` only when friction was observed on the current screen.
Coordinate and action conventions
- All coordinates are in **image space**. The image is the de
Read more
name: playwright-for-android description: End-to-end Android debug loop on an emulator. Builds the APK with a Gradle task, boots a named AVD, installs and launches the target package, then drives a single feature via adb-injected UI actions while capturing a unified logcat-and-actions timeline plus a developer-facing test report. Use when the user wants to debug, test, verify, or reproduce a feature or bug of an Android app by driving an emulator and reflecting on the UI.
playwright-for-android
Tools live in the `playwright-for-android` MCP server. Each tool's schema (parameters, defaults, descriptions) is authoritative — this document covers only the cross-cutting workflow, reasoning rules, and conventions that don't fit in a single tool description.
When to use
- "Debug the login flow on the emulator and tell me where it breaks."
- "Verify that the new VoiceChat screen renders correctly after I changed `MainActivity.kt`."
- "Reproduce the FCM-token-staleness logcat error and show me the exact UI step that triggers it."
- "Test the wake-word fallback path on a fresh install."
- Any time the alternative would be juggling `./gradlew`, `adb install`, `adb shell am start`, `adb logcat`, and manual UI taps to validate a single feature.
One structured task per invocation. Compose a task, start a session, loop through observations and actions, call `finish_test`. Surface the returned report to the user. Repeat for the next task.
Driving an app without building it
`start_debug_session` builds from a Gradle `project_root` by default. To drive an app this server does not build — e.g. boot the AVD and exercise an already-installed Chrome to test a website — pass `skip_build=true`. In that mode no Gradle build runs and `project_root` is not required to be a Gradle project; it only has to be an existing directory, used solely as the run-dir parent (any folder, even a tmp dir, works). `gradle_task` is ignored.
- **Drive an already-installed package**: `skip_build=true` + `skip_install=true` (no `apk_path` needed). Set `package` to the app to launch (e.g. `com.android.chrome`), or add `skip_launch=true` to attach without forcing a relaunch.
- **Install a prebuilt APK without building**: `skip_build=true` + `apk_path=/path/to/app.apk`.
Tools at a glance
- **Lifecycle**: `precheck`, `start_debug_session`, `finish_test`, `abort_session`.
- **Observation**: `observe_screen`.
- **Actions** (each writes a logcat marker, runs adb, settles, returns the new screen): `tap`, `long_press`, `type_text`, `scroll_dir`, `scroll_to_text_tool`, `press_home`, `press_back`, `wait`.
At most one debug session is active per server process. `start_debug_session` installs it; the action and observation tools operate on the current session implicitly. `finish_test` and `abort_session` clear it. There is no `session_id` parameter.
Every action and observation tool returns one text block (task metadata, step counter, last error, UI element list) and one image block (raw screenshot).
Workflow
1. **Pre-flight.** Call `precheck` and inspect the JSON. Resolve:
- **AVD** — if `default_avd` is null OR `available_avds` has more than one entry and there's no other reason to prefer one, ask the user.
- **Device serial** — if `connected_devices` contains more than one emulator (or a mix of real device + emulator and the user hasn't specified), ask. Real-device serials look like `R5CY50ANT9A`; emulator serials always start with `emulator-`.
- **Project root / package** — if not stated in the user's request, ask.
If `adb.found` or `emulator.found` is `false`, stop and tell the user to install the Android SDK / set `ANDROID_SDK_ROOT`.
2. **Start the session.** Call `start_debug_session` with the resolved values. The first observation comes back with the raw screenshot — start reasoning from there.
3. **Loop: observe → decide → act.** Look at the raw screenshot first to establish current state. Reconcile with the prior turn — if the previous action's expected outcome didn't happen, acknowledge it and adapt. Then call exactly one action tool. The response is the next observation; repeat until a verdict is reachable.
Hard cap of **20 steps**. Once the step counter hits `max_steps`, action tools refuse — call `finish_test` next.
4. **Finish.** Call `finish_test(outcome="pass"|"fail"|"inconclusive", report=...)`. Compose `report` as developer-facing markdown — include UX observations as bullets and embed screenshots inline (``). Captured frames live at `screenshots/stepNN_raw.jpg` relative to the run directory. The tool returns the full report markdown as a string — surface it directly to the user.
Information trust hierarchy
1. **Raw screenshot (GROUND TRUTH)** — the unmodified screenshot is the authoritative source for what is on screen. 2. **UI element list (SUPPLEMENTARY)** — useful for locating coordinates of interactive elements, but may include phantom elements (occluded by the keyboard, behind overlays, off-screen, or invisible accessibility nodes). Always cross-reference against the raw screenshot. 3. **Conversation history (INTENDED ACTIONS ONLY)** — records what was tried, not what actually happened. Actions can fail silently. Verify outcomes against the **current** raw screenshot, not against history.
Reasoning order at every step
1. Look at the raw screenshot first and determine the actual current state. 2. Reconcile with prior turns: if the previous action's expected outcome did not happen, acknowledge it and adapt — do not assume success. 3. Use the UI element list to find coordinates for the next action — only after confirming the target element is actually visible in the raw screenshot. 4. Pick exactly one action tool. Pass a past-tense `summary` (≤ 80 chars). Pass `ux_feedback` only when friction was observed on the current screen.
Coordinate and action conventions
- All coordinates are in **image space**. The image is the de
Drive an Android emulator from your LLM. Build, install, launch, and test a feature end-to-end — get a unified logcat-and-actions timeline back.
Repo: fclab-skku/playwright_for_android

