How to fix Text content does not match. Expected: "..." but received: "..." in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025ยท 111 views

This error occurs when React Testing Library's text matching queries (getByText, findByText) fail because the actual text content in the DOM does not match the expected text pattern. It often happens due to whitespace differences, text split across elements, or asynchronous content updates.

Quick fix

Fixes Text content does not match. Expected: "..." but received: "..."

// Problem: trailing space in DOM
<div>Login </div>

// Fails: exact match
screen.getByText("Login");

// Solution 1: trim text content
const element = screen.getByText((content, element) => {
  return element.textContent.trim() === "Login";
});

// Solution 2: include whitespace in query
screen.getByText("Login ");

// Solution 3: use regex with optional whitespace
screen.getByText(/^Login\s*$/);
  1. Check for whitespace differences
  2. Handle text split across elements
  3. Handle asynchronous text updates
  4. Use regex for flexible matching
react โ€” error
// Problem: trailing space in DOM
<div>Login </div>
// Fails: exact match
screen.getByText("Login");
// Solution 1: trim text content
const element = screen.getByText((content, element) => {
return element.textContent.trim() === "Login";
});
// Solution 2: include whitespace in query
screen.getByText("Login ");
// Solution 3: use regex with optional whitespace
screen.getByText(/^Login\s*$/);
Text content does not match. Expected: "..." but received: "..."

What this error means

The "Text content does not match" error indicates that React Testing Library cannot find an element with the specified text content. This happens when the text query (using exact string, regex, or function) does not match any element's textContent in the rendered DOM. The error message shows both the expected text pattern and the actual text received, helping identify mismatches in whitespace, formatting, or element structure.

Typical symptoms

  • Tests fail with "Text content does not match. Expected: "Login" but received: "Login " (with trailing space)
  • getByText or findByText queries return TestingLibraryElementError
  • Text appears visually correct but fails exact string matching
  • Text split across multiple elements (like <span> tags) causes matching failures
  • Dynamic text content (like loading states) causes intermittent failures
  • Whitespace differences (newlines, tabs, multiple spaces) cause mismatches

Common causes

  1. Exact string matching fails due to whitespace differences (trailing/leading spaces)
  2. Text content is split across multiple HTML elements (e.g., text with <span> or <strong> tags in the middle)
  3. Asynchronous content updates not properly awaited (text changes after initial render)
  4. Using exact string matching when text contains dynamic parts (timestamps, IDs, counts)
  5. Hidden text nodes or comments affecting textContent calculation
  6. Case sensitivity mismatches when not using regex with ignoreCase flag
  7. Text normalization differences between browser and test environment

How to fix "Text content does not match. Expected: "..." but received: "...""

1Check for whitespace differences

The most common cause is whitespace mismatches. Use .trim() on expected strings or include whitespace in your query. You can also use regex with \s* to match optional whitespace.

jsx
// Problem: trailing space in DOM
<div>Login </div>

// Fails: exact match
screen.getByText("Login");

// Solution 1: trim text content
const element = screen.getByText((content, element) => {
  return element.textContent.trim() === "Login";
});

// Solution 2: include whitespace in query
screen.getByText("Login ");

// Solution 3: use regex with optional whitespace
screen.getByText(/^Login\s*$/);
2Handle text split across elements

When text is broken by HTML elements, getByText looks at individual text nodes. Use a custom text matcher function or query by partial text.

jsx
// Problem: text split by <span>
<div>2<span>-</span>3</div>

// Fails: looks for "2-3" in a single text node
screen.getByText("2-3");

// Solution 1: query by partial text
screen.getByText("2");
screen.getByText("3");

// Solution 2: custom text matcher function
screen.getByText((content, element) => {
  return element.textContent === "2-3";
});

// Solution 3: getByTextContent helper function
function getByTextContent(text) {
  return screen.getByText((content, element) => {
    return element.textContent === text;
  });
}

const element = getByTextContent("2-3");
3Handle asynchronous text updates

If text content changes after initial render (loading states, API responses), use findByText instead of getByText. findByText returns a Promise and waits for matching text to appear.

jsx
// Using getByText (fails if text not immediately present)
// screen.getByText("Loading...");

// Using findByText (waits for text)
const loadingElement = await screen.findByText("Loading...");

// With custom timeout
const element = await screen.findByText("Data loaded", {}, { timeout: 5000 });

// For text that appears then disappears (like loading states)
await waitFor(() => {
  expect(screen.queryByText("Loading...")).not.toBeInTheDocument();
});
4Use regex for flexible matching

Regular expressions provide more flexible text matching. Use them for case-insensitive matches, partial matches, or patterns with dynamic content.

jsx
// Case insensitive matching
screen.getByText(/login/i);

// Partial text matching
screen.getByText(/Log/); // matches "Login", "Logout", "Logger"

// Match dynamic content (like counts)
screen.getByText(/Items: \d+/); // matches "Items: 5", "Items: 10"

// Match with optional whitespace
screen.getByText(/^\s*Login\s*$/);

// Complex pattern matching
screen.getByText(/User:\s*\w+\s*\(ID: \d+\)/);
5Debug text content with screen.debug()

Use screen.debug() to see the exact DOM structure and text nodes. This helps identify whitespace issues, element splitting, or unexpected text content.

jsx
import { screen } from '@testing-library/react';

// Render your component
render(<MyComponent />);

// Print entire DOM to console
screen.debug();

// Print specific element
const element = screen.getByTestId('my-element');
screen.debug(element);

// Check textContent directly
console.log('Text content:', element.textContent);
console.log('Inner HTML:', element.innerHTML);

// Use logTestingPlaygroundURL for visual debugging
screen.logTestingPlaygroundURL();
6Normalize text before comparison

For complex text matching scenarios, create a helper function to normalize text content before comparison. This handles whitespace, case, and special characters consistently.

jsx
function normalizeText(text) {
  return text
    .trim()
    .replace(/\s+/g, ' ') // collapse multiple spaces
    .replace(/\n/g, ' ') // replace newlines with spaces
    .toLowerCase(); // optional: for case-insensitive
}

// Use in custom matcher
screen.getByText((content, element) => {
  const normalizedActual = normalizeText(element.textContent);
  const normalizedExpected = normalizeText("Expected Text");
  return normalizedActual === normalizedExpected;
});

// Or as a reusable query
function getByNormalizedText(expectedText) {
  return screen.getByText((content, element) => {
    return normalizeText(element.textContent) === normalizeText(expectedText);
  });
}

const element = getByNormalizedText("  Login  "); // handles extra spaces

Advanced notes

React Testing Library's text matching uses the DOM textContent property, which includes text from all descendant nodes. However, it matches against individual text nodes when using string queries. The getByText function has three signatures: string (exact match), regex (pattern match), and function (custom matcher). For complex text scenarios, custom matcher functions provide the most control. Note that textContent includes hidden text (from display: none elements) but not text from aria-hidden="true" elements. When testing internationalized applications, consider text normalization for different languages and character sets.

Frequently asked questions

What does "Text content does not match. Expected: "..." but received: "..."" mean?
The "Text content does not match" error indicates that React Testing Library cannot find an element with the specified text content. This happens when the text query (using exact string, regex, or function) does not match any element's textContent in the rendered DOM. The error message shows both the expected text pattern and the actual text received, helping identify mismatches in whitespace, formatting, or element structure.
How do I fix "Text content does not match. Expected: "..." but received: "...""?
This error occurs when React Testing Library's text matching queries (getByText, findByText) fail because the actual text content in the DOM does not match the expected text pattern. It often happens due to whitespace differences, text split across elements, or asynchronous content updates.
What causes "Text content does not match. Expected: "..." but received: "...""?
Exact string matching fails due to whitespace differences (trailing/leading spaces) Text content is split across multiple HTML elements (e.g., text with <span> or <strong> tags in the middle) Asynchronous content updates not properly awaited (text changes after initial render)
Is the "Text content does not match. Expected: "..." but received: "..."" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading