diff --git a/app/screens/LoadingNavigator/LoadingScreen.test.tsx b/app/components/LoadingScreen.test.tsx similarity index 100% rename from app/screens/LoadingNavigator/LoadingScreen.test.tsx rename to app/components/LoadingScreen.test.tsx diff --git a/app/screens/LoadingNavigator/LoadingScreen.tsx b/app/components/LoadingScreen.tsx similarity index 87% rename from app/screens/LoadingNavigator/LoadingScreen.tsx rename to app/components/LoadingScreen.tsx index 10eca1cfa8..981b1ee2cc 100644 --- a/app/screens/LoadingNavigator/LoadingScreen.tsx +++ b/app/components/LoadingScreen.tsx @@ -1,8 +1,8 @@ import * as React from 'react' import { View } from 'react-native' import Spinner from 'react-native-loading-spinner-overlay' -import { tailwind } from '../../tailwind' -import { translate } from '../../translations' +import { tailwind } from '../tailwind' +import { translate } from '../translations' export default function LoadingScreen (props: { message?: string }): JSX.Element { const { message } = props diff --git a/app/screens/LoadingNavigator/__snapshots__/LoadingScreen.test.tsx.snap b/app/components/__snapshots__/LoadingScreen.test.tsx.snap similarity index 100% rename from app/screens/LoadingNavigator/__snapshots__/LoadingScreen.test.tsx.snap rename to app/components/__snapshots__/LoadingScreen.test.tsx.snap diff --git a/app/screens/AppNavigator/screens/Balances/ConvertScreen.tsx b/app/screens/AppNavigator/screens/Balances/ConvertScreen.tsx index 8a4f16d7f7..3f48813999 100644 --- a/app/screens/AppNavigator/screens/Balances/ConvertScreen.tsx +++ b/app/screens/AppNavigator/screens/Balances/ConvertScreen.tsx @@ -15,6 +15,7 @@ import { Logging } from '../../../../api' import { Text, TextInput, View } from '../../../../components' import { Button } from '../../../../components/Button' import { getTokenIcon } from '../../../../components/icons/tokens/_index' +import LoadingScreen from '../../../../components/LoadingScreen' import { SectionTitle } from '../../../../components/SectionTitle' import { AmountButtonTypes, SetAmountButton } from '../../../../components/SetAmountButton' import { useTokensAPI } from '../../../../hooks/wallet/TokensAPI' @@ -22,7 +23,6 @@ import { RootState } from '../../../../store' import { hasTxQueued, transactionQueue } from '../../../../store/transaction' import { tailwind } from '../../../../tailwind' import { translate } from '../../../../translations' -import LoadingScreen from '../../../LoadingNavigator/LoadingScreen' import { BalanceParamList } from './BalancesNavigator' export type ConversionMode = 'utxosToAccount' | 'accountToUtxos' diff --git a/app/screens/AppNavigator/screens/Balances/screens/TokenDetailScreen.tsx b/app/screens/AppNavigator/screens/Balances/screens/TokenDetailScreen.tsx index f5422f956a..3657fa8797 100644 --- a/app/screens/AppNavigator/screens/Balances/screens/TokenDetailScreen.tsx +++ b/app/screens/AppNavigator/screens/Balances/screens/TokenDetailScreen.tsx @@ -38,7 +38,13 @@ export function TokenDetailScreen ({ route, navigation }: Props): JSX.Element { {value}} + renderText={(value) => ( + {value} + + )} /> 100,000 BTC @@ -345,6 +346,7 @@ exports[`token detail screen should accept Token DFI 1`] = ` }, ] } + testID="token_detail_amount" > 100,000 DFI @@ -536,6 +538,7 @@ exports[`token detail screen should accept UTXO DFI 1`] = ` }, ] } + testID="token_detail_amount" > 100,000 DFI diff --git a/app/screens/AppNavigator/screens/Dex/DexAddLiquidity.tsx b/app/screens/AppNavigator/screens/Dex/DexAddLiquidity.tsx index 459c11327c..ec1a5dbcaf 100644 --- a/app/screens/AppNavigator/screens/Dex/DexAddLiquidity.tsx +++ b/app/screens/AppNavigator/screens/Dex/DexAddLiquidity.tsx @@ -9,12 +9,12 @@ import NumberFormat from 'react-number-format' import { Text, TextInput, View } from '../../../../components' import { Button } from '../../../../components/Button' import { getTokenIcon } from '../../../../components/icons/tokens/_index' +import LoadingScreen from '../../../../components/LoadingScreen' import { SectionTitle } from '../../../../components/SectionTitle' import { AmountButtonTypes, SetAmountButton } from '../../../../components/SetAmountButton' import { useTokensAPI } from '../../../../hooks/wallet/TokensAPI' import { tailwind } from '../../../../tailwind' import { translate } from '../../../../translations' -import LoadingScreen from '../../../LoadingNavigator/LoadingScreen' import { DexParamList } from './DexNavigator' type Props = StackScreenProps diff --git a/app/screens/AppNavigator/screens/Dex/PoolSwap/PoolSwapScreen.tsx b/app/screens/AppNavigator/screens/Dex/PoolSwap/PoolSwapScreen.tsx index 194e9a814e..5e775f47df 100644 --- a/app/screens/AppNavigator/screens/Dex/PoolSwap/PoolSwapScreen.tsx +++ b/app/screens/AppNavigator/screens/Dex/PoolSwap/PoolSwapScreen.tsx @@ -14,6 +14,7 @@ import { Logging } from '../../../../../api' import { Text, TextInput } from '../../../../../components' import { Button } from '../../../../../components/Button' import { getTokenIcon } from '../../../../../components/icons/tokens/_index' +import LoadingScreen from '../../../../../components/LoadingScreen' import { SectionTitle } from '../../../../../components/SectionTitle' import { AmountButtonTypes, SetAmountButton } from '../../../../../components/SetAmountButton' import { useWallet } from '../../../../../contexts/WalletContext' @@ -22,7 +23,6 @@ import { RootState } from '../../../../../store' import { hasTxQueued, transactionQueue } from '../../../../../store/transaction_queue' import { tailwind } from '../../../../../tailwind' import { translate } from '../../../../../translations' -import LoadingScreen from '../../../../LoadingNavigator/LoadingScreen' import { DexParamList } from '../DexNavigator' interface DerivedTokenState { diff --git a/app/screens/AppNavigator/screens/Settings/screens/AboutScreen.test.tsx b/app/screens/AppNavigator/screens/Settings/screens/AboutScreen.test.tsx new file mode 100644 index 0000000000..2f5123193e --- /dev/null +++ b/app/screens/AppNavigator/screens/Settings/screens/AboutScreen.test.tsx @@ -0,0 +1,13 @@ +import { fireEvent, render } from "@testing-library/react-native" +import * as React from 'react' +import { Linking } from 'react-native' +import { AboutScreen } from "./AboutScreen"; + +it(' should match snapshot', async () => { + const tree = render() + expect(tree.toJSON()).toMatchSnapshot() + const privacyPolicy = await tree.findByTestId('privacy_policy_button') + fireEvent.press(privacyPolicy) + expect(Linking.canOpenURL).toBeCalled() +}) + diff --git a/app/screens/AppNavigator/screens/Settings/screens/__snapshots__/AboutScreen.test.tsx.snap b/app/screens/AppNavigator/screens/Settings/screens/__snapshots__/AboutScreen.test.tsx.snap new file mode 100644 index 0000000000..d66017e8ae --- /dev/null +++ b/app/screens/AppNavigator/screens/Settings/screens/__snapshots__/AboutScreen.test.tsx.snap @@ -0,0 +1,318 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should match snapshot 1`] = ` + + + + + + + + + + + + + DeFiChain Wallet + + + vmock + + + + LINKS + + + + White Paper + + + + + Privacy Policy + + + + + Licenses + + + + +`; diff --git a/app/screens/LoadingNavigator/LoadingNavigator.tsx b/app/screens/LoadingNavigator/LoadingNavigator.tsx deleted file mode 100644 index 276eaa105f..0000000000 --- a/app/screens/LoadingNavigator/LoadingNavigator.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { LinkingOptions, NavigationContainer } from '@react-navigation/native' -import { createStackNavigator } from '@react-navigation/stack' -import * as Linking from 'expo-linking' -import * as React from 'react' -import { View } from 'react-native' - -export interface LoadingParamList { - Loading: undefined - - [key: string]: undefined | object -} - -const LoadingStack = createStackNavigator() - -export function LoadingNavigator (): JSX.Element { - return ( - - - - - - ) -} - -const LinkingConfiguration: LinkingOptions = { - prefixes: [Linking.makeUrl('/')], - config: { - screens: { - Loading: 'loading' - } - } -} diff --git a/app/screens/TransactionAuthorization.tsx b/app/screens/TransactionAuthorization.tsx index fe322e9b2b..f2e7f4726d 100644 --- a/app/screens/TransactionAuthorization.tsx +++ b/app/screens/TransactionAuthorization.tsx @@ -214,7 +214,10 @@ export function TransactionAuthorization (): JSX.Element | null { }) }} > - + {translate('components/UnlockWallet', 'CANCEL')} diff --git a/app/screens/WalletNavigator/screens/CreateWallet/EnrollBiometric.tsx b/app/screens/WalletNavigator/screens/CreateWallet/EnrollBiometric.tsx index b7366a6fd9..7e9af65e3b 100644 --- a/app/screens/WalletNavigator/screens/CreateWallet/EnrollBiometric.tsx +++ b/app/screens/WalletNavigator/screens/CreateWallet/EnrollBiometric.tsx @@ -1,20 +1,20 @@ import { StackScreenProps } from '@react-navigation/stack' -import React, { useState, useEffect, useCallback } from 'react' +import * as LocalAuthentication from 'expo-local-authentication' +import { AuthenticationType, SecurityLevel } from 'expo-local-authentication' +import React, { useCallback, useEffect, useState } from 'react' import { Platform, ScrollView, Switch } from 'react-native' import tailwind from 'tailwind-rn' -import { Text, View } from '../../../../components' -import { useWalletPersistenceContext } from '../../../../contexts/WalletPersistenceContext' -import { translate } from '../../../../translations' -import { WalletParamList } from '../../WalletNavigator' -import * as LocalAuthentication from 'expo-local-authentication' -import { SecurityLevel, AuthenticationType } from 'expo-local-authentication' import { Logging } from '../../../../api' -import LoadingScreen from '../../../LoadingNavigator/LoadingScreen' -import { Button } from '../../../../components/Button' import { BiometricProtectedPasscode } from '../../../../api/wallet/biometric_protected_passcode' +import { MnemonicWords } from '../../../../api/wallet/mnemonic_words' +import { Text, View } from '../../../../components' +import { Button } from '../../../../components/Button' import { FaceIdIcon } from '../../../../components/icons/FaceIdIcon' import { TouchIdIcon } from '../../../../components/icons/TouchIdIcon' -import { MnemonicWords } from '../../../../api/wallet/mnemonic_words' +import LoadingScreen from '../../../../components/LoadingScreen' +import { useWalletPersistenceContext } from '../../../../contexts/WalletPersistenceContext' +import { translate } from '../../../../translations' +import { WalletParamList } from '../../WalletNavigator' type Props = StackScreenProps diff --git a/app/screens/WalletNavigator/screens/CreateWallet/VerifyMnemonicWallet.tsx b/app/screens/WalletNavigator/screens/CreateWallet/VerifyMnemonicWallet.tsx index e25c97e946..f9b4aff627 100644 --- a/app/screens/WalletNavigator/screens/CreateWallet/VerifyMnemonicWallet.tsx +++ b/app/screens/WalletNavigator/screens/CreateWallet/VerifyMnemonicWallet.tsx @@ -141,7 +141,7 @@ function RecoveryWordRow ({ index, words, onWordSelect, lineNumber }: RecoveryWo {`#${index + 1}?`} - + { words.map((w, i) => ( , const { width } = Platform.OS === 'web' ? { width: '375px' } : Dimensions.get('window') export function InitialSlide (): JSX.Element { - const { setWallet } = useWalletPersistenceContext() - const onDebugPress = getEnvironment().debug ? async () => { - await setWallet(MnemonicUnprotected.Abandon23Playground) - } : undefined return ( - - - + {translate('screens/OnboardingCarousel', 'DeFiChain')} diff --git a/app/store/block.test.ts b/app/store/block.test.ts new file mode 100644 index 0000000000..20ea53c395 --- /dev/null +++ b/app/store/block.test.ts @@ -0,0 +1,23 @@ +import { block, BlockState } from './block'; + +describe('block reducer', () => { + let initialState: BlockState; + + beforeEach(() => { + initialState = { + count: 77 + }; + }) + + it('should handle initial state', () => { + expect(block.reducer(undefined, { type: 'unknown' })).toEqual({ + count: undefined + }); + }); + + it('should handle updateBlock', () => { + const payload = { count: 99 } + const actual = block.reducer(initialState, block.actions.updateBlock(payload)); + expect(actual).toStrictEqual(payload) + }); +}) diff --git a/app/store/block.ts b/app/store/block.ts index 57027f51ea..386e56021d 100644 --- a/app/store/block.ts +++ b/app/store/block.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' -interface BlockState { +export interface BlockState { count?: number } diff --git a/cypress/integration/functional/onboarding/createMnemonicWallet.spec.ts b/cypress/integration/functional/onboarding/createMnemonicWallet.spec.ts index ce3a2d6d50..bbae2776df 100644 --- a/cypress/integration/functional/onboarding/createMnemonicWallet.spec.ts +++ b/cypress/integration/functional/onboarding/createMnemonicWallet.spec.ts @@ -1,10 +1,11 @@ -context('wallet/createmnemonic', () => { +context('Onboarding - Create Mnemonic Wallet', () => { const numbers = Array.from(Array(24), (v, i) => i + 1) const recoveryWords: string[] = [] const settingsRecoveryWords: string[] = [] + before(function () { cy.visit('/') - cy.getByTestID('playground_wallet_clear').click() + cy.exitWallet() cy.getByTestID('create_wallet_button').click() cy.getByTestID('guidelines_switch').click() cy.getByTestID('create_recovery_words_button').click() @@ -30,6 +31,26 @@ context('wallet/createmnemonic', () => { cy.getByTestID('verify_words_button').should('have.attr', 'disabled') }) + it('should select incorrect words', function () { + [0, 1, 2, 3, 4, 5].forEach((key, index) => { + cy.getByTestID(`line_${index}`).then(($txt: any) => { + const wordIndex = (+$txt[0].textContent.replace('?', '').replace('#', '')) - 1 + cy.getByTestID(`recovery_word_row_${wordIndex}`).children().first().click() + }) + }) + }) + + it('should return to previous page on error', function () { + cy.getByTestID('verify_words_button').should('not.have.attr', 'disabled') + cy.getByTestID('verify_words_button').click() + // validate if they're the same words on return + numbers.forEach((i) => { + cy.getByTestID(`word_${i}`).should('exist') + cy.getByTestID(`word_${i}_number`).should('exist').contains(`${i}.`) + }) + cy.getByTestID('verify_button').click() + }) + it('should be able to select correct words', function () { [0, 1, 2, 3, 4, 5].forEach((key, index) => { cy.getByTestID(`line_${index}`).then(($txt: any) => { @@ -47,44 +68,48 @@ context('wallet/createmnemonic', () => { it('should be able to verify and set pincode', function () { cy.getByTestID('pin_input').type('000000') cy.getByTestID('create_pin_button').click() - cy.getByTestID('pin_confirm_input').type('777777').wait(5000) + cy.getByTestID('pin_confirm_input').type('777777').wait(1000) cy.getByTestID('wrong_passcode_text').should('exist') cy.getByTestID('pin_confirm_input').type('000000') }) - it('should be able to verify mnemonic from settings page', function () { - cy.getByTestID('balances_list').should('exist') - cy.getByTestID('bottom_tab_settings').click() - cy.getByTestID('view_recovery_words').click() - cy.getByTestID('pin_authorize').type('000000') - }) + context('Settings - Mnemonic Verification', () => { + it('should be able to verify mnemonic from settings page', function () { + cy.getByTestID('balances_list').should('exist') + cy.getByTestID('bottom_tab_settings').click() + cy.getByTestID('view_recovery_words').click() + cy.getByTestID('pin_authorize').type('000000') + }) - numbers.forEach((i) => { - it(`settings - should display word #${i}`, function () { - cy.getByTestID(`word_${i}`).should('exist') - cy.getByTestID(`word_${i}_number`).should('exist').contains(`${i}.`) - cy.getByTestID(`word_${i}`).then(($txt: any) => { - settingsRecoveryWords.push($txt[0].textContent) + numbers.forEach((i) => { + it(`should display word #${i}`, function () { + cy.getByTestID(`word_${i}`).should('exist') + cy.getByTestID(`word_${i}_number`).should('exist').contains(`${i}.`) + cy.getByTestID(`word_${i}`).then(($txt: any) => { + settingsRecoveryWords.push($txt[0].textContent) + }) }) }) - }) - it('settings - should be able to have equal words', function () { - expect(recoveryWords).to.deep.eq(settingsRecoveryWords) + it('should be able to have equal words', function () { + expect(recoveryWords).to.deep.eq(settingsRecoveryWords) + }) }) - it('should be able to restore mnemonic words', function () { - cy.getByTestID('playground_wallet_clear').click() - cy.getByTestID('restore_wallet_button').click() - settingsRecoveryWords.forEach((word, index) => { - cy.getByTestID(`recover_word_${index + 1}`).clear().type(word).blur() - cy.getByTestID(`recover_word_${index + 1}`).should('have.css', 'color', 'rgb(0, 0, 0)') + context('Restore - Mnemonic Verification', () => { + it('should be able to restore mnemonic words', function () { + cy.exitWallet() + cy.getByTestID('restore_wallet_button').click() + settingsRecoveryWords.forEach((word, index) => { + cy.getByTestID(`recover_word_${index + 1}`).clear().type(word).blur() + cy.getByTestID(`recover_word_${index + 1}`).should('have.css', 'color', 'rgb(0, 0, 0)') + }) + cy.getByTestID('recover_wallet_button').should('not.have.attr', 'disabled') + cy.getByTestID('recover_wallet_button').click() + cy.getByTestID('pin_input').type('000000') + cy.getByTestID('create_pin_button').click() + cy.getByTestID('pin_confirm_input').type('000000') + cy.getByTestID('balances_list').should('exist') }) - cy.getByTestID('recover_wallet_button').should('not.have.attr', 'disabled') - cy.getByTestID('recover_wallet_button').click() - cy.getByTestID('pin_input').type('000000') - cy.getByTestID('create_pin_button').click() - cy.getByTestID('pin_confirm_input').type('000000') - cy.getByTestID('balances_list').should('exist') }) }) diff --git a/cypress/integration/functional/onboarding/onboarding.spec.ts b/cypress/integration/functional/onboarding/onboarding.spec.ts index d014e1943a..48218cd08f 100644 --- a/cypress/integration/functional/onboarding/onboarding.spec.ts +++ b/cypress/integration/functional/onboarding/onboarding.spec.ts @@ -1,13 +1,13 @@ -context('wallet/onboarding', () => { +context('Onboarding', () => { beforeEach(function () { cy.visit('/') - cy.getByTestID('playground_wallet_clear').click() + cy.exitWallet() }) it('should display elements', function () { cy.getByTestID('onboarding_carousel').should('exist') - cy.getByTestID('create_wallet_button').should('exist') - cy.getByTestID('restore_wallet_button').should('exist') + cy.getByTestID('create_wallet_button').should('exist').should('not.have.attr', 'disabled') + cy.getByTestID('restore_wallet_button').should('exist').should('not.have.attr', 'disabled') }) //* Will be expanded once other screens are ready @@ -21,8 +21,11 @@ context('wallet/onboarding', () => { cy.url().should('include', 'wallet/onboarding/guidelines/recovery') cy.go('back') + cy.getByTestID('create_recovery_words_button').should('have.attr', 'disabled') cy.getByTestID('guidelines_switch').click() + cy.getByTestID('create_recovery_words_button').should('not.have.attr', 'disabled') cy.getByTestID('create_recovery_words_button').click() + cy.url().should('include', 'wallet/mnemonic/create') }) diff --git a/cypress/integration/functional/onboarding/restore.spec.ts b/cypress/integration/functional/onboarding/restore.spec.ts index 2285f748a3..4d99410078 100644 --- a/cypress/integration/functional/onboarding/restore.spec.ts +++ b/cypress/integration/functional/onboarding/restore.spec.ts @@ -1,9 +1,9 @@ -context('wallet/recover', () => { +context('Onboarding - Restore Wallet', () => { const recoveryWords = ['abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'art'] before(function () { cy.visit('/') - cy.getByTestID('playground_wallet_clear').click() + cy.exitWallet() cy.getByTestID('restore_wallet_button').click() cy.url().should('include', 'wallet/mnemonic/restore') }) diff --git a/cypress/integration/functional/wallet/authorization/transactionAuthorization.spec.ts b/cypress/integration/functional/wallet/authorization/transactionAuthorization.spec.ts new file mode 100644 index 0000000000..0991527684 --- /dev/null +++ b/cypress/integration/functional/wallet/authorization/transactionAuthorization.spec.ts @@ -0,0 +1,65 @@ +context('Wallet - Transaction Authorization', () => { + before(function () { + cy.createEmptyWallet(true) + cy.sendDFItoWallet().sendTokenToWallet(['BTC']).wait(10000) + cy.fetchWalletBalance() + cy.getByTestID('bottom_tab_balances').click() + cy.getByTestID('balances_list').should('exist') + cy.getByTestID('balances_row_0_utxo').should('exist') + cy.getByTestID('balances_row_0_utxo_amount').contains(10).click() + cy.getByTestID('send_button').click() + }) + + context('Transaction Authorization', () => { + // TODO(@ivan-zynesis) - Clicking on cancel re-opens twice + /* it('should be able to cancel', function () { + cy.getByTestID('address_input').clear().type('bcrt1q8rfsfny80jx78cmk4rsa069e2ckp6rn83u6ut9') + cy.getByTestID('amount_input').clear().type('1') + cy.getByTestID('send_submit_button').click().wait(3000) + cy.getByTestID('cancel_authorization').click() + }) */ + + it('should be able to exit failed retries', function () { + cy.getByTestID('address_input').clear().type('bcrt1q8rfsfny80jx78cmk4rsa069e2ckp6rn83u6ut9') + cy.getByTestID('amount_input').clear().type('1') + cy.getByTestID('send_submit_button').click() + Array.from(Array(4), (v, i) => i + 1).forEach(() => { + cy.getByTestID('pin_authorize').type('696969').wait(1000) + }) + cy.url().should('include', 'wallet/onboarding') + }) + }) + + context('Non-Transaction Authorization', () => { + it('should be prompt non-signing authorization', function () { + cy.createEmptyWallet(true) + cy.getByTestID('bottom_tab_settings').click() + cy.getByTestID('view_recovery_words').click() + }) + + it('should be able to exit failed retries', function () { + Array.from(Array(4), (v, i) => i + 1).forEach(() => { + cy.getByTestID('pin_authorize').type('696969').wait(1000) + }) + cy.url().should('include', 'wallet/onboarding') + }) + + it('should clear attempt on success', function () { + cy.createEmptyWallet(true) + cy.getByTestID('bottom_tab_settings').click() + cy.getByTestID('view_recovery_words').click() + Array.from(Array(3), (v, i) => i + 1).forEach(() => { + cy.getByTestID('pin_authorize').type('696969').wait(1000) + }) + cy.getByTestID('pin_authorize').type('000000').wait(1000) + cy.getByTestID('recovery_word_screen').should('exist') + cy.go('back') + cy.getByTestID('view_recovery_words').click() + Array.from(Array(1), (v, i) => i + 1).forEach(() => { + cy.getByTestID('pin_authorize').type('696969').wait(1000) + }) + cy.getByTestID('pin_authorize').type('000000').wait(1000) + cy.getByTestID('recovery_word_screen').should('exist') + }) + }) +}) diff --git a/cypress/integration/functional/balances/balances.spec.ts b/cypress/integration/functional/wallet/balances/balances.spec.ts similarity index 71% rename from cypress/integration/functional/balances/balances.spec.ts rename to cypress/integration/functional/wallet/balances/balances.spec.ts index e5d341cd80..5f89a0d54c 100644 --- a/cypress/integration/functional/balances/balances.spec.ts +++ b/cypress/integration/functional/wallet/balances/balances.spec.ts @@ -1,11 +1,11 @@ -context('wallet/balances', () => { +context('Wallet - Balances', () => { beforeEach(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() cy.sendDFItoWallet() .sendDFITokentoWallet() .sendTokenToWallet(['BTC', 'ETH']).wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() }) @@ -20,11 +20,4 @@ context('wallet/balances', () => { cy.getByTestID('balances_row_2').should('exist') cy.getByTestID('balances_row_2_amount').contains(10) }) - - /* it.skip('should display navigation buttons and be able to redirect', function () { - cy.getByTestID('button_RECEIVE').should('exist').click() - cy.location().should((loc) => { - expect(loc.href).contains('Receive') - }) - }) */ }) diff --git a/cypress/integration/functional/balances/convert/convert.spec.ts b/cypress/integration/functional/wallet/balances/convert/convert.spec.ts similarity index 95% rename from cypress/integration/functional/balances/convert/convert.spec.ts rename to cypress/integration/functional/wallet/balances/convert/convert.spec.ts index 015964fad4..f64e9c3c84 100644 --- a/cypress/integration/functional/balances/convert/convert.spec.ts +++ b/cypress/integration/functional/wallet/balances/convert/convert.spec.ts @@ -1,10 +1,10 @@ -context('wallet/balances/convert - bi-direction success case', () => { +context('Wallet - Convert DFI - bi-direction success case', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() cy.sendDFItoWallet().wait(4000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_list').should('exist') @@ -64,7 +64,7 @@ context('wallet/balances/convert - bi-direction success case', () => { // // refresh balance cy.getByTestID('bottom_tab_settings').click() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_list').should('exist') @@ -125,7 +125,7 @@ context('wallet/balances/convert - bi-direction success case', () => { // // refresh balance cy.getByTestID('bottom_tab_settings').click() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_list').should('exist') diff --git a/cypress/integration/functional/balances/convert/convert_account_to_utxos.spec.ts b/cypress/integration/functional/wallet/balances/convert/convert_account_to_utxos.spec.ts similarity index 95% rename from cypress/integration/functional/balances/convert/convert_account_to_utxos.spec.ts rename to cypress/integration/functional/wallet/balances/convert/convert_account_to_utxos.spec.ts index be5c485176..68586c5e56 100644 --- a/cypress/integration/functional/balances/convert/convert_account_to_utxos.spec.ts +++ b/cypress/integration/functional/wallet/balances/convert/convert_account_to_utxos.spec.ts @@ -1,10 +1,10 @@ -context('wallet/balances/convert - accountToUtxos', () => { +context('Wallet - Convert DFI - accountToUtxos', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() cy.sendDFItoWallet().sendDFITokentoWallet().wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_list').should('exist') diff --git a/cypress/integration/functional/balances/convert/convert_utxos_to_account.spec.ts b/cypress/integration/functional/wallet/balances/convert/convert_utxos_to_account.spec.ts similarity index 95% rename from cypress/integration/functional/balances/convert/convert_utxos_to_account.spec.ts rename to cypress/integration/functional/wallet/balances/convert/convert_utxos_to_account.spec.ts index 335fa5096f..cf3baed511 100644 --- a/cypress/integration/functional/balances/convert/convert_utxos_to_account.spec.ts +++ b/cypress/integration/functional/wallet/balances/convert/convert_utxos_to_account.spec.ts @@ -1,10 +1,10 @@ -context('wallet/balances/convert - utxosToAccount', () => { +context('Wallet - Convert DFI - utxosToAccount', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() cy.sendDFItoWallet().wait(4000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_list').should('exist') diff --git a/cypress/integration/functional/balances/send.spec.ts b/cypress/integration/functional/wallet/balances/send.spec.ts similarity index 93% rename from cypress/integration/functional/balances/send.spec.ts rename to cypress/integration/functional/wallet/balances/send.spec.ts index 6cf94b519b..b2e453d2be 100644 --- a/cypress/integration/functional/balances/send.spec.ts +++ b/cypress/integration/functional/wallet/balances/send.spec.ts @@ -1,25 +1,30 @@ import { WhaleApiClient } from '@defichain/whale-api-client' import BigNumber from 'bignumber.js' -context('wallet/send', () => { +context('Wallet - Send', () => { // bech32, p2sh, legacy const addresses = ['bcrt1q8rfsfny80jx78cmk4rsa069e2ckp6rn83u6ut9', '2MxnNb1MYSZvS3c26d4gC7gXsNMkB83UoXB', 'n1xjm9oekw98Rfb3Mv4ApyhwxC5kMuHnCo'] let network: string before(function () { cy.createEmptyWallet(true) cy.sendDFItoWallet().sendTokenToWallet(['BTC']).wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() network = localStorage.getItem('Development.NETWORK') }) describe('DFI UTXO', () => { - it('should be able to validate form', function () { + it('should be able redirect to QR screen page', function () { cy.getByTestID('balances_list').should('exist') cy.getByTestID('balances_row_0_utxo').should('exist') cy.getByTestID('balances_row_0_utxo_amount').contains(10).click() cy.getByTestID('send_button').click() + cy.getByTestID('qr_code_button').click() + cy.url().should('include', 'app/BarCodeScanner') + cy.go('back') + }) + it('should be able to validate form', function () { // Valid form cy.getByTestID('address_input').type(addresses[0]) cy.getByTestID('amount_input').type('0.1') @@ -80,7 +85,7 @@ context('wallet/send', () => { cy.getByTestID('send_submit_button').should('not.have.attr', 'disabled') cy.getByTestID('send_submit_button').click() cy.closeOceanInterface() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() }) @@ -113,12 +118,12 @@ context('wallet/send', () => { cy.getByTestID('MAX_amount_button').click() cy.getByTestID('send_submit_button').click() cy.closeOceanInterface() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_row_1_amount').should('not.exist') cy.sendTokenToWallet(['BTC']).wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() }) }) }) diff --git a/cypress/integration/functional/wallet/balances/tokenDetail.spec.ts b/cypress/integration/functional/wallet/balances/tokenDetail.spec.ts new file mode 100644 index 0000000000..1a780d854e --- /dev/null +++ b/cypress/integration/functional/wallet/balances/tokenDetail.spec.ts @@ -0,0 +1,46 @@ +context('Wallet - Token Detail', () => { + before(function () { + cy.createEmptyWallet(true) + cy.getByTestID('bottom_tab_settings').click() + cy.sendDFItoWallet() + .sendDFITokentoWallet() + .sendTokenToWallet(['BTC']).wait(10000) + cy.fetchWalletBalance() + cy.getByTestID('bottom_tab_balances').click() + }) + + it('should be able to click utxoDFI', function () { + cy.getByTestID('balances_list').should('exist') + cy.getByTestID('balances_row_0_utxo').should('exist') + cy.getByTestID('balances_row_0_utxo_amount').contains(10) + cy.getByTestID('balances_row_0_utxo').click() + cy.getByTestID('token_detail_amount').contains(10) + cy.getByTestID('send_button').should('exist') + cy.getByTestID('receive_button').should('exist') + cy.getByTestID('convert_button').should('exist') + cy.getByTestID('bottom_tab_balances').click() + }) + + it('should be able to click token DFI', function () { + cy.getByTestID('balances_list').should('exist') + cy.getByTestID('balances_row_0').should('exist') + cy.getByTestID('balances_row_0_amount').contains(10) + cy.getByTestID('balances_row_0').click() + cy.getByTestID('token_detail_amount').contains(10) + cy.getByTestID('send_button').should('not.exist') + cy.getByTestID('receive_button').should('not.exist') + cy.getByTestID('convert_button').should('exist') + cy.getByTestID('bottom_tab_balances').click() + }) + + it('should be able to click token BTC', function () { + cy.getByTestID('balances_list').should('exist') + cy.getByTestID('balances_row_1').should('exist') + cy.getByTestID('balances_row_1_amount').contains(10) + cy.getByTestID('balances_row_1').click() + cy.getByTestID('token_detail_amount').contains(10) + cy.getByTestID('send_button').should('exist') + cy.getByTestID('receive_button').should('exist') + cy.getByTestID('convert_button').should('not.exist') + }) +}) diff --git a/cypress/integration/functional/dex/add_liquidity.spec.ts b/cypress/integration/functional/wallet/dex/add_liquidity.spec.ts similarity index 97% rename from cypress/integration/functional/dex/add_liquidity.spec.ts rename to cypress/integration/functional/wallet/dex/add_liquidity.spec.ts index 74589407b8..6b72adfe25 100644 --- a/cypress/integration/functional/dex/add_liquidity.spec.ts +++ b/cypress/integration/functional/wallet/dex/add_liquidity.spec.ts @@ -1,11 +1,11 @@ -context('app/dex/addLiquidity', () => { +context('Wallet - DEX - Add Liquidity', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_dex').click() cy.sendDFItoWallet() .sendDFITokentoWallet() .sendTokenToWallet(['BTC']).wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_dex').click() cy.getByTestID('pool_pair_add_DFI-BTC').click() diff --git a/cypress/integration/functional/dex/available_pool_pairs.spec.ts b/cypress/integration/functional/wallet/dex/available_pool_pairs.spec.ts similarity index 94% rename from cypress/integration/functional/dex/available_pool_pairs.spec.ts rename to cypress/integration/functional/wallet/dex/available_pool_pairs.spec.ts index 81ae54f982..d06aeb111f 100644 --- a/cypress/integration/functional/dex/available_pool_pairs.spec.ts +++ b/cypress/integration/functional/wallet/dex/available_pool_pairs.spec.ts @@ -1,4 +1,4 @@ -context('app/dex/available', () => { +context('Wallet - DEX - Available Pool Pairs', () => { beforeEach(function () { cy.createEmptyWallet() cy.getByTestID('bottom_tab_dex').click() diff --git a/cypress/integration/functional/dex/confirm_add_liq.spec.ts b/cypress/integration/functional/wallet/dex/confirm_add_liq.spec.ts similarity index 90% rename from cypress/integration/functional/dex/confirm_add_liq.spec.ts rename to cypress/integration/functional/wallet/dex/confirm_add_liq.spec.ts index c5526a6ae4..80a9554316 100644 --- a/cypress/integration/functional/dex/confirm_add_liq.spec.ts +++ b/cypress/integration/functional/wallet/dex/confirm_add_liq.spec.ts @@ -1,4 +1,4 @@ -context('app/dex/addLiquidity', () => { +context('Wallet - Confirm Add Liquidity', () => { beforeEach(function () { cy.createEmptyWallet() @@ -7,7 +7,7 @@ context('app/dex/addLiquidity', () => { cy.sendDFItoWallet() .sendDFITokentoWallet() .sendTokenToWallet(['BTC']).wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_dex').click() cy.getByTestID('pool_pair_add_DFI-BTC').click() @@ -41,7 +41,7 @@ context('app/dex/addLiquidity', () => { // wait balance update cy.wait(3100) cy.getByTestID('bottom_tab_settings').click() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_dex').click() cy.getByTestID('pool_pair_row_your').contains('7.80 DFI-BTC') diff --git a/cypress/integration/functional/dex/poolswap.spec.ts b/cypress/integration/functional/wallet/dex/poolswap.spec.ts similarity index 94% rename from cypress/integration/functional/dex/poolswap.spec.ts rename to cypress/integration/functional/wallet/dex/poolswap.spec.ts index cc986d72c0..6d6d787b64 100644 --- a/cypress/integration/functional/dex/poolswap.spec.ts +++ b/cypress/integration/functional/wallet/dex/poolswap.spec.ts @@ -1,6 +1,6 @@ import BigNumber from 'bignumber.js' -context('poolswap without balance', () => { +context('Wallet - DEX - Pool Swap without balance', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_balances').click() @@ -13,12 +13,12 @@ context('poolswap without balance', () => { }) }) -context('poolswap with values', () => { +context('Wallet - DEX - Pool Swap with balance', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() cy.sendDFItoWallet().sendDFITokentoWallet().sendTokenToWallet(['LTC']).wait(10000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('bottom_tab_dex').click() cy.getByTestID('pool_pair_swap-vert_DFI-LTC').click() @@ -76,7 +76,7 @@ context('poolswap with values', () => { const tokenValue = $txt[0].textContent.replace(' LTC', '').replace(',', '') cy.getByTestID('button_submit').click() cy.closeOceanInterface() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_balances').click() cy.getByTestID('balances_row_4').should('exist') diff --git a/cypress/integration/functional/dex/remove_liquidity.spec.ts b/cypress/integration/functional/wallet/dex/remove_liquidity.spec.ts similarity index 94% rename from cypress/integration/functional/dex/remove_liquidity.spec.ts rename to cypress/integration/functional/wallet/dex/remove_liquidity.spec.ts index f240e43b49..411dbec630 100644 --- a/cypress/integration/functional/dex/remove_liquidity.spec.ts +++ b/cypress/integration/functional/wallet/dex/remove_liquidity.spec.ts @@ -1,10 +1,10 @@ -context('app/dex/removeLiquidity', () => { +context('Wallet - DEX - Remove Liquidity', () => { before(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() cy.sendDFItoWallet().sendTokenToWallet(['DFI-ETH']).wait(6000) - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_dex').click().wait(1000) @@ -59,7 +59,7 @@ context('app/dex/removeLiquidity', () => { // refresh balance cy.getByTestID('bottom_tab_settings').click() - cy.getByTestID('playground_wallet_fetch_balances').click() + cy.fetchWalletBalance() cy.getByTestID('bottom_tab_dex').click().wait(100) const list = cy.getByTestID('liquidity_screen_list') diff --git a/cypress/integration/functional/community.spec.ts b/cypress/integration/functional/wallet/settings/community.spec.ts similarity index 95% rename from cypress/integration/functional/community.spec.ts rename to cypress/integration/functional/wallet/settings/community.spec.ts index ee8bbb3cb2..f2d0e86281 100644 --- a/cypress/integration/functional/community.spec.ts +++ b/cypress/integration/functional/wallet/settings/community.spec.ts @@ -36,7 +36,7 @@ const communityLinks = [ } ] -context('wallet/settings/community', () => { +context('Wallet - Settings - Community', () => { beforeEach(function () { cy.createEmptyWallet() cy.getByTestID('bottom_tab_settings').click() diff --git a/cypress/integration/functional/settings.spec.ts b/cypress/integration/functional/wallet/settings/settings.spec.ts similarity index 70% rename from cypress/integration/functional/settings.spec.ts rename to cypress/integration/functional/wallet/settings/settings.spec.ts index beddfc8b2b..5e68b48999 100644 --- a/cypress/integration/functional/settings.spec.ts +++ b/cypress/integration/functional/wallet/settings/settings.spec.ts @@ -1,4 +1,4 @@ -context('wallet/settings', () => { +context('Wallet - Settings', () => { beforeEach(function () { cy.createEmptyWallet(true) cy.getByTestID('bottom_tab_settings').click() @@ -15,12 +15,7 @@ context('wallet/settings', () => { cy.getByTestID('restore_wallet_button').should('exist') }) - it('should navigate to recovery word screen', function () { - cy.getByTestID('view_recovery_words').should('exist').click() - cy.getByTestID('recovery_word_screen').should('exist') - }) - - it.only('should navigate to about page', function () { + it('should navigate to about page', function () { cy.getByTestID('setting_navigate_About').click() cy.url().should('include', 'app/AboutScreen') cy.getByTestID('app_logo').should('exist') diff --git a/cypress/integration/functional/transaction/detail.spec.ts b/cypress/integration/functional/wallet/transaction/detail.spec.ts similarity index 90% rename from cypress/integration/functional/transaction/detail.spec.ts rename to cypress/integration/functional/wallet/transaction/detail.spec.ts index 281e5b1d8f..41a0385d71 100644 --- a/cypress/integration/functional/transaction/detail.spec.ts +++ b/cypress/integration/functional/wallet/transaction/detail.spec.ts @@ -1,4 +1,4 @@ -context('app/transactions/detail', () => { +context('Wallet - Transaction - Detail', () => { before(() => { cy.createEmptyWallet() cy.sendDFItoWallet().wait(4000) diff --git a/cypress/integration/functional/transaction/list.spec.ts b/cypress/integration/functional/wallet/transaction/list.spec.ts similarity index 95% rename from cypress/integration/functional/transaction/list.spec.ts rename to cypress/integration/functional/wallet/transaction/list.spec.ts index eab69094ba..c929cfcc75 100644 --- a/cypress/integration/functional/transaction/list.spec.ts +++ b/cypress/integration/functional/wallet/transaction/list.spec.ts @@ -1,4 +1,4 @@ -context('app/transactions/list', () => { +context('Wallet - Transaction - List', () => { describe('wallet has 2 transactions in history', function () { before(() => { cy.createEmptyWallet(true) diff --git a/cypress/integration/functional/transaction/list_empty.spec.ts b/cypress/integration/functional/wallet/transaction/list_empty.spec.ts similarity index 94% rename from cypress/integration/functional/transaction/list_empty.spec.ts rename to cypress/integration/functional/wallet/transaction/list_empty.spec.ts index f9b5afe565..9675557dde 100644 --- a/cypress/integration/functional/transaction/list_empty.spec.ts +++ b/cypress/integration/functional/wallet/transaction/list_empty.spec.ts @@ -1,4 +1,4 @@ -context('app/transactions/list', () => { +context('Wallet - Transaction - Empty', () => { describe('new wallet', function () { before(() => { cy.createEmptyWallet(true) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index e1223faf07..de74e1f080 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -26,47 +26,59 @@ import '@testing-library/cypress/add-commands' // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) declare global { - namespace Cypress { - interface Chainable { - /** - * @description Custom command to select DOM element by data-testid attribute. - * @example cy.getByTestID('settings') - */ - getByTestID (value: string): Chainable - - /** - * @description Redirects to main page and creates an empty wallet for testing. Useful on starts of tests. - * @param {boolean} [isRandom=false] default = false, creates randomly generated mnemonic seed or abandon x23 - * @example cy.createEmptyWallet(isRandom?: boolean) - */ - createEmptyWallet (isRandom?: boolean): Chainable - - /** - * @description Sends UTXO DFI to wallet. - * @example cy.sendDFItoWallet().wait(4000) - */ - sendDFItoWallet (): Chainable - - /** - * @description Sends DFI Token to wallet. - * @example cy.sendDFITokentoWallet().wait(4000) - */ - sendDFITokentoWallet (): Chainable - - /** - * @description Sends token to wallet. Accepts a list of token symbols to be sent. - * @param {string[]} tokens to be sent - * @example cy.sendTokenToWallet(['BTC', 'ETH']).wait(4000) - */ - sendTokenToWallet (tokens: string[]): Chainable + namespace Cypress { + interface Chainable { + /** + * @description Custom command to select DOM element by data-testid attribute. + * @example cy.getByTestID('settings') + */ + getByTestID (value: string): Chainable + + /** + * @description Redirects to main page and creates an empty wallet for testing. Useful on starts of tests. + * @param {boolean} [isRandom=false] default = false, creates randomly generated mnemonic seed or abandon x23 + * @example cy.createEmptyWallet(isRandom?: boolean) + */ + createEmptyWallet (isRandom?: boolean): Chainable + + /** + * @description Sends UTXO DFI to wallet. + * @example cy.sendDFItoWallet().wait(4000) + */ + sendDFItoWallet (): Chainable + + /** + * @description Sends DFI Token to wallet. + * @example cy.sendDFITokentoWallet().wait(4000) + */ + sendDFITokentoWallet (): Chainable + + /** + * @description Sends token to wallet. Accepts a list of token symbols to be sent. + * @param {string[]} tokens to be sent + * @example cy.sendTokenToWallet(['BTC', 'ETH']).wait(4000) + */ + sendTokenToWallet (tokens: string[]): Chainable /** * @description Wait for the ocean interface to be confirmed then close the drawer * @example cy.closeOceanInterface() */ closeOceanInterface (): Chainable - } - } + + /** + * @description Exit current wallet + * @example cy.exitWallet() + */ + exitWallet (): Chainable + + /** + * @description Fetch wallet balance + * @example cy.fetchWalletBalance() + */ + fetchWalletBalance (): Chainable + } + } } Cypress.Commands.add('getByTestID', (selector, ...args) => { @@ -102,3 +114,11 @@ Cypress.Commands.add('closeOceanInterface', () => { cy.getByTestID('pin_authorize').type('000000') cy.wait(5000).getByTestID('oceanInterface_close').click().wait(2000) }) + +Cypress.Commands.add('exitWallet', () => { + cy.getByTestID('playground_wallet_clear').click() +}) + +Cypress.Commands.add('fetchWalletBalance', () => { + cy.getByTestID('playground_wallet_fetch_balances').click() +}) diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 9389072cea..f129205796 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,8 +1,14 @@ { "compilerOptions": { - "target": "es5", - "lib": ["es5", "dom"], - "types": ["cypress", "@testing-library/cypress"] + "target": "esnext", + "lib": [ + "esnext", + "dom" + ], + "types": [ + "cypress", + "@testing-library/cypress" + ] }, "include": ["**/*.ts"] -} \ No newline at end of file +}