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

byRole queries return only accessibility elements #1244

Merged
merged 11 commits into from
Jan 17, 2023

Conversation

MattAgn
Copy link
Collaborator

@MattAgn MattAgn commented Nov 28, 2022

Summary

Solves #1180. It makes byRole queries return only implicit or explicit accessibility elements. Explicit accessibility elements are those with accessibility prop set to true. Implicit accessibility elements are Text, TextInput, Pressable and Switch (tested with VoiceOver for Switch to check it was indeed accessible even without setting the accessible prop and I checked through a snapshot, behing the scene, Switch resolves to a host component RCTSwitch).

Test plan

  • Unit tests for isAccessibilityElement helper
  • One test to check that byRole only returns accessibility elements

@codecov
Copy link

codecov bot commented Nov 28, 2022

Codecov Report

Base: 94.94% // Head: 95.13% // Increases project coverage by +0.18% 🎉

Coverage data is based on head (937fa2d) compared to base (e38c627).
Patch coverage: 98.61% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1244      +/-   ##
==========================================
+ Coverage   94.94%   95.13%   +0.18%     
==========================================
  Files          45       46       +1     
  Lines        3088     3205     +117     
  Branches      457      483      +26     
==========================================
+ Hits         2932     3049     +117     
  Misses        156      156              
Impacted Files Coverage Δ
src/queries/text.ts 97.67% <93.33%> (+0.37%) ⬆️
src/config.ts 100.00% <100.00%> (ø)
src/fireEvent.ts 98.65% <100.00%> (ø)
src/helpers/accessiblity.ts 100.00% <100.00%> (ø)
src/helpers/host-component-names.tsx 100.00% <100.00%> (ø)
src/helpers/matchers/matchTextContent.ts 100.00% <100.00%> (ø)
src/queries/displayValue.ts 100.00% <100.00%> (ø)
src/queries/placeholderText.ts 100.00% <100.00%> (ø)
src/queries/role.ts 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@mdjastrzebski mdjastrzebski changed the title byRole queries return only accessibility elements [WIP] byRole queries return only accessibility elements Dec 28, 2022
@MattAgn MattAgn changed the title [WIP] byRole queries return only accessibility elements byRole queries return only accessibility elements Jan 13, 2023
@MattAgn MattAgn marked this pull request as ready for review January 13, 2023 12:35
@MattAgn MattAgn force-pushed the fix/byrole-accessible branch from 0476265 to 6947473 Compare January 13, 2023 13:34
Copy link
Member

@mdjastrzebski mdjastrzebski left a comment

Choose a reason for hiding this comment

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

So far looks quite good. Good catch with Switch component! This PR should use useBreakingChanges config option so that we will be able to turn it on for vNext.

Comment on lines 227 to 229
const element = render(
<View accessible={true} testID="view" />
).getByTestId('view');
Copy link
Member

Choose a reason for hiding this comment

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

nit, style: could we separate render and getByTestId calls, as it's more readable and matches with what we suggest to our users in docs and examples.

Suggested change
const element = render(
<View accessible={true} testID="view" />
).getByTestId('view');
const views = render(
<View accessible={true} testID="view" />
)
const element = views.getByTestId('view');

@@ -733,3 +733,12 @@ test('byRole queries support hidden option', () => {
`"Unable to find an element with role: "button""`
);
});

test('takes accessible prop into account', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
test('takes accessible prop into account', () => {
test('ignores elements with accessible={false}', () => {

@@ -733,3 +733,12 @@ test('byRole queries support hidden option', () => {
`"Unable to find an element with role: "button""`
);
});

test('takes accessible prop into account', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Could we add another test that would pass a View with accessibilityRole but without accessible prop, and check that it does not get matched.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

Comment on lines 185 to 191
describe('when accessible prop is not defined', () => {
test('returns true for Text component', () => {
const element = render(<Text testID="text">Hey</Text>).getByTestId(
'text'
);
expect(isAccessibilityElement(element)).toEqual(true);
});
Copy link
Member

Choose a reason for hiding this comment

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

How about structuring the tests a bit different form, by grouping default/true/false tests for given component type together. These tests will be both exhaustive and take less LOCs.

Suggested change
describe('when accessible prop is not defined', () => {
test('returns true for Text component', () => {
const element = render(<Text testID="text">Hey</Text>).getByTestId(
'text'
);
expect(isAccessibilityElement(element)).toEqual(true);
});
test('TextInput matching', () => {
const { getByTestId } = render(<View>
<Text testID="default">Default</Text>
<Text testID="true">True</Text>
<Text testID="false">False</Text>
</View>);
expect(isAccessibilityElement(getByTestId("default"))).toBeTrue();
expect(isAccessibilityElement(getByTestId("true"))).toBeTrue();
expect(isAccessibilityElement(getByTestId("false"))).toBeFalse();
});

Copy link
Member

Choose a reason for hiding this comment

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

We could have such tests for key views that render to host views: View, Text, TextInput, Switch.

Maybe we can also add tests for composite components that render to View with accessible prop: Pressable, TouchableOpacity.

Copy link
Collaborator Author

@MattAgn MattAgn Jan 17, 2023

Choose a reason for hiding this comment

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

good idea! the only downside of this method is that tests title and tests in general are less explicit

Copy link
Collaborator Author

@MattAgn MattAgn Jan 17, 2023

Choose a reason for hiding this comment

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

Now :
CleanShot 2023-01-17 at 11 57 10
Before :
CleanShot 2023-01-17 at 11 58 26

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

what do you prefer? both are fine for me

typeof node.type === 'string' &&
isAccessibilityElement(node) &&
Copy link
Member

Choose a reason for hiding this comment

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

This would be a breaking change so we should apply it only when useBreakingChanges config is set.

@MattAgn MattAgn force-pushed the fix/byrole-accessible branch from 6947473 to 8611599 Compare January 17, 2023 15:23
@MattAgn
Copy link
Collaborator Author

MattAgn commented Jan 17, 2023

@mdjastrzebski thanks for the review! I've fixed everything you mentioned

Copy link
Member

@mdjastrzebski mdjastrzebski left a comment

Choose a reason for hiding this comment

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

All good. Let's merge this 🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants