Bốn nguyên nhân chiếm phần lớn trường hợp:
1. Text bị chia nhỏ qua nhiều element. getByText mặc định so khớp trên từng node text riêng lẻ, không phải chuỗi ghép lại của cả cây DOM.
// <p>Xin chao, <strong>Dinh</strong></p>
screen.getByText("Xin chao, Dinh") // fails
screen.getByText(/xin chao/i) // works: matches the text node onlyCần khớp cả cụm thì dùng hàm matcher hoặc query theo phần tử cha rồi assert toHaveTextContent.
2. So khớp mặc định là exact + normalize whitespace. getByText("Save") không khớp "Save " viết hoa khác hoặc "Save changes". Dùng regex hoặc { exact: false }.
3. Nội dung xuất hiện bất đồng bộ. Nếu chữ chỉ có sau khi fetch xong thì getBy* (đồng bộ) chạy quá sớm — phải dùng findByText (trả về Promise, tự retry).
4. Element bị ẩn. getByRole mặc định bỏ qua node bị ẩn khỏi accessibility tree (display: none, aria-hidden, hidden). Với getByText thì ignore mặc định loại script/style.
Cách debug nhanh: screen.debug() để in DOM hiện tại, hoặc logRoles(container) để xem danh sách role và accessible name mà Testing Library nhìn thấy.