Skip to content
cccskills
FreePublished on GitHub

appium-test-debug

RIPDPI Appium failure triage: flaky tests, locator/session/wait issues, screenshot and element-tree debugging. Use when an Appium test fails or is flaky.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md5.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Appium Test Debug

Systematic troubleshooting for failing or flaky Appium tests in the RIPDPI suite.

Triage Checklist

Work through in order -- stop at the first failure:

  1. Appium server running? -- curl -s http://127.0.0.1:4723/status | jq .value.ready
  2. Device/emulator connected? -- adb devices -l (should show at least one device)
  3. Debug APK installed? -- adb shell pm list packages | grep ripdpi
  4. Route exists in Kotlin? -- Search for the start_route value in Route.kt sealed class
  5. testTag present in the contract? -- check app/src/main/kotlin/com/poyka/ripdpi/ui/testing/RipDpiTestTags.kt and docs/automation/selector-contract.md, then confirm the tag is actually attached in Compose source
  6. Correct preset combination? -- See preset tables in appium-automation-contract skill

Failure Patterns

SymptomCauseFix
NoSuchElementExceptionElement not on screen, wrong tag, or needs scrollVerify tag matches Modifier.testTag() in Compose source. Use scroll_to() if below viewport.
TimeoutException from wait_forScreen didn't load or element not renderedCheck automation contract params -- wrong start_route or data_preset. Increase timeout for slow emulators.
StaleElementReferenceExceptionCompose recomposition invalidated element referenceRe-find the element after any action that triggers recomposition. Don't store element references across interactions.
Session creation failsAppium server down, UiAutomator2 driver missing, or no deviceRun triage checklist steps 1-3. Install driver: appium driver install uiautomator2.
Passes locally, fails in CIAnimation timing, slower emulator, permission stateVerify disable_motion=True in marker. Check CI emulator specs. Increase timeout if needed.
Wrong screen appearsIncorrect start_route or route not handled in contractVerify route exists in Kotlin Route class. Check data_preset matches screen requirements.
Element found but tap has no effectElement overlapped by another, or animation in progressWait for animations to settle. Check if a dialog/overlay is blocking. Use wait_for before tap.

Flakiness Diagnosis

Step-by-step:

  1. Reproduce -- Run the single test 5 times:
    for i in {1..5}; do pytest tests/test_XX.py::test_name -v; done
    
  2. Classify -- Is the failure:
    • Timing (passes with longer timeout)? Increase specific timeout, not global.
    • State (depends on previous test)? Verify reset_state=True in marker.
    • Animation (element moves during interaction)? Verify disable_motion=True.
    • Race condition (element appears then disappears)? Check if Compose recomposes the element.
  3. Check screenshot -- Failure screenshots in appium/screenshots/{test_name}.png show what was actually displayed.
  4. Check element tree -- Add print(driver.page_source) temporarily to dump the XML tree and search for the expected resource-id.
  5. Check Appium logs -- Server logs show the exact command sent and UiAutomator2's response.

Debugging Locators

Verify a tag exists on screen

# In test or debug session:
source = driver.page_source
assert "com.poyka.ripdpi:id/{tag}" in source, f"Tag '{tag}' not in element tree"

Dump element tree via ADB

adb shell uiautomator dump /sdcard/ui.xml
adb pull /sdcard/ui.xml
rg "resource-id" ui.xml  # Search for specific IDs

Match against Compose source

# Find which composable sets the testTag
rg '{tag}|RipDpiTestTags\\.' app/src/main/kotlin/

If the tag is not found, the composable is missing Modifier.testTag("{tag}") -- this is the root cause and must be fixed in the Kotlin source, not the test.

Screenshot Analysis

The conftest.py fixture saves screenshots on failure:

  • Location: appium/screenshots/{test_name}.png
  • Created automatically by launch_app fixture when rep_call.failed is True
  • Check the screenshot to verify: correct screen displayed, element visibility, dialog/overlay blocking

Wait Strategy Fixes

ProblemSolution
Element appears after animationUse wait_for(tag, timeout=10) not find(tag)
Element appears after network callIncrease to wait_for(tag, timeout=15)
Element below viewportUse scroll_to(tag) before interacting
Element disappears after actionUse is_visible(tag, timeout=3) with assert not
Screen takes long to loadOnly increase timeout in conftest.py launch wait (15s), not in individual tests
Element exists in DOM but not renderedUse is_visible() which checks presence, not just DOM

Common Mistakes

MistakeFix
Adding time.sleep() to fix timingUse wait_for() or is_visible() with appropriate timeout
Increasing all timeouts globallyIdentify the specific slow element and adjust only that call
Ignoring reset_state=TrueStale state from previous test causes cascading failures
Catching exceptions to hide failuresLet exceptions propagate; fix the root cause
Re-running flaky test without diagnosisClassify the failure type first (timing/state/animation)

See Also

  • .agents/skills/appium-automation-contract/SKILL.md -- Preset values and launch flow
  • .agents/skills/appium-test-authoring/SKILL.md -- Conventions for writing tests and page objects
  • .agents/skills/android-device-debug/SKILL.md -- ADB commands, logcat, emulator management

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).

The English summary is being prepared. Showing the original description.

po4yka/RIPDPI81Updated Oct 19, 2026

ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.

The English summary is being prepared. Showing the original description.

po4yka/RIPDPI81Updated Oct 19, 2026

RIPDPI Appium launch-contract reference: start routes and permission/service/data presets. Use when a test launches to the wrong screen or a new automation route is added. General flakiness: appium-test-debug.

The English summary is being prepared. Showing the original description.

po4yka/RIPDPI81Updated Oct 19, 2026

RIPDPI Appium test authoring: page objects, resource-id locators, assertions, wait tiers. Use when writing a new Appium test or page object, or adding coverage for a new screen.

The English summary is being prepared. Showing the original description.

po4yka/RIPDPI81Updated Oct 19, 2026

Add or modify a GitHub Actions job. Use when editing a file under .github/workflows/. Not for running a workflow locally (local-ci-act) or release signing (release-signing).

The English summary is being prepared. Showing the original description.

po4yka/RIPDPI81Updated Oct 19, 2026

Conservative review of end-user legal exposure from diagnostics targets and probe hosts, by jurisdiction. Use when shipping or editing diagnostics target lists, probe hosts, or bootstrap endpoints.

The English summary is being prepared. Showing the original description.

po4yka/RIPDPI81Updated Oct 19, 2026

See all skills by po4yka

Report a problem with this skill