Skip to content
This repository was archived by the owner on Mar 5, 2022. It is now read-only.

Commit a5ea166

Browse files
Add i18n example (#413)
1 parent 1c9e798 commit a5ea166

File tree

9 files changed

+191
-13
lines changed

9 files changed

+191
-13
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ Spec | Description
182182
[radioactive-state](cypress/component/advanced/radioactive-state) | Testing components that use [radioactive-state](https://github.com/MananTank/radioactive-state) library
183183
[react-bootstrap](cypress/component/advanced/react-bootstrap) | Confirms [react-bootstrap](https://react-bootstrap.github.io/) components are working
184184
[select React component](cypress/component/advanced/react-book-example/src/components/ProductsList.spec.js) | Uses [cypress-react-selector](https://github.com/abhinaba-ghosh/cypress-react-selector) to find DOM elements using React component name and state values
185+
[i18n](cypress/component/advanced/i18n) | Uses[react-i18next](https://react.i18next.com/) for localizaiton.
185186
<!-- prettier-ignore-end -->
186187

187188
### Full examples
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as React from 'react'
2+
import { I18nextProvider } from 'react-i18next'
3+
import i18n from './i18n'
4+
import { LocalizedComponent } from './LocalizedComponent'
5+
6+
export function App() {
7+
return (
8+
<I18nextProvider i18n={i18n}>
9+
<LocalizedComponent count={15} name="SomeUserName" />
10+
</I18nextProvider>
11+
)
12+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as React from 'react'
2+
import { useTranslation, Trans } from 'react-i18next'
3+
4+
interface LocalizedComponentProps {
5+
name: string
6+
count: number
7+
}
8+
9+
export function LocalizedComponent({ name, count }: LocalizedComponentProps) {
10+
// See ./App.tsx for localization setup
11+
const { t } = useTranslation()
12+
13+
return (
14+
<Trans
15+
i18nKey={count === 1 ? 'userMessagesUnread' : 'userMessagesUnread_plural'}
16+
count={count}
17+
>
18+
Hello <strong> {{ name }} </strong>, you have {{ count }} unread message{' '}
19+
</Trans>
20+
)
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Localization Example
2+
3+
This example uses [react-i18next](https://react.i18next.com/) for app localization. Make sure that in "real life" application locale related setup performs at the root of application ([App.tsx](./App.tsx)) and the components are using context for localization.
4+
5+
Thats why in tests we also need to wrap our component with the same provider as our application. Using function composition we can create our own `mount` function which wraps the component with all required providers:
6+
7+
```js
8+
const localizedMount = (node, { locale }) => {
9+
mount(
10+
<I18nextProvider i18n={i18n.cloneInstance({ lng: locale })}>
11+
{node}
12+
</I18nextProvider>,
13+
)
14+
}
15+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import i18n from 'i18next'
2+
import { initReactI18next } from 'react-i18next'
3+
4+
i18n
5+
.use(initReactI18next) // passes i18n down to react-i18next
6+
.init({
7+
resources: {
8+
en: {
9+
translation: {
10+
userMessagesUnread:
11+
'Hello <1>{{name}}</1>, you have {{count}} unread message.',
12+
userMessagesUnread_plural:
13+
'Hello <1>{{name}}</1>, you have {{count}} unread messages.',
14+
},
15+
},
16+
ru: {
17+
translation: {
18+
userMessagesUnread:
19+
'Привет, <1>{{name}}</1>, y тебя {{count}} непрочитанное сообщение.',
20+
userMessagesUnread_plural:
21+
'Привет, <1>{{name}}</1>, y тебя {{count}} непрочитанных сообщений.',
22+
},
23+
},
24+
},
25+
lng: 'en',
26+
fallbackLng: 'en',
27+
28+
interpolation: {
29+
escapeValue: false,
30+
},
31+
})
32+
33+
export default i18n
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/// <reference types="cypress" />
2+
import * as React from 'react'
3+
import i18n from './i18n'
4+
import { LocalizedComponent } from './LocalizedComponent'
5+
import { mount } from 'cypress-react-unit-test'
6+
import { I18nextProvider } from 'react-i18next'
7+
8+
describe('i18n', () => {
9+
const localizedMount = (node, { locale }) => {
10+
mount(
11+
<I18nextProvider i18n={i18n.cloneInstance({ lng: locale })}>
12+
{node}
13+
</I18nextProvider>,
14+
)
15+
}
16+
17+
it('Plural in en', () => {
18+
localizedMount(<LocalizedComponent count={15} name="Josh" />, {
19+
locale: 'en',
20+
})
21+
22+
cy.contains('Hello Josh, you have 15 unread messages.')
23+
})
24+
25+
it('Single in en', () => {
26+
localizedMount(<LocalizedComponent count={1} name="Josh" />, {
27+
locale: 'en',
28+
})
29+
30+
cy.contains('Hello Josh, you have 1 unread message.')
31+
})
32+
33+
it('Plural in ru', () => {
34+
localizedMount(<LocalizedComponent count={15} name="Костя" />, {
35+
locale: 'ru',
36+
})
37+
38+
cy.contains('Привет, Костя, y тебя 15 непрочитанных сообщений.')
39+
})
40+
41+
it('Single in ru', () => {
42+
localizedMount(<LocalizedComponent count={1} name="Костя" />, {
43+
locale: 'ru',
44+
})
45+
46+
cy.contains('Привет, Костя, y тебя 1 непрочитанное сообщение.')
47+
})
48+
})

cypress/plugins/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const babelConfig = require('../../babel.config.js')
55
// should we just reuse root webpack config?
66
const webpackOptions = {
77
resolve: {
8+
extensions: ['.js', '.ts', '.jsx', '.tsx'],
89
alias: {
910
react: path.resolve('./node_modules/react'),
1011
},

package-lock.json

Lines changed: 58 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@
134134
"babel-plugin-istanbul": "6.0.0",
135135
"debug": "4.1.1",
136136
"find-webpack": "2.0.0",
137+
"i18next": "19.7.0",
137138
"mime-types": "2.1.26",
139+
"react-i18next": "11.7.2",
138140
"unfetch": "4.1.0"
139141
},
140142
"release": {

0 commit comments

Comments
 (0)