screen.getByText('3 mm') can never match an element containing a no-break space, even when the component renders perfectly. Testing Library’s default normalizer collapses U+00A0 to a plain space before comparing, while your matcher string is compared raw. The two are never equal.
Why this wastes time
The failure reads like a bug in the formatting code — the output “looks right” in the DOM dump, because U+00A0 and U+0020 are visually identical. The rendered output is correct the whole time; only the query is wrong.
Root cause
Testing Library’s default normalizer trims, then runs replace(/\s+/g, ' ') over the element’s text. JavaScript’s \s character class includes U+00A0 (along with the rest of Unicode Zs, plus U+FEFF, U+2028, U+2029).
So for <span>3\u00A0mm</span>:
Side
Value compared
DOM text, after normalization
3 + U+0020 + mm
Matcher string (never normalized)
3 + U+00A0 + mm
Not equal. No amount of fixing the formatter helps.
Fix — turn collapsing off for that query
import { getDefaultNormalizer, render, screen } from '@testing-library/react'import { Data } from '../src/components/Data'const NBSP = '\u00A0'const literal = { normalizer: getDefaultNormalizer({ collapseWhitespace: false }) }render(<Data value={3} unit="mm" locale="hu" />)expect(screen.getByText(`3${NBSP}mm`, literal)).toBeDefined()
getDefaultNormalizer({ collapseWhitespace: false }) keeps trimming (usually what you want) but stops the whitespace squash. Define literal once at module scope and pass it to every query that asserts on a formatted number.
The wrong fix, and why it matters
The obvious alternative is to give up and assert on a plain space:
expect(screen.getByText('3 mm')).toBeDefined() // DO NOT
This passes. It also passes when the formatter emits a breaking U+0020 — which is the exact regression the test exists to catch. Because the normalizer collapses both, a plain-space matcher can no longer tell a correct render from a broken one. Turning off collapsing keeps the test meaningful; matching a plain space quietly guts it.
Why muetal is full of NBSP
Law 2 (mono owns every number) routes all numeric output through one component, so U+00A0 shows up in two independent places:
formatMeasure() joins value and unit with \u00A0 so 3 mm never wraps across a line — packages/ui/src/lib/format.ts.
Hungarian’s thousands separator is itself U+00A0. formatNumber(1200, 'hu') returns 1 + U+00A0 + 200, so formatMeasure(1200, 'db', 'hu') contains two no-break spaces.
Related, verified: Intl.NumberFormat('hu-HU').format(1000) returns "1000" — no grouping at all for 4-digit values. muetal passes useGrouping: true explicitly to force 1 + U+00A0 + 000. If you drop that option, the grouping tests fail rather than the NBSP ones.
Applies beyond getByText
getByRole(role, { name }) matches the accessible name, whose computation also normalizes whitespace. Do not try to assert an NBSP through name:; assert on the text node instead.
toHaveTextContent (jest-dom) normalizes whitespace by default and takes { normalizeWhitespace: false } as a third argument. muetal does not install jest-dom today — worth knowing if it is added later.
The same collapse applies to any Unicode space the formatter may emit: narrow no-break space (U+202F), thin space (U+2009), figure space (U+2007). Some locales/Intl versions use these instead of U+00A0, so assert on the value the formatter actually returns rather than on the one you assume.
Debug in one line
Before assuming the formatter is broken, print codepoints: