From a7b5a7730f545d1f82e9b0aaa79b19a7136c42a2 Mon Sep 17 00:00:00 2001 From: MohitMali Date: Fri, 27 Oct 2023 15:45:00 +0530 Subject: [PATCH] Fixed test failure on API level 33. * In the `ZimHostFragment`, there were occasional test failures due to specific conditions. When reattempting the test, it failed to detect the 'WiFi connection detected' dialog because the server was already running. To resolve this issue, we have improved our test case. Now, we first check if the server is already running. If it is, we close the server before running the test case. * In previous test failures within the `ZimHostFragment`, there were instances where the zim file was unselected, causing our test case to fail to locate the required views. To mitigate this, we now check whether the zim file is selected. If it's not selected, we first select the zim file before running the test case. * n the `LocalLibraryFragment` test, there were cases where it was unable to locate the 'file_management_no_files' view due to variations in the order of test cases. This occurred because a zim file was sometimes present in the `LocalLibrary`. To address this, we now check for the presence of any zim files in the `LocalLibrary` and delete them before running our test case. --- .../nav/destination/library/LibraryRobot.kt | 26 ++++++--- .../utils/RecyclerViewItemCount.kt | 41 ++++++++++++++ .../webserver/ZimHostFragmentTest.kt | 7 +++ .../kiwixmobile/webserver/ZimHostRobot.kt | 56 +++++++++++++++++++ 4 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 app/src/androidTest/java/org/kiwix/kiwixmobile/utils/RecyclerViewItemCount.kt 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(