diff --git a/src/__tests__/suggestions.js b/src/__tests__/suggestions.js index 39353d1b..67423e9b 100644 --- a/src/__tests__/suggestions.js +++ b/src/__tests__/suggestions.js @@ -353,3 +353,95 @@ test('getSuggestedQuery returns rich data for tooling', () => { expect(getSuggestedQuery(div).toString()).toEqual(`getByText(/cancel/i)`) }) + +test('getSuggestedQuery can return specified methods in addition to the best', () => { + const {container} = render(` + + + + `) + + const input = container.querySelector('input') + const button = container.querySelector('button') + + expect(getSuggestedQuery(input, 'get', 'Role')).toMatchObject({ + queryName: 'Role', + queryMethod: 'getByRole', + queryArgs: ['textbox', {name: /label/i}], + variant: 'get', + }) + + expect(getSuggestedQuery(input, 'get', 'LabelText')).toMatchObject({ + queryName: 'LabelText', + queryMethod: 'getByLabelText', + queryArgs: [/label/i], + variant: 'get', + }) + + expect(getSuggestedQuery(input, 'get', 'PlaceholderText')).toMatchObject({ + queryName: 'PlaceholderText', + queryMethod: 'getByPlaceholderText', + queryArgs: [/placeholder/i], + variant: 'get', + }) + + expect(getSuggestedQuery(button, 'get', 'Text')).toMatchObject({ + queryName: 'Text', + queryMethod: 'getByText', + queryArgs: [/button/], + variant: 'get', + }) + + expect(getSuggestedQuery(input, 'get', 'DisplayValue')).toMatchObject({ + queryName: 'DisplayValue', + queryMethod: 'getByDisplayValue', + queryArgs: [/value/i], + variant: 'get', + }) + + expect(getSuggestedQuery(input, 'get', 'AltText')).toMatchObject({ + queryName: 'AltText', + queryMethod: 'getByAltText', + queryArgs: [/alt/], + variant: 'get', + }) + + expect(getSuggestedQuery(input, 'get', 'Title')).toMatchObject({ + queryName: 'Title', + queryMethod: 'getByTitle', + queryArgs: [/title/i], + variant: 'get', + }) + + expect(getSuggestedQuery(input, 'get', 'TestId')).toMatchObject({ + queryName: 'TestId', + queryMethod: 'getByTestId', + queryArgs: ['testid'], + variant: 'get', + }) + + // return undefined if requested query can't be made + expect(getSuggestedQuery(button, 'get', 'TestId')).toBeUndefined() +}) + +test('getSuggestedQuery does not create suggestions for script and style elements', () => { + const {container} = render(` + + + `) + + const script = container.querySelector('script') + const style = container.querySelector('style') + + expect(getSuggestedQuery(script, 'get', 'TestId')).toBeUndefined() + expect(getSuggestedQuery(style, 'get', 'TestId')).toBeUndefined() +}) diff --git a/src/suggestions.js b/src/suggestions.js index a8b3f0e6..258a3454 100644 --- a/src/suggestions.js +++ b/src/suggestions.js @@ -35,7 +35,11 @@ function getRegExpMatcher(string) { } function makeSuggestion(queryName, content, {variant = 'get', name}) { - const queryArgs = [queryName === 'Role' ? content : getRegExpMatcher(content)] + const queryArgs = [ + queryName === 'Role' || queryName === 'TestId' + ? content + : getRegExpMatcher(content), + ] if (name) { queryArgs.push({name: new RegExp(escapeRegExp(name.toLowerCase()), 'i')}) @@ -64,10 +68,19 @@ function makeSuggestion(queryName, content, {variant = 'get', name}) { } } -export function getSuggestedQuery(element, variant) { +function canSuggest(currentMethod, requestedMethod, data) { + return data && (!requestedMethod || requestedMethod === currentMethod) +} + +export function getSuggestedQuery(element, variant, method) { + // don't create suggestions for script and style elements + if (element.matches(DEFAULT_IGNORE_TAGS)) { + return undefined + } + const role = element.getAttribute('role') ?? getImplicitAriaRoles(element)?.[0] - if (role) { + if (canSuggest('Role', method, role)) { return makeSuggestion('Role', role, { variant, name: computeAccessibleName(element), @@ -75,34 +88,38 @@ export function getSuggestedQuery(element, variant) { } const labelText = getLabelTextFor(element) - if (labelText) { + if (canSuggest('LabelText', method, labelText)) { return makeSuggestion('LabelText', labelText, {variant}) } const placeholderText = element.getAttribute('placeholder') - if (placeholderText) { + if (canSuggest('PlaceholderText', method, placeholderText)) { return makeSuggestion('PlaceholderText', placeholderText, {variant}) } const textContent = normalize(getNodeText(element)) - if (textContent && !element.matches(DEFAULT_IGNORE_TAGS)) { + if (canSuggest('Text', method, textContent)) { return makeSuggestion('Text', textContent, {variant}) } - if (element.value) { + if (canSuggest('DisplayValue', method, element.value)) { return makeSuggestion('DisplayValue', normalize(element.value), {variant}) } const alt = element.getAttribute('alt') - if (alt) { + if (canSuggest('AltText', method, alt)) { return makeSuggestion('AltText', alt, {variant}) } const title = element.getAttribute('title') - - if (title) { + if (canSuggest('Title', method, title)) { return makeSuggestion('Title', title, {variant}) } + const testId = element.getAttribute('data-testid') + if (canSuggest('TestId', method, testId)) { + return makeSuggestion('TestId', testId, {variant}) + } + return undefined }