Use when an iOS or Android app needs accessibility tests: XCUITest performAccessibilityAudit (iOS 17+), VoiceOver labels and traits, Espresso AccessibilityChecks, Accessibility Scanner and TalkBack order, plus WCAG checks for labels, 44pt and 48dp touch targets, contrast and focus order.
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Extends the core AccessibilityChecks.enable() example in
../SKILL.md. Checks run automatically on any ViewActions action
and cover the acted-on view plus all descendant views (atf).
// app/build.gradle
dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.6.1'
}import androidx.test.espresso.accessibility.AccessibilityChecks
@RunWith(AndroidJUnit4::class)
class CheckoutAccessibilityTest {
init {
AccessibilityChecks.enable().setRunChecksFromRootView(true)
}
@Test
fun applyPromoCode() {
onView(withId(R.id.promo_field)).perform(typeText("WELCOME10"), closeSoftKeyboard())
onView(withId(R.id.apply_button)).perform(click())
// checks fire automatically on every perform()
}
}setRunChecksFromRootView(true) evaluates the whole hierarchy, not just the
interacted view (atf).
AccessibilityChecks.enable().apply {
setSuppressingResultMatcher(
allOf(
matchesCheck(TextContrastCheck::class.java),
matchesViews(withId(R.id.decorative_watermark))
)
)
}The matcher must satisfy both the check type and the specific view (atf).
Each interactive UI element should have a focusable area of at least 48dp x 48dp
(atgt). AccessibilityChecks validates this on every perform() call.
AccessibilityChecks (via the Accessibility Test Framework) checks these on every
perform() call (contrast):
Convey purpose, not visual detail (cd):
// Icon-only button: set contentDescription
Icon(
imageVector = Icons.Filled.Share,
contentDescription = stringResource(R.string.label_share)
)
// Decorative image: suppress from accessibility
Icon(
imageVector = Icons.Filled.Decoration,
contentDescription = null // TalkBack skips this element
)Text composables need no contentDescription; TalkBack reads text content automatically.Verify with Espresso:
onView(withId(R.id.share_button))
.check(matches(withContentDescription(R.string.label_share)))Enable via Settings > Accessibility > TalkBack > On, then (at):
Manual checklist:
AccessibilityChecks.enable(), setRunChecksFromRootView(true), setSuppressingResultMatcher(), per-action firing.contentDescription: purpose not visual detail, null for decorative, unique labels in lists.