# Detox, useTypedTranslation - Mon-Fri, 11th-15th Jan, 2020
I've been slipping writing my diary so far in 2021!
### Detox
Did a lot of work getting Detox working better in CI.
A few learnings I had were:
1. Tests seem more reliable when running on simulator rather than headless
1. Android emulator opens automatically on `detox test` command, but iOS simulator must be opened manually
1. With the exception of writing new tests, always build and test with **release** config. This prevents debug messages such as [YellowBox warnings](https://reactnative.dev/docs/0.62/debugging#warnings) interferring with tests.
1. If you are struggling with a matcher, build the app for dev (`yarn start`, then `yarn ios` / `yarn android`) and use [Flipper](https://fbflipper.com/) to inspect the underlying native view and determine if you are selecting the right element.
1. I find `toExist` to be more reliable than `toBeVisible`
The i18n `useTranslation` hook doesn't allow me to pass a generic in order to get type safety for my different translation strings. I created an improved `useTypedTranslation` hook for the job:
My .ddetoxrc.json:
```json=
{
"testRunner": "jest",
"runnerConfig": "e2e/jest.config.js",
"configurations": {
"ios.cp.debug": {
"binaryPath": "./ios/DerivedData/myapp/Build/Products/Debug-iphonesimulator/myapp.app",
"build": "xcodebuild -workspace ./ios/myapp.xcworkspace -scheme myapp -configuration Debug -sdk iphonesimulator -destination 'name=iPhone 11'",
"type": "ios.simulator",
"name": "iPhone 11"
},
"ios.cp.release": {
"binaryPath": "./ios/DerivedData/myapp/Build/Products/Release-iphonesimulator/myapp.app",
"build": "xcodebuild -workspace ./ios/myapp.xcworkspace -scheme myapp -configuration Release -sdk iphonesimulator",
"type": "ios.simulator",
"device": {
"type": "iPhone 11"
}
},
"android.cp.debug": {
"binaryPath": "./android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
"type": "android.emulator",
"name": "Pixel_3a_API_28"
},
"android.cp.release": {
"binaryPath": "android/app/build/outputs/apk/release/app-release.apk",
"build": "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Pixel_3a_API_28"
}
}
}
}
```
### useTypedTranslation
```typescript=
import { useCallback } from 'react'
import { UseTranslationOptions, useTranslation } from 'react-i18next'
import { translations } from './translations'
type TranslationKeys = keyof typeof translations
type TypedTFunction = (key: TranslationKeys, options?: UseTranslationOptions) => string
export function useTypedTranslation(): { t: TypedTFunction } {
const { t } = useTranslation()
const typedT = useCallback((key: TranslationKeys) => t<string, TranslationKeys>(key), [t])
return {
t: typedT,
}
}
```
###### tags: `programmingjournal` `2021` `translationlocalisation` `detox` `e2e` `usetranslation`