Skip to content

Commit

Permalink
chore(Detox): repair e2e testing library
Browse files Browse the repository at this point in the history
  • Loading branch information
igroza committed Jan 29, 2025
1 parent 02742cb commit a4738dc
Show file tree
Hide file tree
Showing 91 changed files with 1,123 additions and 483 deletions.
4 changes: 2 additions & 2 deletions .detoxrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ module.exports = {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/haqq.app',
build:
'xcodebuild -workspace ios/haqq.xcworkspace -scheme haqq -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build',
'FOR_DETOX=true xcodebuild -workspace ios/haqq.xcworkspace -scheme haqq -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build',
},
'ios.release': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/haqq.app',
build:
'xcodebuild -workspace ios/haqq.xcworkspace -scheme haqq -configuration Release -sdk iphonesimulator -derivedDataPath ios/build',
'FOR_DETOX=true xcodebuild -workspace ios/haqq.xcworkspace -scheme haqq -configuration Release -sdk iphonesimulator -derivedDataPath ios/build',
},
'android.debug': {
type: 'android.apk',
Expand Down
1 change: 0 additions & 1 deletion .metro-health-check-8879-0-5869

This file was deleted.

1 change: 1 addition & 0 deletions __tests__/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ jest.mock('react-native-reanimated', () => {
Easing: {
bezierFn: jest.fn,
},
useAnimatedStyle: jest.fn,
};
});

Expand Down
11 changes: 8 additions & 3 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
const {FOR_DETOX} = require('dotenv').config();

const IS_DETOX_RUNNIG = FOR_DETOX || !!process.env.FOR_DETOX || !!process.env.JEST_WORKER_ID;

module.exports = function (api) {
api.cache(true);
const currentEnv =
process.env.BABEL_ENV || process.env.NODE_ENV || 'development';
const isTestEnv =
(!!process.env.SDKROOT &&
process.env.SDKROOT.includes('iPhoneSimulator')) ||
!!process.env.FOR_DETOX;
process.env.SDKROOT.includes('iPhoneSimulator')) || IS_DETOX_RUNNIG;

const presets = [
'module:@react-native/babel-preset',
'@babel/preset-typescript',
];
const plugins = [
'transform-inline-environment-variables',
[
'module-resolver',
{
alias: {
'@app': './src',
'@assets': './assets',
'@override': './src/overrides'
},
},
],
'react-native-reanimated/plugin',
'react-native-reanimated/plugin'
];

if (currentEnv === 'production' && !isTestEnv) {
Expand Down
102 changes: 102 additions & 0 deletions docs/detox-testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Testing HAQQ Wallet with Detox

## Setup

Install `detox-cli` globally to easily run Detox commands from the command line:

```sh
yarn global add detox-cli
```

This tool is required by Detox to work with iOS simulators.

```sh
brew tap wix/brew
brew install applesimutils
```

## Start testing

> [!IMPORTANT]
> Never set `JEST_WORKER_ID` while using Detox, as it crashes react-native-reanimated.

### Development Environment

To run Detox tests in the development environment, use the following commands:

#### Using dev helper script

- **Show help message**
```sh
yarn detox:test:dev --help
```

Description:
This script is used to start the Metro server and run Detox end-to-end tests.

Usage:
```sh
yarn detox:test:dev [--ios|--android] [testFileNumber]
```

Options:
- `[--ios|--android]`: (Optional) Run the tests on the iOS/Android simulator.
- `testFileNumber`: (Optional) The prefix number of the test file to run.

Examples:
```sh
yarn detox:test:dev
yarn detox:test:dev --ios
yarn detox:test:dev --android 2
```

#### Manually

Before starting dev tests, you should run the Metro bundler with the `FOR_DETOX=true` environment variable:

```sh
FOR_DETOX=true npx react-native start --reset-cache
```

- **Build and run Android tests:**
```sh
yarn detox:android:build:dev
yarn detox:android:test:dev
```

- **Build and run iOS tests:**
```sh
yarn detox:ios:build:dev
yarn detox:ios:test:dev
```

### Release Environment

Before starting testing, set `FOR_DETOX=true` in your `.env` file.

To run Detox tests in the release environment, use the following commands:

- **Build and run Android tests:**
```sh
yarn detox:android:build
yarn detox:android:test
```

- **Build and run iOS tests:**
```sh
yarn detox:ios:build
yarn detox:ios:test
```

### Combined Commands

- **Build and run all iOS tests:**
```sh
yarn detox:ios
```

- **Build and run all Android tests:**
```sh
yarn detox:android
```
5 changes: 3 additions & 2 deletions e2e/1_signup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('Signup', () => {
.toBeVisible()
.whileElement(by.id('backup_warning'))
.scroll(50, 'down');
await element(by.id('backup_warning_checkbox')).tap();
await element(by.id('backup_warning_next')).tap();

const mnemonic_words = [];
Expand All @@ -40,11 +41,11 @@ describe('Signup', () => {
mnemonic_words.push(text);
}

await waitFor(element(by.id('backup_create_checkbox')))
await waitFor(element(by.id('backup_create_next')))
.toBeVisible()
.whileElement(by.id('backup_create'))
.scroll(50, 'down');
await element(by.id('backup_create_checkbox')).tap();

await element(by.id('backup_create_next')).tap();

await waitFor(element(by.id('backup_verify')))
Expand Down
5 changes: 3 additions & 2 deletions e2e/4_settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('Routine', () => {
.toBeVisible()
.whileElement(by.id('backup_warning'))
.scroll(50, 'down');
await element(by.id('backup_warning_checkbox')).tap();
await element(by.id('backup_warning_next')).tap();

for (let i = 1; i <= 12; i++) {
Expand All @@ -42,11 +43,10 @@ describe('Routine', () => {
mnemonic_words.push(text);
}

await waitFor(element(by.id('backup_create_checkbox')))
await waitFor(element(by.id('backup_create_next')))
.toBeVisible()
.whileElement(by.id('backup_create'))
.scroll(50, 'down');
await element(by.id('backup_create_checkbox')).tap();
await element(by.id('backup_create_next')).tap();

await waitFor(element(by.id('backup_verify')))
Expand Down Expand Up @@ -138,6 +138,7 @@ describe('Routine', () => {
.toBeVisible()
.whileElement(by.id('backup_warning'))
.scroll(50, 'down');
await element(by.id('backup_warning_checkbox')).tap();
await element(by.id('backup_warning_next')).tap();

for (let i = 1; i <= 12; i++) {
Expand Down
23 changes: 15 additions & 8 deletions e2e/helpers/createWallet.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import {by, device, element, expect, waitFor} from 'detox';

import {getText} from './i18n';

export const createWallet = async (PIN: string, attempt: number = 1) => {
const isAndroid = device.getPlatform() === 'android';

await expect(element(by.id('welcome'))).toBeVisible();
await waitFor(element(by.id('welcome')))
.toBeVisible()
.withTimeout(120_000);

await expect(element(by.id('welcome_signup'))).toBeVisible();

await element(by.id('welcome_signup')).tap();
Expand All @@ -14,7 +19,9 @@ export const createWallet = async (PIN: string, attempt: number = 1) => {

await element(by.id('sss_login_later')).tap();
// Modal window
await element(by.label('Accept')).atIndex(0).tap();
await element(by.label(getText('accept')))
.atIndex(0)
.tap();
await expect(element(by.id('onboarding_setup_pin_set'))).toBeVisible();

await device.disableSynchronization();
Expand All @@ -23,7 +30,9 @@ export const createWallet = async (PIN: string, attempt: number = 1) => {
}
await device.enableSynchronization();

await expect(element(by.text('Please repeat pin code'))).toBeVisible();
await expect(
element(by.text(getText('onboardingRepeatPinRepeat'))),
).toBeVisible();

await device.disableSynchronization();
for (const num of PIN.split('')) {
Expand All @@ -39,11 +48,6 @@ export const createWallet = async (PIN: string, attempt: number = 1) => {
await expect(element(by.id('onboarding_biometry_title'))).toBeVisible();

await element(by.id('onboarding_biometry_skip')).tap();
await waitFor(element(by.id('onboarding_track_user_activity')))
.toBeVisible()
.withTimeout(5000);

await element(by.id('onboarding_tracking_skip')).tap();

if (attempt === 1) {
await waitFor(element(by.id('onboarding_finish_title')))
Expand All @@ -56,5 +60,8 @@ export const createWallet = async (PIN: string, attempt: number = 1) => {

if (attempt === 1) {
await element(by.id('onboarding_finish_finish')).tap();
await waitFor(element(by.id('home-feed-container')))
.toBeVisible()
.withTimeout(10_000);
}
};
5 changes: 5 additions & 0 deletions e2e/helpers/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import en from '../../assets/locales/en/en.json';

export function getText<Key extends keyof typeof en>(key: Key): string {
return en[key];
}
5 changes: 4 additions & 1 deletion e2e/helpers/launchApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import {device} from 'detox';
export const launchApp = async () => {
await device.launchApp({
newInstance: true,
permissions: {notifications: 'NO'},
permissions: {
notifications: 'YES',
userTracking: 'NO',
},
});
};
3 changes: 3 additions & 0 deletions global.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import Config from 'react-native-config';
import {LoggerService} from '@app/services/logger';

global.Logger = new LoggerService();
global.IS_DETOX =
!!process.env.JEST_WORKER_ID || !!process.env.FOR_DETOX || !!Config.FOR_DETOX;
13 changes: 8 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import '@walletconnect/react-native-compat';
import 'node-libs-react-native/globals';
import '@ethersproject/shims';
import {AppRegistry, I18nManager, LogBox} from 'react-native';
import './global';
import './src/modifiers/json-rpc-provider.modifier';

import {App} from './src/app';
import './src/event-actions';
import {AppRegistry, I18nManager, LogBox} from 'react-native';
import {DEBUG_VARS} from '@app/debug-vars';
import {enableBatchedStateUpdates} from '@app/hooks/batched-set-state';
import {Language} from '@app/models/language';
Expand All @@ -14,11 +16,12 @@ import * as Sentry from '@sentry/react-native';
import Config from 'react-native-config';
import {enableFreeze, enableScreens} from 'react-native-screens';
import {name as appName} from './app.json';
import {App} from './src/app';
import './src/event-actions';
import {Jailbreak} from './src/jailbreak';

LogBox.ignoreAllLogs();
if(IS_DETOX) {
LogBox.ignoreAllLogs();
}

if (!global.BigInt) {
const BigInt = require('big-integer');

Expand Down Expand Up @@ -68,5 +71,5 @@ const Wrapped = DEBUG_VARS.enableSentry ? Sentry.wrap(App) : App;
AppRegistry.registerComponent(appName, () => Wrapped);

AppRegistry.registerComponent('jailbreak', () =>
Config.FOR_DETOX ? Wrapped : Jailbreak,
IS_DETOX ? Wrapped : Jailbreak,
);
Loading

0 comments on commit a4738dc

Please sign in to comment.