diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadRobot.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadRobot.kt index 85000a695..1496b8772 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadRobot.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadRobot.kt @@ -18,7 +18,11 @@ package org.kiwix.kiwixmobile.download +import android.view.View +import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.assertion.ViewAssertions.matches @@ -30,6 +34,7 @@ import applyWithViewHierarchyPrinting import com.adevinta.android.barista.interaction.BaristaSleepInteractions import com.adevinta.android.barista.interaction.BaristaSwipeRefreshInteractions.refresh import junit.framework.AssertionFailedError +import org.hamcrest.Matcher import org.junit.Assert import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.Findable.StringId.TextId @@ -40,6 +45,7 @@ import org.kiwix.kiwixmobile.core.utils.files.Log import org.kiwix.kiwixmobile.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView import org.kiwix.kiwixmobile.utils.RecyclerViewMatcher +import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem fun downloadRobot(func: DownloadRobot.() -> Unit) = DownloadRobot().applyWithViewHierarchyPrinting(func) @@ -102,12 +108,12 @@ class DownloadRobot : BaseRobot() { refresh(R.id.librarySwipeRefresh) } - fun downloadZimFile() { + fun downloadZimFile(position: Int = 1) { pauseForBetterTestPerformance() testFlakyView({ onView( RecyclerViewMatcher(R.id.libraryList).atPosition( - 1 + position ) ).perform(click()) }) @@ -190,4 +196,52 @@ class DownloadRobot : BaseRobot() { ) } } + + fun getSmallestZimFileIndex(it: List?): Int { + var zimFileSizeWithIndex: Pair = 0 to Long.MAX_VALUE + it?.forEachIndexed { index, libraryItem -> + if (libraryItem is LibraryListItem.BookItem) { + val bookSize = libraryItem.book.size.toLong() + if (bookSize < 20000L) { + return@getSmallestZimFileIndex index + } else if (bookSize < zimFileSizeWithIndex.second) { + zimFileSizeWithIndex = index to bookSize + } + } + } + return zimFileSizeWithIndex.first + } + + fun scrollToZimFileIndex(index: Int) { + testFlakyView({ + onView(withId(R.id.libraryList)) + .perform(scrollToTop(index)) + }) + } + + private fun scrollToTop(position: Int): ViewAction { + return object : ViewAction { + override fun getDescription(): String = + "scroll RecyclerView item at position $position to the top" + + override fun getConstraints(): Matcher = + androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom(RecyclerView::class.java) + + override fun perform(uiController: UiController, view: View) { + val recyclerView = view as RecyclerView + val viewHolder = recyclerView.findViewHolderForAdapterPosition(position) + + if (viewHolder?.itemView == null) { + recyclerView.scrollToPosition(position) + uiController.loopMainThreadUntilIdle() + } + + val newViewHolder = recyclerView.findViewHolderForAdapterPosition(position) + newViewHolder?.let { + val top = newViewHolder.itemView.top + recyclerView.scrollBy(0, top) + } + } + } + } } diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadTest.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadTest.kt index a696088ff..cbdfa9717 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadTest.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/download/DownloadTest.kt @@ -19,6 +19,7 @@ package org.kiwix.kiwixmobile.download import androidx.core.content.edit import androidx.lifecycle.Lifecycle +import androidx.navigation.fragment.NavHostFragment import androidx.preference.PreferenceManager import androidx.test.core.app.ActivityScenario import androidx.test.espresso.IdlingPolicies @@ -39,7 +40,6 @@ import org.junit.After import org.junit.Assert import org.junit.Before import org.junit.BeforeClass -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.kiwix.kiwixmobile.BaseActivityTest @@ -49,21 +49,24 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.main.KiwixMainActivity import org.kiwix.kiwixmobile.main.topLevel import org.kiwix.kiwixmobile.nav.destination.library.LibraryRobot +import org.kiwix.kiwixmobile.nav.destination.library.OnlineLibraryFragment import org.kiwix.kiwixmobile.nav.destination.library.library -import org.kiwix.kiwixmobile.testutils.RetryRule import org.kiwix.kiwixmobile.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible import org.kiwix.kiwixmobile.utils.KiwixIdlingResource.Companion.getInstance +import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem import java.util.concurrent.TimeUnit @LargeTest @RunWith(AndroidJUnit4::class) class DownloadTest : BaseActivityTest() { - @Rule - @JvmField - var retryRule = RetryRule() + // @Rule + // @JvmField + // var retryRule = RetryRule() + + private lateinit var kiwixMainActivity: KiwixMainActivity init { AccessibilityChecks.enable().apply { @@ -115,14 +118,24 @@ class DownloadTest : BaseActivityTest() { fun downloadTest() { BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong()) activityScenario.onActivity { + kiwixMainActivity = it it.navigate(R.id.libraryFragment) } try { + // delete all the ZIM files showing in the LocalLibrary + // screen to properly test the scenario. + library { + refreshList() + waitUntilZimFilesRefreshing() + deleteZimIfExists() + } downloadRobot { clickDownloadOnBottomNav() waitForDataToLoad() + val smallestZimFileIndex = getSmallestZimFileIndex(getOnlineLibraryList()) + scrollToZimFileIndex(smallestZimFileIndex) stopDownloadIfAlreadyStarted() - downloadZimFile() + downloadZimFile(smallestZimFileIndex) assertDownloadStart() pauseDownload() assertDownloadPaused() @@ -142,6 +155,15 @@ class DownloadTest : BaseActivityTest() { LeakAssertions.assertNoLeaks() } + private fun getOnlineLibraryList(): List { + val navHostFragment: NavHostFragment = + kiwixMainActivity.supportFragmentManager + .findFragmentById(R.id.nav_host_fragment) as NavHostFragment + val onlineLibraryFragment = + navHostFragment.childFragmentManager.fragments[0] as OnlineLibraryFragment + return onlineLibraryFragment.getOnlineLibraryList() + } + @Test fun testPauseAndResumeInOtherLanguage() { BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong()) @@ -149,6 +171,13 @@ class DownloadTest : BaseActivityTest() { it.navigate(R.id.libraryFragment) } try { + // delete all the ZIM files showing in the LocalLibrary + // screen to properly test the scenario. + library { + refreshList() + waitUntilZimFilesRefreshing() + deleteZimIfExists() + } downloadRobot { // change the application language topLevel { diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt index 9957ea7e7..66e1ed33c 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt @@ -34,6 +34,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.Toolbar @@ -111,6 +112,9 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { requireActivity().viewModel(viewModelFactory) } + @VisibleForTesting + fun getOnlineLibraryList() = libraryAdapter.items + private val libraryAdapter: LibraryAdapter by lazy { LibraryAdapter( LibraryDelegate.BookDelegate(bookUtils, ::onBookItemClick, availableSpaceCalculator),