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.
This commit is contained in:
MohitMali 2023-10-27 15:45:00 +05:30 committed by Kelson
parent 96b1b195d5
commit a7b5a7730f
4 changed files with 123 additions and 7 deletions

View File

@ -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<ViewHolder>(recyclerViewItemsCount - 1))
for (position in 0 until recyclerViewItemsCount) {
// Long-click the item to select it
onView(withId(recyclerViewId))
.perform(actionOnItemAtPosition<ViewHolder>(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())

View File

@ -0,0 +1,41 @@
/*
* Kiwix Android
* Copyright (c) 2023 Kiwix <android.kiwix.org>
* 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 <http://www.gnu.org/licenses/>.
*
*/
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
}
}

View File

@ -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

View File

@ -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(