Search code examples
androidkotlingradlegradle-managed-device

Gradle Managed Devices - ChromeCustomTab not working


I'm starting to use this Gradle Managed Devices feature and I'm facing some problems when running my Espresso tests.

I setup the device as follows :

testOptions {
            animationsDisabled = true
            managedDevices {
                devices {
                    maybeCreate<ManagedVirtualDevice>("pixel2api30").apply {
                        device = "Pixel 2"
                        apiLevel = 30
                        systemImageSource = "google-atd"
                    }
                }
            }
        }

And then I have an Activity that when I press a Button it opens either a ChromeCustomTab or a WebView, the thing is that in my device, emulator (locally) it works but when I try to run them in GMD it doesn't and throws me this error.

es.MyTest > testName[pixel2api30] FAILED 
        android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://www.example.es/... (has extras) }
                at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2067)

And what I'm doing is this :

Intents.init()
    try {
        val expectedIntent = allOf(
            hasAction(Intent.ACTION_VIEW),
            anyOf(
                hasPackage("com.android.chrome"),
                hasPackage("com.android.webview")
            ),
            hasData(Uri.parse(url)),
        )
        //on click to the button to open the `ChromeCustomTab`
        intended(expectedIntent)
    } finally {
        Intents.release()
    }

I also have this for opening a WebView and it works though

Intents.init()
    try {
        //click to the button
        intended(
            allOf(
                hasAction(Intent.ACTION_VIEW),
                hasData(Uri.parse(url)),
            ),
        )
    } finally {
        Intents.release()
    }

Also what I saw is that some test are too fast and makes my MockWebServer and my Dispatcher to fail sometimes so I had to add a small wait to the views.


Solution

  • I was looking the documentation and I found this :

    Which source the system image should come from. Either "google", "google-atd", "aosp", or "aosp-atd". You can also specify an explicit source such as "google_apis_playstore".

    I did not ready the part that I could add the google_apis_playstore that one comes with Google Chrome App that was what I need, however it did not fix the problem since using this command

    ./gradlew :features-myFeature:pixel2api30ReleaseAndroidTest --enable-display -Pandroid.testoptions.manageddevices.emulator.gpu=swiftshader_indirect
    

    was throwing a TimeOutException

    Failed to execute adb command. Command: /Users/* -H localhost -P 5037 -s emulator-5554 install -r -t /Users/*-release-androidTest.apk Timeout: 120 Command timed out: 120 java.util.concurrent.TimeoutException: Command timed out: 120 at com.google.testing.platform.lib.process.SubprocessImpl$waitFor$1.invokeSuspend(SubprocessImpl.kt:286)

    I thought it was going to fix the issue since the --enable-display was launching the emulator and in there I was able to see the Google Chrome App installed.

    So what I did instead is to change the way I was asserting the openWebView() and I'm doing it like this

    fun assertOpenWebView(url: String, action: () -> Unit) {
        Intents.init()
        try {
            val expectedIntent = allOf(
                hasAction(Intent.ACTION_VIEW),
                hasData(Uri.parse(url)),
            )
            intending(expectedIntent).respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null))
            action.invoke()
            intended(allOf(expectedIntent))
        } finally {
            Intents.release()
        }
    }
    
    

    I want to ensure that my code at least does the action of try to open a web view or something similar, and it makes the test pass from now, but I'd like to know if I can make it work like it was before using the google_apis_playstore system image.