From 286fa36ad6f5f488cbe50e44618e2ef3c8ce48ad Mon Sep 17 00:00:00 2001 From: Vlad Novak Date: Wed, 18 Oct 2023 13:59:43 +0300 Subject: [PATCH 1/9] all tests --- e2e/src/features/custom-network.feature | 1 - .../import-account-by-mnemonic.feature | 60 +++++++++++++++++++ .../import-account-by-private-key.feature | 40 +++++++++++++ .../import-account-by-public-key.feature | 32 ++++++++++ .../features/import-existing-wallet.feature | 1 - .../manage-tokens-collectibles.feature | 1 - e2e/src/hooks/after-all.hook.ts | 14 ++--- e2e/src/hooks/after.hook.ts | 60 +++++++++---------- e2e/src/step-definitions/shared.steps.ts | 2 + e2e/src/utils/input-data.utils.ts | 3 + e2e/src/utils/search.utils.ts | 2 +- src/app/atoms/Alert.selectors.ts | 3 +- src/app/atoms/Alert.tsx | 5 +- .../pages/ImportAccount/ByMnemonicForm.tsx | 12 +++- src/app/pages/ImportAccount/selectors.ts | 3 + 15 files changed, 193 insertions(+), 46 deletions(-) diff --git a/e2e/src/features/custom-network.feature b/e2e/src/features/custom-network.feature index 59b87a68d..c4bc94e60 100644 --- a/e2e/src/features/custom-network.feature +++ b/e2e/src/features/custom-network.feature @@ -69,7 +69,6 @@ Feature: Add Custom Node @custom_node - @dev Scenario: Validation check on Add Asset page + other checks [Negative] Given I have imported an existing account diff --git a/e2e/src/features/import-account-by-mnemonic.feature b/e2e/src/features/import-account-by-mnemonic.feature index c0ff1afc4..c3099ac5e 100644 --- a/e2e/src/features/import-account-by-mnemonic.feature +++ b/e2e/src/features/import-account-by-mnemonic.feature @@ -16,3 +16,63 @@ Feature: Import Account by Mnemonic And I press Mnemonic Import Button on the Import Account(Mnemonic) page Then I reveal a private key and compare with importedFirstPrivateKey + + + Scenario: As a user, I'd like to import account by mnemonic with derivation path + password field + Given I have imported an existing account + + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Mnemonic tab + And I am on the ImportAccountMnemonic page + + And I enter second mnemonic + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I am on the Home page + And I check if importedAccountShortHash is corresponded to the selected account + +# importing an account with derivation path + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Mnemonic tab + And I am on the ImportAccountMnemonic page + + And I enter second mnemonic + + And I press Custom Derivation Path Button on the Import Account(Mnemonic) page + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter customDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I scroll 900 pixels on the ImportAccountMnemonic page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I am on the Home page + And I check if importedAccountDerPathShortHash is corresponded to the selected account + +# importing an account with additional 'Password' input + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Mnemonic tab + And I am on the ImportAccountMnemonic page + + And I enter second mnemonic + And I scroll 900 pixels on the ImportAccountMnemonic page + And I enter amount_1 into Mnemonic Password Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I am on the Home page + Then I check if importedAccountByPasswordShortHash is corresponded to the selected account + + diff --git a/e2e/src/features/import-account-by-private-key.feature b/e2e/src/features/import-account-by-private-key.feature index 6e196e6d7..37fd74f89 100644 --- a/e2e/src/features/import-account-by-private-key.feature +++ b/e2e/src/features/import-account-by-private-key.feature @@ -16,3 +16,43 @@ Feature: Import Account by Private Key And I press Private Key Import Button on the Import Account(Private Key) page Then I reveal a private key and compare with importedFirstPrivateKey + + + + + Scenario: Check validation importing by private key + Given I have imported an existing account + + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Private Key tab + And I am on the ImportAccountPrivateKey page + + And I press Private Key Import Button on the Import Account(Private Key) page + And I got the validation-error 'Required' with Input Error element on the Universal Component page + + And I enter shortRandomContent into Private Key Input on the Import Account(Private Key) page + And I press Private Key Import Button on the Import Account(Private Key) page +# checking alert type , title and description of the error + And I got the 'Error' error with Alert title Text element on the Alert page + And I got the validation-error 'Failed to import account. This may happen because provided Key is invalid' with Alert description Text element on the Alert page + + And I clear Private Key Input value on the Import Account(Private Key) page + And I enter defaultFirstPrivateKey into Private Key Input on the Import Account(Private Key) page + And I press Private Key Import Button on the Import Account(Private Key) page + # checking duplicate importing account error + And I got the 'Error' error with Alert title Text element on the Alert page + And I got the validation-error 'Account already exists' with Alert description Text element on the Alert page + + And I clear Private Key Input value on the Import Account(Private Key) page + And I enter importedFirstPrivateKey into Private Key Input on the Import Account(Private Key) page + And I press Private Key Import Button on the Import Account(Private Key) page + + And I am on the Home page + Then I check if importedAccountShortHash is corresponded to the selected account + + diff --git a/e2e/src/features/import-account-by-public-key.feature b/e2e/src/features/import-account-by-public-key.feature index 3520d69ed..ef2a99159 100644 --- a/e2e/src/features/import-account-by-public-key.feature +++ b/e2e/src/features/import-account-by-public-key.feature @@ -16,3 +16,35 @@ Feature: Import an account by public key (Watch-only) And I press Watch Only Import Button on the Import Account(Watch-Only) page Then I check if watchOnlyAccountShortHash is corresponded to the selected account + + + @dev + Scenario: Check validation importing by public key + Given I have imported an existing account + + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Watch-only tab + And I am on the ImportAccountWatchOnly page + + And I enter shortRandomContent into Watch Only Input on the Import Account(Watch-Only) page + And I press Watch Only Import Button on the Import Account(Watch-Only) page + And I got the validation-error 'Invalid address or domain name' with Input Error element on the Universal Component page + + And I clear Watch Only Input value on the Import Account(Watch-Only) page + And I enter defaultFirstPublicKey into Watch Only Input on the Import Account(Watch-Only) page + And I press Watch Only Import Button on the Import Account(Watch-Only) page +# checking alert type , title and description of the error + And I got the 'Error' error with Alert title Text element on the Alert page + And I got the validation-error 'Account already exists' with Alert description Text element on the Alert page + + And I clear Watch Only Input value on the Import Account(Watch-Only) page + And I clear Watch Only Input value on the Import Account(Watch-Only) page + And I enter watchOnlyPublicKey into Watch Only Input on the Import Account(Watch-Only) page + And I press Watch Only Import Button on the Import Account(Watch-Only) page + + Then I check if watchOnlyAccountShortHash is corresponded to the selected account diff --git a/e2e/src/features/import-existing-wallet.feature b/e2e/src/features/import-existing-wallet.feature index 9c259cf13..db9c0490f 100644 --- a/e2e/src/features/import-existing-wallet.feature +++ b/e2e/src/features/import-existing-wallet.feature @@ -60,7 +60,6 @@ Feature: Import existing wallet Then I am on the Home page - @dev Scenario: As a user, I'd like to switch between onboarding pages and skip it [Negative] Given I am on the Welcome page And I press Import Existing Wallet button on the Welcome page diff --git a/e2e/src/features/manage-tokens-collectibles.feature b/e2e/src/features/manage-tokens-collectibles.feature index 5e201eb60..50f76ed80 100644 --- a/e2e/src/features/manage-tokens-collectibles.feature +++ b/e2e/src/features/manage-tokens-collectibles.feature @@ -26,7 +26,6 @@ Feature: Manage tokens + collectibles @manage_assets - @dev Scenario: As a user, I'd like to hide and delete tokens [Positive] Given I have imported an existing account # hardcoded token diff --git a/e2e/src/hooks/after-all.hook.ts b/e2e/src/hooks/after-all.hook.ts index 302c81b42..c4f255438 100644 --- a/e2e/src/hooks/after-all.hook.ts +++ b/e2e/src/hooks/after-all.hook.ts @@ -1,7 +1,7 @@ -import { AfterAll } from '@cucumber/cucumber'; - -import { BrowserContext } from '../classes/browser-context.class'; - -AfterAll(async () => { - await BrowserContext.browser.close(); -}); +// import { AfterAll } from '@cucumber/cucumber'; +// +// import { BrowserContext } from '../classes/browser-context.class'; +// +// AfterAll(async () => { +// await BrowserContext.browser.close(); +// }); diff --git a/e2e/src/hooks/after.hook.ts b/e2e/src/hooks/after.hook.ts index 0cd07ee66..a32482da9 100644 --- a/e2e/src/hooks/after.hook.ts +++ b/e2e/src/hooks/after.hook.ts @@ -1,30 +1,30 @@ -import { After } from '@cucumber/cucumber'; -import retry from 'async-retry'; -import { E2eMessageType } from 'src/lib/e2e/types'; - -import { BrowserContext } from '../classes/browser-context.class'; -import { RETRY_OPTIONS, MEDIUM_TIMEOUT } from '../utils/timing.utils'; - -const FAILED_RESET_ERROR = new Error('Failed to reset extension'); - -After({ timeout: MEDIUM_TIMEOUT }, async () => { - await BrowserContext.recorder.stop(); - - // [ Extension storages full reset ] - - await BrowserContext.page.evaluate( - // @ts-ignore - message => new Promise(res => chrome.runtime.sendMessage(message, res)), - { type: E2eMessageType.ResetRequest } - ); - await BrowserContext.page.evaluate(() => void localStorage.clear()); - - // [ Extension reload ] - - // @ts-ignore - await BrowserContext.page.evaluate(() => void chrome.runtime.reload()).catch(() => void 0); - - await retry(() => { - if (BrowserContext.page.isClosed() === false) throw FAILED_RESET_ERROR; - }, RETRY_OPTIONS); -}); +// import { After } from '@cucumber/cucumber'; +// import retry from 'async-retry'; +// import { E2eMessageType } from 'src/lib/e2e/types'; +// +// import { BrowserContext } from '../classes/browser-context.class'; +// import { RETRY_OPTIONS, MEDIUM_TIMEOUT } from '../utils/timing.utils'; +// +// const FAILED_RESET_ERROR = new Error('Failed to reset extension'); +// +// After({ timeout: MEDIUM_TIMEOUT }, async () => { +// await BrowserContext.recorder.stop(); +// +// // [ Extension storages full reset ] +// +// await BrowserContext.page.evaluate( +// // @ts-ignore +// message => new Promise(res => chrome.runtime.sendMessage(message, res)), +// { type: E2eMessageType.ResetRequest } +// ); +// await BrowserContext.page.evaluate(() => void localStorage.clear()); +// +// // [ Extension reload ] +// +// // @ts-ignore +// await BrowserContext.page.evaluate(() => void chrome.runtime.reload()).catch(() => void 0); +// +// await retry(() => { +// if (BrowserContext.page.isClosed() === false) throw FAILED_RESET_ERROR; +// }, RETRY_OPTIONS); +// }); diff --git a/e2e/src/step-definitions/shared.steps.ts b/e2e/src/step-definitions/shared.steps.ts index d05d08925..dbec996f8 100644 --- a/e2e/src/step-definitions/shared.steps.ts +++ b/e2e/src/step-definitions/shared.steps.ts @@ -41,6 +41,8 @@ Given(/I'm waiting for 'success ✓' operation status/, { timeout: LONG_TIMEOUT const hashObject = { defaultAccountShortHash: envVars.DEFAULT_HD_ACCOUNT_FIRST_HASH_SHORT_FORM, importedAccountShortHash: envVars.IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM, + importedAccountDerPathShortHash: 'tz1RPXf...RE8q', + importedAccountByPasswordShortHash: 'tz1ZfC8...PcHE', // By additional (optional) 'Password' input watchOnlyAccountShortHash: envVars.WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM }; diff --git a/e2e/src/utils/input-data.utils.ts b/e2e/src/utils/input-data.utils.ts index 57560a73e..2fc508927 100644 --- a/e2e/src/utils/input-data.utils.ts +++ b/e2e/src/utils/input-data.utils.ts @@ -15,9 +15,12 @@ const generateRandomContent = () => { export const iEnterValues = { ...iComparePrivateKeys, defaultSeedPhrase: envVars.DEFAULT_HD_ACCOUNT_SEED_PHRASE, + defaultFirstPrivateKey: envVars.DEFAULT_HD_ACCOUNT_FIRST_PRIVATE_KEY, + defaultFirstPublicKey: 'tz1g1NfadfC2qktJH99sHeBETRWGaQyrbiA4', defaultPassword: envVars.DEFAULT_PASSWORD, watchOnlyPublicKey: envVars.WATCH_ONLY_PUBLIC_KEY_HASH, bakerAddress: '', + customDerivationPath: `m/44'/1729'/10'/0'`, // eleventh account in HD // For input validation shortRandomContent: generateRandomContent(), diff --git a/e2e/src/utils/search.utils.ts b/e2e/src/utils/search.utils.ts index bc0070db2..9038d580c 100644 --- a/e2e/src/utils/search.utils.ts +++ b/e2e/src/utils/search.utils.ts @@ -132,7 +132,7 @@ export const getElementText = (element: ElementHandle) => return innerElement.value; } - const textContent = innerElement.textContent; + const textContent = innerElement.textContent?.replace(/\n/g, ' '); if (textContent == null) { throw new Error("Element's content is not text!"); diff --git a/src/app/atoms/Alert.selectors.ts b/src/app/atoms/Alert.selectors.ts index c27bd1c50..b3a72ee2a 100644 --- a/src/app/atoms/Alert.selectors.ts +++ b/src/app/atoms/Alert.selectors.ts @@ -1,3 +1,4 @@ export enum AlertSelectors { - alertTitle = 'Alert/Alert title Text' + alertTitle = 'Alert/Alert title Text', + alertDescription = 'Alert/Alert description Text' } diff --git a/src/app/atoms/Alert.tsx b/src/app/atoms/Alert.tsx index 9f91f1a19..3ea1261f6 100644 --- a/src/app/atoms/Alert.tsx +++ b/src/app/atoms/Alert.tsx @@ -74,7 +74,10 @@ export const Alert: FC = ({ )} {description && ( -
+
{description}
)} diff --git a/src/app/pages/ImportAccount/ByMnemonicForm.tsx b/src/app/pages/ImportAccount/ByMnemonicForm.tsx index c640ae4a4..02cd982a1 100644 --- a/src/app/pages/ImportAccount/ByMnemonicForm.tsx +++ b/src/app/pages/ImportAccount/ByMnemonicForm.tsx @@ -7,12 +7,12 @@ import { Alert, FormField, FormSubmitButton } from 'app/atoms'; import { DEFAULT_DERIVATION_PATH, formatMnemonic } from 'app/defaults'; import { ReactComponent as OkIcon } from 'app/icons/ok.svg'; import { isSeedPhraseFilled, SeedPhraseInput } from 'app/templates/SeedPhraseInput'; -import { useFormAnalytics } from 'lib/analytics'; -import { TID, T, t } from 'lib/i18n'; +import { setTestID, useFormAnalytics } from 'lib/analytics'; +import { T, t, TID } from 'lib/i18n'; import { useTempleClient, validateDerivationPath } from 'lib/temple/front'; import { delay } from 'lib/utils'; -import { ImportAccountSelectors, ImportAccountFormType } from './selectors'; +import { ImportAccountFormType, ImportAccountSelectors } from './selectors'; interface DerivationPath { type: string; @@ -148,6 +148,11 @@ export const ByMnemonicForm: FC = () => { padding: '0.4rem 0.375rem 0.4rem 0.375rem' }} onClick={handleClick} + {...setTestID( + dp.type === 'default' + ? ImportAccountSelectors.defaultAccountButton + : ImportAccountSelectors.customDerivationPathButton + )} >
@@ -176,6 +181,7 @@ export const ByMnemonicForm: FC = () => { placeholder={t('derivationPathExample2')} errorCaption={errors.customDerivationPath?.message} containerClassName="mb-6" + testID={ImportAccountSelectors.customDerivationPathInput} /> )} diff --git a/src/app/pages/ImportAccount/selectors.ts b/src/app/pages/ImportAccount/selectors.ts index fdb23324f..0346f44da 100644 --- a/src/app/pages/ImportAccount/selectors.ts +++ b/src/app/pages/ImportAccount/selectors.ts @@ -5,6 +5,9 @@ export enum ImportAccountSelectors { privateKeyImportButton = 'Import Account(Private Key)/Private Key Import Button', mnemonicWordInput = 'Import Account(Mnemonic)/Mnemonic Word Input', + defaultAccountButton = 'Import Account(Mnemonic)/Default Account (the first one) Button', + customDerivationPathButton = 'Import Account(Mnemonic)/Custom Derivation Path Button', + customDerivationPathInput = 'Import Account(Mnemonic)/Custom Derivation Path Input', mnemonicPasswordInput = 'Import Account(Mnemonic)/Mnemonic Password Input', mnemonicImportButton = 'Import Account(Mnemonic)/Mnemonic Import Button', From 2c9dfa419a6697c3f98a49da07f4deda2940e0f2 Mon Sep 17 00:00:00 2001 From: Vlad Novak Date: Mon, 6 Nov 2023 10:17:53 +0200 Subject: [PATCH 2/9] final stage --- .github/workflows/manual-builds.yml | 4 + .github/workflows/secrets-setup/action.yml | 20 ++- e2e/.env.dist | 7 + .../import-account-by-mnemonic.feature | 133 +++++++++++++++++- .../import-account-by-private-key.feature | 1 - .../import-account-by-public-key.feature | 2 - .../features/import-existing-wallet.feature | 6 +- e2e/src/features/remove-account.feature | 4 +- e2e/src/features/switch-account.feature | 2 +- e2e/src/features/unlock-screen.feature | 2 +- .../import-account-mnemonic-tab.page.ts | 29 +++- .../pages/importing-existing-wallet.page.ts | 13 +- e2e/src/step-definitions/common.steps.ts | 4 + .../step-definitions/import-account.steps.ts | 14 -- .../import-existing-wallet.steps.ts | 10 -- .../import-wallet-or-account.steps.ts | 31 ++++ e2e/src/step-definitions/shared.steps.ts | 3 +- e2e/src/utils/env.utils.ts | 4 + e2e/src/utils/input-data.utils.ts | 26 +++- e2e/src/utils/search.utils.ts | 14 +- src/app/pages/ImportAccount/selectors.ts | 3 + .../SeedLengthOption/SeedLengthOption.tsx | 9 +- .../SeedLengthSelect/SeedLengthSelect.tsx | 6 +- src/app/templates/SeedPhraseInput/index.tsx | 8 +- 24 files changed, 296 insertions(+), 59 deletions(-) delete mode 100644 e2e/src/step-definitions/import-account.steps.ts delete mode 100644 e2e/src/step-definitions/import-existing-wallet.steps.ts create mode 100644 e2e/src/step-definitions/import-wallet-or-account.steps.ts diff --git a/.github/workflows/manual-builds.yml b/.github/workflows/manual-builds.yml index 019278cb0..3bef1e514 100644 --- a/.github/workflows/manual-builds.yml +++ b/.github/workflows/manual-builds.yml @@ -74,6 +74,10 @@ jobs: IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: ${{ secrets.IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }} WATCH_ONLY_PUBLIC_KEY_HASH: ${{ secrets.WATCH_ONLY_PUBLIC_KEY_HASH }} WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM: ${{ secrets.WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM }} + LONG_HD_ACCOUNT_SEED_PHRASE: ${{ secrets.LONG_HD_ACCOUNT_SEED_PHRASE }} + LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY: ${{ secrets.LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY }} + LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY: ${{ secrets.LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY }} + LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: ${{ secrets.LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }} CUSTOM_NETWORK_RPC_URL: ${{ secrets.CUSTOM_NETWORK_RPC_URL }} CUSTOM_NETWORK_SECOND_RPC_URL: ${{ secrets.CUSTOM_NETWORK_SECOND_RPC_URL }} diff --git a/.github/workflows/secrets-setup/action.yml b/.github/workflows/secrets-setup/action.yml index 62c135c3d..2724afee1 100644 --- a/.github/workflows/secrets-setup/action.yml +++ b/.github/workflows/secrets-setup/action.yml @@ -25,6 +25,10 @@ inputs: required: true TEMPLE_FIREBASE_MESSAGING_VAPID_KEY: required: true + TEMPLE_WALLET_ROUTE3_AUTH_TOKEN: + required: true + TEMPLE_WALLET_MOONPAY_API_KEY: + required: true # [e2e] DEFAULT_HD_ACCOUNT_SEED_PHRASE: required: false @@ -50,14 +54,18 @@ inputs: required: false IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: required: false - TEMPLE_WALLET_ROUTE3_AUTH_TOKEN: - required: true - TEMPLE_WALLET_MOONPAY_API_KEY: - required: true WATCH_ONLY_PUBLIC_KEY_HASH: required: false WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM: required: false + LONG_HD_ACCOUNT_SEED_PHRASE: + required: false + LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY: + required: false + LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY: + required: false + LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: + required: false CUSTOM_NETWORK_RPC_URL: required: false CUSTOM_NETWORK_SECOND_RPC_URL: @@ -107,6 +115,10 @@ runs: IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM=${{ inputs.IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }} WATCH_ONLY_PUBLIC_KEY_HASH=${{ inputs.WATCH_ONLY_PUBLIC_KEY_HASH }} WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM=${{ inputs.WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM }} + LONG_HD_ACCOUNT_SEED_PHRASE=${{ inputs.LONG_HD_ACCOUNT_SEED_PHRASE }} + LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY=${{ inputs.LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY }} + LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY=${{ inputs.LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY }} + LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM=${{ inputs.LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }} CUSTOM_NETWORK_RPC_URL=${{ inputs.CUSTOM_NETWORK_RPC_URL }} CUSTOM_NETWORK_SECOND_RPC_URL=${{ inputs.CUSTOM_NETWORK_SECOND_RPC_URL }} EOF diff --git a/e2e/.env.dist b/e2e/.env.dist index ab121bb84..8ec407545 100644 --- a/e2e/.env.dist +++ b/e2e/.env.dist @@ -18,6 +18,13 @@ IMPORTED_HD_ACCOUNT_FIRST_PUBLIC_KEY_HASH= IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM= +LONG_HD_ACCOUNT_SEED_PHRASE= + +LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY= +LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY= +LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM= + + WATCH_ONLY_PUBLIC_KEY_HASH= WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM= diff --git a/e2e/src/features/import-account-by-mnemonic.feature b/e2e/src/features/import-account-by-mnemonic.feature index 08f5edd24..1caf77d36 100644 --- a/e2e/src/features/import-account-by-mnemonic.feature +++ b/e2e/src/features/import-account-by-mnemonic.feature @@ -13,12 +13,11 @@ Feature: Import Account by Mnemonic And I select Mnemonic tab And I am on the ImportAccountMnemonic page - And I enter second mnemonic + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page And I press Mnemonic Import Button on the Import Account(Mnemonic) page Then I reveal a private key and compare with importedFirstPrivateKey - Scenario: As a user, I'd like to import account by mnemonic with derivation path + password field Given I have imported an existing account @@ -31,7 +30,7 @@ Feature: Import Account by Mnemonic And I select Mnemonic tab And I am on the ImportAccountMnemonic page - And I enter second mnemonic + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page And I press Mnemonic Import Button on the Import Account(Mnemonic) page And I am on the Home page @@ -47,8 +46,9 @@ Feature: Import Account by Mnemonic And I select Mnemonic tab And I am on the ImportAccountMnemonic page - And I enter second mnemonic + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page + And I scroll 200 pixels on the ImportAccountMnemonic page And I press Custom Derivation Path Button on the Import Account(Mnemonic) page And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page And I enter customDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page @@ -68,7 +68,7 @@ Feature: Import Account by Mnemonic And I select Mnemonic tab And I am on the ImportAccountMnemonic page - And I enter second mnemonic + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page And I scroll 900 pixels on the ImportAccountMnemonic page And I enter amount_1 into Mnemonic Password Input on the Import Account(Mnemonic) page And I press Mnemonic Import Button on the Import Account(Mnemonic) page @@ -77,3 +77,126 @@ Feature: Import Account by Mnemonic Then I check if importedAccountByPasswordShortHash is corresponded to the selected account +@dev + Scenario: Import account by mnemonic validation + negative cases + Given I have imported an existing account + + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Mnemonic tab + And I am on the ImportAccountMnemonic page +# validation checks 12 words seed + And I scroll 900 pixels on the ImportAccountMnemonic page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + And I got the validation-error 'Seed phrase must contain 12 words' with Mnemonic Validation Error Text element on the Import (Account/Wallet) page + And I scroll -300 pixels on the ImportAccountMnemonic page + And The Mnemonic Drop Down Button on the Import (Account/Wallet) page has correct My Seed phrase is 12 words value +# validation checks 24 words seed + And I press Mnemonic Drop Down Button on the Import (Account/Wallet) page + And I select mnemonic with 24 words + And I scroll 900 pixels on the ImportAccountMnemonic page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + And I got the validation-error 'Seed phrase must contain 24 words' with Mnemonic Validation Error Text element on the Import (Account/Wallet) page + + And I reload the page + And I am on the ImportAccountMnemonic page + +# validation checks word inputs with 'invalidRandomSeedPhrase' + And I enter invalidRandomSeedPhrase mnemonic on the ImportAccountMnemonic page + And I scroll 300 pixels on the ImportAccountMnemonic page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + And I got the validation-error 'Invalid Seed Phrase' with Mnemonic Validation Error Text element on the Import (Account/Wallet) page + + And I scroll -300 pixels on the ImportAccountMnemonic page + And I clear entered mnemonic on the ImportAccountMnemonic page + +# validation checks word inputs with 'incorrectSeedPhrase' + And I enter incorrectSeedPhrase mnemonic on the ImportAccountMnemonic page + And I scroll 300 pixels on the ImportAccountMnemonic page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + And I got the validation-error 'Invalid Seed PhraseMake sure the words spelled correctly' with Mnemonic Validation Error Text element on the Import (Account/Wallet) page + + And I scroll -300 pixels on the ImportAccountMnemonic page + And I clear entered mnemonic on the ImportAccountMnemonic page + +# validation checks word inputs with 'invalidSeedPhrase' + And I enter invalidSeedPhrase mnemonic on the ImportAccountMnemonic page + And I scroll 300 pixels on the ImportAccountMnemonic page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + And I got the validation-error 'Invalid Seed Phrase' with Mnemonic Validation Error Text element on the Import (Account/Wallet) page + + And I scroll -300 pixels on the ImportAccountMnemonic page + And I clear entered mnemonic on the ImportAccountMnemonic page + +# validation checks custom derivation path input + And I scroll 200 pixels on the ImportAccountMnemonic page + And I press Custom Derivation Path Button on the Import Account(Mnemonic) page + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + +# importing 24 words seed + And I scroll -300 pixels on the ImportAccountMnemonic page + And I press Mnemonic Drop Down Button on the Import (Account/Wallet) page + And I select mnemonic with 24 words + And I enter longSeedPhrase24 mnemonic on the ImportAccountMnemonic page + And I scroll 900 pixels on the ImportAccountMnemonic page + + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I am on the Home page + And I check if longFirstAccountShortHash is corresponded to the selected account + +# checking derivation type validation + And I press Account Icon on the Header page + And I am on the AccountsDropdown page + + And I press Import Account Button on the Account Drop-down page + And I am on the ImportAccountTab page + + And I select Mnemonic tab + And I am on the ImportAccountMnemonic page + + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page + And I press Custom Derivation Path Button on the Import Account(Mnemonic) page + And I scroll 900 pixels on the ImportAccountMnemonic page + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter shortRandomContent into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I got the validation-error 'Must start with 'm'' with Input Error element on the Universal Component page + + # invalid path validation + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter invalidDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I got the validation-error 'Invalid path' with Input Error element on the Universal Component page + + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter secondInvalidDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I got the validation-error 'Invalid path' with Input Error element on the Universal Component page + + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter thirdInvalidDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I got the validation-error 'Invalid path' with Input Error element on the Universal Component page + + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter fourthInvalidDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I got the validation-error 'Invalid path' with Input Error element on the Universal Component page + +# valid importing to finish the scenario + And I clear Custom Derivation Path Input value on the Import Account(Mnemonic) page + And I enter basicDerivationPath into Custom Derivation Path Input on the Import Account(Mnemonic) page + And I press Mnemonic Import Button on the Import Account(Mnemonic) page + + And I am on the Home page + Then I check if importedAccountShortHash is corresponded to the selected account diff --git a/e2e/src/features/import-account-by-private-key.feature b/e2e/src/features/import-account-by-private-key.feature index 135c8b308..3994fa1b6 100644 --- a/e2e/src/features/import-account-by-private-key.feature +++ b/e2e/src/features/import-account-by-private-key.feature @@ -20,7 +20,6 @@ Feature: Import Account by Private Key - Scenario: Check validation importing by private key Given I have imported an existing account diff --git a/e2e/src/features/import-account-by-public-key.feature b/e2e/src/features/import-account-by-public-key.feature index 98cd4de5a..1157c1922 100644 --- a/e2e/src/features/import-account-by-public-key.feature +++ b/e2e/src/features/import-account-by-public-key.feature @@ -18,8 +18,6 @@ Feature: Import an account by public key (Watch-only) Then I check if watchOnlyAccountShortHash is corresponded to the selected account - - @dev Scenario: Check validation importing by public key Given I have imported an existing account diff --git a/e2e/src/features/import-existing-wallet.feature b/e2e/src/features/import-existing-wallet.feature index 7889dff6c..4091f0f5a 100644 --- a/e2e/src/features/import-existing-wallet.feature +++ b/e2e/src/features/import-existing-wallet.feature @@ -6,7 +6,7 @@ Feature: Import existing wallet And I press Import Existing Wallet button on the Welcome page And I am on the ImportExistingWallet page - And I enter default mnemonic + And I enter defaultSeedPhrase mnemonic on the ImportExistingWallet page And I press Next button on the Import Existing Seed Phrase page And I am on the SetWallet page @@ -29,7 +29,7 @@ Feature: Import existing wallet And I press Import Existing Wallet button on the Welcome page And I am on the ImportExistingWallet page - And I enter default mnemonic + And I enter defaultSeedPhrase mnemonic on the ImportExistingWallet page And I press Next button on the Import Existing Seed Phrase page And I am on the SetWallet page @@ -66,7 +66,7 @@ Feature: Import existing wallet And I press Import Existing Wallet button on the Welcome page And I am on the ImportExistingWallet page - And I enter default mnemonic + And I enter defaultSeedPhrase mnemonic on the ImportExistingWallet page And I press Next button on the Import Existing Seed Phrase page And I am on the SetWallet page diff --git a/e2e/src/features/remove-account.feature b/e2e/src/features/remove-account.feature index 6ac8d627e..3c24f7cfd 100644 --- a/e2e/src/features/remove-account.feature +++ b/e2e/src/features/remove-account.feature @@ -13,7 +13,7 @@ Feature: Remove an account And I select Mnemonic tab And I am on the ImportAccountMnemonic page - And I enter second mnemonic + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page And I press Mnemonic Import Button on the Import Account(Mnemonic) page And I am on the Home page @@ -122,7 +122,7 @@ Feature: Remove an account And I select Mnemonic tab And I am on the ImportAccountMnemonic page - And I enter second mnemonic + And I enter importedSeedPhrase mnemonic on the ImportAccountMnemonic page And I press Mnemonic Import Button on the Import Account(Mnemonic) page And I am on the Home page diff --git a/e2e/src/features/switch-account.feature b/e2e/src/features/switch-account.feature index 4ee705f41..88d636e69 100644 --- a/e2e/src/features/switch-account.feature +++ b/e2e/src/features/switch-account.feature @@ -1,5 +1,5 @@ Feature: Switch account -@dev + Scenario: As a user, I'd like to switch between my accounts Given I have imported an existing account # creating or restoring second hd account diff --git a/e2e/src/features/unlock-screen.feature b/e2e/src/features/unlock-screen.feature index c05164b9c..ad4d773ff 100644 --- a/e2e/src/features/unlock-screen.feature +++ b/e2e/src/features/unlock-screen.feature @@ -124,7 +124,7 @@ Feature: Unlock Screen # restore a wallet another (second) mnemonic And I am on the ImportExistingWallet page And I got the 'Attention!' warning with Alert title Text element on the Alert page - And I enter default mnemonic + And I enter defaultSeedPhrase mnemonic on the ImportExistingWallet page And I press Next button on the Import Existing Seed Phrase page And I am on the SetWallet page diff --git a/e2e/src/page-objects/pages/import-account-tabs/import-account-mnemonic-tab.page.ts b/e2e/src/page-objects/pages/import-account-tabs/import-account-mnemonic-tab.page.ts index 6e17f49e2..e760e58c7 100644 --- a/e2e/src/page-objects/pages/import-account-tabs/import-account-mnemonic-tab.page.ts +++ b/e2e/src/page-objects/pages/import-account-tabs/import-account-mnemonic-tab.page.ts @@ -1,7 +1,8 @@ import { ImportAccountSelectors } from 'src/app/pages/ImportAccount/selectors'; import { Page } from 'e2e/src/classes/page.class'; -import { createPageElement, findElements } from 'e2e/src/utils/search.utils'; +import { clearDataFromInput, createPageElement, findElement, findElements } from 'e2e/src/utils/search.utils'; +import { SHORT_TIMEOUT } from 'e2e/src/utils/timing.utils'; export class ImportAccountMnemonicTab extends Page { mnemonicWordInput = createPageElement(ImportAccountSelectors.mnemonicWordInput); @@ -22,7 +23,31 @@ export class ImportAccountMnemonicTab extends Page { const word = wordsArray[i]; const input = wordsInputs[i]; - await input.type(word); + await input.type(word.replace('?', '')); } } + + async clearSeedPhrase() { + const wordsInputs = await findElements(ImportAccountSelectors.mnemonicWordInput); + + for (let i = 0; i < wordsInputs.length; i++) { + const input = wordsInputs[i]; + + await input.focus(); + await clearDataFromInput(); + } + } + + async selectMnemonicWordsCount(words: string) { + const mnemonicWordsCount = await findElement( + ImportAccountSelectors.mnemonicWordsRadioButton, + { words }, + SHORT_TIMEOUT, + `Variant of Seed Phrase with ${words} words is not found: + 1) Selected variant is not displayed (bug/issue) + 2) Seed phrase can contain only 12, 15, 18, 21, 24 words` + ); + + await mnemonicWordsCount.click(); + } } diff --git a/e2e/src/page-objects/pages/importing-existing-wallet.page.ts b/e2e/src/page-objects/pages/importing-existing-wallet.page.ts index af2003e0e..b46509f5e 100644 --- a/e2e/src/page-objects/pages/importing-existing-wallet.page.ts +++ b/e2e/src/page-objects/pages/importing-existing-wallet.page.ts @@ -1,7 +1,7 @@ import { ImportFromSeedPhraseSelectors } from 'src/app/pages/NewWallet/import/ImportSeedPhrase/ImportFromSeedPhrase.selectors'; import { Page } from '../../classes/page.class'; -import { createPageElement, findElements } from '../../utils/search.utils'; +import { clearDataFromInput, createPageElement, findElements } from '../../utils/search.utils'; export class ImportExistingWalletPage extends Page { nextButton = createPageElement(ImportFromSeedPhraseSelectors.nextButton); @@ -23,4 +23,15 @@ export class ImportExistingWalletPage extends Page { await input.type(word); } } + + async clearSeedPhrase() { + const wordsInputs = await findElements(ImportFromSeedPhraseSelectors.wordInput); + + for (let i = 0; i < wordsInputs.length; i++) { + const input = wordsInputs[i]; + + await input.focus(); + await clearDataFromInput(); + } + } } diff --git a/e2e/src/step-definitions/common.steps.ts b/e2e/src/step-definitions/common.steps.ts index 8c1a71346..12bb17410 100644 --- a/e2e/src/step-definitions/common.steps.ts +++ b/e2e/src/step-definitions/common.steps.ts @@ -62,3 +62,7 @@ Given( await Pages[page].scrollTo(countOfScroll); } ); + +Given(/I reload the page/, async () => { + await BrowserContext.page.reload(); +}); diff --git a/e2e/src/step-definitions/import-account.steps.ts b/e2e/src/step-definitions/import-account.steps.ts deleted file mode 100644 index eee4f43c6..000000000 --- a/e2e/src/step-definitions/import-account.steps.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Given } from '@cucumber/cucumber'; - -import { MEDIUM_TIMEOUT } from 'e2e/src/utils/timing.utils'; - -import { Pages } from '../page-objects'; -import { envVars } from '../utils/env.utils'; - -Given(/I enter second mnemonic/, { timeout: MEDIUM_TIMEOUT }, async () => { - await Pages.ImportAccountMnemonic.enterSeedPhrase(envVars.IMPORTED_HD_ACCOUNT_SEED_PHRASE); -}); - -Given(/I select (.*) tab/, async (tabName: string) => { - await Pages.ImportAccountTab.selectTab(tabName); -}); diff --git a/e2e/src/step-definitions/import-existing-wallet.steps.ts b/e2e/src/step-definitions/import-existing-wallet.steps.ts deleted file mode 100644 index 2d953829e..000000000 --- a/e2e/src/step-definitions/import-existing-wallet.steps.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Given } from '@cucumber/cucumber'; - -import { MEDIUM_TIMEOUT } from 'e2e/src/utils/timing.utils'; - -import { BrowserContext } from '../classes/browser-context.class'; -import { Pages } from '../page-objects'; - -Given(/I enter default mnemonic/, { timeout: MEDIUM_TIMEOUT }, async () => { - await Pages.ImportExistingWallet.enterSeedPhrase(BrowserContext.seedPhrase); -}); diff --git a/e2e/src/step-definitions/import-wallet-or-account.steps.ts b/e2e/src/step-definitions/import-wallet-or-account.steps.ts new file mode 100644 index 000000000..79b180963 --- /dev/null +++ b/e2e/src/step-definitions/import-wallet-or-account.steps.ts @@ -0,0 +1,31 @@ +import { Given } from '@cucumber/cucumber'; + +import { iEnterValues } from 'e2e/src/utils/input-data.utils'; +import { MEDIUM_TIMEOUT } from 'e2e/src/utils/timing.utils'; + +import { Pages } from '../page-objects'; + +type mnemonicPage = 'ImportAccountMnemonic' | 'ImportExistingWallet'; + +Given( + /I enter (.*) mnemonic on the (\w+) page/, + { timeout: MEDIUM_TIMEOUT }, + async (mnemonic: keyof typeof iEnterValues, page: mnemonicPage) => { + const wrongMnemonic = iEnterValues[mnemonic]; + if (wrongMnemonic === undefined) throw new Error(`${mnemonic} key doesn't exist in the 'iEnterValues' object`); + + await Pages[page].enterSeedPhrase(wrongMnemonic); + } +); + +Given(/I clear entered mnemonic on the (\w+) page/, { timeout: MEDIUM_TIMEOUT }, async (page: mnemonicPage) => { + await Pages[page].clearSeedPhrase(); +}); + +Given(/I select (.*) tab/, async (tabName: string) => { + await Pages.ImportAccountTab.selectTab(tabName); +}); + +Given(/I select mnemonic with (.*) words/, { timeout: MEDIUM_TIMEOUT }, async (wordsCount: string) => { + await Pages.ImportAccountMnemonic.selectMnemonicWordsCount(wordsCount); +}); diff --git a/e2e/src/step-definitions/shared.steps.ts b/e2e/src/step-definitions/shared.steps.ts index eeeaf5be4..b94016593 100644 --- a/e2e/src/step-definitions/shared.steps.ts +++ b/e2e/src/step-definitions/shared.steps.ts @@ -44,7 +44,8 @@ const hashObjectShortForm = { importedAccountShortHash: envVars.IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM, importedAccountDerPathShortHash: 'tz1RPXf...RE8q', importedAccountByPasswordShortHash: 'tz1ZfC8...PcHE', // By additional (optional) 'Password' input - watchOnlyAccountShortHash: envVars.WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM + watchOnlyAccountShortHash: envVars.WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM, + longFirstAccountShortHash: envVars.LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM }; Given( diff --git a/e2e/src/utils/env.utils.ts b/e2e/src/utils/env.utils.ts index 4d6fb07cb..ddf8c0392 100644 --- a/e2e/src/utils/env.utils.ts +++ b/e2e/src/utils/env.utils.ts @@ -17,6 +17,10 @@ export const envVars = { IMPORTED_HD_ACCOUNT_FIRST_PRIVATE_KEY: getEnv('IMPORTED_HD_ACCOUNT_FIRST_PRIVATE_KEY'), IMPORTED_HD_ACCOUNT_FIRST_PUBLIC_KEY_HASH: getEnv('IMPORTED_HD_ACCOUNT_FIRST_PUBLIC_KEY_HASH'), IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: getEnv('IMPORTED_HD_ACCOUNT_FIRST_HASH_SHORT_FORM'), + LONG_HD_ACCOUNT_SEED_PHRASE: getEnv('LONG_HD_ACCOUNT_SEED_PHRASE'), + LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY: getEnv('LONG_HD_ACCOUNT_FIRST_PRIVATE_KEY'), + LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY: getEnv('LONG_HD_ACCOUNT_FIRST_PUBLIC_KEY'), + LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM: getEnv('LONG_HD_ACCOUNT_FIRST_HASH_SHORT_FORM'), WATCH_ONLY_PUBLIC_KEY_HASH: getEnv('WATCH_ONLY_PUBLIC_KEY_HASH'), WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM: getEnv('WATCH_ONLY_PUBLIC_KEY_HASH_SHORT_FORM'), CUSTOM_NETWORK_RPC_URL: getEnv('CUSTOM_NETWORK_RPC_URL'), diff --git a/e2e/src/utils/input-data.utils.ts b/e2e/src/utils/input-data.utils.ts index 2fc508927..1aced81d2 100644 --- a/e2e/src/utils/input-data.utils.ts +++ b/e2e/src/utils/input-data.utils.ts @@ -6,21 +6,41 @@ export const iComparePrivateKeys = { }; const generateRandomContent = () => { - const wordsArray = ['apple', 'banana', 'carrot', 'dog', 'elephant', 'fish', 'grape', 'hat', 'ice cream', 'jungle']; + const wordsArray = ['apple', 'banana', 'carrot', 'dog', 'elephant', 'fish', 'grape', 'hat', 'cream', 'jungle']; const randomWord = Math.floor(Math.random() * wordsArray.length); return wordsArray[randomWord] + Math.floor(Math.random() * 10000).toString(); }; +const randomSeedWord = () => { + const wordsArray = ['about', 'document', 'lesson', 'scatter', 'above', 'dog', 'letter', 'abuse', 'science']; + return wordsArray[Math.floor(Math.random() * wordsArray.length)]; +}; + export const iEnterValues = { ...iComparePrivateKeys, - defaultSeedPhrase: envVars.DEFAULT_HD_ACCOUNT_SEED_PHRASE, defaultFirstPrivateKey: envVars.DEFAULT_HD_ACCOUNT_FIRST_PRIVATE_KEY, - defaultFirstPublicKey: 'tz1g1NfadfC2qktJH99sHeBETRWGaQyrbiA4', + defaultFirstPublicKey: envVars.DEFAULT_HD_ACCOUNT_FIRST_PUBLIC_KEY_HASH, defaultPassword: envVars.DEFAULT_PASSWORD, + watchOnlyPublicKey: envVars.WATCH_ONLY_PUBLIC_KEY_HASH, bakerAddress: '', + + // Derivation paths + basicDerivationPath: `m/44'/1729'/0'/0'`, // first account in HD (main) customDerivationPath: `m/44'/1729'/10'/0'`, // eleventh account in HD + invalidDerivationPath: `m/broken44'/1729'/0'/0'`, + secondInvalidDerivationPath: `m/44'/17broken29'/0'/0'`, + thirdInvalidDerivationPath: `m/44'/1729'/0broken'/0'`, + fourthInvalidDerivationPath: `m/44'/1729'/0'/0broken'`, + + // For testing mnemonic inputs + defaultSeedPhrase: envVars.DEFAULT_HD_ACCOUNT_SEED_PHRASE, + importedSeedPhrase: envVars.IMPORTED_HD_ACCOUNT_SEED_PHRASE, + longSeedPhrase24: envVars.LONG_HD_ACCOUNT_SEED_PHRASE, + invalidSeedPhrase: 'scissors dolphin light ability voice voice sail cruel labor dry screen feature', // words from BIP39 + invalidRandomSeedPhrase: `${randomSeedWord()} document ? ${randomSeedWord()} ${randomSeedWord()} ${randomSeedWord()} dog ? ${randomSeedWord()} ${randomSeedWord()} ? ${randomSeedWord()}`, + incorrectSeedPhrase: 'alsla sadh 123213 sadaj asdj sajd jewd wedn wedn wedbn wedhb criwl', // For input validation shortRandomContent: generateRandomContent(), diff --git a/e2e/src/utils/search.utils.ts b/e2e/src/utils/search.utils.ts index 9038d580c..6d297a20a 100644 --- a/e2e/src/utils/search.utils.ts +++ b/e2e/src/utils/search.utils.ts @@ -89,11 +89,7 @@ class PageElement { } async clearInput() { - await BrowserContext.page.keyboard.press('End'); - await BrowserContext.page.keyboard.down('Shift'); - await BrowserContext.page.keyboard.press('Home'); - await BrowserContext.page.keyboard.up('Shift'); - await BrowserContext.page.keyboard.press('Backspace'); + await clearDataFromInput(); } async getText() { const element = await this.findElement(); @@ -156,3 +152,11 @@ const buildNotSelector = (notSelectors: OtherSelectors) => { const pairs = buildSelectorPairs(notSelectors); return `:not([${pairs.join(']):not([')}])`; }; + +export const clearDataFromInput = async () => { + await BrowserContext.page.keyboard.press('End'); + await BrowserContext.page.keyboard.down('Shift'); + await BrowserContext.page.keyboard.press('Home'); + await BrowserContext.page.keyboard.up('Shift'); + await BrowserContext.page.keyboard.press('Backspace'); +}; diff --git a/src/app/pages/ImportAccount/selectors.ts b/src/app/pages/ImportAccount/selectors.ts index 0346f44da..1e3046118 100644 --- a/src/app/pages/ImportAccount/selectors.ts +++ b/src/app/pages/ImportAccount/selectors.ts @@ -5,11 +5,14 @@ export enum ImportAccountSelectors { privateKeyImportButton = 'Import Account(Private Key)/Private Key Import Button', mnemonicWordInput = 'Import Account(Mnemonic)/Mnemonic Word Input', + mnemonicDropDownButton = 'Import (Account/Wallet)/Mnemonic Drop Down Button', + mnemonicWordsRadioButton = 'Import (Account/Wallet)/Mnemonic Words Radio Button', defaultAccountButton = 'Import Account(Mnemonic)/Default Account (the first one) Button', customDerivationPathButton = 'Import Account(Mnemonic)/Custom Derivation Path Button', customDerivationPathInput = 'Import Account(Mnemonic)/Custom Derivation Path Input', mnemonicPasswordInput = 'Import Account(Mnemonic)/Mnemonic Password Input', mnemonicImportButton = 'Import Account(Mnemonic)/Mnemonic Import Button', + mnemonicValidationErrorText = 'Import (Account/Wallet)/Mnemonic Validation Error Text', watchOnlyInput = 'Import Account(Watch-Only)/Watch Only Input', watchOnlyImportButton = 'Import Account(Watch-Only)/Watch Only Import Button', diff --git a/src/app/templates/SeedPhraseInput/SeedLengthSelect/SeedLengthOption/SeedLengthOption.tsx b/src/app/templates/SeedPhraseInput/SeedLengthSelect/SeedLengthOption/SeedLengthOption.tsx index 6647cf988..13d03d71e 100644 --- a/src/app/templates/SeedPhraseInput/SeedLengthSelect/SeedLengthOption/SeedLengthOption.tsx +++ b/src/app/templates/SeedPhraseInput/SeedLengthSelect/SeedLengthOption/SeedLengthOption.tsx @@ -3,6 +3,8 @@ import React, { FC, memo, useCallback } from 'react'; import { emptyFn } from '@rnw-community/shared'; import classNames from 'clsx'; +import { setAnotherSelector, setTestID } from '../../../../../lib/analytics'; +import { ImportAccountSelectors } from '../../../../pages/ImportAccount/selectors'; import styles from './seedLengthOption.module.css'; interface Props { @@ -28,7 +30,12 @@ export const SeedLengthOption: FC = memo(({ option, selectedOption, onCli 'text-lg' )} > -