From ed4f072048e8e8b01696c2fde0acf25eda793ca1 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Tue, 9 Jan 2024 20:52:25 +0530 Subject: [PATCH 1/4] Fixed: Nowdays CI frequently failing on API level 24, and 33. * Addressed an issue with the `SaveSearchToRecentsTest` test, which occasionally failed. The primary cause of this was the recent modification to save the `RecentSearch` on a background thread using `coroutines`. In some cases, the test was validating the output before the coroutine completed its execution. Consequently, we have adjusted our test case to properly wait for the coroutine to finish its work before validating the output. --- .../viewmodel/effects/SaveSearchToRecentsTest.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt b/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt index 7a7ba92f8..18435c3aa 100644 --- a/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt +++ b/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt @@ -22,20 +22,23 @@ import androidx.appcompat.app.AppCompatActivity import io.mockk.Called import io.mockk.mockk import io.mockk.verify -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineScope +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Test import org.kiwix.kiwixmobile.core.dao.NewRecentSearchDao import org.kiwix.kiwixmobile.core.reader.ZimFileReader import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.RecentSearchListItem +@OptIn(ExperimentalCoroutinesApi::class) internal class SaveSearchToRecentsTest { private val newRecentSearchDao: NewRecentSearchDao = mockk() private val searchListItem = RecentSearchListItem("", ZimFileReader.CONTENT_PREFIX) private val activity: AppCompatActivity = mockk() - private val viewModelScope = CoroutineScope(Dispatchers.IO) + private val testDispatcher = TestCoroutineScope() @Test fun `invoke with null Id does nothing`() { @@ -43,7 +46,7 @@ internal class SaveSearchToRecentsTest { newRecentSearchDao, searchListItem, null, - viewModelScope + testDispatcher ).invokeWith( activity ) @@ -51,14 +54,15 @@ internal class SaveSearchToRecentsTest { } @Test - fun `invoke with non null Id saves search`() { + fun `invoke with non null Id saves search`() = testDispatcher.runBlockingTest { val id = "id" SaveSearchToRecents( newRecentSearchDao, searchListItem, id, - viewModelScope + testDispatcher ).invokeWith(activity) + testDispatcher.advanceUntilIdle() verify { newRecentSearchDao.saveSearch(searchListItem.value, id, ZimFileReader.CONTENT_PREFIX) } } } From 87632c5f6abde83d153ef774a459f3c07f9d30c3 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Tue, 9 Jan 2024 20:58:17 +0530 Subject: [PATCH 2/4] Fixed `ZimHostFragment` which is failing on API level 33. * Improved the permission. * Enabled wifi programmatically in emulator. * Improved test case for showing "Wifi connection dialog". --- .../kiwixmobile/webserver/ZimHostFragmentTest.kt | 6 ++++-- .../kiwix/kiwixmobile/webserver/ZimHostRobot.kt | 16 +++++++++++----- contrib/instrumentation.sh | 4 ++++ 3 files changed, 19 insertions(+), 7 deletions(-) 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 78f74903e..0319abe60 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostFragmentTest.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostFragmentTest.kt @@ -53,14 +53,16 @@ class ZimHostFragmentTest { arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.NEARBY_WIFI_DEVICES + Manifest.permission.NEARBY_WIFI_DEVICES, + Manifest.permission.ACCESS_NETWORK_STATE ) } else { arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_NETWORK_STATE ) } 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 40341a5db..e69c158fb 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostRobot.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/webserver/ZimHostRobot.kt @@ -24,6 +24,7 @@ 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 androidx.test.espresso.matcher.ViewMatchers.withText import applyWithViewHierarchyPrinting import com.adevinta.android.barista.interaction.BaristaSleepInteractions import com.adevinta.android.barista.interaction.BaristaSwipeRefreshInteractions.refresh @@ -64,14 +65,21 @@ class ZimHostRobot : BaseRobot() { } fun clickOnTestZim() { + pauseForBetterTestPerformance() clickOn(Text("Test_Zim")) } fun startServer() { + // stop the server if it is already running. + stopServerIfAlreadyStarted() clickOn(ViewId(R.id.startServerButton)) + assetWifiDialogDisplayed() + onView(withText("PROCEED")).perform(click()) + } + + private fun assetWifiDialogDisplayed() { pauseForBetterTestPerformance() - isVisible(TextId(R.string.wifi_dialog_title)) - clickOn(TextId(R.string.hotspot_dialog_neutral_button)) + isVisible(Text("WiFi connection detected")) } fun assertServerStarted() { @@ -110,7 +118,6 @@ class ZimHostRobot : BaseRobot() { } private fun selectZimFile(position: Int) { - pauseForBetterTestPerformance() try { onView( RecyclerViewMatcher(R.id.recyclerViewZimHost).atPositionOnView( @@ -119,7 +126,6 @@ class ZimHostRobot : BaseRobot() { ) ).check(matches(ViewMatchers.isChecked())) } catch (assertionError: AssertionFailedError) { - pauseForBetterTestPerformance() onView( RecyclerViewMatcher(R.id.recyclerViewZimHost).atPositionOnView( position, @@ -148,6 +154,6 @@ class ZimHostRobot : BaseRobot() { } private fun pauseForBetterTestPerformance() { - BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) + BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong()) } } diff --git a/contrib/instrumentation.sh b/contrib/instrumentation.sh index 6ab3998c5..2b56d296c 100644 --- a/contrib/instrumentation.sh +++ b/contrib/instrumentation.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +# Enable Wi-Fi on the emulator +adb shell svc wifi enable adb logcat -c adb logcat ./*:E -v color & retry=0 @@ -11,6 +13,8 @@ do else adb kill-server adb start-server + # Enable Wi-Fi on the emulator + adb shell svc wifi enable adb logcat -c adb logcat ./*:E -v color & ./gradlew clean From f16e57919479a25e3c5c73a42485a7795c0d7afc Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Tue, 9 Jan 2024 22:17:23 +0530 Subject: [PATCH 3/4] Removed the deprecated method from SaveSearchToRecents. --- .../search/viewmodel/effects/SaveSearchToRecentsTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt b/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt index 18435c3aa..57d2f13b6 100644 --- a/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt +++ b/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/effects/SaveSearchToRecentsTest.kt @@ -23,9 +23,9 @@ import io.mockk.Called import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.TestCoroutineScope +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceUntilIdle -import kotlinx.coroutines.test.runBlockingTest +import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test import org.kiwix.kiwixmobile.core.dao.NewRecentSearchDao import org.kiwix.kiwixmobile.core.reader.ZimFileReader @@ -38,7 +38,7 @@ internal class SaveSearchToRecentsTest { private val searchListItem = RecentSearchListItem("", ZimFileReader.CONTENT_PREFIX) private val activity: AppCompatActivity = mockk() - private val testDispatcher = TestCoroutineScope() + private val testDispatcher = TestScope() @Test fun `invoke with null Id does nothing`() { @@ -54,7 +54,7 @@ internal class SaveSearchToRecentsTest { } @Test - fun `invoke with non null Id saves search`() = testDispatcher.runBlockingTest { + fun `invoke with non null Id saves search`() = testDispatcher.runTest { val id = "id" SaveSearchToRecents( newRecentSearchDao, From adeabcf56c3362e15115c59630881db566e80de8 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Sun, 14 Jan 2024 13:43:00 +0530 Subject: [PATCH 4/4] Removed the extra logs showing in CI. --- contrib/instrumentation.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/instrumentation.sh b/contrib/instrumentation.sh index 2b56d296c..96e6e443b 100644 --- a/contrib/instrumentation.sh +++ b/contrib/instrumentation.sh @@ -3,7 +3,8 @@ # Enable Wi-Fi on the emulator adb shell svc wifi enable adb logcat -c -adb logcat ./*:E -v color & +# shellcheck disable=SC2035 +adb logcat *:E -v color & retry=0 while [ $retry -le 3 ] do @@ -16,7 +17,8 @@ do # Enable Wi-Fi on the emulator adb shell svc wifi enable adb logcat -c - adb logcat ./*:E -v color & + # shellcheck disable=SC2035 + adb logcat *:E -v color & ./gradlew clean retry=$(( retry + 1 )) if [ $retry -eq 3 ]; then