From patrol-qa-automation
Debug failing Patrol UI test files for Android/iOS mobile apps. Use when a Patrol test fails, an element is not found, a tap does not navigate, an assertion fails, or a selector breaks. Triggers: 'patrol fails', 'element not found', 'test failed', 'debug patrol', 'patrol error', 'fix patrol test', 'patrol assertion failed'.
How this skill is triggered — by the user, by Claude, or both
Slash command
/patrol-qa-automation:debug-patrol-test Provide the path to the failing Dart test file and the error message if available.Provide the path to the failing Dart test file and the error message if available.The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Diagnose and fix failing Patrol test files for Android/iOS mobile apps. Follows a **read → run → screenshot → native-tree → fix → re-run** loop.
Diagnose and fix failing Patrol test files for Android/iOS mobile apps. Follows a read → run → screenshot → native-tree → fix → re-run loop.
Element not found error in a testcase or scenarioexpect() assertion fails despite the element appearing on screenmcp_patrol_mcp_status shows a connected device)mcp_patrol_mcp_statusRun the test via MCP:
mcp_patrol_mcp_run testFile="patrol_test/testcases/login/verify_login_form_visible.dart"
Capture the exact error: which assertion/action failed and the error message.
Take a screenshot immediately after the run — the emulator/simulator stays on the screen where the test stopped. This is your primary debugging context.
mcp_patrol_mcp_screenshot
Inspect the native view hierarchy:
mcp_patrol_mcp_native-tree
Look for:
text or label value of the target element (never assume from screenshot)identifier or resourceName if no stable text is availableIdentify the root cause using the Common Failure Patterns table.
Edit the Dart test file with the proposed fix.
Run the test again to validate:
mcp_patrol_mcp_run testFile="patrol_test/testcases/login/verify_login_form_visible.dart"
Check pass/fail via mcp_patrol_mcp_status.
If still failing, take a new screenshot and native-tree, then repeat from Phase 3.
After a fix is confirmed, check if the root cause matches any entry in failure-patterns.md.
If the root cause is NOT already documented:
references/failure-patterns.md following the existing format:
This ensures the knowledge base grows with every debugging session and future failures are resolved faster.
Stop and report findings if:
Semantics, rebuild APK) — report exactly what change is neededSee failure-patterns.md for the full reference table.
Quick reference (most frequent):
| Error | Root Cause | Fix |
|---|---|---|
findsNothing for text element | Exact match fails on partial/merged text | Use containing finder or match full merged text |
findsNothing for text element | Dialog/overlay blocking the element | Dismiss the dialog first with if (await $('Allow').exists) |
findsNothing for text element | Hint text includes character counter | Use Key-based selector or containing |
| Tap does nothing / navigates wrong screen | Duplicate text label (header + button) | Use ancestor chaining: $(Scaffold).$('Submit').tap() |
| Element found on Android but not iOS | Different accessibility tree structure | Use native-tree to inspect platform-specific identifiers |
expect() fails despite text on screen | Label+value merged into one accessibility node | Use containing finder or match full merged text |
| Flow passes but wrong screen | Navigation succeeded but assertion is too loose | Tighten assertion to screen-specific element |
For the full selector priority hierarchy, decision tree, and accessibility node merging rules, see shared-references/selector-rules.md.
Quick reference:
native-tree element has text content (non-empty)?
YES → use $('exact_text').tap()
NO → has resource-id / key?
YES → use $(#keyOrId).tap()
NO → has a Semantics identifier?
YES → use $(#semanticsIdentifier).tap()
NO → same text appears multiple times?
YES → use ancestor chaining: $(Parent).$('text').tap()
NO → add Semantics(identifier: 'name', container: true) to Flutter widget
rebuild app, then use $(#name).tap()
Never use $.native.tap(Offset(x, y)) unless absolutely no other option exists. If a coordinate-based tap exists in the file and is failing, replace it first.
$('text') matches by text content — Use Key-based selectors for elements without stable text.$.native.tap(Offset(x,y)) breaks across screen sizes/densities.Semantics additions are not reflected until you rebuild and reinstall the app.pumpWidgetAndSettle() — Let animations settle after navigation before asserting.1. mcp_patrol_mcp_status → check session state, get device info
2. mcp_patrol_mcp_run(test_file) → run failing test, get error
3. mcp_patrol_mcp_screenshot → see where test stopped
4. mcp_patrol_mcp_native-tree → get actual text/identifier values
5. edit the Dart test file with fix
6. mcp_patrol_mcp_run(test_file) → re-run to verify fix
7. mcp_patrol_mcp_status → check pass/fail
8. append to failure-patterns.md → if root cause was new
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub iqbal-mekari/claude-plugins --plugin patrol-qa-automation