Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent duplicate accessibilityLabel on parent views #31924

Conversation

newyankeecodeshop
Copy link
Contributor

@newyankeecodeshop newyankeecodeshop commented Jul 29, 2021

Summary

In testing React Native apps using Appium, the accessibilityLabel is an important prop which provides an additional means to lookup elements in addition to the testID. More importantly, the accessibilityLabel provides detail to screen readers and other accessibility helpers. React Native on iOS has custom logic (compared to Android), whereby it concatenates the accessibility labels of children. This is useful in a case such as this:

<TouchableHighlight accessibilityRole="button" onPress={...}>
  <Text>This button</Text>
  <Text>Does something useful</Text>
</TouchableHighlight>

The above creates the following accessibility view:

<UIView accessibilityLabel="This button Does something useful" />

and when viewed in Appium Studio

<XCUIElementTypeButton name="This button Does something useful" />

However, if the above is in one or more views, such as:

<View>
  <View>
    <TouchableHighlight accessibilityRole="button" onPress={...}>
      <Text>This button</Text>
      <Text>Does something useful</Text>
    </TouchableHighlight>
  </View>
  <FlatList ... />
</View>

You can get the following from XCUITest and Appium:

<XCUIElementTypeOther name="This button Does something useful">
  <XCUIElementTypeOther name="This button Does something useful">
    <XCUIElementTypeButton name="This button Does something useful" />
  </XCUIElementTypeOther>
</XCUIElementTypeOther>

This happens because the parent Views are using RCTRecursiveAccessibilityLabel() to populate the label from the child Touchable. This doesn't make sense semantically because the TouchableHighlight is an accessible element. It benefits from the concatenation to create its label from the two Text elements, but the container views are not part of that label. They should not include it.

This PR should fix #21830, and it represents a possibly lower impact alternative to #24113, #24118, #29801, and #31222. It's not clear what functionality is relying on the string concatenation as it is currently implemented.

Changelog

Change the recursion algorithm to include labels from accessible elements only if they are not other types of RCTView instances. For example, RCTTextView should be included. This helps to minimize the impact of this change on other developers of custom views.

[iOS] [Changed] - When iterating over subviews, ignore subviews that are accessible elements (e.g. Touchable).

Test Plan

Verified that accessibility labels on <Touchable> elements maintain existing behavior with nested Text elements.
Verified that accessibility labels on non-accessible views do not include all child labels.

I added an example to AccessibilityIOSExample.js which can be used with VoiceOver to see the new behavior. In the example, text nested inside accessible subviews is not part of the spoken label.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 29, 2021
@analysis-bot
Copy link

analysis-bot commented Jul 29, 2021

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: cbec66e

@analysis-bot
Copy link

analysis-bot commented Jul 29, 2021

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 9,181,613 -59,787
android hermes armeabi-v7a 8,708,021 -45,284
android hermes x86 9,623,369 -60,564
android hermes x86_64 9,590,030 -62,751
android jsc arm64-v8a 10,818,191 -59,263
android jsc armeabi-v7a 9,735,875 -44,751
android jsc x86 10,855,347 -60,028
android jsc x86_64 11,463,530 -62,226

Base commit: cbec66e

@newyankeecodeshop
Copy link
Contributor Author

Hi @nfriedly, @mrmacete, it looks like we're all interested in improving the recursive accessibility label algorithm. Do you think my change would meet your needs too? Whichever way we go, I'll try to advocate to get something merged too.

@@ -641,8 +641,14 @@ - (NSObject *)accessibilityElement

static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
{
NSMutableString *result = [NSMutableString stringWithString:@""];
NSMutableString *result = [NSMutableString string];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@nfriedly
Copy link

nfriedly commented Jul 30, 2021

At first glance, this looks fine to me.

I would recommend getting out a physical device, turning on the screen reader, and testing the behavior before and after this change. (The screen reader doesn't work in the iOS simulator.) I think this PR is going to behave better than mine in that regard, but I don't know this stuff well enough to say for sure.

In my case, the concerns were mainly performance related, and we mitigated it by special-casing React Native apps and bypassing RCTRecursiveAccessibilityLabel entirely. (I just now closed my PR.)

(Also, FWIW, #31222 is kind of orthogonal to this, as it only improves performance without changing behavior.)

@p-sun
Copy link
Contributor

p-sun commented Aug 2, 2021

Hi! Could you create a test in AccessibilityExample.js or AccessibilityIOSExample.js for this?

@newyankeecodeshop
Copy link
Contributor Author

@p-sun is my test adequate?

@github-actions github-actions bot added Needs: Attention Issues where the author has responded to feedback. and removed Needs: Author Feedback labels Aug 12, 2021
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Aug 12, 2021
@newyankeecodeshop
Copy link
Contributor Author

Hi @p-sun is there anything I can do to help move this forward?

@p-sun
Copy link
Contributor

p-sun commented Sep 14, 2021

I will take a look at this within the next three days. Thanks for waiting!

@react-native-bot react-native-bot added the Platform: iOS iOS applications. label Oct 1, 2021
@newyankeecodeshop
Copy link
Contributor Author

Hi @p-sun will you have a chance to review this?

@ls-erin-walker
Copy link

Is there any chance this has been reviewed?

@newyankeecodeshop
Copy link
Contributor Author

Hi @p-sun will this get a review or should I close it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Needs: Attention Issues where the author has responded to feedback. Needs: React Native Team Attention Platform: iOS iOS applications. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wrong translation from react-native's accessibilityLabel to iOS name/label
9 participants