-
Notifications
You must be signed in to change notification settings - Fork 69
Troubleshooting
Here's a list of the most common errors and how you could fix them
screen
is an object that has all the queries to retrieve elements from the DOM.
- Import it with
import { screen } from '@testing-library/react'
This error occurs when multiple elements in the document has the same text.
To fix it, you could try screen.getAll*(TEXT)
(e.g., screen.getAllByText(TEXT)
) then select the index for the element.
To find the element index, run yarn jest
but with the DEBUG_PRINT_LIMIT=100000
so it prints all the HTML document.
For the HTML document to show, the function must throw an error. Try to use await screen.findByText(TEXT)
that will throw an error as there are multiple occurrences of the element then locate the element.
Example:
// Throws error because there are 2 elements with this text
const dropdownBtn = await screen.findByText('Select a module')
await userEvent.click(dropdownBtn)
Now we run yarn DEBUG_PRINT_LIMIT=100000 jest <TEST_PATH>
When we intentionally throw an error with screen.findByText
, it prints this HTML:
As we can see, there are two elements with the text Select a module
so it throws an error.
We want the second element that has the text Select a module
which is the dropdown menu. Therefore, we can update our code to:
// [1] will select the dropdown menu
const dropdownBtn = await screen.findAllByText('Select a module')[1]
await userEvent.click(dropdownBtn)
Fun fact, this solution didn't work for us. We had to get the element by its ID. So, here's an alternative if that didn't work:
const dropdownBtn = container.querySelector('#dropdown-lesson')
await userEvent.click(dropdownBtn)
This happens when when the component has an async
code that executes when a certain action happen (e.g., click a button).
To fix it, we can use an waitFor
or if it's an element we're looking for, we can use screen.find*
(e.g, screen.findByText
):
findByText
it('should successfully add an exercise', async () => {
const submitButton = screen.queryByText('Save exercise')
// A mutation is run when the submit button is clicked
// Therefore, we must wait for it as it is async and we are awaiting it
// The mutation code: `await addExercise()`
await userEvent.click(submitButton)
expect(await screen.findByText('Added the exercise successfully!'))
}
waitFor
from '@testing-library/react'
it('should not submit when inputs are empty', async () => {
const submitButton = await screen.findByText('Save exercise')
await userEvent.click(submitButton)
// Alt for findAllByText
await waitFor(() => {
expect(screen.queryAllByText('Required')[0]).toBeInTheDocument()
})
}
After updating getApp
query, you must update its dummy data in order for the mocked queries to return the data of the query correctly.
If you added the following field to the query, you must add it for each lesson object in the dummy data:
getApp.ts
// ...
modules {
id
name
content
order
}
/ ...
lessonData.ts
const dummyLessonsData: Lesson[] = [
// Some lesson
{
// ...
modules: [
{
id: 1,
name: 'module1',
content: 'this is module1',
order: 1,
author: moduleAuthor,
lesson: {
title: 'Foundations of JavaScript',
order: 0,
slug: 'js0',
id: 5,
description: 'A super simple introduction to help you get started!',
challenges: []
}
},
]
// ...
}
]
This isn't the most efficient way to create fake data for our queries. Here's one solution