Automated UI testing has become critical for publishing 5-star apps and many Xamarin.Forms apps display data in a ListView or a RefreshView. But how can our UI tests determine if our list is refreshing? Let's find out!

We'll need to access the platform-specific APIs to check if the list is refreshing. Thus, we'll be using different code to test Android vs iOS.

Testing on Android

To interact with the ListView and the RefreshView on Android, we must use the Invoke method to access the  native Java Android API methods.

On Android, we can check the value returned from SwipeRefreshLayout.isRefreshing() like so:

(bool)app.Query(x => x.Class("ListViewRenderer_SwipeRefreshLayoutWithFixedNestedScrolling").Invoke("isRefreshing")).First();

RefreshView

 (bool)app.Query(x => x.Class("RefreshViewRenderer").Invoke("isRefreshing")).First();

Testing on iOS

For iOS, we can check to see if the UIRefreshControl is visible:

app.Query(x => x.Class("UIRefreshControl")).Any()

Xamarin.UITest Sample

//Xamarin.Forms.ListView
public bool IsListViewRefreshIndicatorDisplayed(Xamarin.UITest.IApp app)
{
    if (app is AndroidApp)
        return (bool)app.Query(x => x.Class("ListViewRenderer_SwipeRefreshLayoutWithFixedNestedScrolling").Invoke("isRefreshing")).First();

    if (app is iOSApp)
        return app.Query(x => x.Class("UIRefreshControl")).Any();

    throw new NotSupportedException("Xamarin.UITest only supports Android and iOS");
}

//Xamarin.Forms.RefreshView
public bool IsRefreshViewRefreshIndicatorDisplayed(Xamarin.UITest.IApp app)
{
    if (app is AndroidApp)
        return (bool)app.Query(x => x.Class("RefreshViewRenderer").Invoke("isRefreshing")).First();

    if (app is iOSApp)
        return app.Query(x => x.Class("UIRefreshControl")).Any();

    throw new NotSupportedException("Xamarin.UITest only supports Android and iOS");
}

Sample App

Putting it all together, here is a sample app that implements this code: https://github.com/brminnick/UITestSampleApp/