| name | accessibility-testing |
| description | Mobile accessibility testing skill for WCAG compliance, VoiceOver/TalkBack validation, dynamic type support, color contrast analysis, and accessibility auditing across iOS and Android platforms. |
| allowed-tools | Read, Grep, Write, Bash, Edit, Glob, WebFetch |
| graph | {"domains":["domain:mobile"],"specializations":["specialization:mobile-development"],"skillAreas":["skill-area:accessibility-testing","skill-area:mobile-ui-automation"],"roles":["role:mobile-engineer"],"workflows":["workflow:feature-development","workflow:release-management"],"topics":["topic:accessibility"]} |
Accessibility Testing Skill
Comprehensive mobile accessibility testing and validation for iOS and Android platforms, ensuring WCAG 2.1/2.2 compliance and optimal screen reader compatibility.
Overview
This skill provides capabilities for testing mobile application accessibility, including screen reader compatibility, dynamic type support, color contrast validation, and compliance with Web Content Accessibility Guidelines (WCAG) adapted for mobile platforms.
Capabilities
Screen Reader Testing
- Validate VoiceOver compatibility (iOS)
- Test TalkBack interaction (Android)
- Verify accessibility labels and hints
- Check reading order and focus navigation
- Test custom accessibility actions
Dynamic Type Support
- Validate iOS Dynamic Type scaling
- Test Android font scaling preferences
- Check layout adaptation at extreme sizes
- Verify text truncation handling
- Test multiline text wrapping
Color Contrast Analysis
- Measure contrast ratios (WCAG AA/AAA)
- Identify low-contrast text and UI elements
- Validate against light/dark mode themes
- Check color-blind accessibility
- Suggest compliant color alternatives
Accessibility Audit
- Run iOS Accessibility Inspector audits
- Execute Android Accessibility Scanner
- Generate compliance reports
- Identify WCAG violations
- Prioritize remediation efforts
Touch Target Validation
- Measure touch target sizes (minimum 44x44pt iOS, 48x48dp Android)
- Check spacing between interactive elements
- Validate gesture-based interactions
- Test single-tap alternatives for complex gestures
Prerequisites
iOS Development
xcode-select --install
pod 'ViewInspector'
Android Development
// build.gradle
dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.5.1'
}
Testing Tools
npm install -g @axe-core/cli
pip install accessibility-checker
Usage Patterns
iOS Accessibility Labels (SwiftUI)
import SwiftUI
struct AccessibleButton: View {
var body: some View {
Button(action: { }) {
Image(systemName: "heart.fill")
}
.accessibilityLabel("Add to favorites")
.accessibilityHint("Double tap to add this item to your favorites list")
.accessibilityAddTraits(.isButton)
}
}
struct AccessibleList: View {
var body: some View {
List {
ForEach(items) { item in
ItemRow(item: item)
.accessibilityElement(children: .combine)
.accessibilityLabel("\(item.title), \(item.subtitle)")
.accessibilityValue(item.isSelected ? "Selected" : "Not selected")
}
}
.accessibilityIdentifier("items_list")
}
}
iOS Accessibility Labels (UIKit)
import UIKit
class AccessibleViewController: UIViewController {
func configureAccessibility() {
button.accessibilityLabel = "Submit order"
button.accessibilityHint = "Double tap to submit your order"
containerView.isAccessibilityElement = true
containerView.accessibilityLabel = "Order summary: 3 items, total $45.99"
cell.accessibilityCustomActions = [
UIAccessibilityCustomAction(name: "Delete", target: self, selector: #selector(deleteItem)),
UIAccessibilityCustomAction(name: "Edit", target: self, selector: #selector(editItem))
]
}
}
Android Accessibility (Jetpack Compose)
import androidx.compose.ui.semantics.*
@Composable
fun AccessibleButton() {
IconButton(
onClick = { },
modifier = Modifier.semantics {
contentDescription = "Add to favorites"
role = Role.Button
}
) {
Icon(Icons.Filled.Favorite, contentDescription = null)
}
}
@Composable
fun AccessibleCard(item: Item) {
Card(
modifier = Modifier.semantics(mergeDescendants = true) {
contentDescription = "${item.title}, ${item.subtitle}"
stateDescription = if (item.isSelected) "Selected" else "Not selected"
}
) {
}
}
Android Accessibility (XML Views)
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo
class AccessibleActivity : AppCompatActivity() {
fun configureAccessibility() {
imageButton.contentDescription = "Add to favorites"
decorativeImage.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
statusTextView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE
customView.accessibilityDelegate = object : View.AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)
info.contentDescription = "Custom description"
}
}
}
}
Color Contrast Validation
import UIKit
func calculateContrastRatio(foreground: UIColor, background: UIColor) -> Double {
let fgLuminance = relativeLuminance(foreground)
let bgLuminance = relativeLuminance(background)
let lighter = max(fgLuminance, bgLuminance)
let darker = min(fgLuminance, bgLuminance)
return (lighter + 0.05) / (darker + 0.05)
}
func relativeLuminance(_ color: UIColor) -> Double {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: nil)
let transform: (CGFloat) -> Double = { value in
let v = Double(value)
v v : pow((v ) , )
}
transform(r) transform(g) transform(b)
}
ratio calculateContrastRatio(foreground: .label, background: .systemBackground)
meetsWCAGAA ratio
meetsWCAGAAA ratio
Accessibility Testing (XCTest)
import XCTest
class AccessibilityTests: XCTestCase {
func testVoiceOverNavigation() {
let app = XCUIApplication()
app.launch()
XCTAssertTrue(app.buttons["Submit order"].exists)
XCTAssertTrue(app.staticTexts["Order total"].exists)
let submitButton = app.buttons["Submit order"]
XCTAssertTrue(submitButton.isEnabled)
let elements = app.descendants(matching: .any).allElementsBoundByAccessibilityElement
XCTAssertGreaterThan(elements.count, 0)
}
func testDynamicTypeSupport() {
let app = XCUIApplication()
app.launchArguments = ["-UIPreferredContentSizeCategoryName", "UICTContentSizeCategoryAccessibilityXXL"]
app.launch()
XCTAssertTrue(app.staticTexts["Title"].exists)
XCTAssertFalse(app.staticTexts["Title"].frame.isEmpty)
}
}
Accessibility Testing (Espresso)
import androidx.test.espresso.accessibility.AccessibilityChecks
import org.junit.BeforeClass
class AccessibilityTest {
companion object {
@BeforeClass
@JvmStatic
fun enableAccessibilityChecks() {
AccessibilityChecks.enable()
.setRunChecksFromRootView(true)
}
}
@Test
fun testScreenAccessibility() {
onView(withId(R.id.main_layout))
.check(matches(isDisplayed()))
onView(withId(R.id.submit_button))
.perform(click())
}
}
Integration with Babysitter SDK
Task Definition Example
const accessibilityTestTask = defineTask({
name: 'accessibility-testing',
description: 'Test mobile app accessibility compliance',
inputs: {
platform: { type: 'string', required: true, enum: ['ios', 'android', 'both'] },
wcagLevel: { type: 'string', required: true, enum: ['A', 'AA', 'AAA'] },
projectPath: { type: 'string', required: true },
testScreens: { type: 'array', items: { type: 'string' } }
},
outputs: {
complianceReport: { type: 'object' },
violations: { type: 'array' },
recommendations: { type: 'array' },
score: { type: 'number' }
},
async run(inputs, taskCtx) {
return {
kind: ,
: ,
: {
: ,
: {
: ,
: inputs.,
: inputs.,
: inputs.,
: inputs.
}
},
: {
: ,
:
}
};
}
});
MCP Server Integration
Using Axiom Accessibility (iOS)
{
"mcpServers": {
"axiom": {
"command": "npx",
"args": ["axiom-mcp"],
"env": {
"XCODE_PROJECT": "/path/to/project.xcodeproj"
}
}
}
}
Available MCP Tools
a11y_audit_ios - Run iOS Accessibility Inspector audit
a11y_audit_android - Run Android Accessibility Scanner
check_contrast_ratio - Validate color contrast
validate_touch_targets - Check touch target sizes
test_screen_reader - Simulate screen reader navigation
generate_a11y_report - Create compliance report
WCAG 2.1 Mobile Checklist
Perceivable
Operable
Understandable
Robust
Best Practices
- Test with Real Users: Include users with disabilities in testing
- Use Native Controls: Leverage platform accessibility features
- Test at Extremes: Check largest Dynamic Type and font scaling
- Verify Reading Order: Ensure logical focus navigation
- Provide Text Alternatives: Label all images and icons
- Support Multiple Input Methods: Touch, voice, switch control
References