Refactored the ErrorActivityTest according to new compose UI.

* Removed unnecessary rules from lintConfig file.
* Refactored the `HelpFragmentTest` according to compose UI.
This commit is contained in:
MohitMaliFtechiz 2025-03-26 19:38:56 +05:30 committed by Kelson
parent 8e3a4c585b
commit 4cdae0f601
7 changed files with 142 additions and 73 deletions

View File

@ -20,25 +20,32 @@ package org.kiwix.kiwixmobile.error
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
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.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
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 import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.help.SEND_DIAGNOSTIC_REPORT_TESTING_TAG
import org.kiwix.kiwixmobile.testutils.TestUtils import org.kiwix.kiwixmobile.testutils.TestUtils
fun errorActivity(func: ErrorActivityRobot.() -> Unit) = ErrorActivityRobot().apply(func) fun errorActivity(func: ErrorActivityRobot.() -> Unit) = ErrorActivityRobot().apply(func)
class ErrorActivityRobot : BaseRobot() { class ErrorActivityRobot : BaseRobot() {
fun assertSendDiagnosticReportDisplayed() { fun assertSendDiagnosticReportDisplayed(composeTestRule: ComposeContentTestRule) {
// Wait a bit for properly visible the HelpFragment. // Wait a bit for properly visible the HelpFragment.
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong()) BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
isVisible(TextId(R.string.send_report)) composeTestRule.apply {
waitForIdle()
onNodeWithTag(SEND_DIAGNOSTIC_REPORT_TESTING_TAG).assertIsDisplayed()
}
} }
fun clickOnSendDiagnosticReport() { fun clickOnSendDiagnosticReport(composeTestRule: ComposeContentTestRule) {
clickOn(TextId(R.string.send_report)) composeTestRule.apply {
waitForIdle()
onNodeWithTag(SEND_DIAGNOSTIC_REPORT_TESTING_TAG).performClick()
}
} }
fun assertErrorActivityDisplayed(composeTestRule: ComposeContentTestRule) { fun assertErrorActivityDisplayed(composeTestRule: ComposeContentTestRule) {

View File

@ -91,8 +91,8 @@ class ErrorActivityTest : BaseActivityTest() {
it.navigate(R.id.helpFragment) it.navigate(R.id.helpFragment)
} }
errorActivity { errorActivity {
assertSendDiagnosticReportDisplayed() assertSendDiagnosticReportDisplayed(composeTestRule)
clickOnSendDiagnosticReport() clickOnSendDiagnosticReport(composeTestRule)
assertErrorActivityDisplayed(composeTestRule) assertErrorActivityDisplayed(composeTestRule)
// Click on "No, Thanks" button to see it's functionality working or not. // Click on "No, Thanks" button to see it's functionality working or not.
clickOnNoThanksButton(composeTestRule) clickOnNoThanksButton(composeTestRule)
@ -101,9 +101,9 @@ class ErrorActivityTest : BaseActivityTest() {
it.navigate(R.id.helpFragment) it.navigate(R.id.helpFragment)
} }
// Assert HelpFragment is visible or not after clicking on the "No, Thanks" button. // Assert HelpFragment is visible or not after clicking on the "No, Thanks" button.
assertSendDiagnosticReportDisplayed() assertSendDiagnosticReportDisplayed(composeTestRule)
// Again click on "Send diagnostic report" button to open the ErrorActivity. // Again click on "Send diagnostic report" button to open the ErrorActivity.
clickOnSendDiagnosticReport() clickOnSendDiagnosticReport(composeTestRule)
assertErrorActivityDisplayed(composeTestRule) assertErrorActivityDisplayed(composeTestRule)
// Check check boxes are displayed or not. // Check check boxes are displayed or not.
assertCheckBoxesDisplayed(composeTestRule) assertCheckBoxesDisplayed(composeTestRule)

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.help package org.kiwix.kiwixmobile.help
import android.os.Build import android.os.Build
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.IdlingRegistry import androidx.test.espresso.IdlingRegistry
@ -33,6 +34,7 @@ import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.R
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.RETRY_RULE_ORDER import org.kiwix.kiwixmobile.core.utils.TestingUtils.RETRY_RULE_ORDER
import org.kiwix.kiwixmobile.main.KiwixMainActivity import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.RetryRule import org.kiwix.kiwixmobile.testutils.RetryRule
@ -43,6 +45,13 @@ import org.kiwix.kiwixmobile.utils.KiwixIdlingResource
class HelpFragmentTest : BaseActivityTest() { class HelpFragmentTest : BaseActivityTest() {
private lateinit var sharedPreferenceUtil: SharedPreferenceUtil private lateinit var sharedPreferenceUtil: SharedPreferenceUtil
@Rule(order = RETRY_RULE_ORDER)
@JvmField
val retryRule = RetryRule()
@get:Rule(order = COMPOSE_TEST_RULE_ORDER)
val composeTestRule = createComposeRule()
@Before @Before
override fun waitForIdle() { override fun waitForIdle() {
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).apply { UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).apply {
@ -66,10 +75,6 @@ class HelpFragmentTest : BaseActivityTest() {
} }
} }
@Rule(order = RETRY_RULE_ORDER)
@JvmField
val retryRule = RetryRule()
init { init {
AccessibilityChecks.enable().setRunChecksFromRootView(true) AccessibilityChecks.enable().setRunChecksFromRootView(true)
} }
@ -81,16 +86,16 @@ class HelpFragmentTest : BaseActivityTest() {
it.navigate(R.id.helpFragment) it.navigate(R.id.helpFragment)
} }
help { help {
clickOnWhatDoesKiwixDo() clickOnWhatDoesKiwixDo(composeTestRule)
assertWhatDoesKiwixDoIsExpanded() assertWhatDoesKiwixDoIsExpanded(composeTestRule)
clickOnWhatDoesKiwixDo() clickOnWhatDoesKiwixDo(composeTestRule)
clickOnWhereIsContent() clickOnWhereIsContent(composeTestRule)
assertWhereIsContentIsExpanded() assertWhereIsContentIsExpanded(composeTestRule)
clickOnWhereIsContent() clickOnWhereIsContent(composeTestRule)
clickOnHowToUpdateContent() clickOnHowToUpdateContent(composeTestRule)
assertHowToUpdateContentIsExpanded() assertHowToUpdateContentIsExpanded(composeTestRule)
clickOnHowToUpdateContent() clickOnHowToUpdateContent(composeTestRule)
assertWhyCopyMoveFilesToAppPublicDirectoryIsNotVisible() assertWhyCopyMoveFilesToAppPublicDirectoryIsNotVisible(composeTestRule)
} }
LeakAssertions.assertNoLeaks() LeakAssertions.assertNoLeaks()
} }
@ -103,18 +108,18 @@ class HelpFragmentTest : BaseActivityTest() {
it.navigate(R.id.helpFragment) it.navigate(R.id.helpFragment)
} }
help { help {
clickOnWhatDoesKiwixDo() clickOnWhatDoesKiwixDo(composeTestRule)
assertWhatDoesKiwixDoIsExpanded() assertWhatDoesKiwixDoIsExpanded(composeTestRule)
clickOnWhatDoesKiwixDo() clickOnWhatDoesKiwixDo(composeTestRule)
clickOnWhereIsContent() clickOnWhereIsContent(composeTestRule)
assertWhereIsContentIsExpanded() assertWhereIsContentIsExpanded(composeTestRule)
clickOnWhereIsContent() clickOnWhereIsContent(composeTestRule)
clickOnHowToUpdateContent() clickOnHowToUpdateContent(composeTestRule)
assertHowToUpdateContentIsExpanded() assertHowToUpdateContentIsExpanded(composeTestRule)
clickOnHowToUpdateContent() clickOnHowToUpdateContent(composeTestRule)
clickWhyCopyMoveFilesToAppPublicDirectory() clickWhyCopyMoveFilesToAppPublicDirectory(composeTestRule)
assertWhyCopyMoveFilesToAppPublicDirectoryIsExpanded() assertWhyCopyMoveFilesToAppPublicDirectoryIsExpanded(composeTestRule)
clickWhyCopyMoveFilesToAppPublicDirectory() clickWhyCopyMoveFilesToAppPublicDirectory(composeTestRule)
} }
LeakAssertions.assertNoLeaks() LeakAssertions.assertNoLeaks()
} }

View File

@ -17,16 +17,21 @@
*/ */
package org.kiwix.kiwixmobile.help package org.kiwix.kiwixmobile.help
import androidx.compose.ui.test.assertContentDescriptionEquals
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.espresso.matcher.ViewMatchers.withText
import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.Findable.StringId.TextId
import org.kiwix.kiwixmobile.Findable.Text
import org.kiwix.kiwixmobile.Findable.ViewId import org.kiwix.kiwixmobile.Findable.ViewId
import org.kiwix.kiwixmobile.core.R.id import org.kiwix.kiwixmobile.core.R.id
import org.kiwix.kiwixmobile.core.R.string import org.kiwix.kiwixmobile.core.R.string
import org.kiwix.kiwixmobile.core.help.HELP_SCREEN_ITEM_DESCRIPTION_TESTING_TAG
import org.kiwix.kiwixmobile.core.help.HELP_SCREEN_ITEM_TITLE_TESTING_TAG
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
fun help(func: HelpRobot.() -> Unit) = HelpRobot().apply(func) fun help(func: HelpRobot.() -> Unit) = HelpRobot().apply(func)
@ -36,28 +41,23 @@ class HelpRobot : BaseRobot() {
isVisible(ViewId(id.toolbar)) isVisible(ViewId(id.toolbar))
} }
fun clickOnWhatDoesKiwixDo() { fun clickOnWhatDoesKiwixDo(composeTestRule: ComposeContentTestRule) {
testFlakyView({ onView(withText(string.help_2)).perform(click()) }) clickOnHelpScreenItemTitle(0, composeTestRule)
} }
fun assertWhatDoesKiwixDoIsExpanded() { fun assertWhatDoesKiwixDoIsExpanded(composeTestRule: ComposeContentTestRule) {
isVisible( assertHelpScreenDescriptionDisplayed(
Text( helpTextFormat(string.help_3, string.help_4),
helpTextFormat( composeTestRule
string.help_3,
string.help_4
)
)
) )
} }
fun clickOnWhereIsContent() { fun clickOnWhereIsContent(composeTestRule: ComposeContentTestRule) {
clickOn(TextId(string.help_5)) clickOnHelpScreenItemTitle(1, composeTestRule)
} }
fun assertWhereIsContentIsExpanded() { fun assertWhereIsContentIsExpanded(composeTestRule: ComposeContentTestRule) {
isVisible( assertHelpScreenDescriptionDisplayed(
Text(
helpTextFormat( helpTextFormat(
string.help_6, string.help_6,
string.help_7, string.help_7,
@ -65,32 +65,76 @@ class HelpRobot : BaseRobot() {
string.help_9, string.help_9,
string.help_10, string.help_10,
string.help_11 string.help_11
) ),
) composeTestRule
) )
} }
fun clickOnHowToUpdateContent() { fun clickOnHowToUpdateContent(composeTestRule: ComposeContentTestRule) {
clickOn(TextId(string.how_to_update_content)) clickOnHelpScreenItemTitle(2, composeTestRule)
} }
fun assertHowToUpdateContentIsExpanded() { fun assertHowToUpdateContentIsExpanded(composeTestRule: ComposeContentTestRule) {
isVisible(TextId(string.update_content_description)) assertHelpScreenDescriptionDisplayed(
context.getString(string.update_content_description),
composeTestRule
)
} }
fun clickWhyCopyMoveFilesToAppPublicDirectory() { fun clickWhyCopyMoveFilesToAppPublicDirectory(composeTestRule: ComposeContentTestRule) {
clickOn(TextId(string.why_copy_move_files_to_app_directory)) clickOnHelpScreenItemTitle(3, composeTestRule)
} }
fun assertWhyCopyMoveFilesToAppPublicDirectoryIsExpanded() { fun assertWhyCopyMoveFilesToAppPublicDirectoryIsExpanded(composeTestRule: ComposeContentTestRule) {
isVisible(Text(context.getString(string.copy_move_files_to_app_directory_description))) assertHelpScreenDescriptionDisplayed(
context.getString(string.copy_move_files_to_app_directory_description),
composeTestRule
)
} }
fun assertWhyCopyMoveFilesToAppPublicDirectoryIsNotVisible() { fun assertWhyCopyMoveFilesToAppPublicDirectoryIsNotVisible(composeTestRule: ComposeContentTestRule) {
composeTestRule.apply {
waitForIdle()
val itemTitleList = onAllNodesWithTag(HELP_SCREEN_ITEM_TITLE_TESTING_TAG)
val itemCount = itemTitleList.fetchSemanticsNodes().size
repeat(itemCount) { index ->
try {
itemTitleList[index]
.assertTextEquals(context.getString(string.why_copy_move_files_to_app_directory))
// If "Why copy/move files to app public directory?" item is visible throw the error.
throw RuntimeException("\"Why copy/move files to app public directory?\" help item is visible in non-playStore variant")
} catch (_: AssertionError) {
// If not found then nothing will do.
}
}
}
onView(withText(string.why_copy_move_files_to_app_directory)) onView(withText(string.why_copy_move_files_to_app_directory))
.check(doesNotExist()) .check(doesNotExist())
} }
private fun clickOnHelpScreenItemTitle(index: Int, composeTestRule: ComposeContentTestRule) {
testFlakyView({
composeTestRule.apply {
waitForIdle()
val itemTitleList = onAllNodesWithTag(HELP_SCREEN_ITEM_TITLE_TESTING_TAG)
itemTitleList[index].performClick()
}
})
}
private fun assertHelpScreenDescriptionDisplayed(
description: String,
composeTestRule: ComposeContentTestRule
) {
testFlakyView({
composeTestRule.apply {
waitForIdle()
onNodeWithTag(HELP_SCREEN_ITEM_DESCRIPTION_TESTING_TAG)
.assertContentDescriptionEquals(description)
}
})
}
private fun helpTextFormat(vararg stringIds: Int) = private fun helpTextFormat(vararg stringIds: Int) =
stringIds.joinToString(separator = "\n", transform = context::getString) stringIds.joinToString(separator = "\n", transform = context::getString)
} }

View File

@ -29,6 +29,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
@ -39,6 +40,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -52,6 +54,11 @@ import org.kiwix.kiwixmobile.core.ui.theme.MineShaftGray600
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.HELP_SCREEN_DIVIDER_HEIGHT import org.kiwix.kiwixmobile.core.utils.ComposeDimens.HELP_SCREEN_DIVIDER_HEIGHT
import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SIXTEEN_DP import org.kiwix.kiwixmobile.core.utils.ComposeDimens.SIXTEEN_DP
const val SEND_DIAGNOSTIC_REPORT_TESTING_TAG = "sendDiagnosticReportTestingTag"
const val HELP_SCREEN_ITEM_TITLE_TESTING_TAG = "helpScreenItemTitleTestingTag"
const val HELP_SCREEN_ITEM_DESCRIPTION_TESTING_TAG = "helpScreenItemDescriptionTestingTag"
@OptIn(ExperimentalMaterial3Api::class)
@Suppress("ComposableLambdaParameterNaming") @Suppress("ComposableLambdaParameterNaming")
@Composable @Composable
fun HelpScreen( fun HelpScreen(
@ -86,7 +93,8 @@ fun SendReportRow() {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { (context as? Activity)?.start<DiagnosticReportActivity>() }, .clickable { (context as? Activity)?.start<DiagnosticReportActivity>() }
.testTag(SEND_DIAGNOSTIC_REPORT_TESTING_TAG),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start horizontalArrangement = Arrangement.Start
) { ) {

View File

@ -56,7 +56,10 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.util.LinkifyCompat import androidx.core.text.util.LinkifyCompat
@ -114,6 +117,7 @@ fun HelpItemHeader(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(interactionSource = interactionSource, indication = null, onClick = onToggle) .clickable(interactionSource = interactionSource, indication = null, onClick = onToggle)
.testTag(HELP_SCREEN_ITEM_TITLE_TESTING_TAG)
) { ) {
Text( Text(
text = title, text = title,
@ -156,6 +160,8 @@ fun HelpItemDescription(context: Context, description: String) {
AndroidView( AndroidView(
factory = { helpItemDescription }, factory = { helpItemDescription },
modifier = Modifier.padding(bottom = SIXTEEN_DP) modifier = Modifier.padding(bottom = SIXTEEN_DP)
.testTag(HELP_SCREEN_ITEM_DESCRIPTION_TESTING_TAG)
.semantics { contentDescription = description }
) { textView -> ) { textView ->
textView.apply { textView.apply {
text = description text = description

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<lint> <lint>
<issue id="PrivateResource" severity="warning" />
<issue id="TypographyQuotes" severity="warning"> <issue id="TypographyQuotes" severity="warning">
<ignore path="**-qq/**.xml" /> <ignore path="**-qq/**.xml" />
<ignore path="**-iw/**.xml" /> <ignore path="**-iw/**.xml" />