Abilyo by WebAbility

Android SDK

Native accessibility testing for Android apps. Wraps Google's accessibility-test-framework + 4 custom Kotlin detectors. In-app overlay, Espresso matchers, AI fix generation.

Kotlin SDK for native Android accessibility audits. Wraps Google's official accessibility-test-framework and adds custom detectors, an in-app debug overlay, and AI fix generation.

Install (Gradle)

// app/build.gradle.kts
dependencies {
    implementation("io.webability:a11y:1.0.0")
    androidTestImplementation("io.webability:a11y:1.0.0")
}

Quick start

import io.webability.a11y.WebAbilityAuditor
 
val auditor = WebAbilityAuditor(context)
val result = auditor.scan(window.decorView, screenName = "home")
Log.d("A11y", "Score: ${result.score}, ${result.summary.total} issues")

Espresso integration

@RunWith(AndroidJUnit4::class)
class AccessibilityTest {
    @get:Rule val rule = ActivityScenarioRule(MainActivity::class.java)
 
    @Test fun mainScreenIsAccessible() {
        rule.scenario.onActivity { activity ->
            val result = WebAbilityAuditor(activity).scan(activity.window.decorView)
            assertThat(result.summary.critical).isEqualTo(0)
            assertThat(result.score).isGreaterThan(85)
        }
    }
}

In-app overlay

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            WebAbilityOverlay.install(this) // shake-to-toggle
        }
    }
}

What we detect

SourceWCAGWhat
Google framework1.4.3Text contrast
Google framework2.5.8Touch target size (≥48dp)
Google framework1.1.1Missing speakable text
Google framework4.1.2Duplicate clickable bounds
Custom Kotlin1.3.1Heading hierarchy
Custom2.4.3Focus / TalkBack order
Custom1.4.1Color-only meaning
Custom2.3.3Reduced motion compliance

AI fix

val client = DashboardClient(apiKey = BuildConfig.WEBABILITY_API_KEY)
val fix = client.generateAIFix(
    issue = result.issues[0],
    framework = DashboardClient.Framework.JETPACK_COMPOSE,
)
println(fix?.alternatives?.firstOrNull()?.frameworkCode)
// → "Modifier.semantics { contentDescription = \"Close\" }"

Frameworks supported: android-xml, jetpack-compose, react-native.

Visual audit (Claude vision)

Catches pixel-level issues structural detectors can't:

val visualAuditor = VisualAuditor(context, apiKey = BuildConfig.WEBABILITY_API_KEY)
 
// Visual-only
val visual = visualAuditor.scan(window.decorView)
 
// Combined: structural + visual, merged
val full = visualAuditor.scanFull(window.decorView, brandColors = listOf("#0052CC"))

Catches (1.4.11 icon contrast, 2.4.7 focus rings, 4.1.2 affordance mismatch, 1.4.5 text-on-images, color-only states) at ~$0.001/screen. Pass brandColors so the model recognizes intentional palette choices.

Requirements

  • minSdk 24 (Android 7.0+)
  • Kotlin 1.9
  • Compose 1.6 (overlay only — core is Compose-free)

On this page