Commit 4c86d8cf authored by Hanwen Cheng's avatar Hanwen Cheng Committed by goldsteinsveta
Browse files

major: HDKD feature (#431)

* create legacy account list and identities switch

* refactor account store for legacyAccountList view

* init identityNew screen

* style: logo

* style: color change

* react vector icons

* component: ButtonIcon

* IdentitySwitch in header

* rename empty to emptyAccount

* finish identityNew screen data binding

* Update IdentitiesSwitch.js

* style: header

* ButtonIcon text option

* remove useless isWelcome and fix lint error

* fix typo

* refactor LegacyAccountBackup

* init IdentityNew

* ButtonIcon onPress isRequired

* font styles component

* style: IdentitySwitch

* style mop up: IdentitySwitch

* style chores

* style: listed cards

* basic account creation for identity backup screen

* IdentityBackup, IdentityPin, PathsList

* shadow and misc styles

* style mop up: listed cards

* network logos

* AccountCard can function as a networkButton

Because in v4 each identity has only one network account for each network, there's no need for visual differenciation between networkButton and AccountCard in AccountList, NetworkChooser, AccountNew, AccountRecover etc.

* style: layout containers for screens with AccountCard

* style and fixedPrefix prop for TextInput

fixedPrefix will be used to indicte full derivation path

* fontStyle for seed phrases

* unlock logic, new seed generation, path derivation

* prepared place for identityList

* integrate idenity serializer

* add and move specs to certain foler

* Button props

* show path with netwok

* merge

* data bind with derivation path screen

* remove navigationOptions and refactoring to stateless component

* finish identity recover feature

* fix all lint warnings

* current identity label on identitiesSwitch

* identiy management and identity backup

* fix derivation and add error handling for wrong derivation path

* group paths in paths list screen

* show path name

* path details screen, delete path function

* add Path Management Screen

* reset disconnect behaviour

* use accountId as address

* ethereum account list in idenitty and remove legacy account creation

* signing function for the account in identity store

* fix according to YJ review, reset some navigation behavior

* fix some warnings

* Update SecurityHeader.js

* scrollable identitySwitch

* show only available networks

* rephrase backup identity

* add scan buttton to the bottom

* start screen with network chooser

* revert conflicts

* settings

* Revert "revert conflicts"

This reverts commit c54069f5.

* e2e test for default substrate account creation

* e2e test for derivation hard key

* show no accountt hint text on androiid

* refactor qr scanner

* add identity management dropdown to every identity

* style: identity screen

* fix initial errors

* update account network chooser

* directly navigation to derivation if there is no key

* add path id for kusama dev

* directly account creation with ethereum account

* networkParams example

* show error icon if network is unknown

* style: pathCard for non-Substrate

* style: group path

* style: substrate derivation

* display path of groupPaths

* vertical spacing for (un)grouped pathCards

* fix address issue

* btns: new derivation and scan

* style: qr

* delete error handling

* after delete non-substrate

* switcher style corrections

* antdesign icons

* icons and headings

* eth address render fix

* heading PathsList

* sign message bug fix, navigate to signedMessage

* style details

* styles: optimised for smaller screens

* ScreenHeader and ButtonMainAction components everywhere

* ButtonMainAction display adjustments

* display logic for different user cases

* scan button fix

* security and errors

* upgrade detox to latest version and merge

* use new fonts

* `add legacy account` button for test backward compatibility

* add test for delete path

* textInput adjustments

* delete idenitity

* add currentIdentity to pathcard

* fix test multi item problem

* add mock file for scanning test

* mock recover identity and update genesisHash

* Screens with seeds

* screens w popups

* identity (mnemonic) icon in paths

* add account signing process

* tested signing process, and bug fixes

* style chores

* correct signing process

* improved touch, scroll and popup behaviours

* new shadows

* error test @YJ

* fix: test_substrate_sign1

* remove test sign1

* fix delete bugs

* style onboarding message

* payload screen styling

* fix navigation after scan

* refactor signed screen

* button position @ios fix

* icon centering @ios fix

* back from debugging

* lead to identitiesSwitch after deletetion

* signed message styling

* fix signed message styling

* fix signing in ethereum

* fix eslint with hooks

* use async functions for setState

* group alerts

* more test cases and soft key fix

* improve path grouping

* sort list and add keys

* hide tac buttons after first login

* put logo on left consistently

* use alternative for regex look behind

* fix e2e test

* use switchNavigator

* remove logs and remarks

* remove useless code

* copyright and use strict everywhere

* comment out unused code

* use accountId instead of address

* remove warnings

* remove logo when back button appear

* Use about screen instead of settings

* fix grumbles

* remove unused refs

* style fix

* back from debugging

* fix card name not shown problem

* style: Substrate TxDetails

* indication of sender/recipient for PathCards

* move duplicated code into component and fix merge error

* fix: loading error

* move method to top

* fix naming in path derivation

* separate soften keys from harden

* use memo to improve performance on pathslist

* Revert "Merge branch 'hanwen-fix-loading' into sveta-hanwen-hdkd"

This reverts commit 7fbcfb25, reversing
changes made to b0375444.

* UI fix, fix unclickable legacy items on legacyAccountList

* TxDetails for small screen

* 8 * 4 = 32

* fixes according to code review

* extract onPress and use PureComponent if possible

* add error handling for derived address generation

* fix signing

* fix grumbles according to review

* save uppercase account id

* fix styling

* fix grumbles

* extract function out of render method

* Update identityManipulation.spec.js

* fix extra separator

* two buttons in row for small screen

* styling fix

* remove extra margin
parent 3292187d
Pipeline #69816 failed with stages
in 36 minutes and 23 seconds
......@@ -2,7 +2,7 @@ module.exports = {
extends: ["@react-native-community", "plugin:prettier/recommended"],
overrides: [
{
"files": ["e2e/*.spec.js", "e2e/init.js"],
"files": ["e2e/*.spec.js", "e2e/init.js", "e2e/e2eUtils.js"],
"rules": {
"no-undef": "off"
}
......@@ -22,6 +22,7 @@ module.exports = {
},
},
rules: {
"no-bitwise": "off",
"comma-dangle": ["error", "never"],
"object-curly-spacing": ["error", "always"],
"quotes": ["error", "single", { "avoidEscape": true }],
......
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import testIDs from './testIDs';
const { IdentityPin } = testIDs;
export const testTap = async buttonId => await element(by.id(buttonId)).tap();
export const testVisible = async componentId =>
await expect(element(by.id(componentId))).toBeVisible();
export const testExist = async componentId =>
await expect(element(by.id(componentId))).toExist();
export const testNotExist = async componentId =>
await expect(element(by.id(componentId))).toNotExist();
export const testNotVisible = async componentId =>
await expect(element(by.id(componentId))).toBeNotVisible();
export const tapBack = async () =>
await element(by.id(testIDs.Header.headerBackButton))
.atIndex(0)
.tap();
export const testInput = async (inputId, inputText) => {
await element(by.id(inputId)).typeText(inputText);
await element(by.id(inputId)).tapReturnKey();
};
export const testScrollAndTap = async (buttonId, screenId) => {
await waitFor(element(by.id(buttonId)))
.toBeVisible()
.whileElement(by.id(screenId))
.scroll(100, 'down');
await testTap(buttonId);
};
export const testUnlockPin = async pinCode => {
await testInput(IdentityPin.unlockPinInput, pinCode);
await testTap(IdentityPin.unlockPinButton);
};
import testIDs from './testIDs';
describe('Load test', () => {
it('should have account list screen', async () => {
await expect(element(by.id(testIDs.TacScreen.tacView))).toBeVisible();
await element(by.id(testIDs.TacScreen.agreePrivacyButton)).tap();
await element(by.id(testIDs.TacScreen.agreeTacButton)).tap();
await element(by.id(testIDs.TacScreen.nextButton)).tap();
await expect(
element(by.id(testIDs.AccountListScreen.accountList))
).toBeVisible();
});
});
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import testIDs from './testIDs';
import {
tapBack,
testExist,
testInput,
testNotExist,
testNotVisible,
testScrollAndTap,
testTap,
testUnlockPin,
testVisible
} from './e2eUtils';
const {
TacScreen,
AccountNetworkChooser,
IdentitiesSwitch,
IdentityManagement,
IdentityNew,
IdentityBackup,
IdentityPin,
PathDerivation,
PathDetail,
PathsList,
SignedTx,
TxDetails
} = testIDs;
const pinCode = '123456';
const mockIdentityName = 'mockIdentity';
const substrateNetworkButtonIndex = AccountNetworkChooser.networkButton + '2'; //Need change if network list changes
const fundingPath = '//funding/0';
const mockSeedPhrase =
'split cradle example drum veteran swear cruel pizza guilt surface mansion film grant benefit educate marble cargo ignore bind include advance grunt exile grow';
const testSetUpDefaultPath = async () => {
await testInput(IdentityPin.setPin, pinCode);
await testInput(IdentityPin.confirmPin, pinCode);
await testTap(IdentityPin.submitButton);
await testVisible(AccountNetworkChooser.chooserScreen);
await testScrollAndTap(
substrateNetworkButtonIndex,
testIDs.AccountNetworkChooser.chooserScreen
);
await testUnlockPin(pinCode);
await testExist(PathsList.pathCard + '//kusama_CC2//default');
};
describe('Load test', async () => {
beforeAll(async () => {
if (device.getPlatform() === 'ios') {
await device.clearKeychain();
}
await device.launchApp({ permissions: { camera: 'YES' } });
});
it('should have account list screen', async () => {
await testVisible(TacScreen.tacView);
await testTap(TacScreen.agreePrivacyButton);
await testTap(TacScreen.agreeTacButton);
await testTap(TacScreen.nextButton);
await testVisible(AccountNetworkChooser.noAccountScreen);
});
it('recover a identity with seed phrase', async () => {
await testTap(AccountNetworkChooser.recoverButton);
await testVisible(IdentityNew.seedInput);
await element(by.id(IdentityNew.seedInput)).typeText(mockSeedPhrase);
await testInput(IdentityNew.nameInput, mockIdentityName);
await testTap(IdentityNew.recoverButton);
await testSetUpDefaultPath();
});
it('create a new identity with default substrate account', async () => {
await tapBack();
await testTap(IdentitiesSwitch.toggleButton);
await testTap(IdentitiesSwitch.addIdentityButton);
await testNotVisible(IdentityNew.seedInput);
await testTap(IdentityNew.createButton);
await testVisible(IdentityBackup.seedText);
await testTap(IdentityBackup.nextButton);
await element(by.text('Proceed')).tap();
await testSetUpDefaultPath();
});
it('derive a new key', async () => {
await testTap(PathsList.deriveButton);
await testInput(PathDerivation.nameInput, 'first one');
await testInput(PathDerivation.pathInput, fundingPath);
await testTap(PathDerivation.deriveButton);
await testUnlockPin(pinCode);
await testExist(PathsList.pathCard + `//kusama_CC2${fundingPath}`);
});
it('delete a path', async () => {
await tapBack();
await testTap(AccountNetworkChooser.networkButton + '0');
await testTap(PathsList.pathCard + `//kusama_CC2${fundingPath}`);
await testTap(PathDetail.popupMenuButton);
await testTap(PathDetail.deleteButton);
await element(by.text('Delete')).tap();
await testUnlockPin(pinCode);
await testNotExist(PathsList.pathCard + `//kusama_CC2${fundingPath}`);
});
it('should sign the transaction', async () => {
await tapBack();
await testTap(AccountNetworkChooser.scanButton);
await testScrollAndTap(TxDetails.signButton, TxDetails.scrollScreen);
await testUnlockPin(pinCode);
await testVisible(SignedTx.qrView);
});
it('delete identity', async () => {
await element(by.id(IdentitiesSwitch.toggleButton))
.atIndex(0)
.tap();
await testTap(IdentitiesSwitch.manageIdentityButton);
await testTap(IdentityManagement.popupMenuButton);
await testTap(IdentityManagement.deleteButton);
await element(by.text('Delete')).tap();
await testUnlockPin(pinCode);
await testVisible(IdentitiesSwitch.modal);
});
});
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
......@@ -12,7 +30,7 @@ jasmine.getEnv().addReporter(adapter);
jasmine.getEnv().addReporter(specReporter);
beforeAll(async () => {
await detox.init(config);
await detox.init(config, { launchApp: false });
});
beforeEach(async () => {
......
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
import { NETWORK_LIST, SubstrateNetworkKeys } from '../src/constants';
export const signingTestIdentityPath = `//${NETWORK_LIST[SubstrateNetworkKeys.KUSAMA].pathID}//default`;
const setRemarkExtrinsicKusama =
'47900000100005301023c36776005aec2f32a34c109dc791a82edef980eec3be80da938ac9bcc68217220170000010c11111165030000fa030000e3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636dbb5aefb451e26bd64faf476301f980437d87c0d88dec1a8c7a3eb3cc82e9bbb0ec';
export const createMockSignRequest = () => ({
bounds: {
height: 1440,
origin: [],
width: 1920
},
data: '',
rawData: setRemarkExtrinsicKusama,
target: 319,
type: 'QR_CODE'
});
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
'use strict';
const testIDs = {
AccountListScreen: {
accountList: 'accountList'
},
AccountNetworkChooser: {
addNewNetworkButton: 'anc_add_button',
chooserScreen: 'anc_chooser_scree',
createButton: 'anc_create_button',
networkButton: 'anc_network_button',
noAccountScreen: 'anc_no_account_screen',
recoverButton: 'anc_recover_button',
scanButton: 'anc_scan_button',
showExistedButton: 'anc_show_existed'
},
Header: {
headerBackButton: 'header_back_button'
},
IdentitiesSwitch: {
addIdentityButton: 'identities_switch_add_identity',
manageIdentityButton: 'identities_switch_manager_button',
modal: 'identity_switch_modal',
toggleButton: 'identities_switch_toggle_button'
},
IdentityBackup: {
nextButton: 'identity_backup_next',
seedText: 'identity_backup_seed'
},
IdentityManagement: {
deleteButton: 'identity_management_delete_button',
popupMenuButton: 'identity_management_popup_menu'
},
IdentityNew: {
createButton: 'identity_new_create_button',
nameInput: 'identity_new_name_input',
recoverButton: 'identity_new_recover_button',
seedInput: 'identity_new_seed_input'
},
IdentityPin: {
confirmPin: 'identity_pin_confirm',
scrollScreen: 'identity_pin_scroll',
setPin: 'identity_pin_set',
submitButton: 'identity_submit_button',
unlockPinButton: 'identity_unlock_pin_button',
unlockPinInput: 'identity_unlock_pin_input'
},
PathDerivation: {
deriveButton: 'path_derivation_derive_button',
nameInput: 'path_derivation_name_input',
pathInput: 'path_derivation_path_input'
},
PathDetail: {
deleteButton: 'path_detail_delete_button',
popupMenuButton: 'path_detail_popup_menu_button'
},
PathsList: {
deriveButton: 'path_list_derive_button',
pathCard: 'path_list_path_card',
scanButton: 'path_list_scan_button'
},
SignedMessage: {},
SignedTx: {
qrView: 'signed_tx_qr_view'
},
TacScreen: {
agreePrivacyButton: 'tac_privacy',
agreeTacButton: 'tac_agree',
nextButton: 'tac_next',
tacView: 'tac_view'
},
TxDetails: {
scrollScreen: 'tx_details_scroll',
signButton: 'tx_details_sign_button'
}
};
......
......@@ -5,7 +5,6 @@
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
......@@ -45,6 +44,7 @@
5DC40D98E51D492C8FF692B5 /* Manifold-CF-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 31AAF2CB51C04377BFC79634 /* Manifold-CF-Light.otf */; };
6686E5A219254E3D8880285E /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F2FB2DDD90964B3BB1FC813C /* Octicons.ttf */; };
6701864923270B1100A14061 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 6701864823270B1100A14061 /* assets */; };
67E3BED3237C17A6007882FA /* RobotoMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 67E3BEA2237C17A6007882FA /* RobotoMono-Regular.ttf */; };
6FBA1E2F42104B26A94F3EE0 /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 84D1117E71B04C839F00F619 /* Ionicons.ttf */; };
740B033F930D4E6FB906D8C2 /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CB5C4A7F0E8B4E4E98E06EFD /* MaterialCommunityIcons.ttf */; };
768CDFD4C47549429C87DEDD /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6A7AB3BD3C1A4E0EB3C4B3B6 /* Entypo.ttf */; };
......@@ -477,6 +477,7 @@
5F744F56289845F0A1085BBB /* Roboto-MediumItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Roboto-MediumItalic.ttf"; path = "../res/fonts/Roboto-MediumItalic.ttf"; sourceTree = "<group>"; };
624E6C0FF4A64A97A7D51BEF /* Manifold-CF-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Manifold-CF-Bold.otf"; path = "../res/fonts/Manifold-CF-Bold.otf"; sourceTree = "<group>"; };
6701864823270B1100A14061 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = "<group>"; };
67E3BEA2237C17A6007882FA /* RobotoMono-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "RobotoMono-Regular.ttf"; sourceTree = "<group>"; };
6A7AB3BD3C1A4E0EB3C4B3B6 /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; };
6C53A63D96B24FDD95AF1C97 /* Fontisto.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Fontisto.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf"; sourceTree = "<group>"; };
7733AB637FF54DE5B174F42C /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; };
......@@ -765,6 +766,7 @@
53880E8FF84C419EB11ACA5C /* Roboto-Light.ttf */,
8C99AB759A004CEB88AC4455 /* Roboto-LightItalic.ttf */,
E3DA81F74A0847378E71E280 /* Roboto-Medium.ttf */,
67E3BEA2237C17A6007882FA /* RobotoMono-Regular.ttf */,
5F744F56289845F0A1085BBB /* Roboto-MediumItalic.ttf */,
5CD421FF72D947B0AA9EBABB /* Roboto-Regular.ttf */,
020454D0D3C74A398EC7F440 /* Roboto-Thin.ttf */,
......@@ -1415,6 +1417,7 @@
7A7137D6EEDE40C184F30C15 /* Roboto-Regular.ttf in Resources */,
16614F66487241CE933918B8 /* Roboto-Thin.ttf in Resources */,
0CFC8839F5B54F888E6C01DE /* Roboto-ThinItalic.ttf in Resources */,
67E3BED3237C17A6007882FA /* RobotoMono-Regular.ttf in Resources */,
3C31DDCB4CD0465084344D5F /* Manifold-CF-Bold.otf in Resources */,
AD0B6F7EACB74BA7A42D2A2E /* Manifold-CF-Demi-Bold.otf in Resources */,
F1569210427145DEBBB5B898 /* Manifold-CF-Extra-Bold.otf in Resources */,
......
......@@ -43,6 +43,7 @@
<string>LaunchScreen</string>
<key>UIAppFonts</key>
<array>
<string>RobotoMono-Regular.ttf</string>
<string>Roboto-Black.ttf</string>
<string>Roboto-BlackItalic.ttf</string>
<string>Roboto-Bold.ttf</string>
......
......@@ -19,7 +19,7 @@ const { defaults } = require('jest-config');
module.exports = {
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'],
preset: 'react-native',
roots: ['<rootDir>/src'],
roots: ['<rootDir>/specs'],
setupFiles: ['<rootDir>/jest-setup.js'],
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/'],
......
......@@ -22,11 +22,11 @@
"start": "NODE_OPTIONS=--max_old_space_size=8192 react-native start",
"test": "jest",
"test-rust": "cd ./rust/signer && cargo test && cd ../..",
"build-e2e:android": "detox build -c android.emu.debug",
"test-e2e:android": "detox test -c android.emu.debug",
"build-e2e:android": "detox build -c android.emu.debug -l info",
"test-e2e:android": "detox test -c android.emu.debug -l info --noStackTrace",
"e2e:android": "yarn run build-e2e:android && yarn run test-e2e:android",
"build-e2e:ios": "detox build -c ios.sim.debug",
"test-e2e:ios": "detox test -c ios.sim.debug",
"build-e2e:ios": "detox build -c ios.sim.debug -l info",
"test-e2e:ios": "detox test -c ios.sim.debug -l info --noStackTrace",
"e2e:ios": "yarn run build-e2e:ios && yarn run test-e2e:ios"
},
"husky": {
......@@ -51,6 +51,7 @@
"react": "^16.9.0",
"react-native": "0.60.5",
"react-native-camera": "^3.4.0",
"react-native-elements": "^1.2.6",
"react-native-gesture-handler": "^1.4.1",
"react-native-keyboard-aware-scroll-view": "^0.9.1",
"react-native-markdown-renderer": "^3.2.8",
......@@ -75,7 +76,7 @@
"babel-eslint": "10.0.3",
"babel-jest": "^24.9.0",
"babel-plugin-rewrite-require": "^1.14.5",
"detox": "^14.5.0",
"detox": "^14.7.0",
"eslint": "^6.3.0",
"eslint-config-prettier": "^6.2.0",
"eslint-plugin-prettier": "^3.1.0",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment