diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/nav/destination/library/LibraryRobot.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/nav/destination/library/LibraryRobot.kt index c1691b8ee..1a4667816 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/nav/destination/library/LibraryRobot.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/nav/destination/library/LibraryRobot.kt @@ -19,20 +19,25 @@ package org.kiwix.kiwixmobile.nav.destination.library import android.util.Log +import androidx.recyclerview.widget.RecyclerView.ViewHolder import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.assertion.ViewAssertions -import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition +import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition +import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withText import applyWithViewHierarchyPrinting import com.adevinta.android.barista.interaction.BaristaSleepInteractions import org.kiwix.kiwixmobile.BaseRobot -import org.kiwix.kiwixmobile.Findable.Text import org.kiwix.kiwixmobile.Findable.ViewId import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.localFileTransfer.LocalFileTransferRobot import org.kiwix.kiwixmobile.localFileTransfer.localFileTransfer import org.kiwix.kiwixmobile.testutils.TestUtils +import org.kiwix.kiwixmobile.utils.RecyclerViewItemCount fun library(func: LibraryRobot.() -> Unit) = LibraryRobot().applyWithViewHierarchyPrinting(func) @@ -60,7 +65,17 @@ class LibraryRobot : BaseRobot() { fun deleteZimIfExists() { try { - longClickOnZimFile() + val recyclerViewId: Int = R.id.zimfilelist + val recyclerViewItemsCount = RecyclerViewItemCount(recyclerViewId).checkRecyclerViewCount() + // Scroll to the end of the RecyclerView to ensure all items are visible + onView(withId(recyclerViewId)) + .perform(scrollToPosition(recyclerViewItemsCount - 1)) + + for (position in 0 until recyclerViewItemsCount) { + // Long-click the item to select it + onView(withId(recyclerViewId)) + .perform(actionOnItemAtPosition(position, longClick())) + } clickOnFileDeleteIcon() assertDeleteDialogDisplayed() clickOnDeleteZimFile() @@ -75,6 +90,7 @@ class LibraryRobot : BaseRobot() { } private fun clickOnFileDeleteIcon() { + pauseForBetterTestPerformance() clickOn(ViewId(R.id.zim_file_delete_item)) } @@ -84,10 +100,6 @@ class LibraryRobot : BaseRobot() { .check(ViewAssertions.matches(isDisplayed())) } - private fun longClickOnZimFile() { - longClickOn(Text(zimFileTitle)) - } - private fun clickOnDeleteZimFile() { pauseForBetterTestPerformance() onView(withText("DELETE")).perform(click()) diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/utils/RecyclerViewItemCount.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/utils/RecyclerViewItemCount.kt new file mode 100644 index 000000000..8e7cddf30 --- /dev/null +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/utils/RecyclerViewItemCount.kt @@ -0,0 +1,41 @@ +/* + * Kiwix Android + * Copyright (c) 2023 Kiwix + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package org.kiwix.kiwixmobile.utils + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.NoMatchingViewException +import androidx.test.espresso.matcher.ViewMatchers.withId + +class RecyclerViewItemCount(private val recyclerViewId: Int) { + fun checkRecyclerViewCount(): Int { + var recyclerViewItemCount = 0 + onView(withId(recyclerViewId)) + .check { view: View, noViewFoundException: NoMatchingViewException? -> + if (noViewFoundException != null) { + throw noViewFoundException + } + val recyclerView = view as RecyclerView + // Get the item count from the RecyclerView + recyclerViewItemCount = recyclerView.adapter?.itemCount ?: 0 + } + return recyclerViewItemCount + } +} diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostFragmentTest.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostFragmentTest.kt index c12560202..a359a4431 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostFragmentTest.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostFragmentTest.kt @@ -104,6 +104,13 @@ class ZimHostFragmentTest { refreshLibraryList() assertZimFilesLoaded() openZimHostFragment() + + // Check if server is already started + stopServerIfAlreadyStarted() + + // Check if both zim file are selected or not to properly run our test case + selectZimFileIfNotAlreadySelected() + clickOnTestZim() // Start the server with one ZIM file diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostRobot.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostRobot.kt index 47d9ff2f5..700003d25 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostRobot.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostRobot.kt @@ -18,10 +18,16 @@ package org.kiwix.kiwixmobile.webserver +import android.util.Log +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.assertThat import applyWithViewHierarchyPrinting import com.adevinta.android.barista.interaction.BaristaSleepInteractions import com.adevinta.android.barista.interaction.BaristaSwipeRefreshInteractions.refresh +import junit.framework.AssertionFailedError import org.hamcrest.CoreMatchers import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.Findable.StringId.TextId @@ -29,6 +35,8 @@ import org.kiwix.kiwixmobile.Findable.Text import org.kiwix.kiwixmobile.Findable.ViewId import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.testutils.TestUtils +import org.kiwix.kiwixmobile.utils.RecyclerViewItemCount +import org.kiwix.kiwixmobile.utils.RecyclerViewMatcher import org.kiwix.kiwixmobile.utils.RecyclerViewSelectedCheckBoxCountAssertion import org.kiwix.kiwixmobile.utils.StandardActions.openDrawer @@ -71,6 +79,54 @@ class ZimHostRobot : BaseRobot() { isVisible(Text("STOP SERVER")) } + fun stopServerIfAlreadyStarted() { + try { + assertServerStarted() + stopServer() + } catch (exception: Exception) { + Log.i( + "ZIM_HOST_FRAGMENT", + "Failed to stop the server, Probably because server is not running" + ) + } + } + + fun selectZimFileIfNotAlreadySelected() { + try { + // check both files are selected. + assertItemHostedOnServer(2) + } catch (assertionFailedError: AssertionFailedError) { + try { + val recyclerViewItemsCount = + RecyclerViewItemCount(R.id.recyclerViewZimHost).checkRecyclerViewCount() + (0 until recyclerViewItemsCount) + .asSequence() + .filter { it != 0 } + .forEach(::selectZimFile) + } catch (assertionFailedError: AssertionFailedError) { + Log.i("ZIM_HOST_FRAGMENT", "Failed to select the zim file, probably it is already selected") + } + } + } + + private fun selectZimFile(position: Int) { + try { + onView( + RecyclerViewMatcher(R.id.recyclerViewZimHost).atPositionOnView( + position, + R.id.itemBookCheckbox + ) + ).check(matches(ViewMatchers.isChecked())) + } catch (assertionError: AssertionFailedError) { + onView( + RecyclerViewMatcher(R.id.recyclerViewZimHost).atPositionOnView( + position, + R.id.itemBookCheckbox + ) + ).perform(click()) + } + } + fun assertItemHostedOnServer(itemCount: Int) { val checkedCheckboxCount = RecyclerViewSelectedCheckBoxCountAssertion(