Skip to content
This repository was archived by the owner on Mar 5, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ Spec | Description
[portal](cypress/component/advanced/portal) | Component test for `ReactDOM.createPortal` feature
[react-bootstrap](cypress/component/advanced/react-bootstrap) | Confirms [react-bootstrap](https://react-bootstrap.github.io/) components are working
[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
[i18n](cypress/component/advanced/i18n) | Uses[react-i18next](https://react.i18next.com/) for localizaiton.
<!-- prettier-ignore-end -->

### Full examples
Expand Down
12 changes: 12 additions & 0 deletions cypress/component/advanced/i18n/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as React from 'react'
import { I18nextProvider } from 'react-i18next'
import i18n from './i18n'
import { LocalizedComponent } from './LocalizedComponent'

export function App() {
return (
<I18nextProvider i18n={i18n}>
<LocalizedComponent count={15} name="SomeUserName" />
</I18nextProvider>
)
}
21 changes: 21 additions & 0 deletions cypress/component/advanced/i18n/LocalizedComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react'
import { useTranslation, Trans } from 'react-i18next'

interface LocalizedComponentProps {
name: string
count: number
}

export function LocalizedComponent({ name, count }: LocalizedComponentProps) {
// See ./App.tsx for localization setup
const { t } = useTranslation()

return (
<Trans
i18nKey={count === 1 ? 'userMessagesUnread' : 'userMessagesUnread_plural'}
count={count}
>
Hello <strong> {{ name }} </strong>, you have {{ count }} unread message{' '}
</Trans>
)
}
15 changes: 15 additions & 0 deletions cypress/component/advanced/i18n/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Localization Example

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.

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:

```js
const localizedMount = (node, { locale }) => {
mount(
<I18nextProvider i18n={i18n.cloneInstance({ lng: locale })}>
{node}
</I18nextProvider>,
)
}
```
33 changes: 33 additions & 0 deletions cypress/component/advanced/i18n/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'

i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources: {
en: {
translation: {
userMessagesUnread:
'Hello <1>{{name}}</1>, you have {{count}} unread message.',
userMessagesUnread_plural:
'Hello <1>{{name}}</1>, you have {{count}} unread messages.',
},
},
ru: {
translation: {
userMessagesUnread:
'Привет, <1>{{name}}</1>, y тебя {{count}} непрочитанное сообщение.',
userMessagesUnread_plural:
'Привет, <1>{{name}}</1>, y тебя {{count}} непрочитанных сообщений.',
},
},
},
lng: 'en',
fallbackLng: 'en',

interpolation: {
escapeValue: false,
},
})

export default i18n
48 changes: 48 additions & 0 deletions cypress/component/advanced/i18n/i18next-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// <reference types="cypress" />
import * as React from 'react'
import i18n from './i18n'
import { LocalizedComponent } from './LocalizedComponent'
import { mount } from 'cypress-react-unit-test'
import { I18nextProvider } from 'react-i18next'

describe('i18n', () => {
const localizedMount = (node, { locale }) => {
mount(
<I18nextProvider i18n={i18n.cloneInstance({ lng: locale })}>
{node}
</I18nextProvider>,
)
}

it('Plural in en', () => {
localizedMount(<LocalizedComponent count={15} name="Josh" />, {
locale: 'en',
})

cy.contains('Hello Josh, you have 15 unread messages.')
})

it('Single in en', () => {
localizedMount(<LocalizedComponent count={1} name="Josh" />, {
locale: 'en',
})

cy.contains('Hello Josh, you have 1 unread message.')
})

it('Plural in ru', () => {
localizedMount(<LocalizedComponent count={15} name="Костя" />, {
locale: 'ru',
})

cy.contains('Привет, Костя, y тебя 15 непрочитанных сообщений.')
})

it('Single in ru', () => {
localizedMount(<LocalizedComponent count={1} name="Костя" />, {
locale: 'ru',
})

cy.contains('Привет, Костя, y тебя 1 непрочитанное сообщение.')
})
})
1 change: 1 addition & 0 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const babelConfig = require('../../babel.config.js')
// should we just reuse root webpack config?
const webpackOptions = {
resolve: {
extensions: ['.js', '.ts', '.jsx', '.tsx'],
alias: {
react: path.resolve('./node_modules/react'),
},
Expand Down
71 changes: 58 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@
"babel-plugin-istanbul": "6.0.0",
"debug": "4.1.1",
"find-webpack": "2.0.0",
"i18next": "19.7.0",
"mime-types": "2.1.26",
"react-i18next": "11.7.2",
"unfetch": "4.1.0"
},
"release": {
Expand Down