Fixed: NavController adding multiple instances of the same fragment in backStack with causing issues when navigating.

* Refactored the `DarkModeViewPainterTest` with compose UI.
* Refactored the `CopyMoveFileHandlerTest` according to compose UI.
* Refactored the test cases to get the fragments in test cases according to compose based navigation.
* Refactored the `SearchFragmentTestForCustomApp` test case.
This commit is contained in:
MohitMaliFtechiz 2025-08-01 00:57:03 +05:30
parent 08880afa17
commit 51bd9e7908
19 changed files with 317 additions and 223 deletions

View File

@ -193,7 +193,7 @@ class DownloadTest : BaseActivityTest() {
downloadRobot { downloadRobot {
// change the application language // change the application language
topLevel { topLevel {
clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity) { clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
clickLanguagePreference(composeTestRule) clickLanguagePreference(composeTestRule)
assertLanguagePrefDialogDisplayed(composeTestRule) assertLanguagePrefDialogDisplayed(composeTestRule)
selectDeviceDefaultLanguage(composeTestRule) selectDeviceDefaultLanguage(composeTestRule)
@ -214,7 +214,7 @@ class DownloadTest : BaseActivityTest() {
stopDownloadIfAlreadyStarted(composeTestRule) stopDownloadIfAlreadyStarted(composeTestRule)
// select the default device language to perform other test cases. // select the default device language to perform other test cases.
topLevel { topLevel {
clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity) { clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
clickLanguagePreference(composeTestRule) clickLanguagePreference(composeTestRule)
assertLanguagePrefDialogDisplayed(composeTestRule) assertLanguagePrefDialogDisplayed(composeTestRule)
selectDeviceDefaultLanguage(composeTestRule) selectDeviceDefaultLanguage(composeTestRule)

View File

@ -39,7 +39,6 @@ import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.core.extensions.deleteFile import org.kiwix.kiwixmobile.core.extensions.deleteFile
import org.kiwix.kiwixmobile.core.extensions.isFileExist import org.kiwix.kiwixmobile.core.extensions.isFileExist
import org.kiwix.kiwixmobile.core.settings.StorageCalculator import org.kiwix.kiwixmobile.core.settings.StorageCalculator
@ -50,6 +49,7 @@ import org.kiwix.kiwixmobile.core.utils.TestingUtils.RETRY_RULE_ORDER
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
import org.kiwix.kiwixmobile.main.KiwixMainActivity import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.nav.destination.library.CopyMoveFileHandler import org.kiwix.kiwixmobile.nav.destination.library.CopyMoveFileHandler
import org.kiwix.kiwixmobile.nav.destination.library.local.LocalLibraryFragment
import org.kiwix.kiwixmobile.testutils.RetryRule import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils
import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout
@ -201,33 +201,29 @@ class CopyMoveFileHandlerTest : BaseActivityTest() {
} }
private fun showMoveFileToPublicDirectoryDialog() { private fun showMoveFileToPublicDirectoryDialog() {
// TODO refactore this with compose based navController. kiwixMainActivity.lifecycleScope.launch {
// kiwixMainActivity.lifecycleScope.launch { val localLibraryFragment =
// val navHostFragment: NavHostFragment = kiwixMainActivity.supportFragmentManager.fragments
// kiwixMainActivity.navController .filterIsInstance<LocalLibraryFragment>()
// .findFragmentById(R.id.nav_host_fragment) as NavHostFragment .firstOrNull()
// val localLibraryFragment = localLibraryFragment?.copyMoveFileHandler?.showMoveFileToPublicDirectoryDialog(
// navHostFragment.childFragmentManager.fragments[0] as LocalLibraryFragment Uri.fromFile(selectedFile),
// localLibraryFragment.copyMoveFileHandler?.showMoveFileToPublicDirectoryDialog( DocumentFile.fromFile(selectedFile),
// Uri.fromFile(selectedFile), fragmentManager = localLibraryFragment.parentFragmentManager
// DocumentFile.fromFile(selectedFile), )
// fragmentManager = localLibraryFragment.parentFragmentManager }
// )
// }
} }
private fun tryOpeningInvalidZimFiles(uri: Uri) { private fun tryOpeningInvalidZimFiles(uri: Uri) {
// TODO refactore this with compose based navController. UiThreadStatement.runOnUiThread {
// UiThreadStatement.runOnUiThread { val localLibraryFragment =
// val navHostFragment: NavHostFragment = kiwixMainActivity.supportFragmentManager.fragments
// kiwixMainActivity.supportFragmentManager .filterIsInstance<LocalLibraryFragment>()
// .findFragmentById(R.id.nav_host_fragment) as NavHostFragment .firstOrNull()
// val localLibraryFragment = localLibraryFragment?.handleSelectedFileUri(
// navHostFragment.childFragmentManager.fragments[0] as LocalLibraryFragment uri,
// localLibraryFragment.handleSelectedFileUri( )
// uri, }
// )
// }
} }
private fun getSelectedFile(): File { private fun getSelectedFile(): File {

View File

@ -19,6 +19,8 @@
package org.kiwix.kiwixmobile.main package org.kiwix.kiwixmobile.main
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
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.lifecycle.Lifecycle
@ -27,7 +29,6 @@ import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario 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.internal.runner.junit4.statement.UiThreadStatement
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheck import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheck
@ -42,13 +43,17 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.ui.components.NAVIGATION_ICON_TESTING_TAG
import org.kiwix.kiwixmobile.core.utils.LanguageUtils import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TestingUtils.COMPOSE_TEST_RULE_ORDER import org.kiwix.kiwixmobile.core.utils.TestingUtils.COMPOSE_TEST_RULE_ORDER
import org.kiwix.kiwixmobile.core.utils.TestingUtils.RETRY_RULE_ORDER import org.kiwix.kiwixmobile.core.utils.TestingUtils.RETRY_RULE_ORDER
import org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment
import org.kiwix.kiwixmobile.settings.settingsRobo import org.kiwix.kiwixmobile.settings.settingsRobo
import org.kiwix.kiwixmobile.testutils.RetryRule import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils
import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST
import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout
import org.kiwix.kiwixmobile.ui.KiwixDestination import org.kiwix.kiwixmobile.ui.KiwixDestination
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -85,6 +90,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
ActivityScenario.launch(KiwixMainActivity::class.java).apply { ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED) moveToState(Lifecycle.State.RESUMED)
onActivity { onActivity {
kiwixMainActivity = it
LanguageUtils.handleLocaleChange( LanguageUtils.handleLocaleChange(
it, it,
"en", "en",
@ -111,6 +117,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
@Test @Test
fun testDarkMode() { fun testDarkMode() {
composeTestRule.waitForIdle()
toggleDarkMode(true) toggleDarkMode(true)
openZimFileInReader() openZimFileInReader()
verifyDarkMode(true) verifyDarkMode(true)
@ -122,13 +129,19 @@ class DarkModeViewPainterTest : BaseActivityTest() {
private fun openZimFileInReader() { private fun openZimFileInReader() {
activityScenario.onActivity { activityScenario.onActivity {
kiwixMainActivity = it kiwixMainActivity = it
kiwixMainActivity.navigate(KiwixDestination.Library.route) }
composeTestRule.apply {
waitUntilTimeout()
onNodeWithTag(NAVIGATION_ICON_TESTING_TAG).performClick()
waitUntilTimeout()
onNodeWithTag(BOTTOM_NAV_LIBRARY_ITEM_TESTING_TAG).performClick()
waitUntilTimeout()
} }
loadZimFileInReader() loadZimFileInReader()
} }
private fun toggleDarkMode(enable: Boolean) { private fun toggleDarkMode(enable: Boolean) {
darkModeViewPainter { openSettings(kiwixMainActivity as CoreMainActivity) } darkModeViewPainter { openSettings(kiwixMainActivity as CoreMainActivity, composeTestRule) }
settingsRobo { clickNightModePreference(composeTestRule) } settingsRobo { clickNightModePreference(composeTestRule) }
darkModeViewPainter { darkModeViewPainter {
if (enable) { if (enable) {
@ -136,33 +149,33 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} else { } else {
enableTheLightMode(composeTestRule) enableTheLightMode(composeTestRule)
} }
pressBack()
} }
} }
private fun verifyDarkMode(isEnabled: Boolean) { private fun verifyDarkMode(isEnabled: Boolean) {
// TODO refactor this with compose based navController. var kiwixReaderFragment: KiwixReaderFragment? = null
// UiThreadStatement.runOnUiThread { composeTestRule.waitForIdle()
// val navHostFragment: NavHostFragment = composeTestRule.waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
// kiwixMainActivity.supportFragmentManager kiwixReaderFragment =
// .findFragmentById(R.id.nav_host_fragment) as NavHostFragment kiwixMainActivity.supportFragmentManager.fragments
// val kiwixReaderFragment = .filterIsInstance<KiwixReaderFragment>()
// navHostFragment.childFragmentManager.fragments[0] as KiwixReaderFragment .firstOrNull()
// val currentWebView = kiwixReaderFragment.getCurrentWebView() kiwixReaderFragment?.getCurrentWebView() != null
// currentWebView?.let { }
// darkModeViewPainter { val currentWebView = kiwixReaderFragment?.getCurrentWebView()
// if (isEnabled) { currentWebView?.let {
// assertNightModeEnabled(it) darkModeViewPainter {
// } else { if (isEnabled) {
// assertLightModeEnabled(it) assertNightModeEnabled(it)
// } } else {
// } assertLightModeEnabled(it)
// } ?: run { }
// throw RuntimeException( }
// "Could not check the dark mode enable or not because zim file is not loaded in the reader" } ?: run {
// ) throw RuntimeException(
// } "Could not check the dark mode enable or not because zim file is not loaded in the reader"
// } )
}
} }
private fun loadZimFileInReader() { private fun loadZimFileInReader() {
@ -185,7 +198,10 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} }
} }
} }
UiThreadStatement.runOnUiThread { activityScenario.onActivity {
kiwixMainActivity = it
}
composeTestRule.runOnIdle {
val navOptions = NavOptions.Builder() val navOptions = NavOptions.Builder()
.setPopUpTo(KiwixDestination.Reader.route, false) .setPopUpTo(KiwixDestination.Reader.route, false)
.build() .build()

View File

@ -20,15 +20,16 @@ package org.kiwix.kiwixmobile.main
import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeContentTestRule
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.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withText
import applyWithViewHierarchyPrinting import applyWithViewHierarchyPrinting
import com.adevinta.android.barista.interaction.BaristaSleepInteractions import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.Findable.StringId.TextId
import org.kiwix.kiwixmobile.core.R.string
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_HELP_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_HISTORY_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_SETTINGS_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_SUPPORT_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_ZIM_HOST_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.help.HelpRobot import org.kiwix.kiwixmobile.help.HelpRobot
import org.kiwix.kiwixmobile.help.help import org.kiwix.kiwixmobile.help.help
import org.kiwix.kiwixmobile.nav.destination.library.LibraryRobot import org.kiwix.kiwixmobile.nav.destination.library.LibraryRobot
@ -99,47 +100,79 @@ class TopLevelDestinationRobot : BaseRobot() {
fun clickBookmarksOnNavDrawer( fun clickBookmarksOnNavDrawer(
coreMainActivity: CoreMainActivity, coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: BookmarksRobot.() -> Unit func: BookmarksRobot.() -> Unit
) { ) {
inNavDrawer(coreMainActivity = coreMainActivity) { inNavDrawer(coreMainActivity = coreMainActivity) {
testFlakyView({ onView(withText(string.bookmarks)).perform(click()) }) testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG).performClick()
})
bookmarks(func) bookmarks(func)
pressBack() pressBack()
} }
} }
fun clickHistoryOnSideNav(coreMainActivity: CoreMainActivity, func: HistoryRobot.() -> Unit) { fun clickHistoryOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: HistoryRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) { inNavDrawer(coreMainActivity) {
clickOn(TextId(string.history)) testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_HISTORY_ITEM_TESTING_TAG).performClick()
})
history(func) history(func)
pressBack() pressBack()
} }
} }
fun clickHostBooksOnSideNav(coreMainActivity: CoreMainActivity, func: ZimHostRobot.() -> Unit) { fun clickHostBooksOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: ZimHostRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) { inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_wifi_hotspot)) testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_ZIM_HOST_ITEM_TESTING_TAG).performClick()
})
zimHost(func) zimHost(func)
} }
} }
fun clickSettingsOnSideNav(coreMainActivity: CoreMainActivity, func: SettingsRobot.() -> Unit) { fun clickSettingsOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: SettingsRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) { inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_settings)) testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_SETTINGS_ITEM_TESTING_TAG).performClick()
})
settingsRobo(func) settingsRobo(func)
} }
} }
fun clickHelpOnSideNav(coreMainActivity: CoreMainActivity, func: HelpRobot.() -> Unit) { fun clickHelpOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: HelpRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) { inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_help)) testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_HELP_ITEM_TESTING_TAG).performClick()
})
help(func) help(func)
} }
} }
fun clickSupportKiwixOnSideNav(coreMainActivity: CoreMainActivity) { fun clickSupportKiwixOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
) {
inNavDrawer(coreMainActivity) { inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_support_kiwix)) testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_SUPPORT_ITEM_TESTING_TAG).performClick()
})
} }
} }
} }

View File

@ -126,26 +126,26 @@ class TopLevelDestinationTest : BaseActivityTest() {
assertReceiveFileTitleVisible(composeTestRule) assertReceiveFileTitleVisible(composeTestRule)
} }
} }
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity) { clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookMarksDisplayed(composeTestRule) assertBookMarksDisplayed(composeTestRule)
clickOnTrashIcon(composeTestRule) clickOnTrashIcon(composeTestRule)
assertDeleteBookmarksDialogDisplayed(composeTestRule) assertDeleteBookmarksDialogDisplayed(composeTestRule)
} }
clickHistoryOnSideNav(kiwixMainActivity as CoreMainActivity) { clickHistoryOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertHistoryDisplayed(composeTestRule) assertHistoryDisplayed(composeTestRule)
clickOnTrashIcon(composeTestRule) clickOnTrashIcon(composeTestRule)
assertDeleteHistoryDialogDisplayed(composeTestRule) assertDeleteHistoryDialogDisplayed(composeTestRule)
} }
clickHostBooksOnSideNav(kiwixMainActivity as CoreMainActivity) { clickHostBooksOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertMenuWifiHotspotDisplayed(composeTestRule) assertMenuWifiHotspotDisplayed(composeTestRule)
} }
clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity) { clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertMenuSettingsDisplayed(composeTestRule) assertMenuSettingsDisplayed(composeTestRule)
} }
clickHelpOnSideNav(kiwixMainActivity as CoreMainActivity) { clickHelpOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertToolbarDisplayed(composeTestRule) assertToolbarDisplayed(composeTestRule)
} }
clickSupportKiwixOnSideNav(kiwixMainActivity as CoreMainActivity) clickSupportKiwixOnSideNav(kiwixMainActivity as CoreMainActivity, 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

@ -24,20 +24,18 @@ import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.longClick import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToNode import androidx.compose.ui.test.performScrollToNode
import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.test.performTouchInput
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withText
import applyWithViewHierarchyPrinting import applyWithViewHierarchyPrinting
import com.adevinta.android.barista.interaction.BaristaSleepInteractions import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.reader.READER_BOTTOM_BAR_BOOKMARK_BUTTON_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.page.NO_ITEMS_TEXT_TESTING_TAG import org.kiwix.kiwixmobile.core.page.NO_ITEMS_TEXT_TESTING_TAG
import org.kiwix.kiwixmobile.core.page.PAGE_LIST_TEST_TAG import org.kiwix.kiwixmobile.core.page.PAGE_LIST_TEST_TAG
@ -47,6 +45,7 @@ import org.kiwix.kiwixmobile.core.utils.dialog.ALERT_DIALOG_CONFIRM_BUTTON_TESTI
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.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils
import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS
import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout
import org.kiwix.kiwixmobile.utils.StandardActions.openDrawer import org.kiwix.kiwixmobile.utils.StandardActions.openDrawer
@ -104,8 +103,11 @@ class BookmarksRobot : BaseRobot() {
fun clickOnSaveBookmarkImage(composeTestRule: ComposeContentTestRule) { fun clickOnSaveBookmarkImage(composeTestRule: ComposeContentTestRule) {
composeTestRule.apply { composeTestRule.apply {
waitUntilTimeout() waitForIdle()
onNodeWithContentDescription(context.getString(R.string.bookmarks)) waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
onNodeWithTag(READER_BOTTOM_BAR_BOOKMARK_BUTTON_TESTING_TAG).isDisplayed()
}
onNodeWithTag(READER_BOTTOM_BAR_BOOKMARK_BUTTON_TESTING_TAG)
.performClick() .performClick()
} }
} }
@ -115,9 +117,13 @@ class BookmarksRobot : BaseRobot() {
timeout: Long = TEST_PAUSE_MS.toLong() timeout: Long = TEST_PAUSE_MS.toLong()
) { ) {
composeTestRule.apply { composeTestRule.apply {
waitForIdle()
// wait for disappearing the snack-bar after removing the bookmark // wait for disappearing the snack-bar after removing the bookmark
waitUntilTimeout(timeout) waitUntilTimeout(timeout)
onNodeWithContentDescription(context.getString(R.string.bookmarks)) waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
onNodeWithTag(READER_BOTTOM_BAR_BOOKMARK_BUTTON_TESTING_TAG).isDisplayed()
}
onNodeWithTag(READER_BOTTOM_BAR_BOOKMARK_BUTTON_TESTING_TAG)
.performTouchInput { .performTouchInput {
longClick() longClick()
} }
@ -144,10 +150,16 @@ class BookmarksRobot : BaseRobot() {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong()) BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong())
} }
fun openBookmarkScreen(coreMainActivity: CoreMainActivity) { fun openBookmarkScreen(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule
) {
testFlakyView({ testFlakyView({
openDrawer(coreMainActivity) openDrawer(coreMainActivity)
onView(withText(R.string.bookmarks)).perform(click()) composeTestRule.apply {
waitUntilTimeout()
onNodeWithTag(LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG).performClick()
}
}) })
} }

View File

@ -33,6 +33,7 @@ import com.google.android.apps.common.testing.accessibility.framework.Accessibil
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
import com.google.android.apps.common.testing.accessibility.framework.checks.SpeakableTextPresentCheck import com.google.android.apps.common.testing.accessibility.framework.checks.SpeakableTextPresentCheck
import com.google.android.apps.common.testing.accessibility.framework.checks.TouchTargetSizeCheck import com.google.android.apps.common.testing.accessibility.framework.checks.TouchTargetSizeCheck
import kotlinx.coroutines.runBlocking
import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.anyOf import org.hamcrest.Matchers.anyOf
import org.junit.Before import org.junit.Before
@ -40,6 +41,8 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.reader.CoreReaderFragment
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.handleLocaleChange
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TestingUtils.COMPOSE_TEST_RULE_ORDER import org.kiwix.kiwixmobile.core.utils.TestingUtils.COMPOSE_TEST_RULE_ORDER
@ -51,6 +54,8 @@ import org.kiwix.kiwixmobile.testutils.TestUtils
import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST
import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout
import org.kiwix.kiwixmobile.ui.KiwixDestination import org.kiwix.kiwixmobile.ui.KiwixDestination
import org.kiwix.libkiwix.Book
import org.kiwix.libkiwix.Bookmark
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.OutputStream import java.io.OutputStream
@ -134,7 +139,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
pressBack() pressBack()
// Test saving bookmark // Test saving bookmark
clickOnSaveBookmarkImage(composeTestRule) clickOnSaveBookmarkImage(composeTestRule)
openBookmarkScreen(kiwixMainActivity as CoreMainActivity) openBookmarkScreen(kiwixMainActivity as CoreMainActivity, composeTestRule)
assertBookmarkSaved(composeTestRule) assertBookmarkSaved(composeTestRule)
pressBack() pressBack()
// Test removing bookmark // Test removing bookmark
@ -154,7 +159,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
kiwixMainActivity = it kiwixMainActivity = it
} }
topLevel { topLevel {
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity) { clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookmarkSaved(composeTestRule) assertBookmarkSaved(composeTestRule)
} }
} }
@ -184,41 +189,39 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
pressBack() pressBack()
} }
composeTestRule.waitUntilTimeout() composeTestRule.waitUntilTimeout()
// TODO refactor this wih compose based navController. val coreReaderFragment = kiwixMainActivity.supportFragmentManager.fragments
// val navHostFragment: NavHostFragment = .filterIsInstance<CoreReaderFragment>()
// kiwixMainActivity.supportFragmentManager .firstOrNull()
// .findFragmentById(R.id.nav_host_fragment) as NavHostFragment val libKiwixBook =
// val coreReaderFragment = navHostFragment.childFragmentManager.fragments[0] as CoreReaderFragment Book().apply {
// val libKiwixBook = update(coreReaderFragment?.zimReaderContainer?.zimFileReader?.jniKiwixReader)
// Book().apply { }
// update(coreReaderFragment.zimReaderContainer?.zimFileReader?.jniKiwixReader) val bookmarkList = arrayListOf<LibkiwixBookmarkItem>()
// } for (i in 1..500) {
// val bookmarkList = arrayListOf<LibkiwixBookmarkItem>() val bookmark =
// for (i in 1..500) { Bookmark().apply {
// val bookmark = bookId = coreReaderFragment?.zimReaderContainer?.zimFileReader?.id
// Bookmark().apply { title = "bookmark$i"
// bookId = coreReaderFragment.zimReaderContainer?.zimFileReader?.id url = "http://kiwix.org/demoBookmark$i"
// title = "bookmark$i" bookTitle = libKiwixBook.title
// url = "http://kiwix.org/demoBookmark$i" }
// bookTitle = libKiwixBook.title val libkiwixItem =
// } LibkiwixBookmarkItem(
// val libkiwixItem = bookmark,
// LibkiwixBookmarkItem( coreReaderFragment?.zimReaderContainer?.zimFileReader?.favicon,
// bookmark, coreReaderFragment?.zimReaderContainer?.zimFileReader?.zimReaderSource
// coreReaderFragment.zimReaderContainer?.zimFileReader?.favicon, )
// coreReaderFragment.zimReaderContainer?.zimFileReader?.zimReaderSource runBlocking {
// ) coreReaderFragment?.libkiwixBookmarks?.saveBookmark(libkiwixItem).also {
// runBlocking { bookmarkList.add(libkiwixItem)
// coreReaderFragment.libkiwixBookmarks?.saveBookmark(libkiwixItem).also { }
// bookmarkList.add(libkiwixItem) }
// } }
// } bookmarks {
// } // test all the saved bookmarks are showing on the bookmarks screen
// bookmarks { openBookmarkScreen(kiwixMainActivity as CoreMainActivity, composeTestRule)
// // test all the saved bookmarks are showing on the bookmarks screen testAllBookmarkShowing(bookmarkList, composeTestRule)
// openBookmarkScreen() }
// testAllBookmarkShowing(bookmarkList, composeTestRule)
// }
} }
private fun getZimFile(): File { private fun getZimFile(): File {

View File

@ -19,9 +19,9 @@ package org.kiwix.kiwixmobile.page.history
import android.util.Log import android.util.Log
import androidx.compose.ui.test.assertTextEquals import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.longClick import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.onNodeWithContentDescription
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.compose.ui.test.performTouchInput import androidx.compose.ui.test.performTouchInput
@ -34,6 +34,8 @@ import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import junit.framework.AssertionFailedError import junit.framework.AssertionFailedError
import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.main.reader.READER_BOTTOM_BAR_NEXT_SCREEN_BUTTON_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.reader.READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.reader.READER_SCREEN_TESTING_TAG 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
@ -41,6 +43,7 @@ import org.kiwix.kiwixmobile.core.ui.components.TOOLBAR_TITLE_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
import org.kiwix.kiwixmobile.testutils.TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout import org.kiwix.kiwixmobile.testutils.TestUtils.waitUntilTimeout
@ -99,9 +102,12 @@ class NavigationHistoryRobot : BaseRobot() {
fun longClickOnBackwardButton(composeTestRule: ComposeContentTestRule) { fun longClickOnBackwardButton(composeTestRule: ComposeContentTestRule) {
composeTestRule.apply { composeTestRule.apply {
waitUntilTimeout() waitForIdle()
waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
onNodeWithTag(READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG).isDisplayed()
}
testFlakyView({ testFlakyView({
onNodeWithContentDescription(context.getString(R.string.go_to_previous_page)) onNodeWithTag(READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG)
.performTouchInput { longClick() } .performTouchInput { longClick() }
}) })
} }
@ -109,9 +115,12 @@ class NavigationHistoryRobot : BaseRobot() {
fun longClickOnForwardButton(composeTestRule: ComposeContentTestRule) { fun longClickOnForwardButton(composeTestRule: ComposeContentTestRule) {
composeTestRule.apply { composeTestRule.apply {
waitUntilTimeout() waitForIdle()
waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
onNodeWithTag(READER_BOTTOM_BAR_NEXT_SCREEN_BUTTON_TESTING_TAG).isDisplayed()
}
testFlakyView({ testFlakyView({
onNodeWithContentDescription(context.getString(R.string.go_to_next_page)) onNodeWithTag(READER_BOTTOM_BAR_NEXT_SCREEN_BUTTON_TESTING_TAG)
.performTouchInput { longClick() } .performTouchInput { longClick() }
}) })
} }
@ -135,8 +144,11 @@ class NavigationHistoryRobot : BaseRobot() {
fun clickOnBackwardButton(composeTestRule: ComposeContentTestRule) { fun clickOnBackwardButton(composeTestRule: ComposeContentTestRule) {
composeTestRule.apply { composeTestRule.apply {
waitUntilTimeout() waitForIdle()
onNodeWithContentDescription(context.getString(R.string.go_to_previous_page)) waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
onNodeWithTag(READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG).isDisplayed()
}
onNodeWithTag(READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG)
.performClick() .performClick()
} }
} }

View File

@ -142,26 +142,26 @@ class GetContentShortcutTest {
assertReceiveFileTitleVisible(composeTestRule) assertReceiveFileTitleVisible(composeTestRule)
} }
} }
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity) { clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookMarksDisplayed(composeTestRule) assertBookMarksDisplayed(composeTestRule)
clickOnTrashIcon(composeTestRule) clickOnTrashIcon(composeTestRule)
assertDeleteBookmarksDialogDisplayed(composeTestRule) assertDeleteBookmarksDialogDisplayed(composeTestRule)
} }
clickHistoryOnSideNav(kiwixMainActivity as CoreMainActivity) { clickHistoryOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertHistoryDisplayed(composeTestRule) assertHistoryDisplayed(composeTestRule)
clickOnTrashIcon(composeTestRule) clickOnTrashIcon(composeTestRule)
assertDeleteHistoryDialogDisplayed(composeTestRule) assertDeleteHistoryDialogDisplayed(composeTestRule)
} }
clickHostBooksOnSideNav(kiwixMainActivity as CoreMainActivity) { clickHostBooksOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertMenuWifiHotspotDisplayed(composeTestRule) assertMenuWifiHotspotDisplayed(composeTestRule)
} }
clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity) { clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertMenuSettingsDisplayed(composeTestRule) assertMenuSettingsDisplayed(composeTestRule)
} }
clickHelpOnSideNav(kiwixMainActivity as CoreMainActivity) { clickHelpOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
HelpRobot().assertToolbarDisplayed(composeTestRule) HelpRobot().assertToolbarDisplayed(composeTestRule)
} }
clickSupportKiwixOnSideNav(kiwixMainActivity as CoreMainActivity) clickSupportKiwixOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule)
pressBack() pressBack()
} }
} }

View File

@ -24,7 +24,6 @@ import androidx.test.espresso.Espresso
import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
import com.adevinta.android.barista.interaction.BaristaDialogInteractions import com.adevinta.android.barista.interaction.BaristaDialogInteractions
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_SETTINGS_ITEM_TESTING_TAG import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_SETTINGS_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.utils.files.Log import org.kiwix.kiwixmobile.core.utils.files.Log
@ -43,12 +42,10 @@ object StandardActions {
} }
fun openDrawer(coreMainActivity: CoreMainActivity) { fun openDrawer(coreMainActivity: CoreMainActivity) {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
coreMainActivity.openNavigationDrawer() coreMainActivity.openNavigationDrawer()
} }
fun closeDrawer(coreMainActivity: CoreMainActivity) { fun closeDrawer(coreMainActivity: CoreMainActivity) {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
coreMainActivity.closeNavigationDrawer() coreMainActivity.closeNavigationDrawer()
} }

View File

@ -20,7 +20,6 @@ package org.kiwix.kiwixmobile.ui
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
@ -40,6 +39,7 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.navArgument import androidx.navigation.navArgument
import androidx.navigation.navDeepLink import androidx.navigation.navDeepLink
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.main.BOOKMARK_FRAGMENT import org.kiwix.kiwixmobile.core.main.BOOKMARK_FRAGMENT
import org.kiwix.kiwixmobile.core.main.DOWNLOAD_FRAGMENT import org.kiwix.kiwixmobile.core.main.DOWNLOAD_FRAGMENT
import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING
@ -121,7 +121,7 @@ fun KiwixNavGraph(
val shouldOpenInNewTab = backStackEntry.arguments?.getBoolean(SHOULD_OPEN_IN_NEW_TAB) ?: false val shouldOpenInNewTab = backStackEntry.arguments?.getBoolean(SHOULD_OPEN_IN_NEW_TAB) ?: false
val searchItemTitle = backStackEntry.arguments?.getString(SEARCH_ITEM_TITLE_KEY).orEmpty() val searchItemTitle = backStackEntry.arguments?.getString(SEARCH_ITEM_TITLE_KEY).orEmpty()
FragmentContainer { FragmentContainer(R.id.readerFragmentContainer) {
KiwixReaderFragment().apply { KiwixReaderFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
putString(ZIM_FILE_URI_KEY, zimFileUri) putString(ZIM_FILE_URI_KEY, zimFileUri)
@ -144,7 +144,7 @@ fun KiwixNavGraph(
) { backStackEntry -> ) { backStackEntry ->
val zimFileUri = backStackEntry.arguments?.getString(ZIM_FILE_URI_KEY).orEmpty() val zimFileUri = backStackEntry.arguments?.getString(ZIM_FILE_URI_KEY).orEmpty()
FragmentContainer { FragmentContainer(R.id.localLibraryFragmentContainer) {
LocalLibraryFragment().apply { LocalLibraryFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
putString(ZIM_FILE_URI_KEY, zimFileUri) putString(ZIM_FILE_URI_KEY, zimFileUri)
@ -153,32 +153,32 @@ fun KiwixNavGraph(
} }
} }
composable(KiwixDestination.Downloads.route) { composable(KiwixDestination.Downloads.route) {
FragmentContainer { FragmentContainer(R.id.downloadFragmentContainer) {
OnlineLibraryFragment() OnlineLibraryFragment()
} }
} }
composable(KiwixDestination.Bookmarks.route) { composable(KiwixDestination.Bookmarks.route) {
FragmentContainer { FragmentContainer(R.id.bookmarksFragmentContainer) {
BookmarksFragment() BookmarksFragment()
} }
} }
composable(KiwixDestination.Notes.route) { composable(KiwixDestination.Notes.route) {
FragmentContainer { FragmentContainer(R.id.notesFragmentContainer) {
NotesFragment() NotesFragment()
} }
} }
composable(KiwixDestination.Intro.route) { composable(KiwixDestination.Intro.route) {
FragmentContainer { FragmentContainer(R.id.introFragmentContainer) {
IntroFragment() IntroFragment()
} }
} }
composable(KiwixDestination.History.route) { composable(KiwixDestination.History.route) {
FragmentContainer { FragmentContainer(R.id.historyFragmentContainer) {
HistoryFragment() HistoryFragment()
} }
} }
composable(KiwixDestination.Language.route) { composable(KiwixDestination.Language.route) {
FragmentContainer { FragmentContainer(R.id.languageFragmentContainer) {
LanguageFragment() LanguageFragment()
} }
} }
@ -186,17 +186,17 @@ fun KiwixNavGraph(
KiwixDestination.ZimHost.route, KiwixDestination.ZimHost.route,
deepLinks = listOf(navDeepLink { uriPattern = ZIM_HOST_NAV_DEEP_LINK }) deepLinks = listOf(navDeepLink { uriPattern = ZIM_HOST_NAV_DEEP_LINK })
) { ) {
FragmentContainer { FragmentContainer(R.id.zimHostFragmentContainer) {
ZimHostFragment() ZimHostFragment()
} }
} }
composable(KiwixDestination.Help.route) { composable(KiwixDestination.Help.route) {
FragmentContainer { FragmentContainer(R.id.helpFragmentContainer) {
KiwixHelpFragment() KiwixHelpFragment()
} }
} }
composable(KiwixDestination.Settings.route) { composable(KiwixDestination.Settings.route) {
FragmentContainer { FragmentContainer(R.id.settingsFragmentContainer) {
KiwixSettingsFragment() KiwixSettingsFragment()
} }
} }
@ -221,7 +221,7 @@ fun KiwixNavGraph(
val isOpenedFromTabSwitcher = val isOpenedFromTabSwitcher =
backStackEntry.arguments?.getBoolean(TAG_FROM_TAB_SWITCHER) ?: false backStackEntry.arguments?.getBoolean(TAG_FROM_TAB_SWITCHER) ?: false
val isVoice = backStackEntry.arguments?.getBoolean(EXTRA_IS_WIDGET_VOICE) ?: false val isVoice = backStackEntry.arguments?.getBoolean(EXTRA_IS_WIDGET_VOICE) ?: false
FragmentContainer { FragmentContainer(R.id.searchFragmentContainer) {
SearchFragment().apply { SearchFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
putString(NAV_ARG_SEARCH_STRING, searchString) putString(NAV_ARG_SEARCH_STRING, searchString)
@ -247,7 +247,7 @@ fun KiwixNavGraph(
Uri.decode(it).toUri() Uri.decode(it).toUri()
} }
FragmentContainer { FragmentContainer(R.id.localFileTransferFragmentContainer) {
LocalFileTransferFragment().apply { LocalFileTransferFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
putParcelableArray( putParcelableArray(
@ -264,24 +264,23 @@ fun KiwixNavGraph(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun FragmentContainer( fun FragmentContainer(
fragmentId: Int,
fragmentProvider: () -> Fragment fragmentProvider: () -> Fragment
) { ) {
val context = LocalContext.current val context = LocalContext.current
val fragmentManager = remember { val fragmentManager = remember {
(context as AppCompatActivity).supportFragmentManager (context as AppCompatActivity).supportFragmentManager
} }
val viewId = remember { View.generateViewId() } val fragment = remember { fragmentProvider() }
AndroidView( AndroidView(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
factory = { ctx -> factory = { ctx ->
FragmentContainerView(ctx).apply { FragmentContainerView(ctx).apply {
id = viewId id = fragmentId
doOnAttach { doOnAttach {
fragmentManager.commit { fragmentManager.commit {
if (fragmentManager.findFragmentById(viewId) == null) { replace(fragmentId, fragment)
add(viewId, fragmentProvider())
}
} }
} }
} }

View File

@ -89,8 +89,12 @@ const val HELP_FRAGMENT = "helpFragment"
const val SETTINGS_FRAGMENT = "settingsFragment" const val SETTINGS_FRAGMENT = "settingsFragment"
const val SEARCH_FRAGMENT = "searchFragment" const val SEARCH_FRAGMENT = "searchFragment"
const val LOCAL_FILE_TRANSFER_FRAGMENT = "localFileTransferFragment" const val LOCAL_FILE_TRANSFER_FRAGMENT = "localFileTransferFragment"
// Zim host deep link for opening the ZimHost fragment from notification.
const val ZIM_HOST_DEEP_LINK_SCHEME = "kiwix" const val ZIM_HOST_DEEP_LINK_SCHEME = "kiwix"
const val ZIM_HOST_NAV_DEEP_LINK = "$ZIM_HOST_DEEP_LINK_SCHEME://zimhost" const val ZIM_HOST_NAV_DEEP_LINK = "$ZIM_HOST_DEEP_LINK_SCHEME://zimhost"
// Left drawer items testing tag.
const val LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG = "leftDrawerBookmarkItemTestingTag" const val LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG = "leftDrawerBookmarkItemTestingTag"
const val LEFT_DRAWER_HISTORY_ITEM_TESTING_TAG = "leftDrawerHistoryItemTestingTag" const val LEFT_DRAWER_HISTORY_ITEM_TESTING_TAG = "leftDrawerHistoryItemTestingTag"
const val LEFT_DRAWER_NOTES_ITEM_TESTING_TAG = "leftDrawerNotesItemTestingTag" const val LEFT_DRAWER_NOTES_ITEM_TESTING_TAG = "leftDrawerNotesItemTestingTag"

View File

@ -35,6 +35,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.ui.components.ONE import org.kiwix.kiwixmobile.core.ui.components.ONE
import org.kiwix.kiwixmobile.core.ui.models.IconItem import org.kiwix.kiwixmobile.core.ui.models.IconItem
@ -105,5 +107,6 @@ private fun DrawerMenuItemView(item: DrawerMenuItem) {
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { item.onClick.invoke() } .clickable { item.onClick.invoke() }
.semantics { testTag = item.testingTag }
) )
} }

View File

@ -167,6 +167,14 @@ const val TAB_SWITCHER_VIEW_TESTING_TAG = "tabSwitcherViewTestingTag"
const val READER_SCREEN_TESTING_TAG = "readerScreenTestingTag" const val READER_SCREEN_TESTING_TAG = "readerScreenTestingTag"
const val CLOSE_ALL_TABS_BUTTON_TESTING_TAG = "closeAllTabsButtonTestingTag" const val CLOSE_ALL_TABS_BUTTON_TESTING_TAG = "closeAllTabsButtonTestingTag"
const val TAB_TITLE_TESTING_TAG = "tabTitleTestingTag" const val TAB_TITLE_TESTING_TAG = "tabTitleTestingTag"
const val READER_BOTTOM_BAR_BOOKMARK_BUTTON_TESTING_TAG = "readerBottomBarBookmarkButtonTestingTag"
const val READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG =
"readerBottomBarPreviousScreenButtonTestingTag"
const val READER_BOTTOM_BAR_NEXT_SCREEN_BUTTON_TESTING_TAG =
"readerBottomBarNextScreenButtonTestingTag"
const val READER_BOTTOM_BAR_HOME_BUTTON_TESTING_TAG = "readerBottomBarHomeButtonTestingTag"
const val READER_BOTTOM_BAR_TABLE_CONTENT_BUTTON_TESTING_TAG =
"readerBottomBarTableContentButtonTestingTag"
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Suppress("ComposableLambdaParameterNaming", "LongMethod") @Suppress("ComposableLambdaParameterNaming", "LongMethod")
@ -666,7 +674,8 @@ private fun BottomAppBarOfReaderScreen(
onClick = bookmarkButtonItem.first, onClick = bookmarkButtonItem.first,
onLongClick = bookmarkButtonItem.second, onLongClick = bookmarkButtonItem.second,
buttonIcon = bookmarkButtonItem.third, buttonIcon = bookmarkButtonItem.third,
contentDescription = stringResource(R.string.bookmarks) contentDescription = stringResource(R.string.bookmarks),
testingTag = READER_BOTTOM_BAR_BOOKMARK_BUTTON_TESTING_TAG
) )
// Back Icon(for going to previous page) // Back Icon(for going to previous page)
BottomAppBarButtonIcon( BottomAppBarButtonIcon(
@ -674,13 +683,15 @@ private fun BottomAppBarOfReaderScreen(
onLongClick = previousPageButtonItem.second, onLongClick = previousPageButtonItem.second,
buttonIcon = Drawable(R.drawable.ic_keyboard_arrow_left_24dp), buttonIcon = Drawable(R.drawable.ic_keyboard_arrow_left_24dp),
shouldEnable = previousPageButtonItem.third, shouldEnable = previousPageButtonItem.third,
contentDescription = stringResource(R.string.go_to_previous_page) contentDescription = stringResource(R.string.go_to_previous_page),
testingTag = READER_BOTTOM_BAR_PREVIOUS_SCREEN_BUTTON_TESTING_TAG
) )
// Home Icon(to open the home page of ZIM file) // Home Icon(to open the home page of ZIM file)
BottomAppBarButtonIcon( BottomAppBarButtonIcon(
onClick = onHomeButtonClick, onClick = onHomeButtonClick,
buttonIcon = Drawable(R.drawable.action_home), buttonIcon = Drawable(R.drawable.action_home),
contentDescription = stringResource(R.string.menu_home) contentDescription = stringResource(R.string.menu_home),
testingTag = READER_BOTTOM_BAR_HOME_BUTTON_TESTING_TAG
) )
// Forward Icon(for going to next page) // Forward Icon(for going to next page)
BottomAppBarButtonIcon( BottomAppBarButtonIcon(
@ -688,14 +699,16 @@ private fun BottomAppBarOfReaderScreen(
onLongClick = nextPageButtonItem.second, onLongClick = nextPageButtonItem.second,
buttonIcon = Drawable(R.drawable.ic_keyboard_arrow_right_24dp), buttonIcon = Drawable(R.drawable.ic_keyboard_arrow_right_24dp),
shouldEnable = nextPageButtonItem.third, shouldEnable = nextPageButtonItem.third,
contentDescription = stringResource(R.string.go_to_next_page) contentDescription = stringResource(R.string.go_to_next_page),
testingTag = READER_BOTTOM_BAR_NEXT_SCREEN_BUTTON_TESTING_TAG
) )
// Toggle Icon(to open the table of content in right side bar) // Toggle Icon(to open the table of content in right side bar)
BottomAppBarButtonIcon( BottomAppBarButtonIcon(
shouldEnable = tocButtonItem.first, shouldEnable = tocButtonItem.first,
onClick = tocButtonItem.second, onClick = tocButtonItem.second,
buttonIcon = Drawable(R.drawable.ic_toc_24dp), buttonIcon = Drawable(R.drawable.ic_toc_24dp),
contentDescription = stringResource(R.string.table_of_contents) contentDescription = stringResource(R.string.table_of_contents),
testingTag = READER_BOTTOM_BAR_TABLE_CONTENT_BUTTON_TESTING_TAG
) )
} }
} }
@ -707,7 +720,8 @@ private fun BottomAppBarButtonIcon(
onLongClick: (() -> Unit)? = null, onLongClick: (() -> Unit)? = null,
buttonIcon: IconItem, buttonIcon: IconItem,
shouldEnable: Boolean = true, shouldEnable: Boolean = true,
contentDescription: String contentDescription: String,
testingTag: String
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier
@ -717,7 +731,7 @@ private fun BottomAppBarButtonIcon(
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
enabled = shouldEnable enabled = shouldEnable
), ).testTag(testingTag),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Icon( Icon(

View File

@ -1,8 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<item name="tabsAdapterContentImageView" type="id" /> <item type="id" name="readerFragmentContainer" />
<item name="tabsAdapterCloseImageView" type="id" /> <item type="id" name="localLibraryFragmentContainer" />
<item name="tabsAdapterCardView" type="id" /> <item type="id" name="bookmarksFragmentContainer" />
<item name="tabsAdapterTextView" type="id" /> <item type="id" name="downloadFragmentContainer" />
<item name="nav_host_fragment" type="id" /> <item type="id" name="notesFragmentContainer" />
<item type="id" name="introFragmentContainer" />
<item type="id" name="historyFragmentContainer" />
<item type="id" name="languageFragmentContainer" />
<item type="id" name="zimHostFragmentContainer" />
<item type="id" name="helpFragmentContainer" />
<item type="id" name="settingsFragmentContainer" />
<item type="id" name="searchFragmentContainer" />
<item type="id" name="localFileTransferFragmentContainer" />
</resources> </resources>

View File

@ -24,7 +24,6 @@ import android.content.res.AssetFileDescriptor
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.core.content.edit import androidx.core.content.edit
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.NavHostFragment
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.pressBack import androidx.test.espresso.Espresso.pressBack
@ -48,6 +47,7 @@ import org.kiwix.kiwixmobile.core.di.modules.CALL_TIMEOUT
import org.kiwix.kiwixmobile.core.di.modules.CONNECTION_TIMEOUT import org.kiwix.kiwixmobile.core.di.modules.CONNECTION_TIMEOUT
import org.kiwix.kiwixmobile.core.di.modules.READ_TIMEOUT import org.kiwix.kiwixmobile.core.di.modules.READ_TIMEOUT
import org.kiwix.kiwixmobile.core.di.modules.USER_AGENT import org.kiwix.kiwixmobile.core.di.modules.USER_AGENT
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.search.SearchFragment import org.kiwix.kiwixmobile.core.search.SearchFragment
import org.kiwix.kiwixmobile.core.search.viewmodel.Action import org.kiwix.kiwixmobile.core.search.viewmodel.Action
@ -236,34 +236,31 @@ class SearchFragmentTestForCustomApp {
openSearchWithQuery(searchTerms[0]) openSearchWithQuery(searchTerms[0])
// wait for searchFragment become visible on screen. // wait for searchFragment become visible on screen.
delay(2000) delay(2000)
val navHostFragment: NavHostFragment = val searchFragment = customMainActivity.supportFragmentManager.fragments
customMainActivity.supportFragmentManager .filterIsInstance<SearchFragment>()
.findFragmentById( .firstOrNull()
customMainActivity.activityCustomMainBinding.customNavController.id
) as NavHostFragment
val searchFragment = navHostFragment.childFragmentManager.fragments[0] as SearchFragment
for (i in 1..100) { for (i in 1..100) {
// This will execute the render method 100 times frequently. // This will execute the render method 100 times frequently.
val searchTerm = searchTerms[i % searchTerms.size] val searchTerm = searchTerms[i % searchTerms.size]
searchFragment.searchViewModel.actions.trySend(Action.Filter(searchTerm)).isSuccess searchFragment?.searchViewModel?.actions?.trySend(Action.Filter(searchTerm))?.isSuccess
} }
for (i in 1..100) { for (i in 1..100) {
// this will execute the render method 100 times with 100MS delay. // this will execute the render method 100 times with 100MS delay.
delay(100) delay(100)
val searchTerm = searchTerms[i % searchTerms.size] val searchTerm = searchTerms[i % searchTerms.size]
searchFragment.searchViewModel.actions.trySend(Action.Filter(searchTerm)).isSuccess searchFragment?.searchViewModel?.actions?.trySend(Action.Filter(searchTerm))?.isSuccess
} }
for (i in 1..100) { for (i in 1..100) {
// this will execute the render method 100 times with 200MS delay. // this will execute the render method 100 times with 200MS delay.
delay(200) delay(200)
val searchTerm = searchTerms[i % searchTerms.size] val searchTerm = searchTerms[i % searchTerms.size]
searchFragment.searchViewModel.actions.trySend(Action.Filter(searchTerm)).isSuccess searchFragment?.searchViewModel?.actions?.trySend(Action.Filter(searchTerm))?.isSuccess
} }
for (i in 1..100) { for (i in 1..100) {
// this will execute the render method 100 times with 200MS delay. // this will execute the render method 100 times with 200MS delay.
delay(300) delay(300)
val searchTerm = searchTerms[i % searchTerms.size] val searchTerm = searchTerms[i % searchTerms.size]
searchFragment.searchViewModel.actions.trySend(Action.Filter(searchTerm)).isSuccess searchFragment?.searchViewModel?.actions?.trySend(Action.Filter(searchTerm))?.isSuccess
} }
} }
@ -293,12 +290,12 @@ class SearchFragmentTestForCustomApp {
openZimFileInReader(zimFile = downloadingZimFile) openZimFileInReader(zimFile = downloadingZimFile)
search { search {
// click on home button to load the main page of ZIM file. // click on home button to load the main page of ZIM file.
clickOnHomeButton(composeTestRule, customMainActivity) clickOnHomeButton(composeTestRule)
// click on an article to load the other page. // click on an article to load the other page.
clickOnAFoolForYouArticle() clickOnAFoolForYouArticle()
assertAFoolForYouArticleLoaded() assertAFoolForYouArticleLoaded()
// open note screen. // open note screen.
openNoteFragment() openNoteFragment(customMainActivity as CoreMainActivity, composeTestRule)
pressBack() pressBack()
// after came back check the previously loaded article is still showing or not. // after came back check the previously loaded article is still showing or not.
assertAFoolForYouArticleLoaded() assertAFoolForYouArticleLoaded()
@ -316,21 +313,18 @@ class SearchFragmentTestForCustomApp {
zimFile: File? = null zimFile: File? = null
) { ) {
UiThreadStatement.runOnUiThread { UiThreadStatement.runOnUiThread {
val navHostFragment: NavHostFragment =
customMainActivity.supportFragmentManager
.findFragmentById(
customMainActivity.activityCustomMainBinding.customNavController.id
) as NavHostFragment
val customReaderFragment = val customReaderFragment =
navHostFragment.childFragmentManager.fragments[0] as CustomReaderFragment customMainActivity.supportFragmentManager.fragments
.filterIsInstance<CustomReaderFragment>()
.firstOrNull()
runBlocking { runBlocking {
assetFileDescriptor?.let { assetFileDescriptor?.let {
customReaderFragment.openZimFile( customReaderFragment?.openZimFile(
ZimReaderSource(assetFileDescriptorList = listOf(assetFileDescriptor)), ZimReaderSource(assetFileDescriptorList = listOf(assetFileDescriptor)),
true true
) )
} ?: run { } ?: run {
customReaderFragment.openZimFile( customReaderFragment?.openZimFile(
ZimReaderSource(zimFile), ZimReaderSource(zimFile),
true true
) )

View File

@ -21,17 +21,13 @@ package org.kiwix.kiwixmobile.custom.search
import android.view.KeyEvent import android.view.KeyEvent
import androidx.compose.ui.test.assert import androidx.compose.ui.test.assert
import androidx.compose.ui.test.hasText import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.onAllNodesWithTag import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithContentDescription
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.compose.ui.test.performTextClearance import androidx.compose.ui.test.performTextClearance
import androidx.compose.ui.test.performTextInput import androidx.compose.ui.test.performTextInput
import androidx.core.view.GravityCompat
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.espresso.web.assertion.WebViewAssertions.webMatches import androidx.test.espresso.web.assertion.WebViewAssertions.webMatches
import androidx.test.espresso.web.sugar.Web import androidx.test.espresso.web.sugar.Web
import androidx.test.espresso.web.sugar.Web.onWebView import androidx.test.espresso.web.sugar.Web.onWebView
@ -41,17 +37,17 @@ import androidx.test.espresso.web.webdriver.DriverAtoms.getText
import androidx.test.espresso.web.webdriver.DriverAtoms.webClick import androidx.test.espresso.web.webdriver.DriverAtoms.webClick
import androidx.test.espresso.web.webdriver.Locator import androidx.test.espresso.web.webdriver.Locator
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import com.adevinta.android.barista.interaction.BaristaDrawerInteractions.openDrawerWithGravity
import com.adevinta.android.barista.interaction.BaristaSleepInteractions import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.hamcrest.CoreMatchers.containsString import org.hamcrest.CoreMatchers.containsString
import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.LEFT_DRAWER_NOTES_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.main.reader.READER_BOTTOM_BAR_HOME_BUTTON_TESTING_TAG
import org.kiwix.kiwixmobile.core.page.SEARCH_ICON_TESTING_TAG import org.kiwix.kiwixmobile.core.page.SEARCH_ICON_TESTING_TAG
import org.kiwix.kiwixmobile.core.search.SEARCH_FIELD_TESTING_TAG import org.kiwix.kiwixmobile.core.search.SEARCH_FIELD_TESTING_TAG
import org.kiwix.kiwixmobile.core.search.SEARCH_ITEM_TESTING_TAG import org.kiwix.kiwixmobile.core.search.SEARCH_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.custom.R.id
import org.kiwix.kiwixmobile.custom.main.CustomMainActivity
import org.kiwix.kiwixmobile.custom.testutils.TestUtils import org.kiwix.kiwixmobile.custom.testutils.TestUtils
import org.kiwix.kiwixmobile.custom.testutils.TestUtils.TEST_PAUSE_MS import org.kiwix.kiwixmobile.custom.testutils.TestUtils.TEST_PAUSE_MS
import org.kiwix.kiwixmobile.custom.testutils.TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST
import org.kiwix.kiwixmobile.custom.testutils.TestUtils.testFlakyView import org.kiwix.kiwixmobile.custom.testutils.TestUtils.testFlakyView
import org.kiwix.kiwixmobile.custom.testutils.TestUtils.waitUntilTimeout import org.kiwix.kiwixmobile.custom.testutils.TestUtils.waitUntilTimeout
@ -146,12 +142,13 @@ class SearchRobot {
}) })
} }
fun clickOnHomeButton( fun clickOnHomeButton(composeTestRule: ComposeContentTestRule) {
composeTestRule: ComposeContentTestRule,
customMainActivity: CustomMainActivity
) {
composeTestRule.apply { composeTestRule.apply {
onNodeWithContentDescription(customMainActivity.getString(R.string.menu_home)) waitForIdle()
waitUntil(TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong()) {
onNodeWithTag(READER_BOTTOM_BAR_HOME_BUTTON_TESTING_TAG).isDisplayed()
}
onNodeWithTag(READER_BOTTOM_BAR_HOME_BUTTON_TESTING_TAG)
.performClick() .performClick()
} }
} }
@ -182,9 +179,16 @@ class SearchRobot {
}) })
} }
fun openNoteFragment() { fun openNoteFragment(
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong()) coreMainActivity: CoreMainActivity,
openDrawerWithGravity(id.custom_drawer_container, GravityCompat.START) composeTestRule: ComposeContentTestRule
testFlakyView({ onView(withText(R.string.pref_notes)).perform(click()) }) ) {
coreMainActivity.openNavigationDrawer()
testFlakyView({
composeTestRule.apply {
waitUntilTimeout()
onNodeWithTag(LEFT_DRAWER_NOTES_ITEM_TESTING_TAG).performClick()
}
})
} }
} }

View File

@ -33,7 +33,7 @@ import java.util.TimerTask
object TestUtils { object TestUtils {
private const val TAG = "TESTUTILS" private const val TAG = "TESTUTILS"
const val TEST_PAUSE_MS_FOR_SEARCH_TEST = 1000 const val TEST_PAUSE_MS_FOR_SEARCH_TEST = 10000
const val TEST_PAUSE_MS = 3000 const val TEST_PAUSE_MS = 3000
@JvmStatic @JvmStatic

View File

@ -20,7 +20,6 @@ package org.kiwix.kiwixmobile.custom.main
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
@ -38,6 +37,7 @@ import androidx.navigation.NavType
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.navArgument import androidx.navigation.navArgument
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.main.BOOKMARK_FRAGMENT import org.kiwix.kiwixmobile.core.main.BOOKMARK_FRAGMENT
import org.kiwix.kiwixmobile.core.main.DOWNLOAD_FRAGMENT import org.kiwix.kiwixmobile.core.main.DOWNLOAD_FRAGMENT
import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING
@ -95,7 +95,7 @@ fun CustomNavGraph(
val pageUrl = backStackEntry.arguments?.getString(PAGE_URL_KEY).orEmpty() val pageUrl = backStackEntry.arguments?.getString(PAGE_URL_KEY).orEmpty()
val shouldOpenInNewTab = backStackEntry.arguments?.getBoolean(SHOULD_OPEN_IN_NEW_TAB) ?: false val shouldOpenInNewTab = backStackEntry.arguments?.getBoolean(SHOULD_OPEN_IN_NEW_TAB) ?: false
FragmentContainer { FragmentContainer(R.id.readerFragmentContainer) {
CustomReaderFragment().apply { CustomReaderFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
putString(FIND_IN_PAGE_SEARCH_STRING, findInPageSearchString) putString(FIND_IN_PAGE_SEARCH_STRING, findInPageSearchString)
@ -106,32 +106,32 @@ fun CustomNavGraph(
} }
} }
composable(CustomDestination.History.route) { composable(CustomDestination.History.route) {
FragmentContainer { FragmentContainer(R.id.historyFragmentContainer) {
HistoryFragment() HistoryFragment()
} }
} }
composable(CustomDestination.Notes.route) { composable(CustomDestination.Notes.route) {
FragmentContainer { FragmentContainer(R.id.notesFragmentContainer) {
NotesFragment() NotesFragment()
} }
} }
composable(CustomDestination.Bookmarks.route) { composable(CustomDestination.Bookmarks.route) {
FragmentContainer { FragmentContainer(R.id.bookmarksFragmentContainer) {
BookmarksFragment() BookmarksFragment()
} }
} }
composable(CustomDestination.Help.route) { composable(CustomDestination.Help.route) {
FragmentContainer { FragmentContainer(R.id.helpFragmentContainer) {
CustomHelpFragment() CustomHelpFragment()
} }
} }
composable(CustomDestination.Settings.route) { composable(CustomDestination.Settings.route) {
FragmentContainer { FragmentContainer(R.id.settingsFragmentContainer) {
CustomSettingsFragment() CustomSettingsFragment()
} }
} }
composable(CustomDestination.Downloads.route) { composable(CustomDestination.Downloads.route) {
FragmentContainer { FragmentContainer(R.id.downloadFragmentContainer) {
CustomDownloadFragment() CustomDownloadFragment()
} }
} }
@ -156,7 +156,7 @@ fun CustomNavGraph(
val isOpenedFromTabSwitcher = val isOpenedFromTabSwitcher =
backStackEntry.arguments?.getBoolean(TAG_FROM_TAB_SWITCHER) ?: false backStackEntry.arguments?.getBoolean(TAG_FROM_TAB_SWITCHER) ?: false
val isVoice = backStackEntry.arguments?.getBoolean(EXTRA_IS_WIDGET_VOICE) ?: false val isVoice = backStackEntry.arguments?.getBoolean(EXTRA_IS_WIDGET_VOICE) ?: false
FragmentContainer { FragmentContainer(R.id.searchFragmentContainer) {
SearchFragment().apply { SearchFragment().apply {
arguments = Bundle().apply { arguments = Bundle().apply {
putString(NAV_ARG_SEARCH_STRING, searchString) putString(NAV_ARG_SEARCH_STRING, searchString)
@ -172,24 +172,23 @@ fun CustomNavGraph(
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun FragmentContainer( fun FragmentContainer(
fragmentId: Int,
fragmentProvider: () -> Fragment fragmentProvider: () -> Fragment
) { ) {
val context = LocalContext.current val context = LocalContext.current
val fragmentManager = remember { val fragmentManager = remember {
(context as AppCompatActivity).supportFragmentManager (context as AppCompatActivity).supportFragmentManager
} }
val viewId = remember { View.generateViewId() } val fragment = remember { fragmentProvider() }
AndroidView( AndroidView(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
factory = { ctx -> factory = { ctx ->
FragmentContainerView(ctx).apply { FragmentContainerView(ctx).apply {
id = viewId id = fragmentId
doOnAttach { doOnAttach {
fragmentManager.commit { fragmentManager.commit {
if (fragmentManager.findFragmentById(viewId) == null) { replace(fragmentId, fragment)
add(viewId, fragmentProvider())
}
} }
} }
} }