Refactored the LibkiwixBookmarkTest test according to compose UI.

This commit is contained in:
MohitMaliFtechiz 2025-04-15 13:03:28 +05:30
parent af94018285
commit 12e17e4d87
4 changed files with 91 additions and 42 deletions

View File

@ -18,25 +18,29 @@
package org.kiwix.kiwixmobile.page.bookmarks
import androidx.recyclerview.widget.RecyclerView
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.ComposeTestRule
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.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.longClick
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import applyWithViewHierarchyPrinting
import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.Findable.StringId.ContentDesc
import org.kiwix.kiwixmobile.Findable.StringId.TextId
import org.kiwix.kiwixmobile.Findable.Text
import org.kiwix.kiwixmobile.Findable.ViewId
import org.kiwix.kiwixmobile.core.R
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
import org.kiwix.kiwixmobile.core.page.SWITCH_TEXT_TESTING_TAG
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem
import org.kiwix.kiwixmobile.testutils.TestUtils
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
@ -49,12 +53,20 @@ fun bookmarks(func: BookmarksRobot.() -> Unit) =
class BookmarksRobot : BaseRobot() {
private var retryCountForBookmarkAddedButton = 5
fun assertBookMarksDisplayed() {
assertDisplayed(R.string.bookmarks_from_current_book)
fun assertBookMarksDisplayed(composeTestRule: ComposeTestRule) {
composeTestRule.apply {
waitForIdle()
onNodeWithTag(SWITCH_TEXT_TESTING_TAG)
.assertTextEquals(context.getString(R.string.bookmarks_from_current_book))
}
}
fun clickOnTrashIcon() {
clickOn(ContentDesc(R.string.pref_clear_all_bookmarks_title))
fun clickOnTrashIcon(composeTestRule: ComposeTestRule) {
composeTestRule.apply {
waitForIdle()
onNodeWithTag(DELETE_MENU_ICON_TESTING_TAG)
.performClick()
}
}
fun assertDeleteBookmarksDialogDisplayed() {
@ -66,8 +78,12 @@ class BookmarksRobot : BaseRobot() {
testFlakyView({ onView(withText("DELETE")).perform(click()) })
}
fun assertNoBookMarkTextDisplayed() {
testFlakyView({ isVisible(TextId(R.string.no_bookmarks)) })
fun assertNoBookMarkTextDisplayed(composeTestRule: ComposeTestRule) {
composeTestRule.apply {
waitForIdle()
onNodeWithTag(NO_ITEMS_TEXT_TESTING_TAG)
.assertTextEquals(context.getString(R.string.no_bookmarks))
}
}
fun clickOnSaveBookmarkImage() {
@ -97,14 +113,20 @@ class BookmarksRobot : BaseRobot() {
}
}
fun assertBookmarkSaved() {
fun assertBookmarkSaved(composeTestRule: ComposeContentTestRule) {
pauseForBetterTestPerformance()
isVisible(Text("Test Zim"))
composeTestRule.apply {
waitForIdle()
composeTestRule.onNodeWithText("Test Zim").assertExists()
}
}
fun assertBookmarkRemoved() {
fun assertBookmarkRemoved(composeTestRule: ComposeTestRule) {
pauseForBetterTestPerformance()
onView(withText("Test Zim")).check(ViewAssertions.doesNotExist())
composeTestRule.apply {
waitForIdle()
composeTestRule.onNodeWithText("Test Zim").assertDoesNotExist()
}
}
private fun pauseForBetterTestPerformance() {
@ -118,13 +140,19 @@ class BookmarksRobot : BaseRobot() {
})
}
fun testAllBookmarkShowing(bookmarkList: ArrayList<LibkiwixBookmarkItem>) {
bookmarkList.forEachIndexed { index, libkiwixBookmarkItem ->
testFlakyView({
onView(withId(R.id.recycler_view))
.perform(RecyclerViewActions.scrollToPosition<RecyclerView.ViewHolder>(index))
.check(matches(hasDescendant(withText(libkiwixBookmarkItem.title))))
})
fun testAllBookmarkShowing(
bookmarkList: ArrayList<LibkiwixBookmarkItem>,
composeTestRule: ComposeTestRule
) {
composeTestRule.apply {
waitForIdle()
bookmarkList.forEachIndexed { index, libkiwixBookmarkItem ->
testFlakyView({
composeTestRule.onNodeWithTag(PAGE_LIST_TEST_TAG)
.performScrollToNode(hasText(libkiwixBookmarkItem.title))
composeTestRule.onNodeWithText(libkiwixBookmarkItem.title).assertExists()
})
}
}
}
}

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.page.bookmarks
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
@ -42,6 +43,7 @@ import org.kiwix.kiwixmobile.core.main.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
import org.kiwix.kiwixmobile.core.utils.TestingUtils.RETRY_RULE_ORDER
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.main.topLevel
@ -59,6 +61,9 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
@JvmField
val retryRule = RetryRule()
@get:Rule(order = COMPOSE_TEST_RULE_ORDER)
val composeTestRule = createComposeRule()
private lateinit var kiwixMainActivity: KiwixMainActivity
@Before
@ -119,20 +124,20 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
bookmarks {
// delete any bookmark if already saved to properly perform this test case.
longClickOnSaveBookmarkImage()
clickOnTrashIcon()
clickOnTrashIcon(composeTestRule)
assertDeleteBookmarksDialogDisplayed()
clickOnDeleteButton()
assertNoBookMarkTextDisplayed()
assertNoBookMarkTextDisplayed(composeTestRule)
pressBack()
// Test saving bookmark
clickOnSaveBookmarkImage()
clickOnOpenSavedBookmarkButton()
assertBookmarkSaved()
assertBookmarkSaved(composeTestRule)
pressBack()
// Test removing bookmark
clickOnSaveBookmarkImage()
longClickOnSaveBookmarkImage()
assertBookmarkRemoved()
assertBookmarkRemoved(composeTestRule)
pressBack()
// Save the bookmark to test whether it remains saved after the application restarts or not.
clickOnSaveBookmarkImage()
@ -142,7 +147,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
@Test
fun testBookmarkRemainsSavedOrNot() {
topLevel {
clickBookmarksOnNavDrawer(BookmarksRobot::assertBookmarkSaved)
clickBookmarksOnNavDrawer { assertBookmarkSaved(composeTestRule) }
}
}
@ -160,10 +165,10 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
bookmarks {
// delete any bookmark if already saved to properly perform this test case.
longClickOnSaveBookmarkImage()
clickOnTrashIcon()
clickOnTrashIcon(composeTestRule)
assertDeleteBookmarksDialogDisplayed()
clickOnDeleteButton()
assertNoBookMarkTextDisplayed()
assertNoBookMarkTextDisplayed(composeTestRule)
pressBack()
}
val navHostFragment: NavHostFragment =
@ -198,7 +203,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
bookmarks {
// test all the saved bookmarks are showing on the bookmarks screen
openBookmarkScreen()
testAllBookmarkShowing(bookmarkList)
testAllBookmarkShowing(bookmarkList, composeTestRule)
}
}

View File

@ -35,6 +35,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.style.TextOverflow
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.downloader.model.Base64String
@ -45,6 +47,8 @@ import org.kiwix.kiwixmobile.core.utils.ComposeDimens.EIGHT_DP
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.PAGE_LIST_ITEM_FAVICON_SIZE
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SIXTEEN_DP
const val PAGE_ITEM_TITLE_TESTING_TAG = "pageItemTitleTestingTag"
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun PageListItem(
@ -81,7 +85,9 @@ fun PageListItem(
Text(
text = page.title,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.weight(1f),
modifier = Modifier
.weight(1f)
.semantics { testTag = PAGE_ITEM_TITLE_TESTING_TAG },
maxLines = 1,
overflow = TextOverflow.Ellipsis
)

View File

@ -49,7 +49,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.TextStyle
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.isCustomApp
@ -72,6 +75,10 @@ import org.threeten.bp.LocalDate
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.format.DateTimeParseException
const val SWITCH_TEXT_TESTING_TAG = "switchTextTestingTag"
const val NO_ITEMS_TEXT_TESTING_TAG = "noItemsTextTestingTag"
const val PAGE_LIST_TEST_TAG = "pageListTestingTag"
@Suppress("ComposableLambdaParameterNaming")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -109,7 +116,9 @@ fun PageScreen(
Text(
text = state.noItemsString,
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.align(Alignment.Center)
modifier = Modifier
.align(Alignment.Center)
.semantics { testTag = NO_ITEMS_TEXT_TESTING_TAG }
)
} else {
PageList(
@ -140,7 +149,7 @@ private fun PageList(
}
}
LazyColumn(state = listState) {
LazyColumn(state = listState, modifier = Modifier.semantics { testTag = PAGE_LIST_TEST_TAG }) {
items(state.pageState.visiblePageItems) { item ->
when (item) {
is Page -> PageListItem(page = item, itemClickListener = itemClickListener)
@ -171,14 +180,14 @@ private fun searchBarIfActive(
fun PageSwitchRow(
state: PageFragmentScreenState
) {
val switchTextColor = if (isSystemInDarkTheme()) {
AlabasterWhite
} else {
White
}
val context = LocalActivity.current as CoreMainActivity
// hide switches for custom apps, see more info here https://github.com/kiwix/kiwix-android/issues/3523
if (!context.isCustomApp()) {
val switchTextColor = if (isSystemInDarkTheme()) {
AlabasterWhite
} else {
White
}
Row(
modifier = Modifier
.fillMaxWidth()
@ -190,7 +199,8 @@ fun PageSwitchRow(
Text(
state.switchString,
color = switchTextColor,
style = TextStyle(fontSize = FOURTEEN_SP)
style = TextStyle(fontSize = FOURTEEN_SP),
modifier = Modifier.testTag(SWITCH_TEXT_TESTING_TAG)
)
Switch(
checked = state.switchIsChecked,