diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/BookmarksRobot.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/BookmarksRobot.kt index 28496938b..7eb5e5db0 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/BookmarksRobot.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/BookmarksRobot.kt @@ -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) { - bookmarkList.forEachIndexed { index, libkiwixBookmarkItem -> - testFlakyView({ - onView(withId(R.id.recycler_view)) - .perform(RecyclerViewActions.scrollToPosition(index)) - .check(matches(hasDescendant(withText(libkiwixBookmarkItem.title)))) - }) + fun testAllBookmarkShowing( + bookmarkList: ArrayList, + 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() + }) + } } } } diff --git a/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/LibkiwixBookmarkTest.kt b/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/LibkiwixBookmarkTest.kt index db2750340..ed40d750f 100644 --- a/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/LibkiwixBookmarkTest.kt +++ b/app/src/androidTest/java/org/kiwix/kiwixmobile/page/bookmarks/LibkiwixBookmarkTest.kt @@ -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) } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageListItem.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageListItem.kt index 411aa9b9e..7c37cfcc8 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageListItem.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageListItem.kt @@ -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 ) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageScreen.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageScreen.kt index 139c0ee36..a2317018c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageScreen.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/page/PageScreen.kt @@ -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,