Skip to main content
🎉 A11y Issue Detection Agent is now live! Detect accessibility issues like a WCAG expert with AI. Try now!
No Result Found
Get your setup working faster. Join our Discord for optimisation tips from elite testers. Join our DiscordJoin our Discord

Use executors to test screen reader interactions

Learn how to use executors to automate screen reader gestures, capture spoken output, and add accessibility assertions.

Screen Reader Automation is currently in the Beta phase and is available on Android and iOS devices under the Ultimate plan. To get access, contact BrowserStack Support. For more details on the Ultimate plan, check the pricing page.

With BrowserStack App Accessibility, you can automate screen reader accessibility testing by simulating screen reader interactions, capturing screen reader output, and validating accessibility metadata directly within your test scripts. This guide helps you get started with setting up and using Screen Reader Automation on Android and iOS.

How screen reader automation works

BrowserStack provides the browserstack_executor command, which gives you granular control over the screen reader environment within your tests. It is a custom extension that lets your test scripts send commands to control the screen reader on real BrowserStack devices.

The command can be used only with Appium. However, it is language-agnostic and can be used in any Appium-supported language to run tests on BrowserStack real devices.

This feature provides the following capabilities:

  • Programmatic control: Enable and disable the screen reader directly from your test scripts.
  • Gesture simulation: Programmatically simulate common accessibility gestures, such as moving between elements, activating an element, or scrolling.
  • Real output capture: Capture the screen reader’s actual spoken output as plain text.
  • Assertions: Use the captured spoken output to add assertions in your test scripts, so your app meets accessibility standards.

The following video provides an overview of the Screen Reader Automation executor’s capabilities:

Supported platforms and screen readers

You can automate screen reader accessibility testing on the following platforms and their corresponding screen readers:

Platform Screen Reader
Android TalkBack
iOS VoiceOver

Set up screen reader automation

To set up screen reader automation, execute interactions, and add assertions, select your platform and follow the corresponding steps.

Implement screen reader automation

Integrate the browserstack_executor command into your test scripts to enable or disable the screen reader, simulate screen reader gestures, or capture spoken output.

Enable or disable the screen reader

Use the screenReader action to enable or disable TalkBack.

  • To enable TalkBack:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReader\",\"arguments\": {\"enable\" : \"true\"}}");
    
  • To disable TalkBack:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReader\",\"arguments\": {\"enable\" : \"false\"}}");
    

Simulate screen reader gestures

Use the screenReaderGesture action to simulate common screen reader gestures, such as navigate, activate, or scroll.

  • To simulate a navigate next gesture:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReaderGesture\",\"arguments\": {\"gesture\" : \"navigate_next\"}}");
    
  • To simulate an activate gesture:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReaderGesture\",\"arguments\": {\"gesture\" : \"activate_item\"}}");
    
  • To simulate a scroll down gesture:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReaderGesture\",\"arguments\": {\"gesture\" : \"scroll_down\"}}");
    

List of supported gestures

The following gestures are supported for TalkBack automation:

Gestures supported on both Android and iOS use the same argument names, so you can reuse them across platforms. Gestures supported on iOS only aren’t available on Android.

Gesture Argument
Move focus to next element "navigate_next"
Move focus to previous element "navigate_previous"
Activate focused element "activate_item"
Scroll down "scroll_down"
Scroll up "scroll_up"
Navigate back "back"
Return to home screen "home"

Capture spoken output

Use the screenReaderSpokenDescription action to capture the spoken output of a specific UI element. Identify the element in one of the following ways:

  • resourceId: the resource ID of the element.
  • rect: the coordinates of the element’s bounding box.

Use coordinates when the element has no resource ID. Elements often have no resource ID in apps built with Jetpack Compose, where a semantics tree describes the UI instead. If you don’t specify either identifier, the command returns the spoken output for all elements captured by the screen reader.

  • To capture the spoken output by resource ID:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReaderSpokenDescription\",\"arguments\": {\"resourceId\" : \"<your-element-resource-id>\"}}")
    
  • To capture the spoken output by coordinates:
    driver.execute_script("browserstack_executor: {\"action\":\"screenReaderSpokenDescription\",\"arguments\": {\"rect\" : {\"x\": <x-coordinate>, \"y\": <y-coordinate>, \"width\": <width>, \"height\": <height>}}}")
    

You can’t pass an XPath expression to the browserstack_executor command. XPath is an Appium locator, not an Android accessibility attribute, so the screen reader can’t resolve XPath. To target an element you locate by XPath, read the element’s coordinates in your test script. Pass those coordinates in the rect argument.

The command groups the spoken output by the identifier you use. The following example shows the output when you use both identifiers to target the same element:

{
  "spoken_description": {
    "by_resource_id": {
      "com.example.app:id/sign_in": ["Sign In, Button, Double-tap to activate"]
    },
    "by_rect": {
      "70 1171 1010 1297": ["Sign In, Button, Double-tap to activate"]
    }
  }
}

Output you request by resource ID appears under by_resource_id. Output you request by coordinates appears under by_rect, listed under the element’s bounds in the form left top right bottom. You can log this output, use it for assertions, or save it to a file for offline review.

If you pass neither identifier, the command returns the spoken output for every captured element, listed under both by_resource_id and by_rect. You get the same full output when you pass a resource ID for an element that has no accessibility metadata. Use the output to debug missing accessibility labels or an incorrect focus order.

Add accessibility assertions

With the captured screen reader data, you can add assertions to your test scripts. This lets you verify critical accessibility aspects:

  • Focusability: Verify that all relevant UI elements receive focus and are reachable by the screen reader.
  • Spoken output verification: Check that elements expose the correct accessibility metadata to screen readers, such as labels, roles, and hints, and that the actual spoken output matches your expected accessibility label or announcement.
  • Traversal order: Record the screen reader traversal sequence. Compare it to the Accessibility Tree or a visual test to confirm the focus order follows a logical reading flow.

Enable assertions

You can enable assertions in your test scripts by using the browserstack_executor command with the screenReaderSpokenDescription action to capture the spoken output of a specific UI element and verify it against your expected values.

To enable assertions using resourceId:

driver.execute_script("browserstack_executor: {\"action\":\"screenReaderSpokenDescription\",\"arguments\": {\"resourceId\" : \"<your-element-resource-id>\"}}");

You can also enable assertions with rect by passing the element’s coordinates.

Example assertion

  • Spoken output verification:
    The following example captures the spoken output of an element by its resource ID and asserts that the output matches the expected description:
    print("Getting spoken text of element\n")
      out = driver.execute_script("browserstack_executor: {\"action\":\"screenReaderSpokenDescription\",\"arguments\": {\"resourceId\" : \"<your-element-resource-id>\"}}");
      expected_description = "Master Switch, ON"
      actual_description = out['spoken_description']['by_resource_id']['<your-element-resource-id>'][0]
    
      if actual_description == expected_description
        puts "Assertion Passed: Spoken description is correct."
      else
        raise "Assertion Failed: Expected '#{expected_description}', but got '#{actual_description}'"
      end
    

To assert on the output for an element you captured by its coordinates, use by_rect instead, for example out['spoken_description']['by_rect']['<left> <top> <right> <bottom>'][0]. Take the left top right bottom values from the captured output, as shown in Capture spoken output.

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked





Thank you for your valuable feedback

Is this page helping you?

Yes
No

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked





Thank you for your valuable feedback!

Talk to an Expert
Download Copy Check Circle