فهرست منبع

Merge pull request #13192 from nextcloud/fix-ss-tests

Fix ss tests
Alper Öztürk 11 ماه پیش
والد
کامیت
ffbff3f2f2

+ 1 - 0
app/build.gradle

@@ -391,6 +391,7 @@ dependencies {
     androidTestImplementation "androidx.test.espresso:espresso-web:$espressoVersion"
     androidTestImplementation "androidx.test.espresso:espresso-accessibility:$espressoVersion"
     androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
+    androidTestImplementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
 
     // Mocking support
     androidTestImplementation 'com.github.tmurakami:dexopener:2.0.5' // required to allow mocking on API 27 and older

BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_empty.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.trashbin.TrashbinActivityIT_loading.png


+ 11 - 8
app/src/androidTest/java/com/nextcloud/client/AuthenticatorActivityIT.java

@@ -18,14 +18,13 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
 
-import androidx.test.espresso.intent.rule.IntentsTestRule;
+import androidx.test.core.app.ActivityScenario;
 
 
 public class AuthenticatorActivityIT extends AbstractIT {
+    private final String testClassName = "com.nextcloud.client.AuthenticatorActivityIT";
+
     private static final String URL = "cloud.nextcloud.com";
-    @Rule public IntentsTestRule<AuthenticatorActivity> activityRule = new IntentsTestRule<>(AuthenticatorActivity.class,
-                                                                                             true,
-                                                                                             false);
 
     @Rule
     public final TestRule permissionRule = GrantStoragePermissionRule.grant();
@@ -33,9 +32,13 @@ public class AuthenticatorActivityIT extends AbstractIT {
     @Test
     @ScreenshotTest
     public void login() {
-        AuthenticatorActivity sut = activityRule.launchActivity(null);
-        ((TextView) sut.findViewById(R.id.host_url_input)).setText(URL);
-        sut.runOnUiThread(() -> sut.getAccountSetupBinding().hostUrlInput.clearFocus());
-        screenshot(sut);
+        try (ActivityScenario<AuthenticatorActivity> scenario = ActivityScenario.launch(AuthenticatorActivity.class)) {
+            scenario.onActivity(sut -> onIdleSync(() -> {
+                ((TextView) sut.findViewById(R.id.host_url_input)).setText(URL);
+                sut.runOnUiThread(() -> sut.getAccountSetupBinding().hostUrlInput.clearFocus());
+                String screenShotName = createName(testClassName + "_" + "login", "");
+                screenshotViaName(sut, screenShotName);
+            }));
+        }
     }
 }

+ 64 - 47
app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt

@@ -16,6 +16,7 @@ import androidx.test.espresso.matcher.ViewMatchers
 import androidx.test.rule.GrantPermissionRule
 import com.owncloud.android.AbstractIT
 import com.owncloud.android.R
+import com.owncloud.android.lib.common.utils.Log_OC
 import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.utils.ScreenshotTest
 import org.junit.Assert
@@ -31,77 +32,93 @@ class FileDisplayActivityScreenshotIT : AbstractIT() {
     )
 
     @get:Rule
-    val permissionRule = GrantPermissionRule.grant(
+    val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(
         Manifest.permission.WRITE_EXTERNAL_STORAGE
     )
 
+    companion object {
+        private const val TAG = "FileDisplayActivityScreenshotIT"
+    }
+
     @Test
     @ScreenshotTest
     fun open() {
-        val sut = activityRule.launchActivity(null)
+        try {
+            val sut = activityRule.launchActivity(null)
 
-        shortSleep()
-        sut.runOnUiThread {
-            sut.listOfFilesFragment!!.setFabEnabled(false)
-            sut.resetScrolling(true)
-            sut.listOfFilesFragment!!.setEmptyListLoadingMessage()
-            sut.listOfFilesFragment!!.isLoading = false
+            shortSleep()
+            sut.runOnUiThread {
+                sut.listOfFilesFragment!!.setFabEnabled(false)
+                sut.resetScrolling(true)
+                sut.listOfFilesFragment!!.setEmptyListLoadingMessage()
+                sut.listOfFilesFragment!!.isLoading = false
+            }
+            shortSleep()
+            waitForIdleSync()
+            screenshot(sut)
+        } catch (e: SecurityException) {
+            Log_OC.e(TAG, "Error caught at open $e")
         }
-        shortSleep()
-        waitForIdleSync()
-        screenshot(sut)
     }
 
     @Test
     @ScreenshotTest
     fun showMediaThenAllFiles() {
-        val fileDisplayActivity = activityRule.launchActivity(null)
-        val sut = fileDisplayActivity.listOfFilesFragment
-        Assert.assertNotNull(sut)
-        sut!!.setFabEnabled(false)
-        sut.setEmptyListLoadingMessage()
-        sut.isLoading = false
+        try {
+            val fileDisplayActivity = activityRule.launchActivity(null)
+            val sut = fileDisplayActivity.listOfFilesFragment
+            Assert.assertNotNull(sut)
+            sut!!.setFabEnabled(false)
+            sut.setEmptyListLoadingMessage()
+            sut.isLoading = false
 
-        // open drawer
-        Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
+            // open drawer
+            Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
 
-        // click "all files"
-        Espresso.onView(ViewMatchers.withId(R.id.nav_view))
-            .perform(NavigationViewActions.navigateTo(R.id.nav_gallery))
+            // click "all files"
+            Espresso.onView(ViewMatchers.withId(R.id.nav_view))
+                .perform(NavigationViewActions.navigateTo(R.id.nav_gallery))
 
-        // wait
-        shortSleep()
+            // wait
+            shortSleep()
 
-        // click "all files"
-        Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
-        Espresso.onView(ViewMatchers.withId(R.id.nav_view))
-            .perform(NavigationViewActions.navigateTo(R.id.nav_all_files))
+            // click "all files"
+            Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
+            Espresso.onView(ViewMatchers.withId(R.id.nav_view))
+                .perform(NavigationViewActions.navigateTo(R.id.nav_all_files))
 
-        // then compare screenshot
-        shortSleep()
-        sut.setFabEnabled(false)
-        sut.setEmptyListLoadingMessage()
-        sut.isLoading = false
-        shortSleep()
-        screenshot(fileDisplayActivity)
+            // then compare screenshot
+            shortSleep()
+            sut.setFabEnabled(false)
+            sut.setEmptyListLoadingMessage()
+            sut.isLoading = false
+            shortSleep()
+            screenshot(fileDisplayActivity)
+        } catch (e: SecurityException) {
+            Log_OC.e(TAG, "Error caught at open $e")
+        }
     }
 
     @Test
     @ScreenshotTest
     fun drawer() {
-        val sut = activityRule.launchActivity(null)
-        Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
+        try {
+            val sut = activityRule.launchActivity(null)
+            Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
 
-        shortSleep()
-        sut.runOnUiThread {
-            sut.hideInfoBox()
-            sut.resetScrolling(true)
-            sut.listOfFilesFragment!!.setFabEnabled(false)
-            sut.listOfFilesFragment!!.setEmptyListLoadingMessage()
-            sut.listOfFilesFragment!!.isLoading = false
+            shortSleep()
+            sut.runOnUiThread {
+                sut.hideInfoBox()
+                sut.resetScrolling(true)
+                sut.listOfFilesFragment!!.setFabEnabled(false)
+                sut.listOfFilesFragment!!.setEmptyListLoadingMessage()
+                sut.listOfFilesFragment!!.isLoading = false
+            }
+            shortSleep()
+            waitForIdleSync()
+            screenshot(sut)
+        } catch (e: SecurityException) {
+            Log_OC.e(TAG, "Error caught at open $e")
         }
-        shortSleep()
-        waitForIdleSync()
-        screenshot(sut)
     }
 }

+ 16 - 3
app/src/androidTest/java/com/owncloud/android/AbstractIT.java

@@ -301,6 +301,10 @@ public abstract class AbstractIT {
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
+    protected void onIdleSync(Runnable recipient) {
+        InstrumentationRegistry.getInstrumentation().waitForIdle(recipient);
+    }
+
     protected void openDrawer(IntentsTestRule activityRule) {
         Activity sut = activityRule.launchActivity(null);
 
@@ -453,6 +457,12 @@ public abstract class AbstractIT {
         screenshot(view, "");
     }
 
+    protected void screenshotViaName(Activity activity, String name) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            Screenshot.snapActivity(activity).setName(name).record();
+        }
+    }
+
     protected void screenshot(View view, String prefix) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
             Screenshot.snap(view).setName(createName(prefix)).record();
@@ -473,9 +483,7 @@ public abstract class AbstractIT {
         return createName("");
     }
 
-    private String createName(String prefix) {
-        String name = TestNameDetector.getTestClass() + "_" + TestNameDetector.getTestName();
-
+    public String createName(String name, String prefix) {
         if (!TextUtils.isEmpty(prefix)) {
             name = name + "_" + prefix;
         }
@@ -491,6 +499,11 @@ public abstract class AbstractIT {
         return name;
     }
 
+    private String createName(String prefix) {
+        String name = TestNameDetector.getTestClass() + "_" + TestNameDetector.getTestName();
+        return createName(name, prefix);
+    }
+
     public static String getUserId(User user) {
         return AccountManager.get(targetContext).getUserData(user.toPlatformAccount(), KEY_USER_ID);
     }

+ 58 - 25
app/src/androidTest/java/com/owncloud/android/ui/activity/NotificationsActivityIT.kt

@@ -7,35 +7,57 @@
  */
 package com.owncloud.android.ui.activity
 
-import androidx.test.espresso.intent.rule.IntentsTestRule
+import androidx.annotation.UiThread
+import androidx.test.core.app.launchActivity
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.IdlingRegistry
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.isRoot
+import com.owncloud.android.utils.EspressoIdlingResource
 import com.owncloud.android.AbstractIT
 import com.owncloud.android.lib.resources.notifications.models.Action
 import com.owncloud.android.lib.resources.notifications.models.Notification
 import com.owncloud.android.lib.resources.notifications.models.RichObject
 import com.owncloud.android.utils.ScreenshotTest
-import org.junit.Rule
+import org.junit.After
+import org.junit.Before
 import org.junit.Test
 import java.util.GregorianCalendar
 
 class NotificationsActivityIT : AbstractIT() {
-    @get:Rule
-    var activityRule = IntentsTestRule(NotificationsActivity::class.java, true, false)
+    private val testClassName = "com.owncloud.android.ui.activity.NotificationsActivityIT"
+
+    @Before
+    fun registerIdlingResource() {
+        IdlingRegistry.getInstance().register(EspressoIdlingResource.countingIdlingResource)
+    }
+
+    @After
+    fun unregisterIdlingResource() {
+        IdlingRegistry.getInstance().unregister(EspressoIdlingResource.countingIdlingResource)
+    }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun empty() {
-        val sut: NotificationsActivity = activityRule.launchActivity(null)
-
-        waitForIdleSync()
-
-        sut.runOnUiThread { sut.populateList(ArrayList<Notification>()) }
-
-        shortSleep()
-
-        screenshot(sut)
+        launchActivity<NotificationsActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.populateList(ArrayList())
+                    EspressoIdlingResource.decrement()
+                    val screenShotName = createName(testClassName + "_" + "empty", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     @SuppressWarnings("MagicNumber")
     fun showNotifications() {
@@ -117,24 +139,35 @@ class NotificationsActivityIT : AbstractIT() {
             )
         )
 
-        activityRule.launchActivity(null).apply {
-            runOnUiThread {
-                populateList(notifications)
+        launchActivity<NotificationsActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.populateList(notifications)
+                    EspressoIdlingResource.decrement()
+                    val screenShotName = createName(testClassName + "_" + "showNotifications", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
             }
-            shortSleep()
-            screenshot(binding.list)
         }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun error() {
-        val sut: NotificationsActivity = activityRule.launchActivity(null)
-
-        shortSleep()
-
-        sut.runOnUiThread { sut.setEmptyContent("Error", "Error! Please try again later!") }
-
-        screenshot(sut)
+        launchActivity<NotificationsActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.setEmptyContent("Error", "Error! Please try again later!")
+                    EspressoIdlingResource.decrement()
+                    val screenShotName = createName(testClassName + "_" + "error", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 }

+ 127 - 81
app/src/androidTest/java/com/owncloud/android/ui/trashbin/TrashbinActivityIT.kt

@@ -10,130 +10,176 @@ package com.owncloud.android.ui.trashbin
 import android.accounts.Account
 import android.accounts.AccountManager
 import android.content.Intent
-import androidx.test.espresso.intent.rule.IntentsTestRule
+import androidx.annotation.UiThread
+import androidx.test.core.app.launchActivity
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.IdlingRegistry
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.isRoot
+import com.owncloud.android.utils.EspressoIdlingResource
 import com.owncloud.android.AbstractIT
 import com.owncloud.android.MainApp
 import com.owncloud.android.lib.common.accounts.AccountUtils
 import com.owncloud.android.utils.ScreenshotTest
-import org.junit.Rule
+import org.junit.After
+import org.junit.Before
 import org.junit.Test
 
 class TrashbinActivityIT : AbstractIT() {
+    private val testClassName = "com.owncloud.android.ui.trashbin.TrashbinActivityIT"
+
     enum class TestCase {
         ERROR,
         EMPTY,
         FILES
     }
 
-    @get:Rule
-    var activityRule = IntentsTestRule(TrashbinActivity::class.java, true, false)
+    @Before
+    fun registerIdlingResource() {
+        IdlingRegistry.getInstance().register(EspressoIdlingResource.countingIdlingResource)
+    }
+
+    @After
+    fun unregisterIdlingResource() {
+        IdlingRegistry.getInstance().unregister(EspressoIdlingResource.countingIdlingResource)
+    }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun error() {
-        val sut: TrashbinActivity = activityRule.launchActivity(null)
-
-        val trashbinRepository = TrashbinLocalRepository(TestCase.ERROR)
-
-        sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
-
-        sut.runOnUiThread { sut.loadFolder() }
-
-        shortSleep()
-
-        screenshot(sut)
+        launchActivity<TrashbinActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                val trashbinRepository = TrashbinLocalRepository(TestCase.ERROR)
+                sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.loadFolder(
+                        onComplete = { EspressoIdlingResource.decrement() },
+                        onError = { EspressoIdlingResource.decrement() }
+                    )
+                    val screenShotName = createName(testClassName + "_" + "error", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun files() {
-        val sut: TrashbinActivity = activityRule.launchActivity(null)
-
-        val trashbinRepository = TrashbinLocalRepository(TestCase.FILES)
-
-        sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
-
-        sut.runOnUiThread { sut.loadFolder() }
-
-        waitForIdleSync()
-        shortSleep()
-        shortSleep()
-
-        screenshot(sut)
+        launchActivity<TrashbinActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                val trashbinRepository = TrashbinLocalRepository(TestCase.FILES)
+                sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.loadFolder(
+                        onComplete = { EspressoIdlingResource.decrement() },
+                        onError = { EspressoIdlingResource.decrement() }
+                    )
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    val screenShotName = createName(testClassName + "_" + "files", "")
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun empty() {
-        val sut: TrashbinActivity = activityRule.launchActivity(null)
-
-        val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
-
-        sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
-
-        sut.runOnUiThread { sut.loadFolder() }
-
-        shortSleep()
-        shortSleep()
-        waitForIdleSync()
-
-        screenshot(sut.binding.emptyList.emptyListView)
+        launchActivity<TrashbinActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
+                sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.loadFolder(
+                        onComplete = { EspressoIdlingResource.decrement() },
+                        onError = { EspressoIdlingResource.decrement() }
+                    )
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    val screenShotName = createName(testClassName + "_" + "empty", "")
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun loading() {
-        val sut: TrashbinActivity = activityRule.launchActivity(null)
-
-        val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
-
-        sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
-
-        sut.runOnUiThread { sut.showInitialLoading() }
-
-        shortSleep()
-
-        screenshot(sut.binding.listFragmentLayout)
+        launchActivity<TrashbinActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
+                sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.showInitialLoading()
+                    EspressoIdlingResource.decrement()
+                    val screenShotName = createName(testClassName + "_" + "loading", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun normalUser() {
-        val sut: TrashbinActivity = activityRule.launchActivity(null)
-
-        val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
-
-        sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
-
-        sut.runOnUiThread { sut.showUser() }
-
-        shortSleep()
-
-        screenshot(sut)
+        launchActivity<TrashbinActivity>().use { scenario ->
+            scenario.onActivity { sut ->
+                val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
+                sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.showUser()
+                    EspressoIdlingResource.decrement()
+                    val screenShotName = createName(testClassName + "_" + "normalUser", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 
     @Test
+    @UiThread
     @ScreenshotTest
     fun differentUser() {
         val temp = Account("differentUser@https://nextcloud.localhost", MainApp.getAccountType(targetContext))
 
-        val platformAccountManager = AccountManager.get(targetContext)
-        platformAccountManager.addAccountExplicitly(temp, "password", null)
-        platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, "https://nextcloud.localhost")
-        platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_USER_ID, "differentUser")
-
-        val intent = Intent()
-        intent.putExtra(Intent.EXTRA_USER, "differentUser@https://nextcloud.localhost")
-        val sut: TrashbinActivity = activityRule.launchActivity(intent)
-
-        val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
-
-        sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
-
-        sut.runOnUiThread { sut.showUser() }
-
-        shortSleep()
-
-        screenshot(sut)
+        AccountManager.get(targetContext).apply {
+            addAccountExplicitly(temp, "password", null)
+            setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, "https://nextcloud.localhost")
+            setUserData(temp, AccountUtils.Constants.KEY_USER_ID, "differentUser")
+        }
+
+        val intent = Intent(targetContext, TrashbinActivity::class.java).apply {
+            putExtra(Intent.EXTRA_USER, "differentUser@https://nextcloud.localhost")
+        }
+
+        launchActivity<TrashbinActivity>(intent).use { scenario ->
+            scenario.onActivity { sut ->
+                val trashbinRepository = TrashbinLocalRepository(TestCase.EMPTY)
+                sut.trashbinPresenter = TrashbinPresenter(trashbinRepository, sut)
+                onIdleSync {
+                    EspressoIdlingResource.increment()
+                    sut.showUser()
+                    EspressoIdlingResource.decrement()
+                    val screenShotName = createName(testClassName + "_" + "differentUser", "")
+                    onView(isRoot()).check(matches(isDisplayed()))
+                    screenshotViaName(sut, screenShotName)
+                }
+            }
+        }
     }
 }

+ 27 - 0
app/src/androidTest/java/com/owncloud/android/utils/EspressoIdlingResource.kt

@@ -0,0 +1,27 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.owncloud.android.utils
+
+import androidx.test.espresso.idling.CountingIdlingResource
+
+object EspressoIdlingResource {
+
+    private const val RESOURCE = "GLOBAL"
+
+    @JvmField val countingIdlingResource = CountingIdlingResource(RESOURCE)
+
+    fun increment() {
+        countingIdlingResource.increment()
+    }
+
+    fun decrement() {
+        if (!countingIdlingResource.isIdleNow) {
+            countingIdlingResource.decrement()
+        }
+    }
+}

+ 2 - 2
app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt

@@ -176,7 +176,7 @@ class TrashbinActivity :
         )
     }
 
-    fun loadFolder() {
+    fun loadFolder(onComplete: () -> Unit = {}, onError: () -> Unit = {}) {
         trashbinListAdapter?.let {
             if (it.itemCount > EMPTY_LIST_COUNT) {
                 binding.swipeContainingList.isRefreshing = true
@@ -184,7 +184,7 @@ class TrashbinActivity :
                 showInitialLoading()
             }
 
-            trashbinPresenter?.loadFolder()
+            trashbinPresenter?.loadFolder(onComplete, onError)
         }
     }
 

+ 1 - 1
app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinContract.kt

@@ -25,7 +25,7 @@ interface TrashbinContract {
 
     interface Presenter {
         val isRoot: Boolean
-        fun loadFolder()
+        fun loadFolder(onCompleted: () -> Unit = {}, onError: () -> Unit = {})
         fun navigateUp()
         fun enterFolder(folder: String?)
         fun restoreTrashbinFile(file: TrashbinFile?)

+ 3 - 1
app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinPresenter.kt

@@ -43,16 +43,18 @@ class TrashbinPresenter(
         }
     }
 
-    override fun loadFolder() {
+    override fun loadFolder(onCompleted: () -> Unit, onError: () -> Unit) {
         trashbinRepository.getFolder(
             currentPath,
             object : LoadFolderCallback {
                 override fun onSuccess(files: List<TrashbinFile?>?) {
                     trashbinView.showTrashbinFolder(files)
+                    onCompleted()
                 }
 
                 override fun onError(error: Int) {
                     trashbinView.showError(error)
+                    onError()
                 }
             }
         )

+ 13 - 0
gradle/verification-metadata.xml

@@ -6384,6 +6384,14 @@
             <sha256 value="e4bb54753c36a27a0e5d70154a5034fedd8feac4282295034bfd483d6c7aae78" origin="Generated by Gradle"/>
          </artifact>
       </component>
+      <component group="com.google.android.apps.common.testing.accessibility.framework" name="accessibility-test-framework" version="3.1">
+         <artifact name="accessibility-test-framework-3.1.aar">
+            <sha256 value="e641e2a2c7287afd41b85310dd8f1344a8668034bbbfc4b02f58a48fd9c05ec7" origin="Generated by Gradle" reason="Artifact is not signed"/>
+         </artifact>
+         <artifact name="accessibility-test-framework-3.1.pom">
+            <sha256 value="80567228cdbd44d61e5320cd090883de7232dbc1ed7ebf5ab5c9810c11cd67e0" origin="Generated by Gradle" reason="Artifact is not signed"/>
+         </artifact>
+      </component>
       <component group="com.google.android.apps.common.testing.accessibility.framework" name="accessibility-test-framework" version="3.1.2">
          <artifact name="accessibility-test-framework-3.1.2.aar">
             <sha256 value="9b586dc8eeeb4f601038e23ef8ffd6a1deeca1163276d02797b0d2b8f9764b62" origin="Generated by Gradle" reason="Artifact is not signed"/>
@@ -7567,6 +7575,11 @@
             <sha256 value="47f0635b33c969e5f55ac9f1a4a8e10c120b8bab2cb3f06faaabc0e82057e276" origin="Generated by Gradle"/>
          </artifact>
       </component>
+      <component group="com.h3xstream.findsecbugs" name="findsecbugs-root-pom" version="1.13.0">
+         <artifact name="findsecbugs-root-pom-1.13.0.pom">
+            <sha256 value="da8755645ba7ae39588598e548f62eb0be1d2f47a6eee57efc5eb2865a4a556b" origin="Generated by Gradle"/>
+         </artifact>
+      </component>
       <component group="com.intellij" name="annotations" version="12.0">
          <artifact name="annotations-12.0.jar">
             <sha256 value="f8ab13b14be080fe2f617f90e55599760e4a1b4deeea5c595df63d0d6375ed6d" origin="Generated by Gradle"/>