diff --git a/src/__tests__/__snapshots__/get-by-errors.js.snap b/src/__tests__/__snapshots__/get-by-errors.js.snap new file mode 100644 index 00000000..45f4cde1 --- /dev/null +++ b/src/__tests__/__snapshots__/get-by-errors.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`getByLabelText query will throw the custom error returned by config.getElementError 1`] = `"My custom error: Unable to find a label with the text of: TEST QUERY"`; + +exports[`getByText query will throw the custom error returned by config.getElementError 1`] = `"My custom error: Unable to find an element with the text: TEST QUERY. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible."`; diff --git a/src/__tests__/get-by-errors.js b/src/__tests__/get-by-errors.js index 6069caec..c7e8cadf 100644 --- a/src/__tests__/get-by-errors.js +++ b/src/__tests__/get-by-errors.js @@ -1,6 +1,13 @@ import cases from 'jest-in-case' +import {screen} from '../' +import {configure, getConfig} from '../config' import {render} from './helpers/test-utils' +const originalConfig = getConfig() +beforeEach(() => { + configure(originalConfig) +}) + cases( 'getBy* queries throw an error when there are multiple elements returned', ({name, query, html}) => { @@ -39,6 +46,19 @@ cases( }, ) +test.each([['getByText'], ['getByLabelText']])( + '%s query will throw the custom error returned by config.getElementError', + query => { + const getElementError = jest.fn( + (message, _container) => new Error(`My custom error: ${message}`), + ) + configure({getElementError}) + document.body.innerHTML = '
Hello
' + expect(() => screen[query]('TEST QUERY')).toThrowErrorMatchingSnapshot() + expect(getElementError).toBeCalledTimes(1) + }, +) + cases( 'queryBy* queries throw an error when there are multiple elements returned', ({name, query, html}) => { diff --git a/src/config.js b/src/config.js index f8109352..dbb80da0 100644 --- a/src/config.js +++ b/src/config.js @@ -1,3 +1,5 @@ +import {prettyDOM} from './pretty-dom' + // It would be cleaner for this to live inside './queries', but // other parts of the code assume that all exports from // './queries' are query functions. @@ -14,6 +16,13 @@ let config = { asyncWrapper: cb => cb(), // default value for the `hidden` option in `ByRole` queries defaultHidden: false, + + // called when getBy* queries fail. (message, container) => Error + getElementError(message, container) { + return new Error( + [message, prettyDOM(container)].filter(Boolean).join('\n\n'), + ) + }, } export function configure(newConfig) { diff --git a/src/queries/label-text.js b/src/queries/label-text.js index 3669db20..59fce539 100644 --- a/src/queries/label-text.js +++ b/src/queries/label-text.js @@ -1,8 +1,8 @@ +import {getConfig} from '../config' import { fuzzyMatches, matches, makeNormalizer, - getElementError, queryAllByAttribute, makeFindQuery, makeSingleQuery, @@ -104,12 +104,12 @@ function getAllByLabelText(container, text, ...rest) { if (!els.length) { const labels = queryAllLabelsByText(container, text, ...rest) if (labels.length) { - throw getElementError( + throw getConfig().getElementError( `Found a label with the text of: ${text}, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.`, container, ) } else { - throw getElementError( + throw getConfig().getElementError( `Unable to find a label with the text of: ${text}`, container, ) diff --git a/src/query-helpers.js b/src/query-helpers.js index 062e9df9..3c3295ae 100644 --- a/src/query-helpers.js +++ b/src/query-helpers.js @@ -1,13 +1,9 @@ -import {prettyDOM} from './pretty-dom' import {fuzzyMatches, matches, makeNormalizer} from './matches' import {waitForElement} from './wait-for-element' - -function getElementError(message, container) { - return new Error([message, prettyDOM(container)].filter(Boolean).join('\n\n')) -} +import {getConfig} from './config' function getMultipleElementsFoundError(message, container) { - return getElementError( + return getConfig().getElementError( `${message}\n\n(If this is intentional, then use the \`*AllBy*\` variant of the query (like \`queryAllByText\`, \`getAllByText\`, or \`findAllByText\`)).`, container, ) @@ -59,7 +55,10 @@ function makeGetAllQuery(allQuery, getMissingError) { return (container, ...args) => { const els = allQuery(container, ...args) if (!els.length) { - throw getElementError(getMissingError(container, ...args), container) + throw getConfig().getElementError( + getMissingError(container, ...args), + container, + ) } return els } @@ -86,7 +85,6 @@ function buildQueries(queryAllBy, getMultipleError, getMissingError) { } export { - getElementError, getMultipleElementsFoundError, queryAllByAttribute, queryByAttribute,