unit test cases

This commit is contained in:
ArpitxGit
2024-04-27 09:52:43 +05:30
parent a055b43c41
commit 8daf3dd4d9
10 changed files with 336 additions and 199 deletions

View File

@@ -1,3 +1,4 @@
{
"java.compile.nullAnalysis.mode": "automatic"
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "automatic"
}

View File

@@ -1,47 +1,64 @@
import {NativeModules} from 'react-native';
import {by, element, waitFor} from 'detox';
import {
getName,
getDefaultPhoneNumber,
generateIdentifier,
} from '../../android/app/src/main/java/com/lpaapp/IdentityManager/IdentityManagerModule.java';
// import {getName} from '../../android/app/src/main/java/com/lpaapp/IdentityManagerModule.java';
jest.mock(
'../../android/app/src/main/java/com/lpaapp/IdentityManager/IdentityManagerModule.java',
() => ({
getName: jest.fn(),
getDefaultPhoneNumber: jest.fn(),
generateIdentifier: jest.fn(),
}),
);
// jest.mock(
// '../../android/app/src/main/java/com/lpaapp/IdentityManager/IdentityManagerModule.java',
// () => ({
// getName: jest.fn(),
// }),
// );
describe('IdentityManagerNativeModule', () => {
beforeAll(() => {
NativeModules.IdentityManager = {
getName,
getDefaultPhoneNumber,
generateIdentifier,
};
});
// describe('IdentityManagerNativeModule', () => {
// // beforeAll(() => {
// // NativeModules.IdentityManager = {
// // getName: jest.fn(),
// // getDefaultPhoneNumber: jest.fn(),
// // }
// // });
describe('getName', () => {
it('returns the name of the module', async () => {
getName.mockReturnValueOnce('IdentityManager');
const moduleName = await NativeModules.IdentityManager.getName();
expect(moduleName).toBe('IdentityManager');
});
});
// describe('get name', () => {
// it('returns name of the module', async () => {
// const moduleName = await NativeModules.IdentityManager.getName();
// expect(moduleName).toBe('IdentityManager');
// });
// });
// });
describe('getDefaultPhoneNumber', () => {
it('fetches the default phone number', async () => {
const phoneNumber = '1234567890'; // Replace with a sample phone number
getDefaultPhoneNumber.mockResolvedValueOnce(phoneNumber);
const retrievedPhoneNumber =
await NativeModules.IdentityManager.getDefaultPhoneNumber();
expect(retrievedPhoneNumber).toBe(phoneNumber);
});
});
jest.mock('react-native', () => {
const RN = jest.requireActual('react-native'); // use original implementation, which comes with mocks out of the box
describe('generateIdentifier', () => {
it('generates a unique identifier', async () => {
const phoneNumber = '1234567890'; // Replace with a sample phone number
const uniqueIdentifier = 'sampleUniqueIdentifier'; // Replace with a sample unique identifier
generateIdentifier.mockResolvedValueOnce(uniqueIdentifier);
// mock modules/components created by assigning to NativeModules
RN.NativeModules.ReanimatedModule = {
configureProps: jest.fn(),
createNode: jest.fn(),
connectNodes: jest.fn(),
connectNodeToView: jest.fn(),
};
// Mock the UI interaction
await element(by.text('Fetch Unique ID')).tap();
await waitFor(element(by.id('uniqueID')))
.toBeVisible()
.withTimeout(5000);
// mock modules created through UIManager
RN.UIManager.getViewManagerConfig = name => {
if (name === 'SomeNativeModule') {
return {someMethod: jest.fn()};
}
return {};
};
return RN;
// Verify the identifier is fetched and displayed
const retrievedIdentifier = await element(
by.id('uniqueID'),
).getAttributes('text');
expect(retrievedIdentifier).toBe(uniqueIdentifier);
});
});
});

View File

@@ -5,7 +5,7 @@
* @format
*/
import React, { useEffect, useRef, useState } from 'react';
import React, {useEffect, useRef, useState} from 'react';
import {
NativeModules,
SafeAreaView,
@@ -14,12 +14,12 @@ import {
Text,
View,
TouchableOpacity,
PermissionsAndroid
PermissionsAndroid,
} from 'react-native';
import { Button } from './components/Button';
import { Modal } from './components/Modal';
import {Button} from './components/Button';
import {Modal} from './components/Modal';
import { MMKVLoader, useMMKVStorage } from 'react-native-mmkv-storage';
import {MMKVLoader, useMMKVStorage} from 'react-native-mmkv-storage';
interface ILog {
command: string;
@@ -34,37 +34,47 @@ export default function App() {
const toggleModalVisibility = () => {
setIsModalVisible(visible => !visible);
}
};
// Store and retrieve data
// TODO: Handle other datatypes
const storeData = (key, value) => {
storageObj.setString(key, value);
storageObj.setString(key, value);
};
const retrieveData = (key) => {
const retrieveData = key => {
return storageObj.getString(key);
}
};
const getEIDs = async () => {
try {
const eid = await NativeModules.EuiccManager.getEID();
console.log("EID: ", eid);
console.log('EID: ', eid);
} catch (e) {
console.log("error occurred: ", e);
console.log('error occurred: ', e);
}
};
const requestPhoneStatePermission = async () => {
try {
await PermissionsAndroid.requestMultiple([PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE, PermissionsAndroid.PERMISSIONS.READ_PHONE_NUMBERS]).then((result) => {
if (result['android.permission.READ_PHONE_STATE'] && result['android.permission.READ_PHONE_NUMBERS'] === 'granted') {
this.setState({ permissionsGranted: true });
}
else if (result['android.permission.READ_PHONE_STATE'] || result['android.permission.READ_PHONE_NUMBERS'] === 'never_ask_again') {
this.refs.toast.show('Please Go into Settings -> Applications -> APP_NAME -> Permissions and Allow permissions to continue');
}
});
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE,
PermissionsAndroid.PERMISSIONS.READ_PHONE_NUMBERS,
]).then(result => {
if (
result['android.permission.READ_PHONE_STATE'] &&
result['android.permission.READ_PHONE_NUMBERS'] === 'granted'
) {
this.setState({permissionsGranted: true});
} else if (
result['android.permission.READ_PHONE_STATE'] ||
result['android.permission.READ_PHONE_NUMBERS'] === 'never_ask_again'
) {
this.refs.toast.show(
'Please Go into Settings -> Applications -> APP_NAME -> Permissions and Allow permissions to continue',
);
}
});
} catch (err) {
console.log(err);
}
@@ -72,7 +82,9 @@ export default function App() {
useEffect(() => {
console.log('UseEffect Asking permission');
(async () => { await requestPhoneStatePermission(); })();
(async () => {
await requestPhoneStatePermission();
})();
}, []);
useEffect(() => {
@@ -81,28 +93,28 @@ export default function App() {
const id = await getUniqueIdentifier();
setIdentifier(id);
})();
}, [isModalVisible])
}, [isModalVisible]);
const getUniqueIdentifier = async () => {
const phNumber = await NativeModules.IdentityManager.getDefaultPhoneNumber();
console.log("phNumber: ", phNumber);
const phNumber =
await NativeModules.IdentityManager.getDefaultPhoneNumber();
console.log('phNumber: ', phNumber);
const retrievedHash = retrieveData(phNumber);
console.log("retrievedHash: ", retrievedHash);
console.log('retrievedHash: ', retrievedHash);
if(retrievedHash == null) {
if (retrievedHash == null) {
try {
const uniqueIdentifier = await NativeModules.IdentityManager.generateIdentifier(phNumber);
console.log("uniqueIdentifier: ", uniqueIdentifier);
const uniqueIdentifier =
await NativeModules.IdentityManager.generateIdentifier(phNumber);
console.log('uniqueIdentifier: ', uniqueIdentifier);
storeData(phNumber, uniqueIdentifier);
return retrieveData(phNumber);
} catch (error) {
console.log("error: ", error);
console.log('error: ', error);
}
}
else {
} else {
return retrieveData(phNumber);
}
};
@@ -130,21 +142,21 @@ export default function App() {
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: "bold",
fontWeight: 'bold',
},
text: {
fontSize: 16,
fontWeight: "400",
textAlign: "center",
fontWeight: '400',
textAlign: 'center',
},
separator: {
marginVertical: 30,
height: 1,
width: "80%",
width: '80%',
},
});

131
e2e/README.md Normal file
View File

@@ -0,0 +1,131 @@
This README provides an overview of the testing setup and execution process using Detox for end-to-end (E2E) testing and Jest for unit testing.
## Setup Instructions
### Prerequisites
- Node.js and npm installed
- Android Studio (for Android testing) or Xcode (for iOS testing) installed
- React Native project set up and running
### Installation
1. Clone the repository: `git clone https://github.com/Blockchain-Powered-eSIM/LPA`
2. Navigate to the project directory: `cd LPA`
3. Install dependencies: `npm install`
### Configuration
- Detox configuration: Configure Detox in the `.detoxrc.js` file to specify test runner arguments, app configurations, device types, etc.
- Jest configuration: Configure Jest in the `e2e/jest.config.js` and `base.jest.config.js` files for unit and E2E testing settings.
_Make sure to run the app before running test because because of different emulator settings_
## Running Tests
### Unit Tests
- Run unit tests using Jest:
`npm test`
### End-to-End (E2E) Tests with Detox
1. Build the app for testing:
`npm run build`
2. Start the Detox test environment:
`npm run test`
### Expected Results
```
> LPAapp@0.0.1 test
> detox test --configuration android.emu.debug
09:34:03.799 detox[78599] B jest --config e2e/jest.config.js
09:34:06.951 detox[78600] i firstTest.spec.js is assigned to emulator-5554 (Pixel_3a_API_34_extension_level_7_arm64-v8a)
09:34:06.953 detox[78600] i App Launch Test: should launch the app successfully
09:34:09.312 detox[78600] i App Launch Test: should launch the app successfully [OK]
09:34:09.313 detox[78600] i Modal Visibility Test: should initially hide the modal
09:34:09.444 detox[78600] i Modal Visibility Test: should initially hide the modal [OK]
09:34:09.445 detox[78600] i Unique ID Fetch Test: should fetch and display unique ID in modal
09:34:10.922 detox[78600] i Unique ID Fetch Test: should fetch and display unique ID in modal [OK]
09:34:10.924 detox[78600] i Modal Dismissal Test: should dismiss the modal when "Back" button is pressed
09:34:12.092 detox[78600] i Modal Dismissal Test: should dismiss the modal when "Back" button is pressed [OK]
PASS e2e/firstTest.spec.js (7.712 s)
App Launch Test
✓ should launch the app successfully (2358 ms)
Modal Visibility Test
✓ should initially hide the modal (131 ms)
Unique ID Fetch Test
✓ should fetch and display unique ID in modal (1476 ms)
Modal Dismissal Test
✓ should dismiss the modal when "Back" button is pressed (1167 ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 7.783 s, estimated 8 s
Ran all test suites.
```
## Troubleshooting
### Test Failures
- If tests fail, review the error messages and logs provided by Jest and Detox for insights into the cause of the failure.
- Check for issues related to emulator/device setup, app launch, test environment configuration, etc.
### Emulator/Device Issues
- If the emulator or device does not respond or encounters errors, try restarting it.
- Ensure that the emulator/device is properly configured and has the necessary permissions and resources allocated.
### Configuration Errors
- Double-check the configuration settings in `.detoxrc.js` and `e2e/jest.config.js` for correctness and compatibility with your testing environment.
## Additional Resources
- [Detox Documentation](https://github.com/wix/Detox/blob/master/docs/README.md): Official Detox documentation for detailed usage instructions and troubleshooting tips.
- [Jest Documentation](https://jestjs.io/docs/getting-started): Official Jest documentation for comprehensive guides and API references.
- [React Native Documentation](https://reactnative.dev/docs/getting-started): Official React Native documentation for learning and reference.
# Error Scenario
## Unknown AVD Name
When attempting to wipe the data and restart an Android Virtual Device (AVD) emulator, the error message "PANIC: Unknown AVD name [avd_name]" is encountered. This error indicates that the specified AVD name is not recognized or does not exist.
### Error Message
```
PANIC: Unknown AVD name [avd_name], use -list-avds to see valid list.
HOME is defined but there is no file avd_name.ini in $HOME/.android/avd
(Note: Directories are searched in the order $ANDROID_AVD_HOME, $ANDROID_SDK_HOME/avd, and $HOME/.android/avd)
```
### Possible Causes
- Incorrect AVD name specified.
- AVD not created or configured properly.
- Emulator or AVD Manager misconfiguration.
## Resolution Steps
1. **List Available AVDs**: Open Terminal or Command Prompt and navigate to your Android SDK tools directory. Run the following command to list the available AVDs:
emulator -list-avds
2. **Identify AVD Name**: Look for the name of the emulator you want to wipe in the list that's displayed.
3. **Run AVD Manager Command**: Once you've identified the correct AVD name, run the AVD Manager command with the correct AVD name to wipe its data:
`emulator -avd your_avd_name -wipe-data`
Replace `your_avd_name` with the name of the AVD you want to wipe.
4. **Wait for Emulator to Restart**: The emulator will restart with wiped data. Wait for it to finish booting up.
5. **Retry Tests**: Once the emulator is up and running again, retry running your Detox tests to see if the issue is resolved.

View File

@@ -1,13 +1,55 @@
describe('Example', () => {
beforeAll(async () => {
await device.launchApp();
describe('App Launch Test', () => {
beforeEach(async () => {
await device.launchApp({permissions: {phone: 'YES'}});
});
afterAll(async () => {
await device.terminateApp();
});
it('should have welcome message', async () => {
await expect(element(by.text('Welcome'))).toBeVisible();
it('should launch the app successfully', async () => {
// Check if the app launched without any errors
await expect(element(by.text('eSIM Wallet app'))).toBeVisible(); // Adjust the selector based on your root component
});
});
describe('Modal Visibility Test', () => {
beforeEach(async () => {
await device.launchApp({permissions: {phone: 'YES'}});
});
it('should initially hide the modal', async () => {
// Check if the modal is initially not visible
await expect(element(by.id('toggleModalVisibility'))).not.toBeVisible();
});
});
describe('Unique ID Fetch Test', () => {
beforeEach(async () => {
await device.launchApp({permissions: {phone: 'YES'}});
});
it('should fetch and display unique ID in modal', async () => {
// Tap on the button to fetch the unique ID
await element(by.text('Fetch Unique ID')).tap();
// Check if the modal is visible
await expect(element(by.text('Device Data'))).toBeVisible();
// Check if the unique ID text is displayed
await expect(element(by.text('Back'))).toBeVisible(); //since unique ID should not be exposed
});
});
describe('Modal Dismissal Test', () => {
beforeEach(async () => {
await device.launchApp({permissions: {phone: 'YES'}});
});
it('should dismiss the modal when "Back" button is pressed', async () => {
// Check if the modal is visible
await expect(element(by.text('Device Data'))).toBeVisible();
// Tap on the "Back" button
await element(by.text('Back')).tap();
// Check if the modal is hidden after tapping "Back" button
await expect(element(by.id('isModalVisible'))).not.toBeVisible();
});
});

View File

@@ -1,19 +0,0 @@
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
jest.setTimeout(120000);
jasmine.getEnv().addReporter(adapter);
beforeAll(async () => {
await detox.init(config);
});
beforeEach(async () => {
await adapter.beforeEach();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});

View File

@@ -1,29 +1,25 @@
//const baseConfig = require('../base.jest.config.js');
//
///** @type {import('@jest/types').Config} */
//module.exports = {
// ...baseConfig,
// rootDir: '..',
// testMatch: ['<rootDir>/e2e/**/*.test.js'],
// testTimeout: 180000,
// maxWorkers: 1,
// globalSetup: 'detox/runners/jest/globalSetup',
// globalTeardown: 'detox/runners/jest/globalTeardown',
// reporters: ['detox/runners/jest/reporter'],
// testEnvironment: 'detox/runners/jest/testEnvironment',
// verbose: true,
// // setupFilesAfterEnv: ['./init.ts'],
// setupFiles: [
// '<rootDir>/node_modules/react-native-mmkv-storage/jest/mmkvJestSetup.js',
// ], // Adjusted path here
// testPathIgnorePatterns: ['/node_modules/'],
// transformIgnorePatterns: [
// 'node_modules/(?!(react-native|@react-native|react-navigation|@react-navigation)/)',
// ],
//};
const baseConfig = require('../base.jest.config.js');
/** @type {import('@jest/types').Config} */
module.exports = {
preset: 'react-native',
setupFilesAfterEnv: ['./init.js'],
testTimeout: 120000,
...baseConfig,
rootDir: '..',
testMatch: [
'<rootDir>/e2e/firstTest.spec.js',
'<rootDir>/__test__/native/IdentityManager.test.js',
],
testTimeout: 180000,
maxWorkers: 1,
globalSetup: 'detox/runners/jest/globalSetup',
globalTeardown: 'detox/runners/jest/globalTeardown',
reporters: ['detox/runners/jest/reporter'],
testEnvironment: 'detox/runners/jest/testEnvironment',
verbose: true,
setupFiles: [
'<rootDir>/node_modules/react-native-mmkv-storage/jest/mmkvJestSetup.js',
], // Adjusted path here
testPathIgnorePatterns: ['/node_modules/'],
transformIgnorePatterns: [
'node_modules/(?!(react-native|@react-native|react-navigation|@react-navigation)/)',
],
};

View File

@@ -1,38 +0,0 @@
// describe('Example', () => {
// beforeAll(async () => {
// await device.launchApp();
// });
// beforeEach(async () => {
// await device.reloadReactNative();
// });
// it('should have welcome screen', async () => {
// await expect(element(by.id('welcome'))).toBeVisible();
// });
// it('should show hello screen after tap', async () => {
// await element(by.id('hello_button')).tap();
// await expect(element(by.text('Hello!!!'))).toBeVisible();
// });
// it('should show world screen after tap', async () => {
// await element(by.id('world_button')).tap();
// await expect(element(by.text('World!!!'))).toBeVisible();
// });
// });
import {NativeModules} from 'react-native';
describe('IdentityManagerModule Test', () => {
beforeAll(async () => {
await device.launchApp();
});
beforeEach(async () => {
await device.reloadReactNative();
});
it('should match module name', async () => {
const moduleName = await NativeModules.IdentityManager.getName();
expect(moduleName).should.equal('IdentityManager');
});
});

39
package-lock.json generated
View File

@@ -18,15 +18,15 @@
"devDependencies": {
"@babel/core": "^7.24.4",
"@babel/preset-env": "^7.24.4",
"@babel/runtime": "^7.20.0",
"@babel/runtime": "^7.24.4",
"@react-native/babel-preset": "0.73.21",
"@react-native/eslint-config": "0.73.2",
"@react-native/metro-config": "0.73.5",
"@react-native/typescript-config": "0.73.1",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"@types/react": "^18.3.1",
"@types/react-test-renderer": "18.3.0",
"babel-jest": "^29.7.0",
"detox": "^20.20.1",
"detox": "^20.20.3",
"eslint": "^8.19.0",
"jest": "^29.7.0",
"prettier": "2.8.8",
@@ -1976,9 +1976,9 @@
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
},
"node_modules/@babel/runtime": {
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz",
"integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==",
"version": "7.24.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
"integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -4434,31 +4434,24 @@
"dev": true
},
"node_modules/@types/react": {
"version": "18.2.69",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.69.tgz",
"integrity": "sha512-W1HOMUWY/1Yyw0ba5TkCV+oqynRjG7BnteBB+B7JmAK7iw3l2SW+VGOxL+akPweix6jk2NNJtyJKpn4TkpfK3Q==",
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz",
"integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-test-renderer": {
"version": "18.0.7",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.7.tgz",
"integrity": "sha512-1+ANPOWc6rB3IkSnElhjv6VLlKg2dSv/OWClUyZimbLsQyBn8Js9Vtdsi3UICJ2rIQ3k2la06dkB+C92QfhKmg==",
"version": "18.3.0",
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.3.0.tgz",
"integrity": "sha512-HW4MuEYxfDbOHQsVlY/XtOvNHftCVEPhJF2pQXXwcUiUF+Oyb0usgp48HSgpK5rt8m9KZb22yqOeZm+rrVG8gw==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
"dev": true
},
"node_modules/@types/semver": {
"version": "7.5.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
@@ -6736,9 +6729,9 @@
}
},
"node_modules/detox": {
"version": "20.20.1",
"resolved": "https://registry.npmjs.org/detox/-/detox-20.20.1.tgz",
"integrity": "sha512-QGdmz+XZhJg1T2ySomdWDTSV7uRXn0WS438XGfC7f7fxePFrPOhxaJioXsDtTeGITWGr78lo2jehwYhRTjh4Pw==",
"version": "20.20.3",
"resolved": "https://registry.npmjs.org/detox/-/detox-20.20.3.tgz",
"integrity": "sha512-sca2z+6SYnA5+9jF1pf/t4RBOcvnBO0vmsTtrmnpej76Q5rhX0acZpFbDgvQQPGKu/TDdH+KFYK0tQ2VrTNY1w==",
"dev": true,
"hasInstallScript": true,
"dependencies": {

View File

@@ -9,7 +9,9 @@
"start": "react-native start",
"test": "detox test --configuration android.emu.debug",
"build": "./mmkv-build-script.sh && detox build --configuration android.emu.debug",
"watch": "tsc --watch"
"watch": "tsc --watch",
"clear-jest-cache": "jest --clearCache",
"test:unit": "jest"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
@@ -22,15 +24,15 @@
"devDependencies": {
"@babel/core": "^7.24.4",
"@babel/preset-env": "^7.24.4",
"@babel/runtime": "^7.20.0",
"@babel/runtime": "^7.24.4",
"@react-native/babel-preset": "0.73.21",
"@react-native/eslint-config": "0.73.2",
"@react-native/metro-config": "0.73.5",
"@react-native/typescript-config": "0.73.1",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"@types/react": "^18.3.1",
"@types/react-test-renderer": "18.3.0",
"babel-jest": "^29.7.0",
"detox": "^20.20.1",
"detox": "^20.20.3",
"eslint": "^8.19.0",
"jest": "^29.7.0",
"prettier": "2.8.8",
@@ -47,11 +49,11 @@
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android && ./gradlew app:assembleDebug app:assembleAndroidTest -DtestBuildType=debug && cd ..",
"device": {
"avdName": "Pixel_3a_API_30"
"avdName": "Pixel_3a_API_34_extension_level_7_arm64-v8a"
}
}
},
"test-runner": "jest",
"runner-config": "e2e/config.json"
"runner-config": "e2e/jest.config.json"
}
}