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

View File

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

View File

@ -19,6 +19,8 @@
package org.kiwix.kiwixmobile.main
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.net.toUri
import androidx.lifecycle.Lifecycle
@ -27,7 +29,6 @@ import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
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.kiwix.kiwixmobile.BaseActivityTest
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.SharedPreferenceUtil
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.nav.destination.reader.KiwixReaderFragment
import org.kiwix.kiwixmobile.settings.settingsRobo
import org.kiwix.kiwixmobile.testutils.RetryRule
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 java.io.File
import java.io.FileOutputStream
@ -85,6 +90,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
onActivity {
kiwixMainActivity = it
LanguageUtils.handleLocaleChange(
it,
"en",
@ -111,6 +117,7 @@ class DarkModeViewPainterTest : BaseActivityTest() {
@Test
fun testDarkMode() {
composeTestRule.waitForIdle()
toggleDarkMode(true)
openZimFileInReader()
verifyDarkMode(true)
@ -122,13 +129,19 @@ class DarkModeViewPainterTest : BaseActivityTest() {
private fun openZimFileInReader() {
activityScenario.onActivity {
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()
}
private fun toggleDarkMode(enable: Boolean) {
darkModeViewPainter { openSettings(kiwixMainActivity as CoreMainActivity) }
darkModeViewPainter { openSettings(kiwixMainActivity as CoreMainActivity, composeTestRule) }
settingsRobo { clickNightModePreference(composeTestRule) }
darkModeViewPainter {
if (enable) {
@ -136,33 +149,33 @@ class DarkModeViewPainterTest : BaseActivityTest() {
} else {
enableTheLightMode(composeTestRule)
}
pressBack()
}
}
private fun verifyDarkMode(isEnabled: Boolean) {
// TODO refactor this with compose based navController.
// UiThreadStatement.runOnUiThread {
// val navHostFragment: NavHostFragment =
// kiwixMainActivity.supportFragmentManager
// .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
// val kiwixReaderFragment =
// navHostFragment.childFragmentManager.fragments[0] as KiwixReaderFragment
// val currentWebView = kiwixReaderFragment.getCurrentWebView()
// currentWebView?.let {
// darkModeViewPainter {
// if (isEnabled) {
// 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"
// )
// }
// }
var kiwixReaderFragment: KiwixReaderFragment? = null
composeTestRule.waitForIdle()
composeTestRule.waitUntil(TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong()) {
kiwixReaderFragment =
kiwixMainActivity.supportFragmentManager.fragments
.filterIsInstance<KiwixReaderFragment>()
.firstOrNull()
kiwixReaderFragment?.getCurrentWebView() != null
}
val currentWebView = kiwixReaderFragment?.getCurrentWebView()
currentWebView?.let {
darkModeViewPainter {
if (isEnabled) {
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"
)
}
}
private fun loadZimFileInReader() {
@ -185,7 +198,10 @@ class DarkModeViewPainterTest : BaseActivityTest() {
}
}
}
UiThreadStatement.runOnUiThread {
activityScenario.onActivity {
kiwixMainActivity = it
}
composeTestRule.runOnIdle {
val navOptions = NavOptions.Builder()
.setPopUpTo(KiwixDestination.Reader.route, false)
.build()

View File

@ -20,15 +20,16 @@ package org.kiwix.kiwixmobile.main
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.onNodeWithTag
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 com.adevinta.android.barista.interaction.BaristaSleepInteractions
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.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.help
import org.kiwix.kiwixmobile.nav.destination.library.LibraryRobot
@ -99,47 +100,79 @@ class TopLevelDestinationRobot : BaseRobot() {
fun clickBookmarksOnNavDrawer(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: BookmarksRobot.() -> Unit
) {
inNavDrawer(coreMainActivity = coreMainActivity) {
testFlakyView({ onView(withText(string.bookmarks)).perform(click()) })
testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_BOOKMARK_ITEM_TESTING_TAG).performClick()
})
bookmarks(func)
pressBack()
}
}
fun clickHistoryOnSideNav(coreMainActivity: CoreMainActivity, func: HistoryRobot.() -> Unit) {
fun clickHistoryOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: HistoryRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) {
clickOn(TextId(string.history))
testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_HISTORY_ITEM_TESTING_TAG).performClick()
})
history(func)
pressBack()
}
}
fun clickHostBooksOnSideNav(coreMainActivity: CoreMainActivity, func: ZimHostRobot.() -> Unit) {
fun clickHostBooksOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: ZimHostRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_wifi_hotspot))
testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_ZIM_HOST_ITEM_TESTING_TAG).performClick()
})
zimHost(func)
}
}
fun clickSettingsOnSideNav(coreMainActivity: CoreMainActivity, func: SettingsRobot.() -> Unit) {
fun clickSettingsOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: SettingsRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_settings))
testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_SETTINGS_ITEM_TESTING_TAG).performClick()
})
settingsRobo(func)
}
}
fun clickHelpOnSideNav(coreMainActivity: CoreMainActivity, func: HelpRobot.() -> Unit) {
fun clickHelpOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
func: HelpRobot.() -> Unit
) {
inNavDrawer(coreMainActivity) {
clickOn(TextId(string.menu_help))
testFlakyView({
composeTestRule.onNodeWithTag(LEFT_DRAWER_HELP_ITEM_TESTING_TAG).performClick()
})
help(func)
}
}
fun clickSupportKiwixOnSideNav(coreMainActivity: CoreMainActivity) {
fun clickSupportKiwixOnSideNav(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule,
) {
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)
}
}
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity) {
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookMarksDisplayed(composeTestRule)
clickOnTrashIcon(composeTestRule)
assertDeleteBookmarksDialogDisplayed(composeTestRule)
}
clickHistoryOnSideNav(kiwixMainActivity as CoreMainActivity) {
clickHistoryOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertHistoryDisplayed(composeTestRule)
clickOnTrashIcon(composeTestRule)
assertDeleteHistoryDialogDisplayed(composeTestRule)
}
clickHostBooksOnSideNav(kiwixMainActivity as CoreMainActivity) {
clickHostBooksOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertMenuWifiHotspotDisplayed(composeTestRule)
}
clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity) {
clickSettingsOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertMenuSettingsDisplayed(composeTestRule)
}
clickHelpOnSideNav(kiwixMainActivity as CoreMainActivity) {
clickHelpOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertToolbarDisplayed(composeTestRule)
}
clickSupportKiwixOnSideNav(kiwixMainActivity as CoreMainActivity)
clickSupportKiwixOnSideNav(kiwixMainActivity as CoreMainActivity, composeTestRule)
pressBack()
}
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.ComposeTestRule
import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToNode
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 com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.core.R
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.NO_ITEMS_TEXT_TESTING_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.testutils.TestUtils
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.waitUntilTimeout
import org.kiwix.kiwixmobile.utils.StandardActions.openDrawer
@ -104,8 +103,11 @@ class BookmarksRobot : BaseRobot() {
fun clickOnSaveBookmarkImage(composeTestRule: ComposeContentTestRule) {
composeTestRule.apply {
waitUntilTimeout()
onNodeWithContentDescription(context.getString(R.string.bookmarks))
waitForIdle()
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()
}
}
@ -115,9 +117,13 @@ class BookmarksRobot : BaseRobot() {
timeout: Long = TEST_PAUSE_MS.toLong()
) {
composeTestRule.apply {
waitForIdle()
// wait for disappearing the snack-bar after removing the bookmark
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 {
longClick()
}
@ -144,10 +150,16 @@ class BookmarksRobot : BaseRobot() {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong())
}
fun openBookmarkScreen(coreMainActivity: CoreMainActivity) {
fun openBookmarkScreen(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule
) {
testFlakyView({
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.checks.SpeakableTextPresentCheck
import com.google.android.apps.common.testing.accessibility.framework.checks.TouchTargetSizeCheck
import kotlinx.coroutines.runBlocking
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.anyOf
import org.junit.Before
@ -40,6 +41,8 @@ import org.junit.Rule
import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest
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.SharedPreferenceUtil
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.waitUntilTimeout
import org.kiwix.kiwixmobile.ui.KiwixDestination
import org.kiwix.libkiwix.Book
import org.kiwix.libkiwix.Bookmark
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
@ -134,7 +139,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
pressBack()
// Test saving bookmark
clickOnSaveBookmarkImage(composeTestRule)
openBookmarkScreen(kiwixMainActivity as CoreMainActivity)
openBookmarkScreen(kiwixMainActivity as CoreMainActivity, composeTestRule)
assertBookmarkSaved(composeTestRule)
pressBack()
// Test removing bookmark
@ -154,7 +159,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
kiwixMainActivity = it
}
topLevel {
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity) {
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookmarkSaved(composeTestRule)
}
}
@ -184,41 +189,39 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
pressBack()
}
composeTestRule.waitUntilTimeout()
// TODO refactor this wih compose based navController.
// val navHostFragment: NavHostFragment =
// kiwixMainActivity.supportFragmentManager
// .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
// val coreReaderFragment = navHostFragment.childFragmentManager.fragments[0] as CoreReaderFragment
// val libKiwixBook =
// Book().apply {
// update(coreReaderFragment.zimReaderContainer?.zimFileReader?.jniKiwixReader)
// }
// val bookmarkList = arrayListOf<LibkiwixBookmarkItem>()
// for (i in 1..500) {
// val bookmark =
// Bookmark().apply {
// bookId = coreReaderFragment.zimReaderContainer?.zimFileReader?.id
// title = "bookmark$i"
// url = "http://kiwix.org/demoBookmark$i"
// bookTitle = libKiwixBook.title
// }
// val libkiwixItem =
// LibkiwixBookmarkItem(
// bookmark,
// coreReaderFragment.zimReaderContainer?.zimFileReader?.favicon,
// coreReaderFragment.zimReaderContainer?.zimFileReader?.zimReaderSource
// )
// runBlocking {
// coreReaderFragment.libkiwixBookmarks?.saveBookmark(libkiwixItem).also {
// bookmarkList.add(libkiwixItem)
// }
// }
// }
// bookmarks {
// // test all the saved bookmarks are showing on the bookmarks screen
// openBookmarkScreen()
// testAllBookmarkShowing(bookmarkList, composeTestRule)
// }
val coreReaderFragment = kiwixMainActivity.supportFragmentManager.fragments
.filterIsInstance<CoreReaderFragment>()
.firstOrNull()
val libKiwixBook =
Book().apply {
update(coreReaderFragment?.zimReaderContainer?.zimFileReader?.jniKiwixReader)
}
val bookmarkList = arrayListOf<LibkiwixBookmarkItem>()
for (i in 1..500) {
val bookmark =
Bookmark().apply {
bookId = coreReaderFragment?.zimReaderContainer?.zimFileReader?.id
title = "bookmark$i"
url = "http://kiwix.org/demoBookmark$i"
bookTitle = libKiwixBook.title
}
val libkiwixItem =
LibkiwixBookmarkItem(
bookmark,
coreReaderFragment?.zimReaderContainer?.zimFileReader?.favicon,
coreReaderFragment?.zimReaderContainer?.zimFileReader?.zimReaderSource
)
runBlocking {
coreReaderFragment?.libkiwixBookmarks?.saveBookmark(libkiwixItem).also {
bookmarkList.add(libkiwixItem)
}
}
}
bookmarks {
// test all the saved bookmarks are showing on the bookmarks screen
openBookmarkScreen(kiwixMainActivity as CoreMainActivity, composeTestRule)
testAllBookmarkShowing(bookmarkList, composeTestRule)
}
}
private fun getZimFile(): File {

View File

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

View File

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

View File

@ -24,7 +24,6 @@ import androidx.test.espresso.Espresso
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers
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.LEFT_DRAWER_SETTINGS_ITEM_TESTING_TAG
import org.kiwix.kiwixmobile.core.utils.files.Log
@ -43,12 +42,10 @@ object StandardActions {
}
fun openDrawer(coreMainActivity: CoreMainActivity) {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
coreMainActivity.openNavigationDrawer()
}
fun closeDrawer(coreMainActivity: CoreMainActivity) {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
coreMainActivity.closeNavigationDrawer()
}

View File

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

View File

@ -89,8 +89,12 @@ const val HELP_FRAGMENT = "helpFragment"
const val SETTINGS_FRAGMENT = "settingsFragment"
const val SEARCH_FRAGMENT = "searchFragment"
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_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_HISTORY_ITEM_TESTING_TAG = "leftDrawerHistoryItemTestingTag"
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.layout.ContentScale
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.ui.components.ONE
import org.kiwix.kiwixmobile.core.ui.models.IconItem
@ -105,5 +107,6 @@ private fun DrawerMenuItemView(item: DrawerMenuItem) {
modifier = Modifier
.fillMaxWidth()
.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 CLOSE_ALL_TABS_BUTTON_TESTING_TAG = "closeAllTabsButtonTestingTag"
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)
@Suppress("ComposableLambdaParameterNaming", "LongMethod")
@ -666,7 +674,8 @@ private fun BottomAppBarOfReaderScreen(
onClick = bookmarkButtonItem.first,
onLongClick = bookmarkButtonItem.second,
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)
BottomAppBarButtonIcon(
@ -674,13 +683,15 @@ private fun BottomAppBarOfReaderScreen(
onLongClick = previousPageButtonItem.second,
buttonIcon = Drawable(R.drawable.ic_keyboard_arrow_left_24dp),
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)
BottomAppBarButtonIcon(
onClick = onHomeButtonClick,
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)
BottomAppBarButtonIcon(
@ -688,14 +699,16 @@ private fun BottomAppBarOfReaderScreen(
onLongClick = nextPageButtonItem.second,
buttonIcon = Drawable(R.drawable.ic_keyboard_arrow_right_24dp),
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)
BottomAppBarButtonIcon(
shouldEnable = tocButtonItem.first,
onClick = tocButtonItem.second,
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,
buttonIcon: IconItem,
shouldEnable: Boolean = true,
contentDescription: String
contentDescription: String,
testingTag: String
) {
Box(
modifier = Modifier
@ -717,7 +731,7 @@ private fun BottomAppBarButtonIcon(
onClick = onClick,
onLongClick = onLongClick,
enabled = shouldEnable
),
).testTag(testingTag),
contentAlignment = Alignment.Center
) {
Icon(

View File

@ -1,8 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="tabsAdapterContentImageView" type="id" />
<item name="tabsAdapterCloseImageView" type="id" />
<item name="tabsAdapterCardView" type="id" />
<item name="tabsAdapterTextView" type="id" />
<item name="nav_host_fragment" type="id" />
<item type="id" name="readerFragmentContainer" />
<item type="id" name="localLibraryFragmentContainer" />
<item type="id" name="bookmarksFragmentContainer" />
<item type="id" name="downloadFragmentContainer" />
<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>

View File

@ -24,7 +24,6 @@ import android.content.res.AssetFileDescriptor
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.navigation.fragment.NavHostFragment
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
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.READ_TIMEOUT
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.search.SearchFragment
import org.kiwix.kiwixmobile.core.search.viewmodel.Action
@ -236,34 +236,31 @@ class SearchFragmentTestForCustomApp {
openSearchWithQuery(searchTerms[0])
// wait for searchFragment become visible on screen.
delay(2000)
val navHostFragment: NavHostFragment =
customMainActivity.supportFragmentManager
.findFragmentById(
customMainActivity.activityCustomMainBinding.customNavController.id
) as NavHostFragment
val searchFragment = navHostFragment.childFragmentManager.fragments[0] as SearchFragment
val searchFragment = customMainActivity.supportFragmentManager.fragments
.filterIsInstance<SearchFragment>()
.firstOrNull()
for (i in 1..100) {
// This will execute the render method 100 times frequently.
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) {
// this will execute the render method 100 times with 100MS delay.
delay(100)
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) {
// this will execute the render method 100 times with 200MS delay.
delay(200)
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) {
// this will execute the render method 100 times with 200MS delay.
delay(300)
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)
search {
// 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.
clickOnAFoolForYouArticle()
assertAFoolForYouArticleLoaded()
// open note screen.
openNoteFragment()
openNoteFragment(customMainActivity as CoreMainActivity, composeTestRule)
pressBack()
// after came back check the previously loaded article is still showing or not.
assertAFoolForYouArticleLoaded()
@ -316,21 +313,18 @@ class SearchFragmentTestForCustomApp {
zimFile: File? = null
) {
UiThreadStatement.runOnUiThread {
val navHostFragment: NavHostFragment =
customMainActivity.supportFragmentManager
.findFragmentById(
customMainActivity.activityCustomMainBinding.customNavController.id
) as NavHostFragment
val customReaderFragment =
navHostFragment.childFragmentManager.fragments[0] as CustomReaderFragment
customMainActivity.supportFragmentManager.fragments
.filterIsInstance<CustomReaderFragment>()
.firstOrNull()
runBlocking {
assetFileDescriptor?.let {
customReaderFragment.openZimFile(
customReaderFragment?.openZimFile(
ZimReaderSource(assetFileDescriptorList = listOf(assetFileDescriptor)),
true
)
} ?: run {
customReaderFragment.openZimFile(
customReaderFragment?.openZimFile(
ZimReaderSource(zimFile),
true
)

View File

@ -21,17 +21,13 @@ package org.kiwix.kiwixmobile.custom.search
import android.view.KeyEvent
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextClearance
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.sugar.Web
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.Locator
import androidx.test.uiautomator.UiDevice
import com.adevinta.android.barista.interaction.BaristaDrawerInteractions.openDrawerWithGravity
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
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.search.SEARCH_FIELD_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.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.waitUntilTimeout
@ -146,12 +142,13 @@ class SearchRobot {
})
}
fun clickOnHomeButton(
composeTestRule: ComposeContentTestRule,
customMainActivity: CustomMainActivity
) {
fun clickOnHomeButton(composeTestRule: ComposeContentTestRule) {
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()
}
}
@ -182,9 +179,16 @@ class SearchRobot {
})
}
fun openNoteFragment() {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
openDrawerWithGravity(id.custom_drawer_container, GravityCompat.START)
testFlakyView({ onView(withText(R.string.pref_notes)).perform(click()) })
fun openNoteFragment(
coreMainActivity: CoreMainActivity,
composeTestRule: ComposeContentTestRule
) {
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 {
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
@JvmStatic

View File

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