Added ErrorActivity UI test case for testing the compose UI.

* Removed the unused code from project.
This commit is contained in:
MohitMaliFtechiz 2025-03-03 21:08:25 +05:30 committed by Kelson
parent cca03cc06e
commit 1743d7b231
9 changed files with 188 additions and 174 deletions

View File

@ -127,6 +127,7 @@ androidComponents {
} }
dependencies { dependencies {
androidTestImplementation(Libs.ANDROIDX_COMPOSE_UI_TEST_JUNIT4)
androidTestImplementation(Libs.leakcanary_android_instrumentation) androidTestImplementation(Libs.leakcanary_android_instrumentation)
testImplementation(Libs.kotlinx_coroutines_test) testImplementation(Libs.kotlinx_coroutines_test)
} }

View File

@ -0,0 +1,68 @@
/*
* Kiwix Android
* Copyright (c) 2025 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.error
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
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
import org.kiwix.kiwixmobile.testutils.TestUtils
fun errorActivity(func: ErrorActivityRobot.() -> Unit) = ErrorActivityRobot().apply(func)
class ErrorActivityRobot : BaseRobot() {
fun assertSendDiagnosticReportDisplayed() {
// Wait a bit for properly visible the HelpFragment.
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
isVisible(TextId(R.string.send_report))
}
fun clickOnSendDiagnosticReport() {
clickOn(TextId(R.string.send_report))
}
fun assertErrorActivityDisplayed(composeTestRule: ComposeContentTestRule) {
// Wait a bit for properly visible the ErrorActivity.
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS.toLong())
composeTestRule.onNodeWithText(context.getString(R.string.diagnostic_report))
.assertIsDisplayed()
}
fun clickOnNoThanksButton(composeTestRule: ComposeContentTestRule) {
composeTestRule.onNodeWithText(context.getString(R.string.no_thanks).uppercase()).performClick()
}
fun assertCheckBoxesDisplayed(composeTestRule: ComposeContentTestRule) {
composeTestRule.onNodeWithText(context.getString(R.string.crash_checkbox_language))
.assertIsDisplayed()
composeTestRule.onNodeWithText(context.getString(R.string.crash_checkbox_logs))
.assertIsDisplayed()
composeTestRule.onNodeWithText(context.getString(R.string.crash_checkbox_zimfiles))
.assertIsDisplayed()
}
fun clickOnSendDetailsButton(composeTestRule: ComposeContentTestRule) {
composeTestRule.onNodeWithText(context.getString(R.string.crash_button_confirm).uppercase())
.performClick()
}
}

View File

@ -0,0 +1,108 @@
/*
* Kiwix Android
* Copyright (c) 2025 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.error
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
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.utils.LanguageUtils.Companion.handleLocaleChange
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils.closeSystemDialogs
import org.kiwix.kiwixmobile.testutils.TestUtils.isSystemUINotRespondingDialogVisible
class ErrorActivityTest : BaseActivityTest() {
@Rule
@JvmField
var retryRule = RetryRule()
@get:Rule
val composeTestRule = createComposeRule()
@Before
override fun waitForIdle() {
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).apply {
if (isSystemUINotRespondingDialogVisible(this)) {
closeSystemDialogs(context, this)
}
waitForIdle()
}
PreferenceManager.getDefaultSharedPreferences(context)
.edit {
putBoolean(SharedPreferenceUtil.PREF_SHOW_INTRO, false)
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
putString(SharedPreferenceUtil.PREF_LANG, "en")
putLong(
SharedPreferenceUtil.PREF_LAST_DONATION_POPUP_SHOWN_IN_MILLISECONDS,
System.currentTimeMillis()
)
}
activityScenario =
ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
onActivity {
handleLocaleChange(
it,
"en",
SharedPreferenceUtil(context).apply {
lastDonationPopupShownInMilliSeconds = System.currentTimeMillis()
}
)
}
}
}
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Test
fun verifyErrorActivity() {
activityScenario.onActivity {
it.navigate(R.id.helpFragment)
}
errorActivity {
assertSendDiagnosticReportDisplayed()
clickOnSendDiagnosticReport()
assertErrorActivityDisplayed(composeTestRule)
// Click on "No, Thanks" button to see it's functionality working or not.
clickOnNoThanksButton(composeTestRule)
// Assert HelpFragment is visible or not after clicking on the "No, Thanks" button.
assertSendDiagnosticReportDisplayed()
// Again click on "Send diagnostic report" button to open the ErrorActivity.
clickOnSendDiagnosticReport()
assertErrorActivityDisplayed(composeTestRule)
// Check check boxes are displayed or not.
assertCheckBoxesDisplayed(composeTestRule)
// Click on "Send details" button.
clickOnSendDetailsButton(composeTestRule)
}
}
}

View File

@ -401,8 +401,11 @@ object Libs {
* testing libraries for compose * testing libraries for compose
*/ */
const val ANDROIDX_COMPOSE_UI_TEST_JUNIT4: String = const val ANDROIDX_COMPOSE_UI_TEST_JUNIT4: String =
"androidx.compose.ui:ui-test-junit4" "androidx.compose.ui:ui-test-junit4:${Versions.ANDROIDX_COMPOSE_UI_VERSION}"
const val ANDROIDX_COMPOSE_UI_TOOLING: String = const val ANDROIDX_COMPOSE_UI_TOOLING: String =
"androidx.compose.ui:ui-tooling" "androidx.compose.ui:ui-tooling"
const val ANDROIDX_COMPOSE_UI_TEST_MANIFEST =
"androidx.compose.ui:ui-test-manifest:${Versions.ANDROIDX_COMPOSE_UI_VERSION}"
} }

View File

@ -65,6 +65,6 @@ dependencies {
implementation(Libs.zxing) implementation(Libs.zxing)
implementation(platform(Libs.ANDROIDX_COMPOSE_BOM)) implementation(platform(Libs.ANDROIDX_COMPOSE_BOM))
// For Compose UI Testing // For Compose UI Testing
androidTestImplementation(Libs.ANDROIDX_COMPOSE_UI_TEST_JUNIT4)
debugImplementation(Libs.ANDROIDX_COMPOSE_UI_TOOLING) debugImplementation(Libs.ANDROIDX_COMPOSE_UI_TOOLING)
debugImplementation(Libs.ANDROIDX_COMPOSE_UI_TEST_MANIFEST)
} }

View File

@ -1,169 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/error_activity_background"
tools:context=".error.ErrorActivity"
tools:ignore="Overdraw">
<TextView
android:id="@+id/messageText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="@string/crash_description"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView2" />
<Button
android:id="@+id/reportButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
android:maxLines="1"
android:singleLine="true"
android:text="@string/crash_button_confirm"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/restartButton"
app:layout_constraintHorizontal_bias="0.173"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/restartButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
android:text="@string/no_thanks"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.769"
app:layout_constraintStart_toEndOf="@+id/reportButton" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="8dp"
android:text="@string/crash_title"
android:textColor="@color/alabaster_white"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.505"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_marginStart="8dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="8dp"
android:src="@mipmap/ic_launcher"
android:contentDescription="@string/app_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="17dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/reportButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/messageText">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<CheckBox
android:id="@+id/allowLanguage"
style="@android:style/Widget.Holo.CompoundButton.CheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="8dp"
android:buttonTint="@color/denim_blue200"
android:checked="true"
android:text="@string/crash_checkbox_language"
android:textColor="@color/white" />
<CheckBox
android:id="@+id/allowLogs"
style="@android:style/Widget.Holo.CompoundButton.CheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="8dp"
android:buttonTint="@color/denim_blue200"
android:checked="true"
android:text="@string/crash_checkbox_logs"
android:textColor="@color/white" />
<CheckBox
android:id="@+id/allowCrash"
style="@android:style/Widget.Holo.CompoundButton.CheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="8dp"
android:buttonTint="@color/denim_blue200"
android:checked="true"
android:text="@string/crash_checkbox_exception"
android:textColor="@color/white" />
<CheckBox
android:id="@+id/allowZims"
style="@android:style/Widget.Holo.CompoundButton.CheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="8dp"
android:buttonTint="@color/denim_blue200"
android:checked="true"
android:text="@string/crash_checkbox_zimfiles"
android:textColor="@color/white" />
<CheckBox
android:id="@+id/allowDeviceDetails"
style="@android:style/Widget.Holo.CompoundButton.CheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="8dp"
android:buttonTint="@color/denim_blue200"
android:checked="true"
android:text="@string/crash_checkbox_device"
android:textColor="@color/white" />
<CheckBox
android:id="@+id/allowFileSystemDetails"
style="@android:style/Widget.Holo.CompoundButton.CheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="8dp"
android:buttonTint="@color/denim_blue200"
android:checked="true"
android:text="@string/crash_checkbox_file_system"
android:textColor="@color/white" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -8,7 +8,8 @@
android:minHeight="@dimen/material_minimum_height_and_width" android:minHeight="@dimen/material_minimum_height_and_width"
android:minWidth="@dimen/material_minimum_height_and_width" android:minWidth="@dimen/material_minimum_height_and_width"
android:paddingStart="12dp" android:paddingStart="12dp"
android:paddingEnd="12dp"> android:paddingEnd="12dp"
tools:ignore="Overdraw">
<TextView <TextView
android:id="@+id/ic_tab_switcher_text" android:id="@+id/ic_tab_switcher_text"

View File

@ -4,7 +4,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"> android:background="?android:attr/selectableItemBackground"
tools:ignore="Overdraw">
<ImageView <ImageView
android:id="@+id/favicon" android:id="@+id/favicon"

View File

@ -7,7 +7,8 @@
android:clickable="false" android:clickable="false"
android:focusable="false" android:focusable="false"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal"
tools:ignore="Overdraw">
<TextView <TextView
android:id="@+id/titleText" android:id="@+id/titleText"