In my react app, I use a custom hook to retrieve localized text from a JSON file with translations. It works fine, but whenever I use testing-library to run tests expecting to find text, the text cannot be found, because the hook has not fired and populated the text at the time that the snapshot of the component is taken. I am wondering if there is a way to properly test this?
//locales JSON file
"LABELS": {
"WELCOME": {
"title": "Welcome"
},
}
//homepage.ts
const homePageText = [
{
variableName: "welcomeText",
key: "LABELS.WELCOME.title",
defaultValue: "Welcome",
},
//useGetLocalizedText custom hook
import { useMemo, useState } from "react"
import { useSelector } from "react-redux"
import translate from "@localization/translate"
import intl from "react-intl-universal"
export const useGetLocalizedText = (moduleName: string) => {
const [messages, setMessages] = useState([])
;(async () => {
const msgArray = await import(
`@localization/modules/${moduleName}.ts`
).then((msgs) => msgs)
setMessages(msgArray?.default ? msgArray.default : [])
})()
const initComplete: boolean = testInitComplete ? testInitComplete : useSelector(
(state) => state.localization.initComplete
)
const localizedText = useMemo(() => {
const localizedTextTemp: any = {}
messages?.length > 0 &&
messages.forEach((msg) => {
localizedTextTemp[msg.variableName] = translate(
intl,
msg.key,
initComplete,
msg.defaultValue
)
})
return localizedTextTemp
}, [initComplete, messages])
return localizedText
}
export default useGetLocalizedText
//Homepage.tsx
const HomePage = () => {
const localizedText = useGetLocalizedText("homePage")
return (
<div>
<span> {localizedText.welcome} </span>
</div>
)
}
When I run the app, the text appears correctly, but when I run the tests the snapshot shows and empty span and I get the error "TestingLibraryElementError: Unable to find an element with the text: Funds Movement Template. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible."
//homepage-test.tsx
import React from "react"
import { customRender } from "../testUtils"
import { screen } from "@testing-library/react"
import HomePage from "@pages/home/"
describe("Home Page", () => {
it("renders without crashing", () => {
customRender(
<HomePage/>
)
expect(screen.getByText("Welcome")).toBeInTheDocument()
})
//snapshot
<div> <span> </span> <div>
So my question is, is there a way to run a test that will find this text/create the snapshot so the text is there? I know I can pass in hardcoded text as a prop simply for testing but don't think that is a great solution.