diff --git a/src/__tests__/element-queries.js b/src/__tests__/element-queries.js index 364de4aa..f3bc0ab0 100644 --- a/src/__tests__/element-queries.js +++ b/src/__tests__/element-queries.js @@ -788,23 +788,21 @@ test('queryAllByRole returns semantic html elements', () => { `) - expect(queryAllByRole(/table/i)).toHaveLength(1) - expect(queryAllByRole(/tabl/i, {exact: false})).toHaveLength(1) - expect(queryAllByRole(/columnheader/i)).toHaveLength(1) - expect(queryAllByRole(/rowheader/i)).toHaveLength(1) - expect(queryAllByRole(/grid/i)).toHaveLength(1) - expect(queryAllByRole(/form/i)).toHaveLength(0) - expect(queryAllByRole(/button/i)).toHaveLength(1) - expect(queryAllByRole(/heading/i)).toHaveLength(6) + expect(queryAllByRole('table')).toHaveLength(1) + expect(queryAllByRole('columnheader')).toHaveLength(1) + expect(queryAllByRole('rowheader')).toHaveLength(1) + expect(queryAllByRole('grid')).toHaveLength(1) + expect(queryAllByRole('form')).toHaveLength(0) + expect(queryAllByRole('button')).toHaveLength(1) + expect(queryAllByRole('heading')).toHaveLength(6) expect(queryAllByRole('list')).toHaveLength(2) - expect(queryAllByRole(/listitem/i)).toHaveLength(3) - expect(queryAllByRole(/textbox/i)).toHaveLength(2) - expect(queryAllByRole(/checkbox/i)).toHaveLength(1) - expect(queryAllByRole(/radio/i)).toHaveLength(1) + expect(queryAllByRole('listitem')).toHaveLength(3) + expect(queryAllByRole('textbox')).toHaveLength(2) + expect(queryAllByRole('checkbox')).toHaveLength(1) + expect(queryAllByRole('radio')).toHaveLength(1) expect(queryAllByRole('row')).toHaveLength(3) - expect(queryAllByRole(/rowgroup/i)).toHaveLength(2) - expect(queryAllByRole(/(table)|(textbox)/i)).toHaveLength(3) - expect(queryAllByRole(/img/i)).toHaveLength(1) + expect(queryAllByRole('rowgroup')).toHaveLength(2) + expect(queryAllByRole('img')).toHaveLength(1) expect(queryAllByRole('meter')).toHaveLength(1) expect(queryAllByRole('progressbar')).toHaveLength(0) expect(queryAllByRole('progressbar', {queryFallbacks: true})).toHaveLength(1) @@ -812,11 +810,6 @@ test('queryAllByRole returns semantic html elements', () => { expect(queryAllByRole('listbox')).toHaveLength(1) }) -test('queryByRole matches case with non-string matcher', () => { - const {queryByRole} = render(``) - expect(queryByRole(1)).toBeTruthy() -}) - test('getAll* matchers return an array', () => { const { getAllByAltText, @@ -827,7 +820,7 @@ test('getAll* matchers return an array', () => { getAllByText, getAllByRole, } = render(` -
+
finding nemo poster { expect(getAllByDisplayValue('Japanese cars')).toHaveLength(1) expect(getAllByDisplayValue(/cars$/)).toHaveLength(2) expect(getAllByText(/^where/i)).toHaveLength(1) - expect(getAllByRole(/container/i)).toHaveLength(1) + expect(getAllByRole('section')).toHaveLength(1) expect(getAllByRole('meter')).toHaveLength(1) expect(getAllByRole('progressbar', {queryFallbacks: true})).toHaveLength(1) }) @@ -879,7 +872,7 @@ test('getAll* matchers throw for 0 matches', () => { getAllByText, getAllByRole, } = render(` -
+
, `) diff --git a/src/__tests__/get-by-errors.js b/src/__tests__/get-by-errors.js index c7e8cadf..47b4d896 100644 --- a/src/__tests__/get-by-errors.js +++ b/src/__tests__/get-by-errors.js @@ -36,8 +36,8 @@ cases( html: `
`, }, getByRole: { - query: /his/, - html: `
`, + query: 'button', + html: `
two`, }, getByTestId: { query: /his/, @@ -87,8 +87,8 @@ cases( html: `
`, }, queryByRole: { - query: /his/, - html: `
`, + query: 'button', + html: `
two`, }, queryByTestId: { query: /his/, diff --git a/src/__tests__/text-matchers.js b/src/__tests__/text-matchers.js index d272f15a..05d096f7 100644 --- a/src/__tests__/text-matchers.js +++ b/src/__tests__/text-matchers.js @@ -291,10 +291,6 @@ cases( dom: ``, queryFn: 'queryAllByDisplayValue', }, - queryAllByRole: { - dom: ``, - queryFn: 'queryAllByRole', - }, }, ) diff --git a/src/queries/role.ts b/src/queries/role.ts index b1066467..f8e976a4 100644 --- a/src/queries/role.ts +++ b/src/queries/role.ts @@ -29,28 +29,17 @@ import { Matcher, MatcherFunction, MatcherOptions, - NormalizerFn, } from '../../types' -import { - buildQueries, - fuzzyMatches, - getConfig, - makeNormalizer, - matches, -} from './all-utils' +import {buildQueries, getConfig, matches} from './all-utils' const queryAllByRole: AllByRole = ( container, role, { - exact = true, - collapseWhitespace, hidden = getConfig().defaultHidden, name, description, - trim, - normalizer, queryFallbacks = false, selected, checked, @@ -61,8 +50,6 @@ const queryAllByRole: AllByRole = ( } = {}, ) => { checkContainerType(container) - const matcher = exact ? matches : fuzzyMatches - const matchNormalizer = makeNormalizer({collapseWhitespace, trim, normalizer}) if (selected !== undefined) { // guard against unknown roles @@ -136,7 +123,7 @@ const queryAllByRole: AllByRole = ( return Array.from( container.querySelectorAll( // Only query elements that can be matched by the following filters - makeRoleSelector(role, exact, normalizer ? matchNormalizer : undefined), + makeRoleSelector(role), ), ) .filter(node => { @@ -148,22 +135,18 @@ const queryAllByRole: AllByRole = ( return roleValue .split(' ') .filter(Boolean) - .some(text => matcher(text, node, role as Matcher, matchNormalizer)) - } - // if a custom normalizer is passed then let normalizer handle the role value - if (normalizer) { - return matcher(roleValue, node, role as Matcher, matchNormalizer) + .some(roleAttributeToken => roleAttributeToken === role) } - // other wise only send the first word to match - const [firstWord] = roleValue.split(' ') - return matcher(firstWord, node, role as Matcher, matchNormalizer) + // other wise only send the first token to match + const [firstRoleAttributeToken] = roleValue.split(' ') + return firstRoleAttributeToken === role } const implicitRoles = getImplicitAriaRoles(node) as string[] - return implicitRoles.some(implicitRole => - matcher(implicitRole, node, role as Matcher, matchNormalizer), - ) + return implicitRoles.some(implicitRole => { + return implicitRole === role + }) }) .filter(element => { if (selected !== undefined) { @@ -228,18 +211,8 @@ const queryAllByRole: AllByRole = ( }) } -function makeRoleSelector( - role: ByRoleMatcher, - exact: boolean, - customNormalizer?: NormalizerFn, -) { - if (typeof role !== 'string') { - // For non-string role parameters we can not determine the implicitRoleSelectors. - return '*' - } - - const explicitRoleSelector = - exact && !customNormalizer ? `*[role~="${role}"]` : '*[role]' +function makeRoleSelector(role: ByRoleMatcher) { + const explicitRoleSelector = `*[role~="${role}"]` const roleRelations = roleElements.get(role as ARIARoleDefinitionKey) ?? new Set() diff --git a/types/__tests__/type-tests.ts b/types/__tests__/type-tests.ts index b0240e6a..4e1a4fb2 100644 --- a/types/__tests__/type-tests.ts +++ b/types/__tests__/type-tests.ts @@ -183,9 +183,7 @@ export async function testByRole() { ) console.assert(queryByRole(element, 'foo') === null) - console.assert(queryByRole(element, /foo/) === null) console.assert(screen.queryByRole('foo') === null) - console.assert(screen.queryByRole(/foo/) === null) } export function testA11yHelper() { diff --git a/types/matches.d.ts b/types/matches.d.ts index 13fa3692..9df51680 100644 --- a/types/matches.d.ts +++ b/types/matches.d.ts @@ -7,8 +7,8 @@ export type MatcherFunction = ( export type Matcher = MatcherFunction | RegExp | number | string // Get autocomplete for ARIARole union types, while still supporting another string -// Ref: https://github.com/microsoft/TypeScript/issues/29729#issuecomment-505826972 -export type ByRoleMatcher = ARIARole | MatcherFunction | {} +// Ref: https://github.com/microsoft/TypeScript/issues/29729#issuecomment-567871939 +export type ByRoleMatcher = ARIARole | (string & {}) export type NormalizerFn = (text: string) => string diff --git a/types/queries.d.ts b/types/queries.d.ts index 1fb66b7d..cea02365 100644 --- a/types/queries.d.ts +++ b/types/queries.d.ts @@ -66,7 +66,9 @@ export type FindByText = ( waitForElementOptions?: waitForOptions, ) => Promise -export interface ByRoleOptions extends MatcherOptions { +export interface ByRoleOptions { + /** suppress suggestions for a specific query */ + suggest?: boolean /** * If true includes elements in the query set that are usually excluded from * the accessibility tree. `role="none"` or `role="presentation"` are included