From db88ec97e11ddbda8142ef702f3ed1501f058e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Wed, 6 Sep 2023 17:20:23 +0200 Subject: [PATCH 1/4] feat: default accessibility roles --- src/helpers/accessiblity.ts | 45 +++++++++++++++++++++++++---- src/queries/__tests__/role.test.tsx | 15 ++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/helpers/accessiblity.ts b/src/helpers/accessiblity.ts index aed19ced6..b6bcc4bae 100644 --- a/src/helpers/accessiblity.ts +++ b/src/helpers/accessiblity.ts @@ -4,9 +4,13 @@ import { StyleSheet, } from 'react-native'; import { ReactTestInstance } from 'react-test-renderer'; -import { getTextContent } from './text-content'; import { getHostSiblings, getUnsafeRootElement } from './component-tree'; -import { getHostComponentNames } from './host-component-names'; +import { + getHostComponentNames, + isHostText, + isHostTextInput, +} from './host-component-names'; +import { getTextContent } from './text-content'; type IsInaccessibleOptions = { cache?: WeakMap; @@ -113,10 +117,39 @@ export function isAccessibilityElement( ); } -export function getAccessibilityRole( - element: ReactTestInstance -): string | undefined { - return element.props.role ?? element.props.accessibilityRole; +/** + * Returns the accessibility role for given element. It will return explicit + * role from either `role` or `accessibilityRole` props if set. + * + * If explicit role is not available, it would try to return default element + * role: + * - `text` for `Text` elements + * - `textbox`* for `TextInput` elements. + * + * Note: `textbox` is not an official React Native role, you cannot set it + * explicitly on an element. However, it is an ARIA role that better characterizes + * TextInput elements than the default `none` role. + * + * In all other cases this functions returns `none`. + * + * @param element + * @returns + */ +export function getAccessibilityRole(element: ReactTestInstance) { + const explicitRole = element.props.role ?? element.props.accessibilityRole; + if (explicitRole) { + return explicitRole; + } + + if (isHostText(element)) { + return 'text'; + } + + if (isHostTextInput(element)) { + return 'textbox'; + } + + return 'none'; } export function getAccessibilityViewIsModal(element: ReactTestInstance) { diff --git a/src/queries/__tests__/role.test.tsx b/src/queries/__tests__/role.test.tsx index 4782e6a5c..b1937f01e 100644 --- a/src/queries/__tests__/role.test.tsx +++ b/src/queries/__tests__/role.test.tsx @@ -3,6 +3,7 @@ import { TouchableOpacity, TouchableWithoutFeedback, Text, + TextInput, View, Pressable, Button as RNButton, @@ -110,6 +111,20 @@ test('supports role prop', () => { expect(screen.getByRole('button')).toBeTruthy(); }); +test('supports default roles', () => { + const screen = render( + <> + + + + + ); + + expect(screen.getByRole('none').props.testID).toBe('view-default'); + expect(screen.getByRole('text').props.testID).toBe('text-default'); + expect(screen.getByRole('textbox').props.testID).toBe('text-input-default'); +}); + describe('supports name option', () => { test('returns an element that has the corresponding role and a children with the name', () => { const { getByRole } = render( From ee5b3049b8329b130c239fa3fb476f5291ede5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Jastrze=CC=A8bski?= Date: Wed, 15 Nov 2023 22:40:23 +0100 Subject: [PATCH 2/4] chore: remove default text input role --- src/helpers/accessiblity.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/helpers/accessiblity.ts b/src/helpers/accessiblity.ts index b6bcc4bae..ca63252d7 100644 --- a/src/helpers/accessiblity.ts +++ b/src/helpers/accessiblity.ts @@ -5,11 +5,7 @@ import { } from 'react-native'; import { ReactTestInstance } from 'react-test-renderer'; import { getHostSiblings, getUnsafeRootElement } from './component-tree'; -import { - getHostComponentNames, - isHostText, - isHostTextInput, -} from './host-component-names'; +import { getHostComponentNames, isHostText } from './host-component-names'; import { getTextContent } from './text-content'; type IsInaccessibleOptions = { @@ -145,10 +141,6 @@ export function getAccessibilityRole(element: ReactTestInstance) { return 'text'; } - if (isHostTextInput(element)) { - return 'textbox'; - } - return 'none'; } From 1a3ab4cf096aab7e5432e432c7a649a7045d41cb Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Fri, 17 Nov 2023 10:20:40 +0100 Subject: [PATCH 3/4] chore: update tests --- src/queries/__tests__/role.test.tsx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/queries/__tests__/role.test.tsx b/src/queries/__tests__/role.test.tsx index b1937f01e..b24c6a6d6 100644 --- a/src/queries/__tests__/role.test.tsx +++ b/src/queries/__tests__/role.test.tsx @@ -111,18 +111,19 @@ test('supports role prop', () => { expect(screen.getByRole('button')).toBeTruthy(); }); -test('supports default roles', () => { - const screen = render( - <> - - - - - ); +test('supports default View component "none" role', () => { + const screen = render(); + expect(screen.getByRole('none').props.testID).toBe('view'); +}); + +test('supports default Text component "text" role', () => { + const screen = render(); + expect(screen.getByRole('text').props.testID).toBe('text'); +}); - expect(screen.getByRole('none').props.testID).toBe('view-default'); - expect(screen.getByRole('text').props.testID).toBe('text-default'); - expect(screen.getByRole('textbox').props.testID).toBe('text-input-default'); +test('supports default TextInput component "none" role', () => { + const screen = render(); + expect(screen.getByRole('none').props.testID).toBe('text-input'); }); describe('supports name option', () => { From d4eabf2eba9e80c42ef5a04034c5d53113e9f15f Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Fri, 17 Nov 2023 10:29:25 +0100 Subject: [PATCH 4/4] chore: update docs --- src/helpers/accessiblity.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/helpers/accessiblity.ts b/src/helpers/accessiblity.ts index ca63252d7..fa1d7dbf3 100644 --- a/src/helpers/accessiblity.ts +++ b/src/helpers/accessiblity.ts @@ -120,11 +120,6 @@ export function isAccessibilityElement( * If explicit role is not available, it would try to return default element * role: * - `text` for `Text` elements - * - `textbox`* for `TextInput` elements. - * - * Note: `textbox` is not an official React Native role, you cannot set it - * explicitly on an element. However, it is an ARIA role that better characterizes - * TextInput elements than the default `none` role. * * In all other cases this functions returns `none`. *