Disallow the use of getBy*
queries when checking elements are not present (no-get-by-for-checking-element-not-present)
The (DOM) Testing Library allows to query DOM elements using different types of queries such as getBy*
and queryBy*
. Using getBy*
throws an error in case the element is not found. This is useful when:
- using method like
waitForElement
, which areasync
functions that will wait for the element to be found until a certain timeout, after that the test will fail. - using
getBy
queries as an assert itself, so if the element is not found the error thrown will work as the check itself within the test.
However, when asserting if an element is not present or waiting for disappearance, using getBy*
will make the test fail immediately. Instead it is recommended to use queryBy*
, which does not throw and therefore we can:
- assert element does not exist:
expect(queryByText("Foo")).not.toBeInTheDocument()
- wait for disappearance:
await waitForElementToBeRemoved(() => queryByText('the mummy'))
This rule fires whenever:
expect
is used to assert element does not exist with.not.toBeInTheDocument()
or.toBeNull()
matcherswaitForElementToBeRemoved
async util is used to wait for element to be removed from DOM
Examples of incorrect code for this rule:
test('some test', () => {
const { getByText } = render(<App />);
expect(getByText('Foo')).not.toBeInTheDocument();
expect(getByText('Foo')).not.toBeTruthy();
expect(getByText('Foo')).toBeFalsy();
expect(getByText('Foo')).toBeNull();
});
test('some test', async () => {
const utils = render(<App />);
await waitForElementToBeRemoved(() => utils.getByText('Foo'));
});
Examples of correct code for this rule:
test('some test', () => {
const { getByText } = render(<App />);
expect(getByText('Foo')).toBeInTheDocument();
expect(getByText('Foo')).not.toBeDisabled();
expect(queryByText('Foo')).not.toBeInTheDocument();
expect(queryByText('Foo')).toBeFalsy();
});
test('some test', async () => {
const utils = render(<App />);
await waitForElementToBeRemoved(() => utils.queryByText('Foo'));
});