This post assumes you've already fiddled with RedwoodJS and are looking further into it for something you'd show the world. It is about testing & translation, hence the title. If you have experience with both topics, the article might not be very relevant to you, instead I'd suggest checking out RedwoodJS.
Context
A while back as I was trying to set up my current project, I tried to follow the Redwood Way ( no definitive specification on that one as of yet, AFAIK ) and implement frontend tests. I had never worked with frontend tests before and soon enough I stumbled onto performance issues. The ticket doesn't show the real story, but what happened was that I had errors thrown and no way to gather enough information to understand what was going on - and having to wait 90 seconds for any file update quickly became an obstacle I couldn't deal with.
I left the frontend tests aside until @jtoar pinged me on the original issue this week. v0.42 ships with improvements on testing, I had to try it and see where we were at now.
To do so I met my following problem: tests were still failing, but in 10s, which is way better and let me investigate a bit more the core of my problem - translation.
Hands on
If your application supports translation, you may find yourself with many components relying on i18n
's ( or your library of choice to handle that ) functions or components. Those may impair your tests if you do not use proper mocks.
Fortunately this is rather straightforward. This example works with react-i18next
.
First, let's define a component that will use the library. Let's KISS this:
import { useTranslation } from 'react-i18next'
const Input = ({ pointer, name }) => {
const { t } = useTranslation()
return (
<div>
<label>{t(pointer)}</label>
<input name={name} />
</div>
)
}
export default Input
Second, we need to define a test configuration for the library:
# src/configuration/i18nForTests.ts
import i18n from 'i18next'
i18n
.init({
lng: 'en',
fallbackLng: 'en',
// have a common namespace used around the full app
ns: ['site'],
defaultNS: 'site',
debug: false,
interpolation: {
escapeValue: false, // not needed for react!!
},
resources: { fr: { site: {} } },
})
export default i18n
Finally, we can run some tests:
import 'src/configuration/i18nForTests'
import { fireEvent, render, screen } from '@redwoodjs/testing'
import Input from './Input'
jest.mock('react-i18next', () => ({
// this mock makes sure any components using the translate hook can use it without a warning being shown
useTranslation: () => {
return {
t: (str) => str,
i18n: {
changeLanguage: () => new Promise(() => {}),
},
}
},
}))
describe('UI/Input', function () {
it('Renders successfully', function () {
render(<Input name={'someInput'} pointer={'site:input.text'} />)
expect(screen.getByRole('textbox')).toBeInstanceOf(HTMLInputElement)
})
})
That should do the trick. 10s of success, now!
There's a debug
prop in the configuration object for i18n
, if set to true you'll get information about missing keys. I haven't played with that, but if I had time, that could be valuable.
Happy coding.
Notes
RedwoodJS let's you setup translation with an out of the box cli command:
yarn rw setup i18n
If you pickup RedwoodJS and don't have strong preferences on translation libs, there's a solution for you.
Top comments (0)