Added the androidx.test.espresso:espresso-accessibility dependency to test the accessibility issues in our application.

* This testing library only work with `ViewAction` like if we perform any click on any screen then it starts checking the accessibility issues, so we have modify our test cases according to this.
* Suppress a few known accessibility issue e.g. on `LocalFileTransfer` screen we have a `skip` text which we are not using but it is giving the error for that.
* Fixed the `TouchTargetIssue` in ZimHostFragment.
* Added the `contentDescription` to search recyclerView.
This commit is contained in:
MohitMaliFtechiz 2024-05-14 19:17:02 +05:30
parent 037d02ab8c
commit ff5f9fe162
23 changed files with 140 additions and 13 deletions

View File

@ -22,6 +22,7 @@ import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
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
@ -45,6 +46,10 @@ class DeepLinksTest : BaseActivityTest() {
var retryRule = RetryRule()
private lateinit var sharedPreferenceUtil: SharedPreferenceUtil
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Before
override fun waitForIdle() {
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).apply {

View File

@ -102,7 +102,7 @@ class DownloadRobot : BaseRobot() {
}
private fun stopDownload() {
clickOn(ViewId(R.id.stop))
testFlakyView({ onView(withId(R.id.stop)).perform(click()) })
}
fun pauseDownload() {

View File

@ -23,6 +23,7 @@ import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.IdlingPolicies
import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
@ -58,6 +59,10 @@ class DownloadTest : BaseActivityTest() {
@JvmField
var retryRule = RetryRule()
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Before
override fun waitForIdle() {
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).apply {

View File

@ -21,6 +21,7 @@ import android.os.Build
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import leakcanary.LeakAssertions
@ -66,6 +67,10 @@ class HelpFragmentTest : BaseActivityTest() {
@JvmField
var retryRule = RetryRule()
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Test
fun verifyHelpActivity() {
setShowPlayStoreRestriction(false)

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.help
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.kiwix.kiwixmobile.BaseRobot
@ -27,6 +28,7 @@ import org.kiwix.kiwixmobile.Findable.ViewId
import org.kiwix.kiwixmobile.core.R.id
import org.kiwix.kiwixmobile.core.R.string
import org.kiwix.kiwixmobile.core.main.KIWIX_APK_WEBSITE_URL
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
fun help(func: HelpRobot.() -> Unit) = HelpRobot().apply(func)
@ -37,7 +39,7 @@ class HelpRobot : BaseRobot() {
}
fun clickOnWhatDoesKiwixDo() {
clickOn(TextId(string.help_2))
testFlakyView({ onView(withText(string.help_2)).perform(click()) })
}
fun assertWhatDoesKiwixDoIsExpanded() {

View File

@ -69,7 +69,7 @@ class InitialDownloadRobot : BaseRobot() {
}
fun downloadZimFile() {
clickOn(Text(zimFileTitle))
testFlakyView({ onView(withText(zimFileTitle)).perform(click()) })
}
fun assertStorageConfigureDialogDisplayed() {
@ -89,7 +89,7 @@ class InitialDownloadRobot : BaseRobot() {
}
fun stopDownload() {
clickOn(ViewId(R.id.stop))
testFlakyView({ onView(withId(R.id.stop)).perform(click()) })
}
fun assertDownloadStop() {

View File

@ -22,6 +22,7 @@ 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.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
@ -51,6 +52,10 @@ class InitialDownloadTest : BaseActivityTest() {
@JvmField
var retryRule = RetryRule()
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Before
override fun waitForIdle() {
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).apply {

View File

@ -21,6 +21,7 @@ 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 leakcanary.LeakAssertions
@ -42,6 +43,10 @@ class IntroFragmentTest : BaseActivityTest() {
@JvmField
var retryRule = RetryRule()
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Test
fun viewIsSwipeableAndNavigatesToMain() {
activityScenario.onActivity {

View File

@ -18,6 +18,9 @@
package org.kiwix.kiwixmobile.intro
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withId
import applyWithViewHierarchyPrinting
import attempt
import org.kiwix.kiwixmobile.BaseRobot
@ -26,15 +29,14 @@ import org.kiwix.kiwixmobile.Findable.ViewId
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.main.TopLevelDestinationRobot
import org.kiwix.kiwixmobile.main.topLevel
import org.kiwix.kiwixmobile.testutils.TestUtils.testFlakyView
fun intro(func: IntroRobot.() -> Unit) = IntroRobot().applyWithViewHierarchyPrinting(func)
class IntroRobot : BaseRobot() {
private val getStarted = ViewId(R.id.get_started)
fun swipeLeft() {
isVisible(getStarted)
isVisible(ViewId(R.id.get_started))
isVisible(TextId(R.string.welcome_to_the_family))
isVisible(TextId(R.string.humankind_knowledge))
attempt(10) {
@ -44,7 +46,7 @@ class IntroRobot : BaseRobot() {
}
infix fun clickGetStarted(func: TopLevelDestinationRobot.() -> Unit): TopLevelDestinationRobot {
clickOn(getStarted)
testFlakyView({ onView(withId(R.id.get_started)).perform(click()) })
return topLevel(func)
}
}

View File

@ -23,6 +23,7 @@ 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.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
@ -63,6 +64,10 @@ class LanguageFragmentTest {
InstrumentationRegistry.getInstrumentation()
}
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Before
fun setUp() {
UiDevice.getInstance(instrumentation).apply {

View File

@ -23,6 +23,7 @@ import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isChecked
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
import androidx.test.espresso.matcher.ViewMatchers.withId
import applyWithViewHierarchyPrinting
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import junit.framework.AssertionFailedError
@ -63,7 +64,7 @@ class LanguageRobot : BaseRobot() {
}
fun clickOnLanguageSearchIcon() {
clickOn(ViewId(R.id.menu_language_search))
testFlakyView({ onView(withId(R.id.menu_language_search)).perform(click()) })
}
fun searchLanguage(searchLanguage: String) {

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.localFileTransfer
import android.util.Log
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.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
@ -85,7 +86,7 @@ class LocalFileTransferRobot : BaseRobot() {
fun clickOnGotItButton() {
pauseForBetterTestPerformance()
clickOn(TextId(R.string.got_it))
testFlakyView({ onView(withText(R.string.got_it)).perform(click()) })
}
fun assertDeviceNameMessageVisible() {

View File

@ -26,10 +26,18 @@ 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.espresso.matcher.ViewMatchers.withId
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import androidx.test.uiautomator.UiDevice
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheck
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 leakcanary.LeakAssertions
import org.hamcrest.core.AllOf.allOf
import org.hamcrest.core.AnyOf.anyOf
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -71,6 +79,28 @@ class LocalFileTransferTest {
InstrumentationRegistry.getInstrumentation()
}
init {
AccessibilityChecks.enable().apply {
setRunChecksFromRootView(true)
setSuppressingResultMatcher(
anyOf(
allOf(
matchesCheck(SpeakableTextPresentCheck::class.java),
matchesViews(withId(R.id.tv_skip))
),
allOf(
matchesCheck(TouchTargetSizeCheck::class.java),
matchesViews(withId(R.id.tv_skip))
),
allOf(
matchesCheck(TouchTargetSizeCheck::class.java),
matchesViews(withId(R.id.text_view_device_name))
)
)
)
}
}
@Before
fun setup() {
context = instrumentation.targetContext.applicationContext

View File

@ -23,13 +23,19 @@ import androidx.core.net.toUri
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.matcher.ViewMatchers
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
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
import com.google.android.apps.common.testing.accessibility.framework.checks.TouchTargetSizeCheck
import leakcanary.LeakAssertions
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.ResponseBody
import org.hamcrest.Matchers.allOf
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -88,6 +94,18 @@ class SearchFragmentTest : BaseActivityTest() {
}
}
init {
AccessibilityChecks.enable().apply {
setRunChecksFromRootView(true)
setSuppressingResultMatcher(
allOf(
matchesCheck(TouchTargetSizeCheck::class.java),
matchesViews(ViewMatchers.withId(R.id.menu_searchintext))
)
)
}
}
@Test
fun searchFragmentSimple() {
activityScenario.onActivity {

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.settings
import android.Manifest
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
import androidx.test.platform.app.InstrumentationRegistry
@ -57,6 +58,10 @@ class KiwixSettingsFragmentTest {
var permissionRules: GrantPermissionRule =
GrantPermissionRule.grant(*permissions)
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Before
fun setup() {
// Go to IntroFragment

View File

@ -22,6 +22,7 @@ import android.content.Context
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers
@ -67,6 +68,10 @@ class KiwixSplashActivityTest {
GrantPermissionRule.grant(*permissions)
private lateinit var context: Context
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Before
fun setUp() {
Intents.init()

View File

@ -23,10 +23,16 @@ import android.content.Context
import android.os.Build
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import androidx.test.uiautomator.UiDevice
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesCheck
import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
import com.google.android.apps.common.testing.accessibility.framework.checks.DuplicateClickableBoundsCheck
import leakcanary.LeakAssertions
import org.hamcrest.Matchers.allOf
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -73,6 +79,18 @@ class ZimHostFragmentTest {
GrantPermissionRule.grant(*permissions)
private var context: Context? = null
init {
AccessibilityChecks.enable().apply {
setRunChecksFromRootView(true)
setSuppressingResultMatcher(
allOf(
matchesCheck(DuplicateClickableBoundsCheck::class.java),
matchesViews(withId(R.id.get_zim_nearby_device))
)
)
}
}
@Before
fun waitForIdle() {
context = InstrumentationRegistry.getInstrumentation().targetContext

View File

@ -23,6 +23,7 @@ import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.assertThat
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import applyWithViewHierarchyPrinting
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
@ -153,7 +154,7 @@ class ZimHostRobot : BaseRobot() {
}
fun stopServer() {
clickOn(ViewId(R.id.startServerButton))
testFlakyView({ onView(withId(R.id.startServerButton)).perform(click()) })
}
fun assertServerStopped() {

View File

@ -50,6 +50,12 @@ object Libs {
const val espresso_web: String = "androidx.test.espresso:espresso-web:" +
Versions.androidx_test_espresso
/**
* https://developer.android.com/testing
*/
const val espresso_accessibility: String = "androidx.test.espresso:espresso-accessibility:" +
Versions.androidx_test_espresso
/**
* https://github.com/square/retrofit
*/
@ -343,5 +349,6 @@ object Libs {
/**
* https://github.com/deano2390/MaterialShowcaseView
*/
const val material_show_case_view: String = "com.github.deano2390:MaterialShowcaseView:" + Versions.material_show_case_view
const val material_show_case_view: String =
"com.github.deano2390:MaterialShowcaseView:" + Versions.material_show_case_view
}

View File

@ -104,6 +104,7 @@ class AppConfigurer {
androidTestImplementation(Libs.espresso_web)
androidTestImplementation(Libs.espresso_intents)
androidTestImplementation(Libs.espresso_contrib)
androidTestImplementation(Libs.espresso_accessibility)
androidTestImplementation(Libs.annotation)
androidTestImplementation(Libs.junit)
androidTestImplementation(Libs.junit_jupiter)

View File

@ -32,9 +32,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="50dp"
android:autoLink="web"
android:gravity="center|start"
android:minHeight="@dimen/material_minimum_height_and_width"
android:text="@string/server_textview_default_message"
app:layout_constraintEnd_toStartOf="@id/shareServerUrlIcon"
app:layout_constraintStart_toStartOf="parent"
@ -46,6 +47,9 @@
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginEnd="16dp"
android:scaleType="centerInside"
android:minHeight="@dimen/material_minimum_height_and_width"
android:minWidth="@dimen/material_minimum_height_and_width"
android:contentDescription="@string/share_host_address"
android:src="@drawable/ic_share_35dp"
android:visibility="gone"

View File

@ -21,6 +21,7 @@
app:layout_constraintBottom_toTopOf="@+id/loadingMoreDataIndicator"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="@string/searched_list"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="?actionBarSize"
tools:listitem="@layout/list_item_search" />

View File

@ -18,6 +18,7 @@
<string name="save_media_error">An error occurred when trying to save the media!</string>
<string name="save_media_saved">Saved media as %s to Downloads/org.kiwix…/</string>
<string name="search_label">Search</string>
<string name="searched_list">Searched list</string>
<string name="choose_file" tools:keep="@string/choose_file">Select a Content File (*.zim)</string>
<string name="open_in_new_tab">Open link in new tab?</string>
<string name="hotspot_service_channel_name" tools:keep="@string/hotspot_service_channel_name">Hotspot Service Channel</string>