Skip to main content
This recipe covers accessibility spot-checking for native mobile. For operationalized a11y monitoring — scheduled runs, trend tracking, aggregated reports, and stakeholder dashboards — talk to your QA Wolf team about full-service accessibility testing.

Examples

Verify a screen’s key elements are reachable via accessibility semantics:
const email     = await driver.$("~Email");
const password  = await driver.$("~Password");
const loginBtn  = await driver.$("~Log in");

await expect(email).toBeDisplayed();
await expect(password).toBeDisplayed();
await expect(loginBtn).toBeEnabled();

await email.setValue(process.env.USER_EMAIL);
await password.setValue(process.env.USER_PASSWORD);
await loginBtn.click();

const homeHeader = await driver.$("~Home");
await expect(homeHeader).toBeDisplayed();
If you can’t locate an element using ~, that element is likely missing an accessibility label entirely — an accessibility bug worth raising with your dev team before writing the test.
Assert that icon buttons have meaningful accessible names:
const menuIcon = await driver.$("~Main menu");
await expect(menuIcon).toBeDisplayed();

const label = await menuIcon.getAttribute("content-desc");
if (!label || label.trim().length < 3) {
  throw new Error("A11y: menu icon accessible label is missing or too short");
}

When to use

  • You want to verify that a screen’s key interactive elements are exposed to VoiceOver (iOS) or TalkBack (Android)
  • You need to catch regressions where a developer removed or renamed an accessibility label
  • Your team wants a lightweight proxy for accessibility hygiene without a full WCAG audit
  • You want to confirm that icon-only buttons have meaningful accessible names, not blank or placeholder labels

How it works

Tests locate elements using accessibility identifiers — attributes set by your developers that expose UI components to the OS accessibility layer.
PlatformAttributeWebdriverIO selector
Androidcontent-descdriver.$('~your-label')
iOSaccessibilityIdentifier / accessible namedriver.$('~your-id')
The ~ prefix is the WebdriverIO shorthand for locating an element by its accessibility ID. This is a double win: it proves the element is correctly exposed to the accessibility layer, and it keeps your tests stable across visual refactors.

Quick reference

GoalHow to do it
Prove an element is on the accessibility layerLocate it with driver.$('~accessibility-id')
Assert a screen is navigable via accessibility semanticsUse ~ selectors throughout the full flow
Assert an icon button has a meaningful labelgetAttribute('content-desc') and check length
Assert an error or toast is readableawait expect($('~error-id')).toHaveText('...')

Notes

QA Wolf does not run a WCAG rules engine against native app views. Native apps don’t have a DOM, so axe-core style scanning isn’t available for native iOS or Android.
For deeper audits — color contrast, touch target size, reading order — supplement these tests with manual testing using VoiceOver on iOS, TalkBack on Android, or the Xcode Accessibility Inspector and Android Studio Layout Inspector.
Last modified on April 17, 2026