Taming the Android Password Manager Beast: A Guide for UI Test Automation

Taming the Android Password Manager Beast: A Guide for UI Test Automation
A photo of some code in an IDE, unrelated to anything I’m discussing

How to prevent Google’s well-intentioned password manager from sabotaging your automated tests

If you’ve run Android UI tests that involve sign-in flows, you’ve probably encountered this frustrating scenario: your tests run perfectly on your development machine, but fail mysteriously in CI/CD. The culprit? Google’s Password Manager and its newer sibling, the Credential Manager.

In this post, I’ll explain why Android’s password managers break automated tests, how the problem evolved across Android versions, and share the comprehensive solution I use to completely disable these services during test runs.

The Problem: When Helpful Features Become Test Blockers

When your test suite performs sign-in operations, Android’s built-in password management services spring into action. They detect credential input fields and automatically display system modal dialogs offering to save or autofill passwords.

While this is incredibly helpful for end users, it creates significant problems for automated testing.

Four Ways Password Manager Popups Break Tests

1. They block test execution

The popup appears over your test UI, intercepting touch events that were meant for your app’s elements. When your test tries to tap a “Sign In” button, it might inadvertently tap the “Save password?” dialog instead.

2. They’re invisible to test frameworks

Espresso and Compose UI testing frameworks cannot interact with system-level modals that exist outside your app’s UI hierarchy. Your test assertions fail because the expected UI elements are obscured or inaccessible.

3. They create flaky tests

The timing of when these popups appear is inconsistent. Sometimes they show up before your test can interact with the UI, sometimes after. This unpredictability leads to tests that pass sometimes and fail other times — the worst kind of test failure.

4. They persist across test runs

Simply dismissing the modal doesn’t prevent it from reappearing in subsequent tests. The password manager “remembers” that your app has credential fields and will continue offering its services.

Why This Happens: Understanding the Intent vs. Reality

Android’s autofill framework and password managers are designed with the best intentions. They help users by:

  • Automatically detecting username and password fields in any app
  • Offering to save credentials when users sign in successfully
  • Providing autofill suggestions on subsequent sign-in attempts
  • Supporting modern authentication methods like passkeys and federated identity

But here’s the catch: The Android OS treats password management as a security feature that apps shouldn’t be able to disable programmatically. This makes perfect sense for production apps, but it’s problematic for testing.

In an automated testing environment, these well-intentioned features become obstacles because:

  • Tests require predictable, uninterrupted UI interactions to verify app behavior
  • System modals cannot be controlled or dismissed via standard test automation frameworks
  • Apps have no programmatic way to suppress these system-level services
  • Test isolation breaks down when system services persist state between test runs

The Challenge Grows: Android 14’s Credential Manager

The challenge of dealing with password managers in automated tests has evolved as Android has matured.

Android 8–13: The Simpler Days

In these versions, Google Password Manager was part of Google Mobile Services (GMS). The autofill framework was controlled primarily through a single system setting. Disabling it was relatively straightforward:

adb shell settings put secure autofill_service null

Android 14+: Everything Changed

With Android 14, Google introduced the Credential Manager API — a platform-level service that consolidates password managers, passkeys, and other credential providers into a unified system.

This added significant complexity with several new components:

  • credential_manager_enabled — Master switch for the entire Credential Manager system
  • credential_service — The active credential provider service
  • credential_service_primary — The primary credential provider
  • autofill_field_classification — Enhanced autofill detection capabilities

The new architecture means that disabling just the autofill_service is no longer sufficient on Android 14+ devices. The Credential Manager can still inject its UI into your app's authentication flows.

Our Solution: A Three-Pronged Approach

After many failed CI builds and debugging sessions, I developed a comprehensive approach that works across all Android versions. The solution involves executing a series of ADB commands before each test run.

Step 1: Clear Google Mobile Services Data

adb shell pm clear com.google.android.gms

What this does:

  • Resets Google Mobile Services to factory state
  • Clears any stored password manager preferences
  • Forces the password manager to “forget” previous autofill decisions

Why it’s necessary: Even if you disable the autofill service, previously saved preferences might cause the system to re-enable it. Clearing GMS data provides a clean slate.

Step 2: Disable Autofill Services (Android 8+)

adb shell settings put secure autofill_service null
adb shell settings put secure autofill_field_classification 0
adb shell settings put secure autofill_feature_field_classification 0

What this does:

  • Removes any registered autofill service from the system
  • Disables field detection and classification algorithms
  • Prevents the autofill framework from analyzing text input fields

Why it’s necessary: This tackles the core autofill framework that has existed since Android 8. Without this, the system will still try to detect password fields and offer autofill suggestions.

Step 3: Disable Credential Manager (Android 14+)

adb shell settings put secure credential_manager_enabled 0
adb shell settings put secure credential_service null
adb shell settings put secure credential_service_primary null

What this does:

  • Disables the new platform-level Credential Manager
  • Removes Google’s credential provider service
  • Prevents passkey and password autofill prompts

Why it’s necessary: On Android 14+ devices, the new Credential Manager operates independently of the older autofill framework. You need to disable both systems.

Putting It All Together: Our CI/CD Implementation

Here’s how we integrate this into our TeamCity build configuration. Before our test runner executes tests, we prepare each device:

# Wake up and unlock all connected devices
echo "Waking up and unlocking devices..."
for device in $(adb devices | grep -v "List" | grep "device$" | awk '{print $1}'); do
    echo "  Preparing device: $device"
    # Wake and unlock
    adb -s $device shell input keyevent KEYCODE_WAKEUP || true
    adb -s $device shell wm dismiss-keyguard || true
    echo "  Disabling autofill/password manager..."
    # Step 1: Clear GMS data
    adb -s $device shell pm clear com.google.android.gms || true
    # Step 2: Disable autofill (all versions)
    adb -s $device shell settings put secure autofill_service null || true
    adb -s $device shell settings put secure autofill_field_classification 0 || true
    adb -s $device shell settings put secure autofill_feature_field_classification 0 || true
    # Step 3: Disable Credential Manager (Android 14+)
    adb -s $device shell settings put secure credential_manager_enabled 0 || true
    adb -s $device shell settings put secure credential_service null || true
    adb -s $device shell settings put secure credential_service_primary null || true
done

The Magic of || true

Notice that every command ends with || true. This is crucial because:

  • Commands that don’t apply to certain Android versions can fail gracefully
  • The script continues executing all disablement steps regardless of individual failures
  • Devices with different Android versions can coexist in the same device pool

For example, credential_manager_enabled doesn't exist on Android 13 and earlier. Without || true, that command would fail and stop the entire device preparation process.

The Results: Night and Day Difference

After implementing this comprehensive strategy, our test reliability transformed dramatically:

Before

❌ Flaky sign-in tests with ~30% failure rate
❌ Inconsistent behavior across different Android versions
❌ CI builds failing mysteriously while local runs passed
❌ Wasted developer time investigating non-existent bugs

After

✅ Sign-in tests complete without system interruptions
✅ UI interactions reach their intended targets every time
✅ Test results are consistent and repeatable across all devices
✅ Both legacy (Android 8–13) and modern (Android 14+) devices work correctly
✅ Stable CI builds with reliable test results

Use It On Your Development Device Too

Developers can apply these same commands to their local test devices. This is especially useful when running instrumented tests from Android Studio or debugging flaky tests.

Quick Setup Script

# For all Android versions:
adb shell pm clear com.google.android.gms
adb shell settings put secure autofill_service null
adb shell settings put secure autofill_field_classification 0
adb shell settings put secure autofill_feature_field_classification 0
# Additionally for Android 14+ devices:
adb shell settings put secure credential_manager_enabled 0
adb shell settings put secure credential_service null
adb shell settings put secure credential_service_primary null

Important Caveats

Settings Persistence

These settings persist across:
✅ App installations and uninstallations
✅ App data clearing
✅ Multiple test runs

But they reset after:
❌ Device reboots
❌ System updates
❌ Factory resets

Best practice: Always reapply these settings as part of your test setup process.

Impact on Normal Device Use

If you apply these settings to a device you use for regular development:

  • You won’t see password save prompts in any app
  • Autofill won’t work in Chrome, email apps, or other applications
  • You’ll need to manually type credentials every time

Recommendation: Use dedicated test devices, or re-enable these services when you’re done testing.

What We Tried That Didn’t Work

Before settling on this solution, we explored several alternatives:

❌ Programmatically disabling autofill in the app Android’s security model prevents apps from disabling system autofill. Settings like importantForAutofill="no" are hints, not guarantees.

❌ Using UI Automator to dismiss the popups System modals appear with unpredictable timing. Dismissing them adds flakiness rather than removing it, and doesn’t prevent them from reappearing.

❌ Test-only build flavors with modified manifests You can’t override system-level autofill behavior from the app layer.

❌ Firebase Test Lab’s autofill disablement Only works in Firebase Test Lab environment. We needed a solution for our on-premise device farm.

Key Takeaways

1. Android 14 changed the game The new Credential Manager requires additional settings to be disabled beyond the traditional autofill framework.

2. Multiple layers are necessary No single command solves the problem — you need to address GMS, autofill, and credential management.

3. Always reapply settings Make these commands part of your test setup, not a one-time device configuration.

4. Use || true for compatibility Allow commands to fail gracefully so devices with different Android versions can coexist.

5. Test early, test often Apply these settings to your development devices to catch autofill-related issues before they reach CI/CD.

Wrapping Up

Dealing with Android’s password managers in automated testing is a perfect example of how production features designed to improve user experience can inadvertently complicate testing.

Our three-pronged strategy — clearing GMS data, disabling autofill services, and disabling the Credential Manager — provides comprehensive coverage across all Android versions from 8 through 14+. By implementing this as part of your device preparation workflow, you can eliminate an entire category of flaky test failures.

Have you encountered similar challenges with Android’s password managers? What solutions have worked for you? I’d love to hear about your experiences in the comments!

Additional Resources