Fixed: DarkModeViewPainterTest which was failing on CI.

This commit is contained in:
MohitMaliFtechiz 2025-08-06 16:40:43 +05:30
parent 0dc94eaeaf
commit 7b03c5da3e
5 changed files with 62 additions and 46 deletions

View File

@ -18,15 +18,13 @@
package org.kiwix.kiwixmobile.main package org.kiwix.kiwixmobile.main
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.core.content.edit import androidx.core.content.edit
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.navigation.NavOptions import androidx.navigation.NavOptions
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.accessibility.AccessibilityChecks import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
@ -65,7 +63,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
val retryRule = RetryRule() val retryRule = RetryRule()
@get:Rule(order = COMPOSE_TEST_RULE_ORDER) @get:Rule(order = COMPOSE_TEST_RULE_ORDER)
val composeTestRule = createComposeRule() val composeTestRule = createAndroidComposeRule<KiwixMainActivity>()
private lateinit var kiwixMainActivity: KiwixMainActivity private lateinit var kiwixMainActivity: KiwixMainActivity
@Before @Before
@ -86,18 +84,17 @@ class DarkModeViewPainterTest : BaseActivityTest() {
putBoolean(SharedPreferenceUtil.PREF_SHOW_SHOWCASE, false) putBoolean(SharedPreferenceUtil.PREF_SHOW_SHOWCASE, false)
putString(SharedPreferenceUtil.PREF_LANG, "en") putString(SharedPreferenceUtil.PREF_LANG, "en")
} }
activityScenario = composeTestRule.apply {
ActivityScenario.launch(KiwixMainActivity::class.java).apply { kiwixMainActivity = activity
moveToState(Lifecycle.State.RESUMED) runOnUiThread {
onActivity { LanguageUtils.handleLocaleChange(
kiwixMainActivity = it kiwixMainActivity,
LanguageUtils.handleLocaleChange( "en",
it, SharedPreferenceUtil(context)
"en", )
SharedPreferenceUtil(context)
)
}
} }
waitForIdle()
}
} }
init { init {
@ -118,6 +115,9 @@ class DarkModeViewPainterTest : BaseActivityTest() {
@Test @Test
fun testDarkMode() { fun testDarkMode() {
composeTestRule.waitForIdle() composeTestRule.waitForIdle()
composeTestRule.runOnUiThread {
composeTestRule.activity.navigate(KiwixDestination.Library.route)
}
toggleDarkMode(true) toggleDarkMode(true)
openZimFileInReader() openZimFileInReader()
verifyDarkMode(true) verifyDarkMode(true)
@ -127,10 +127,9 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} }
private fun openZimFileInReader() { private fun openZimFileInReader() {
activityScenario.onActivity { kiwixMainActivity = composeTestRule.activity
kiwixMainActivity = it
}
composeTestRule.apply { composeTestRule.apply {
waitForIdle()
waitUntilTimeout() waitUntilTimeout()
onNodeWithTag(NAVIGATION_ICON_TESTING_TAG).performClick() onNodeWithTag(NAVIGATION_ICON_TESTING_TAG).performClick()
waitUntilTimeout() waitUntilTimeout()
@ -141,6 +140,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} }
private fun toggleDarkMode(enable: Boolean) { private fun toggleDarkMode(enable: Boolean) {
composeTestRule.waitForIdle()
darkModeViewPainter { openSettings(kiwixMainActivity as CoreMainActivity, composeTestRule) } darkModeViewPainter { openSettings(kiwixMainActivity as CoreMainActivity, composeTestRule) }
settingsRobo { clickNightModePreference(composeTestRule) } settingsRobo { clickNightModePreference(composeTestRule) }
darkModeViewPainter { darkModeViewPainter {
@ -155,6 +155,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
private fun verifyDarkMode(isEnabled: Boolean) { private fun verifyDarkMode(isEnabled: Boolean) {
var kiwixReaderFragment: KiwixReaderFragment? = null var kiwixReaderFragment: KiwixReaderFragment? = null
composeTestRule.waitForIdle() composeTestRule.waitForIdle()
kiwixMainActivity = composeTestRule.activity
composeTestRule.waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) { composeTestRule.waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
kiwixReaderFragment = kiwixReaderFragment =
kiwixMainActivity.supportFragmentManager.fragments kiwixMainActivity.supportFragmentManager.fragments
@ -171,6 +172,8 @@ class DarkModeViewPainterTest : BaseActivityTest() {
assertLightModeEnabled(it) assertLightModeEnabled(it)
} }
} }
composeTestRule.waitForIdle()
composeTestRule.waitUntilTimeout()
} ?: run { } ?: run {
throw RuntimeException( throw RuntimeException(
"Could not check the dark mode enable or not because zim file is not loaded in the reader" "Could not check the dark mode enable or not because zim file is not loaded in the reader"
@ -179,6 +182,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} }
private fun loadZimFileInReader() { private fun loadZimFileInReader() {
composeTestRule.waitForIdle()
val loadFileStream = val loadFileStream =
DarkModeViewPainterTest::class.java.classLoader.getResourceAsStream("testzim.zim") DarkModeViewPainterTest::class.java.classLoader.getResourceAsStream("testzim.zim")
val zimFile = val zimFile =
@ -198,18 +202,16 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} }
} }
} }
activityScenario.onActivity {
kiwixMainActivity = it
}
composeTestRule.runOnIdle { composeTestRule.runOnIdle {
val navOptions = NavOptions.Builder() val navOptions = NavOptions.Builder()
.setPopUpTo(KiwixDestination.Reader.route, false) .setPopUpTo(KiwixDestination.Reader.route, false)
.build() .build()
kiwixMainActivity.navigate( composeTestRule.activity.navigate(
KiwixDestination.Reader.createRoute(zimFileUri = zimFile.toUri().toString()), KiwixDestination.Reader.createRoute(zimFileUri = zimFile.toUri().toString()),
navOptions navOptions
) )
} }
composeTestRule.waitForIdle()
} }
@After @After

View File

@ -39,6 +39,7 @@ import org.kiwix.kiwixmobile.core.main.reader.READER_SCREEN_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.reader.TAB_SWITCHER_VIEW_TESTING_TAG import org.kiwix.kiwixmobile.core.main.reader.TAB_SWITCHER_VIEW_TESTING_TAG
import org.kiwix.kiwixmobile.core.page.DELETE_MENU_ICON_TESTING_TAG import org.kiwix.kiwixmobile.core.page.DELETE_MENU_ICON_TESTING_TAG
import org.kiwix.kiwixmobile.core.ui.components.TOOLBAR_TITLE_TESTING_TAG import org.kiwix.kiwixmobile.core.ui.components.TOOLBAR_TITLE_TESTING_TAG
import org.kiwix.kiwixmobile.core.utils.dialog.ALERT_DIALOG_DISMISS_BUTTON_TESTING_TAG
import org.kiwix.kiwixmobile.core.utils.dialog.ALERT_DIALOG_TITLE_TEXT_TESTING_TAG import org.kiwix.kiwixmobile.core.utils.dialog.ALERT_DIALOG_TITLE_TEXT_TESTING_TAG
import org.kiwix.kiwixmobile.main.BOTTOM_NAV_READER_ITEM_TESTING_TAG import org.kiwix.kiwixmobile.main.BOTTOM_NAV_READER_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils
@ -198,4 +199,13 @@ class NavigationHistoryRobot : BaseRobot() {
} }
}) })
} }
fun clickOnCancelButton(composeTestRule: ComposeContentTestRule) {
testFlakyView({
composeTestRule.apply {
waitUntilTimeout()
onNodeWithTag(ALERT_DIALOG_DISMISS_BUTTON_TESTING_TAG).performClick()
}
})
}
} }

View File

@ -114,7 +114,7 @@ class NavigationHistoryTest : BaseActivityTest() {
composeTestRule.apply { composeTestRule.apply {
waitForIdle() waitForIdle()
runOnUiThread { runOnUiThread {
kiwixMainActivity.navigate(KiwixDestination.Library.route) activity.navigate(KiwixDestination.Library.route)
} }
} }
val loadFileStream = val loadFileStream =
@ -142,7 +142,7 @@ class NavigationHistoryTest : BaseActivityTest() {
val navOptions = NavOptions.Builder() val navOptions = NavOptions.Builder()
.setPopUpTo(KiwixDestination.Reader.route, false) .setPopUpTo(KiwixDestination.Reader.route, false)
.build() .build()
kiwixMainActivity.navigate( activity.navigate(
KiwixDestination.Reader.createRoute(zimFileUri = zimFile.toUri().toString()), KiwixDestination.Reader.createRoute(zimFileUri = zimFile.toUri().toString()),
navOptions navOptions
) )
@ -162,7 +162,7 @@ class NavigationHistoryTest : BaseActivityTest() {
assertForwardNavigationHistoryDialogDisplayed(composeTestRule) assertForwardNavigationHistoryDialogDisplayed(composeTestRule)
clickOnDeleteHistory(composeTestRule) clickOnDeleteHistory(composeTestRule)
assertDeleteDialogDisplayed(composeTestRule) assertDeleteDialogDisplayed(composeTestRule)
pressBack() clickOnCancelButton(composeTestRule)
pressBack() pressBack()
} }
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1 && if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1 &&

View File

@ -104,8 +104,12 @@ object ActivityExtensions {
} }
private fun <T> Activity.getObservableNavigationResult(key: String = "result") = private fun <T> Activity.getObservableNavigationResult(key: String = "result") =
coreMainActivity.navController.currentBackStackEntry?.savedStateHandle if (coreMainActivity.isNavControllerInitialized) {
?.getLiveData<T>(key) coreMainActivity.navController.currentBackStackEntry?.savedStateHandle
?.getLiveData<T>(key)
} else {
null
}
fun <T> Activity.observeNavigationResult( fun <T> Activity.observeNavigationResult(
key: String, key: String,
@ -119,20 +123,28 @@ object ActivityExtensions {
} }
fun <T> Activity.consumeObservable(key: String = "result") = fun <T> Activity.consumeObservable(key: String = "result") =
coreMainActivity.navController.currentBackStackEntry?.savedStateHandle?.remove<T>(key) if (coreMainActivity.isNavControllerInitialized) {
coreMainActivity.navController.currentBackStackEntry?.savedStateHandle?.remove<T>(key)
} else {
// do nothing.
}
fun <T> Activity.setNavigationResult(result: T, key: String = "result") { fun <T> Activity.setNavigationResult(result: T, key: String = "result") {
coreMainActivity.navController.previousBackStackEntry?.savedStateHandle?.set( if (coreMainActivity.isNavControllerInitialized) {
key, coreMainActivity.navController.previousBackStackEntry?.savedStateHandle?.set(
result key,
) result
)
}
} }
fun <T> Activity.setNavigationResultOnCurrent(result: T, key: String = "result") { fun <T> Activity.setNavigationResultOnCurrent(result: T, key: String = "result") {
coreMainActivity.navController.currentBackStackEntry?.savedStateHandle?.set( if (coreMainActivity.isNavControllerInitialized) {
key, coreMainActivity.navController.currentBackStackEntry?.savedStateHandle?.set(
result key,
) result
)
}
} }
fun Activity.hasNotificationPermission(sharedPreferenceUtil: SharedPreferenceUtil?) = fun Activity.hasNotificationPermission(sharedPreferenceUtil: SharedPreferenceUtil?) =
@ -181,16 +193,6 @@ object ActivityExtensions {
fun Activity.isLandScapeMode(): Boolean = fun Activity.isLandScapeMode(): Boolean =
resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
@Suppress("MagicNumber")
fun Activity.isTablet(): Boolean {
val configuration = resources.configuration
val isLargeOrXLarge =
configuration.screenLayout and
Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_LARGE
val isWideEnough = configuration.smallestScreenWidthDp >= 600
return isLargeOrXLarge && isWideEnough
}
/** /**
* Sets the window background color to black for Android 15 and above. * Sets the window background color to black for Android 15 and above.
* *

View File

@ -118,6 +118,8 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
* is responsibility of child activities such as KiwixMainActivity, and CustomMainActivity. * is responsibility of child activities such as KiwixMainActivity, and CustomMainActivity.
*/ */
lateinit var navController: NavHostController lateinit var navController: NavHostController
val isNavControllerInitialized: Boolean
get() = ::navController.isInitialized
/** /**
* For managing the leftDrawer. * For managing the leftDrawer.