This error occurs when React Testing Library cannot locate an element containing the specified text in your rendered component. It's one of the most common testing failures and usually indicates issues with text matching, async rendering, or component state.
The "Unable to find an element with the text:" error in React Testing Library means your test tried to find an element (like a button, heading, or paragraph) containing specific text, but no matching element was found in the rendered DOM. This typically happens because: 1. The text doesn't match exactly (including case, whitespace, or punctuation) 2. The element hasn't rendered yet (async operations) 3. The component is in a different state than expected 4. The text is nested inside another element or component Testing Library uses exact text matching by default, so even minor differences like extra spaces or line breaks can cause this failure.
Check that the text in your query exactly matches what's rendered, including:
- Case sensitivity (Hello vs hello)
- Whitespace (extra spaces, line breaks)
- Punctuation
- Special characters
Use screen.debug() to see the rendered DOM:
import { screen } from '@testing-library/react';
// Debug to see exact rendered output
screen.debug();
// Then check your query matches exactly
const element = screen.getByText('Exact Text Here');If the element renders after async operations, use findByText instead of getByText:
// ❌ Fails if element renders async
const element = screen.getByText('Loading...');
// ✅ Waits for element to appear (up to default timeout)
const element = await screen.findByText('Data loaded');
// ✅ With custom timeout
const element = await screen.findByText('Data loaded', {}, { timeout: 3000 });findBy queries automatically wait for the element to appear (default 1000ms timeout).
Ensure the element is actually visible and accessible:
// Check if element is hidden
const element = screen.getByText('Submit');
expect(element).not.toHaveStyle('display: none');
expect(element).not.toHaveAttribute('aria-hidden', 'true');
// Use getByRole for better accessibility testing
const button = screen.getByRole('button', { name: /submit/i });
// Check if in document but not visible
const element = screen.queryByText('Submit');
if (element) {
console.log('Element exists but might be hidden:', element);
}Use regex or string matching options for partial or case-insensitive matches:
// Exact match (default)
screen.getByText('Hello World');
// Case-insensitive regex
screen.getByText(/hello world/i);
// Partial text match
screen.getByText('Hello', { exact: false });
// Contains specific text
screen.getByText((content, element) => {
return content.includes('Hello') && element.tagName === 'BUTTON';
});Use Testing Playground to visually debug your rendered component:
import { screen } from '@testing-library/react';
// Generates a URL to visualize your rendered DOM
screen.logTestingPlaygroundURL();
// Or get the HTML directly
console.log(screen.container.innerHTML);
// Use prettyDOM for formatted output
import { prettyDOM } from '@testing-library/react';
console.log(prettyDOM(screen.container));Visit the generated URL to see your rendered component and test queries interactively.
Ensure your component is receiving the correct props and is in the expected state:
// Mock necessary dependencies
jest.mock('../api', () => ({
fetchData: jest.fn().mockResolvedValue({ data: 'test' })
}));
// Set up initial state
const initialState = { loading: false, data: 'Expected Text' };
render(<MyComponent initialState={initialState} />);
// Or use act for state updates
import { act } from '@testing-library/react';
await act(async () => {
// Trigger state update
fireEvent.click(screen.getByText('Load Data'));
});
// Now query for the element
expect(await screen.findByText('Expected Text')).toBeInTheDocument();Testing Library Philosophy: Remember that Testing Library encourages testing from the user's perspective. Instead of testing implementation details, focus on what users see and interact with.
Common Pitfalls:
1. Over-specification: Testing exact text when users would recognize partial text
2. Implementation coupling: Testing text that might change frequently
3. Missing await: Forgetting to await async operations before querying
4. Incorrect query choice: Using getByText when getByRole would be more appropriate
Best Practices:
- Prefer getByRole over getByText for interactive elements
- Use findBy for anything that appears asynchronously
- Add data-testid as a last resort for elements that are hard to query
- Keep tests resilient to text changes by using partial matches or test IDs for critical elements
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite