From 4f5ec38d33e05264327aa800a2ce884dbbf90f59 Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Mon, 20 Nov 2023 09:19:42 +0100 Subject: [PATCH 1/9] chore: first pass --- e2e/src/Send.spec.js | 8 +-- e2e/src/usecases/SecureSend.js | 128 +++++++++++++++++---------------- e2e/src/usecases/Send.js | 4 ++ e2e/src/utils/utils.js | 11 +-- 4 files changed, 77 insertions(+), 74 deletions(-) diff --git a/e2e/src/Send.spec.js b/e2e/src/Send.spec.js index 2ae52359b24..ebf8975403d 100644 --- a/e2e/src/Send.spec.js +++ b/e2e/src/Send.spec.js @@ -1,13 +1,7 @@ import SecureSend from './usecases/SecureSend' import Send from './usecases/Send' -import { quickOnboarding } from './utils/utils' describe('Given', () => { - beforeAll(async () => { - await quickOnboarding() - }) - describe('Send', Send) - // TODO: unskip this test if we enable CPV in CI - describe.skip('SecureSend cUSD', SecureSend) + describe('SecureSend with CPV', SecureSend) }) diff --git a/e2e/src/usecases/SecureSend.js b/e2e/src/usecases/SecureSend.js index c250bc08e3e..6721ae34155 100644 --- a/e2e/src/usecases/SecureSend.js +++ b/e2e/src/usecases/SecureSend.js @@ -1,86 +1,88 @@ -import { reloadReactNative } from '../utils/retries' +import { SAMPLE_BACKUP_KEY_VERIFIED } from '../utils/consts' +import { launchApp } from '../utils/retries' import { addComment, enterPinUiIfNecessary, inputNumberKeypad, scrollIntoView, sleep, + quickOnboarding, } from '../utils/utils' const faker = require('@faker-js/faker') -const PHONE_NUMBER = '+12057368924' -const LAST_ACCOUNT_CHARACTERS = 'FD08' +// const PHONE_NUMBER = '+15203140983' +const PHONE_NUMBER = '+31619789443' +const LAST_ACCOUNT_CHARACTERS = 'f192' const AMOUNT_TO_SEND = '0.1' export default SecureSend = () => { - beforeEach(async () => { - await reloadReactNative() - }) + describe.each([{ web3Library: 'contract-kit' }, { web3Library: 'viem' }])( + 'Secure send flow with phone number lookup (with $web3Library)', + ({ web3Library }) => { + beforeAll(async () => { + // uninstall the app to remove secure send mapping + await device.uninstallApp() + await device.installApp() + await launchApp({ + newInstance: true, + permissions: { notifications: 'YES', contacts: 'YES' }, + launchArgs: { + statsigGateOverrides: `use_new_send_flow=false,use_viem_for_send=${ + web3Library === 'viem' + }`, + }, + }) + await quickOnboarding(SAMPLE_BACKUP_KEY_VERIFIED) + }) - it('Send cUSD to phone number with multiple mappings', async () => { - let randomContent = faker.lorem.words() - await waitFor(element(by.id('HomeAction-Send'))) - .toBeVisible() - .withTimeout(30000) - await element(by.id('HomeAction-Send')).tap() + it('Send cUSD to phone number with multiple mappings', async () => { + let randomContent = faker.lorem.words() + await waitFor(element(by.id('HomeAction-Send'))) + .toBeVisible() + .withTimeout(30000) + await element(by.id('HomeAction-Send')).tap() + await waitFor(element(by.id('SendSearchInput'))).toBeVisible() - // Look for an address and tap on it. - await element(by.id('SearchInput')).tap() - await element(by.id('SearchInput')).replaceText(PHONE_NUMBER) - await element(by.id('RecipientItem')).tap() + await element(by.id('SearchInput')).tap() + await element(by.id('SearchInput')).replaceText(PHONE_NUMBER) + await element(by.id('RecipientItem')).tap() - // Select the currency - await waitFor(element(by.id('cUSDBalance'))) - .toBeVisible() - .withTimeout(30 * 1000) - await element(by.id('cUSDBalance')).tap() + // Select the currency + await waitFor(element(by.id('cUSDTouchable'))).toBeVisible() + await element(by.id('cUSDTouchable')).tap() - // Enter the amount and review - await inputNumberKeypad(AMOUNT_TO_SEND) - await element(by.id('Review')).tap() + // Enter the amount and review + await inputNumberKeypad(AMOUNT_TO_SEND) + await element(by.id('Review')).tap() - // hack: we shouldn't need this but the test fails without - await sleep(3000) + // Use the last digits of the account to confirm the sender. + await waitFor(element(by.id('confirmAccountButton'))).toBeVisible() + await element(by.id('confirmAccountButton')).tap() + for (let index = 0; index < 4; index++) { + const character = LAST_ACCOUNT_CHARACTERS[index] + await element(by.id(`SingleDigitInput/digit${index}`)).replaceText(character) + } - // Click Edit if confirm account isn't served - try { - await element(by.id('accountEditButton')).tap() - } catch {} + // Scroll to see submit button + await scrollIntoView('Submit', 'KeyboardAwareScrollView', 50) + await element(by.id('ConfirmAccountButton')).tap() - // Use the last digits of the account to confirm the sender. - await waitFor(element(by.id('confirmAccountButton'))) - .toBeVisible() - .withTimeout(30000) - await element(by.id('confirmAccountButton')).tap() - for (let index = 0; index < 4; index++) { - const character = LAST_ACCOUNT_CHARACTERS[index] - await element(by.id(`SingleDigitInput/digit${index}`)).replaceText(character) - } - - // Scroll to see submit button - await scrollIntoView('Submit', 'KeyboardAwareScrollView', 50) - await element(by.id('ConfirmAccountButton')).tap() - - // Write a comment. - await addComment(randomContent) + // Write a comment. + await addComment(randomContent) - // Wait for the confirm button to be clickable. If it takes too long this test - // will be flaky :( - await sleep(3000) + // Confirm and input PIN if necessary. + await element(by.id('ConfirmButton')).tap() + await enterPinUiIfNecessary() - // Confirm and input PIN if necessary. - await element(by.id('ConfirmButton')).tap() - await enterPinUiIfNecessary() + // Return to home screen. + await waitFor(element(by.id('HomeAction-Send'))) + .toBeVisible() + .withTimeout(30 * 1000) - // Return to home screen. - await waitFor(element(by.id('HomeAction-Send'))) - .toBeVisible() - .withTimeout(30 * 1000) - - // TODO: See why these are taking so long in e2e tests to appear - // Look for the latest transaction and assert - // await waitFor(element(by.text(`${randomContent}`))) - // .toBeVisible() - // .withTimeout(60000) - }) + await waitFor(element(by.text(`${randomContent}`))) + .toBeVisible() + .withTimeout(60000) + }) + } + ) } diff --git a/e2e/src/usecases/Send.js b/e2e/src/usecases/Send.js index f2731884762..2dd2c14d90d 100644 --- a/e2e/src/usecases/Send.js +++ b/e2e/src/usecases/Send.js @@ -5,6 +5,10 @@ const faker = require('@faker-js/faker') import jestExpect from 'expect' export default Send = () => { + beforeAll(async () => { + await quickOnboarding() + }) + let randomComment = faker.lorem.words() describe.each([{ web3Library: 'contract-kit' }, { web3Library: 'viem' }])( 'When multi-token send flow (with $web3Library)', diff --git a/e2e/src/utils/utils.js b/e2e/src/utils/utils.js index fefa17f0510..f77eb3160fb 100644 --- a/e2e/src/utils/utils.js +++ b/e2e/src/utils/utils.js @@ -201,10 +201,13 @@ export async function quickOnboarding(mnemonic = SAMPLE_BACKUP_KEY) { await element(by.id('ConfirmUseAccountDialog/PrimaryAction')).tap() } catch {} - // Verify Education - await waitForElementId('PhoneVerificationSkipHeader') - // Skip - await element(by.id('PhoneVerificationSkipHeader')).tap() + // this onboarding step is bypassed for already verified wallets + try { + // Verify Education + await waitForElementId('PhoneVerificationSkipHeader') + // Skip + await element(by.id('PhoneVerificationSkipHeader')).tap() + } catch {} // Assert on Wallet Home Screen await dismissCashInBottomSheet() From 422e4ef5def3507d3230022818895f2a8ce3e59b Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Mon, 20 Nov 2023 10:36:38 +0100 Subject: [PATCH 2/9] chore: update consts --- e2e/src/usecases/SecureSend.js | 26 +++++++++++++++----------- e2e/src/utils/consts.js | 4 ++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/e2e/src/usecases/SecureSend.js b/e2e/src/usecases/SecureSend.js index 6721ae34155..e788e54b409 100644 --- a/e2e/src/usecases/SecureSend.js +++ b/e2e/src/usecases/SecureSend.js @@ -1,19 +1,19 @@ -import { SAMPLE_BACKUP_KEY_VERIFIED } from '../utils/consts' +import { + SAMPLE_BACKUP_KEY_VERIFIED, + VERIFIED_PHONE_NUMBER, + SAMPLE_WALLET_ADDRESS_VERIFIED_2, +} from '../utils/consts' import { launchApp } from '../utils/retries' import { addComment, enterPinUiIfNecessary, inputNumberKeypad, scrollIntoView, - sleep, quickOnboarding, } from '../utils/utils' const faker = require('@faker-js/faker') -// const PHONE_NUMBER = '+15203140983' -const PHONE_NUMBER = '+31619789443' -const LAST_ACCOUNT_CHARACTERS = 'f192' -const AMOUNT_TO_SEND = '0.1' +const AMOUNT_TO_SEND = '0.01' export default SecureSend = () => { describe.each([{ web3Library: 'contract-kit' }, { web3Library: 'viem' }])( @@ -44,7 +44,7 @@ export default SecureSend = () => { await waitFor(element(by.id('SendSearchInput'))).toBeVisible() await element(by.id('SearchInput')).tap() - await element(by.id('SearchInput')).replaceText(PHONE_NUMBER) + await element(by.id('SearchInput')).replaceText(VERIFIED_PHONE_NUMBER) await element(by.id('RecipientItem')).tap() // Select the currency @@ -58,10 +58,14 @@ export default SecureSend = () => { // Use the last digits of the account to confirm the sender. await waitFor(element(by.id('confirmAccountButton'))).toBeVisible() await element(by.id('confirmAccountButton')).tap() - for (let index = 0; index < 4; index++) { - const character = LAST_ACCOUNT_CHARACTERS[index] - await element(by.id(`SingleDigitInput/digit${index}`)).replaceText(character) - } + // TODO: test case for AddressValidationType.PARTIAL but relies on mapping phone number to another address with unique last 4 digits + // for (let index = 0; index < 4; index++) { + // const character = LAST_ACCOUNT_CHARACTERS[index] + // await element(by.id(`SingleDigitInput/digit${index}`)).replaceText(character) + // } + await element(by.id('ValidateRecipientAccount/TextInput')).replaceText( + SAMPLE_WALLET_ADDRESS_VERIFIED_2 + ) // Scroll to see submit button await scrollIntoView('Submit', 'KeyboardAwareScrollView', 50) diff --git a/e2e/src/utils/consts.js b/e2e/src/utils/consts.js index 1ee7f6e0a26..ae33024e1b9 100644 --- a/e2e/src/utils/consts.js +++ b/e2e/src/utils/consts.js @@ -7,6 +7,10 @@ export const SAMPLE_WALLET_ADDRESS = '0x6131a6d616a4be3737b38988847270a64bc10caa export const SAMPLE_BACKUP_KEY_VERIFIED = 'embody siege middle glory soda solar nasty report swap now never any' export const SAMPLE_WALLET_ADDRESS_VERIFIED = '0x86b8f44386cb2d457db79c3dab8cf42f9d8a3fc0' // corresponds to the backup key above +export const SAMPLE_BACKUP_KEY_VERIFIED_2 = + 'bench album relax truth pond orchard diet unaware cloud tackle twin tongue' +export const SAMPLE_WALLET_ADDRESS_VERIFIED_2 = '0x5fe1407f47b1310ff232a8d368b36099eff61604' // corresponds to the backup key above +export const VERIFIED_PHONE_NUMBER = '+15203140983' // all verified addresses are using this number export const SAMPLE_BACKUP_KEY_12_WORDS = 'cheese size muscle either false spend price lunar undo share kite whisper' export const SAMPLE_WALLET_ADDRESS_12_WORDS = '0x19cf37810fd5933bd63e02388e37203841c703de' // corresponds to the backup key above From 6d39db7ff08af81cf402ab51a6c0b39c4507dd5b Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Mon, 20 Nov 2023 10:49:10 +0100 Subject: [PATCH 3/9] chore: ensure fund account --- e2e/scripts/consts.ts | 1 + e2e/scripts/fund-e2e-accounts.ts | 17 ++++++++++++++--- scripts/fund_e2e_account.sh | 31 ------------------------------- 3 files changed, 15 insertions(+), 34 deletions(-) delete mode 100755 scripts/fund_e2e_account.sh diff --git a/e2e/scripts/consts.ts b/e2e/scripts/consts.ts index 93982baf142..d57d5a0b369 100644 --- a/e2e/scripts/consts.ts +++ b/e2e/scripts/consts.ts @@ -1,2 +1,3 @@ export const E2E_TEST_WALLET = '0x6131a6d616a4be3737b38988847270a64bc10caa' +export const E2E_TEST_WALLET_SECURE_SEND = '0x86b8f44386cb2d457db79c3dab8cf42f9d8a3fc0' export const E2E_TEST_FAUCET = '0xe5F5363e31351C38ac82DBAdeaD91Fd5a7B08846' diff --git a/e2e/scripts/fund-e2e-accounts.ts b/e2e/scripts/fund-e2e-accounts.ts index 2fd13fa492d..795b24662ff 100644 --- a/e2e/scripts/fund-e2e-accounts.ts +++ b/e2e/scripts/fund-e2e-accounts.ts @@ -1,7 +1,7 @@ import { newKitFromWeb3, StableToken } from '@celo/contractkit' import dotenv from 'dotenv' import Web3 from 'web3' -import { E2E_TEST_FAUCET, E2E_TEST_WALLET } from './consts' +import { E2E_TEST_FAUCET, E2E_TEST_WALLET, E2E_TEST_WALLET_SECURE_SEND } from './consts' import { checkBalance, getBalance } from './utils' dotenv.config({ path: `${__dirname}/../.env` }) @@ -12,9 +12,16 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! ;(async () => { // Get E2E Test Wallet Balance & Valora Faucet Balance - const receivingBalance = await getBalance(E2E_TEST_WALLET) + const [balanceE2ETestWallet, balanceSecureSendWallet] = await Promise.all([ + getBalance(E2E_TEST_WALLET), + getBalance(E2E_TEST_WALLET_SECURE_SEND), + ]) + const receivingBalance = { + ...balanceE2ETestWallet, + ...balanceSecureSendWallet, + } const sendingBalance = (await getBalance(E2E_TEST_FAUCET)) ?? {} - console.table(await getBalance(E2E_TEST_FAUCET)) + console.table(sendingBalance) // Connect Valora E2E Test Faucet - Private Key Stored in GitHub Secrets kit.connection.addAccount( @@ -190,7 +197,11 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! // Log Balances console.log('E2E Test Account:', E2E_TEST_WALLET) console.table(await getBalance(E2E_TEST_WALLET)) + console.log('E2E Test Account Secure Send:', E2E_TEST_WALLET_SECURE_SEND) + console.table(await getBalance(E2E_TEST_WALLET_SECURE_SEND)) console.log('Valora Test Facuet:', E2E_TEST_FAUCET) console.table(await getBalance(E2E_TEST_FAUCET)) + await checkBalance(E2E_TEST_WALLET) + await checkBalance(E2E_TEST_WALLET_SECURE_SEND) })() diff --git a/scripts/fund_e2e_account.sh b/scripts/fund_e2e_account.sh deleted file mode 100755 index eaca1f13484..00000000000 --- a/scripts/fund_e2e_account.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env sh -set -euo pipefail - -CURRENT_CONFIG=$(celocli config:get | awk '{print $2 }') -celocli config:set -n https://alfajores-forno.celo-testnet.org - -TEST_ACCOUNT=0x6131a6d616a4be3737b38988847270a64bc10caa - -echo "Verifying balancess of test account: $TEST_ACCOUNT" - -celocli account:balance $TEST_ACCOUNT >> balance.tmp -WEI_DECIMALS=$((10**18)) -printf -v USD_BALANCE "%.f" "$(grep usd balance.tmp | awk -v wei_decimals="$WEI_DECIMALS" '{print $2 / wei_decimals}')" -printf -v CELO_BALANCE "%.f" "$(grep gold balance.tmp | awk -v wei_decimals="$WEI_DECIMALS" '{print $2 / wei_decimals}')" - -echo "cUSD balance: $USD_BALANCE" -echo "CELO balance: $CELO_BALANCE" - -if [ "$USD_BALANCE" -lt "200" ]; then - echo "Adding USD to test account" - celotooljs account faucet --celo-env alfajores --account $TEST_ACCOUNT --dollar 1000 --yesreally -fi -if [ "$CELO_BALANCE" -lt "200" ]; then - echo "Adding CELO to test account" - celotooljs account faucet --celo-env alfajores --account $TEST_ACCOUNT --gold 1000 --yesreally -fi - -echo "Restoring celocli to use $CURRENT_CONFIG" -celocli config:set -n $CURRENT_CONFIG - -rm balance.tmp From 67cd20a913adf60abb5e842431163bc1e1bdec35 Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Mon, 20 Nov 2023 10:56:33 +0100 Subject: [PATCH 4/9] chore: add balance check --- e2e/scripts/check-e2e-wallet-balance.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/e2e/scripts/check-e2e-wallet-balance.ts b/e2e/scripts/check-e2e-wallet-balance.ts index 6b3d39e6df0..2d448961a3c 100644 --- a/e2e/scripts/check-e2e-wallet-balance.ts +++ b/e2e/scripts/check-e2e-wallet-balance.ts @@ -1,7 +1,11 @@ -import { E2E_TEST_WALLET } from './consts' +import { E2E_TEST_WALLET, E2E_TEST_WALLET_SECURE_SEND } from './consts' import { checkBalance, getBalance } from './utils' ;(async () => { console.log(E2E_TEST_WALLET) console.table(await getBalance(E2E_TEST_WALLET)) await checkBalance(E2E_TEST_WALLET) + + console.log(E2E_TEST_WALLET_SECURE_SEND) + console.table(await getBalance(E2E_TEST_WALLET_SECURE_SEND)) + await checkBalance(E2E_TEST_WALLET_SECURE_SEND) })() From f68577233b25233f11f6b0bd28b5e117f54016bc Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Mon, 20 Nov 2023 11:02:38 +0100 Subject: [PATCH 5/9] chore: fix balance check --- e2e/scripts/check-e2e-wallet-balance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/scripts/check-e2e-wallet-balance.ts b/e2e/scripts/check-e2e-wallet-balance.ts index 2d448961a3c..58639c34d6c 100644 --- a/e2e/scripts/check-e2e-wallet-balance.ts +++ b/e2e/scripts/check-e2e-wallet-balance.ts @@ -7,5 +7,5 @@ import { checkBalance, getBalance } from './utils' console.log(E2E_TEST_WALLET_SECURE_SEND) console.table(await getBalance(E2E_TEST_WALLET_SECURE_SEND)) - await checkBalance(E2E_TEST_WALLET_SECURE_SEND) + await checkBalance(E2E_TEST_WALLET_SECURE_SEND, 2) })() From 958405063bd494d612785c77cb3c83f549fa05a4 Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Mon, 20 Nov 2023 12:25:20 +0100 Subject: [PATCH 6/9] fix: broken import --- e2e/src/usecases/Send.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/e2e/src/usecases/Send.js b/e2e/src/usecases/Send.js index 2dd2c14d90d..0bb978c7072 100644 --- a/e2e/src/usecases/Send.js +++ b/e2e/src/usecases/Send.js @@ -1,6 +1,11 @@ import { DEFAULT_RECIPIENT_ADDRESS } from '../utils/consts' import { launchApp, reloadReactNative } from '../utils/retries' -import { enterPinUiIfNecessary, inputNumberKeypad, addComment } from '../utils/utils' +import { + enterPinUiIfNecessary, + inputNumberKeypad, + addComment, + quickOnboarding, +} from '../utils/utils' const faker = require('@faker-js/faker') import jestExpect from 'expect' From e8ee85f4f0ae8b11b5f59cf797adbfc049756f20 Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Tue, 21 Nov 2023 10:15:00 +0100 Subject: [PATCH 7/9] fix: script --- e2e/scripts/fund-e2e-accounts.ts | 66 +++++++++++++++----------------- e2e/src/utils/utils.js | 6 ++- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/e2e/scripts/fund-e2e-accounts.ts b/e2e/scripts/fund-e2e-accounts.ts index 795b24662ff..4f6d23efaf3 100644 --- a/e2e/scripts/fund-e2e-accounts.ts +++ b/e2e/scripts/fund-e2e-accounts.ts @@ -11,15 +11,8 @@ const kit = newKitFromWeb3(web3) const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! ;(async () => { - // Get E2E Test Wallet Balance & Valora Faucet Balance - const [balanceE2ETestWallet, balanceSecureSendWallet] = await Promise.all([ - getBalance(E2E_TEST_WALLET), - getBalance(E2E_TEST_WALLET_SECURE_SEND), - ]) - const receivingBalance = { - ...balanceE2ETestWallet, - ...balanceSecureSendWallet, - } + const walletsToBeFunded = [E2E_TEST_WALLET, E2E_TEST_WALLET_SECURE_SEND] + const walletBalances = await Promise.all(walletsToBeFunded.map(getBalance)) const sendingBalance = (await getBalance(E2E_TEST_FAUCET)) ?? {} console.table(sendingBalance) @@ -47,6 +40,7 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! if (targetTokenRegex.test(balance)) sum += balances[balance] } + // Ensure that the faucet has enough funds for (let balance in balances) { const target = sum / numOfTokens if (balances[balance] >= sum / numOfTokens) { @@ -162,35 +156,35 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! } // Set Amount To Send - let amountToSend = web3.utils.toWei('100', 'ether') + const amountToSend = web3.utils.toWei('100', 'ether') - // Loop through E2E Test Wallet Balance Object - for (const coin in receivingBalance) { - let tx: any - // Add funds if balance is less than 100 add 100 - if (receivingBalance[coin] < 200 && sendingBalance[coin] > 100) { - switch (coin) { - case 'CELO': - tx = await celoToken - .transfer(E2E_TEST_WALLET, amountToSend) - .send({ from: E2E_TEST_FAUCET }) - break - case 'cUSD': - tx = await cusdToken - .transfer(E2E_TEST_WALLET, amountToSend) - .send({ from: E2E_TEST_FAUCET }) - break - case 'cEUR': - tx = await ceurToken - .transfer(E2E_TEST_WALLET, amountToSend) - .send({ from: E2E_TEST_FAUCET }) - break - } - // Wait for the transactions to be processed - let receipt = await tx.waitReceipt() + for (let i = 0; i < walletsToBeFunded.length; i++) { + const walletAddress = walletsToBeFunded[i] + const walletBalance = walletBalances[i] + for (const coin in walletBalance) { + if (walletBalance[coin] < 200 && sendingBalance[coin] > 100) { + let tx: any + switch (coin) { + case 'CELO': + tx = await celoToken + .transfer(walletAddress, amountToSend) + .send({ from: E2E_TEST_FAUCET }) + break + case 'cUSD': + tx = await cusdToken + .transfer(walletAddress, amountToSend) + .send({ from: E2E_TEST_FAUCET }) + break + case 'cEUR': + tx = await ceurToken + .transfer(walletAddress, amountToSend) + .send({ from: E2E_TEST_FAUCET }) + break + } + const receipt = await tx.waitReceipt() - // Print Receipt - console.log(' Transaction receipt: %o', receipt) + console.log(' Transaction receipt: %o', receipt) + } } } diff --git a/e2e/src/utils/utils.js b/e2e/src/utils/utils.js index f77eb3160fb..338ad6bfb7c 100644 --- a/e2e/src/utils/utils.js +++ b/e2e/src/utils/utils.js @@ -207,7 +207,11 @@ export async function quickOnboarding(mnemonic = SAMPLE_BACKUP_KEY) { await waitForElementId('PhoneVerificationSkipHeader') // Skip await element(by.id('PhoneVerificationSkipHeader')).tap() - } catch {} + } catch { + console.log( + 'Error trying to skip phone verification step during onboarding, likely due to wallet already being verified' + ) + } // Assert on Wallet Home Screen await dismissCashInBottomSheet() From 8688c2366e8415c562e4d3813e185199708c005a Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Tue, 21 Nov 2023 12:55:41 +0100 Subject: [PATCH 8/9] fix: improve fund script --- e2e/scripts/fund-e2e-accounts.ts | 85 +++++++++++++++++++------------- e2e/scripts/utils.ts | 8 +-- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/e2e/scripts/fund-e2e-accounts.ts b/e2e/scripts/fund-e2e-accounts.ts index 4f6d23efaf3..6006cb94a41 100644 --- a/e2e/scripts/fund-e2e-accounts.ts +++ b/e2e/scripts/fund-e2e-accounts.ts @@ -11,10 +11,18 @@ const kit = newKitFromWeb3(web3) const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! ;(async () => { + const refillTokens = ['CELO', 'cUSD', 'cEUR'] + const walletsToBeFunded = [E2E_TEST_WALLET, E2E_TEST_WALLET_SECURE_SEND] const walletBalances = await Promise.all(walletsToBeFunded.map(getBalance)) - const sendingBalance = (await getBalance(E2E_TEST_FAUCET)) ?? {} - console.table(sendingBalance) + for (let i = 0; i < walletsToBeFunded.length; i++) { + console.log(`Initial balance for ${walletsToBeFunded[i]}:`) + console.table(walletBalances[i]) + } + + const faucetTokenBalances = (await getBalance(E2E_TEST_FAUCET)) ?? {} + console.log('Initial faucet balance:') + console.table(faucetTokenBalances) // Connect Valora E2E Test Faucet - Private Key Stored in GitHub Secrets kit.connection.addAccount( @@ -30,25 +38,27 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! const ceurExchange = await kit.contracts.getExchange(StableToken.cEUR) // Balance Faucet - let targetTokenRegex = /[cusd|celo|ceur]/gi - let balances = await getBalance(E2E_TEST_FAUCET) - let sum = 0 - const numOfTokens = 3 // Only cusd, celo and ceur - for (let balance in balances) { - console.log(`${balance}: ${balances[balance]}`) - // Sum only the target balances - if (targetTokenRegex.test(balance)) sum += balances[balance] - } + let totalTokenHoldings = 0 // the absolute number of faucet tokens the faucet is holding + Object.entries(faucetTokenBalances).forEach(([tokenSymbol, tokenBalance]) => { + if (refillTokens.includes(tokenSymbol)) { + totalTokenHoldings += tokenBalance + } + }) + const targetFaucetTokenBalance = totalTokenHoldings / refillTokens.length + + // Ensure that the faucet has enough balance for each refill tokens + for (const [tokenSymbol, tokenBalance] of Object.entries(faucetTokenBalances)) { + if (!refillTokens.includes(tokenSymbol)) { + continue + } - // Ensure that the faucet has enough funds - for (let balance in balances) { - const target = sum / numOfTokens - if (balances[balance] >= sum / numOfTokens) { - const toSell = balances[balance] - target - console.log(toSell) - const amountToExchange = kit.web3.utils.toWei(`${toSell}`, 'ether') - console.log(`${balance} balance higher than ${sum / numOfTokens}`) - switch (balance) { + if (tokenBalance >= targetFaucetTokenBalance) { + const sellAmount = tokenBalance - targetFaucetTokenBalance + const amountToExchange = kit.web3.utils.toWei(`${sellAmount}`, 'ether') + console.log( + `${tokenSymbol} balance is ${tokenBalance}, which is higher than target ${targetFaucetTokenBalance}. Selling ${sellAmount}.` + ) + switch (tokenSymbol) { case 'CELO': try { const celoApproveTx = await celoToken @@ -99,10 +109,12 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! } } } else { - const toBuy = target - balances[balance] - const amountToExchange = kit.web3.utils.toWei(`${toBuy}`, 'ether') - console.log(`${balance} balance lower than ${sum / numOfTokens}`) - switch (balance) { + const buyAmount = targetFaucetTokenBalance - tokenBalance + const amountToExchange = kit.web3.utils.toWei(`${buyAmount}`, 'ether') + console.log( + `${tokenSymbol} balance is ${tokenBalance}, which is lower than target ${targetFaucetTokenBalance}. Buying ${buyAmount}.` + ) + switch (tokenSymbol) { case 'CELO': try { const celoApproveTx = await celoToken @@ -156,37 +168,42 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! } // Set Amount To Send - const amountToSend = web3.utils.toWei('100', 'ether') + const amountToSend = '100' + const amountToSendWei = web3.utils.toWei(amountToSend, 'ether') for (let i = 0; i < walletsToBeFunded.length; i++) { const walletAddress = walletsToBeFunded[i] const walletBalance = walletBalances[i] - for (const coin in walletBalance) { - if (walletBalance[coin] < 200 && sendingBalance[coin] > 100) { + for (const tokenSymbol of refillTokens) { + if (walletBalance && walletBalance[tokenSymbol] < 200) { + console.log(`Sending ${amountToSend} ${tokenSymbol} to ${walletAddress}`) let tx: any - switch (coin) { + switch (tokenSymbol) { case 'CELO': tx = await celoToken - .transfer(walletAddress, amountToSend) + .transfer(walletAddress, amountToSendWei) .send({ from: E2E_TEST_FAUCET }) break case 'cUSD': tx = await cusdToken - .transfer(walletAddress, amountToSend) + .transfer(walletAddress, amountToSendWei) .send({ from: E2E_TEST_FAUCET }) break case 'cEUR': tx = await ceurToken - .transfer(walletAddress, amountToSend) + .transfer(walletAddress, amountToSendWei) .send({ from: E2E_TEST_FAUCET }) break } const receipt = await tx.waitReceipt() - console.log(' Transaction receipt: %o', receipt) + console.log( + `Received tx hash ${receipt.transactionHash} for ${tokenSymbol} transfer to ${walletAddress}` + ) } } } + console.log('Finished funding wallets.') // Log Balances console.log('E2E Test Account:', E2E_TEST_WALLET) @@ -196,6 +213,6 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! console.log('Valora Test Facuet:', E2E_TEST_FAUCET) console.table(await getBalance(E2E_TEST_FAUCET)) - await checkBalance(E2E_TEST_WALLET) - await checkBalance(E2E_TEST_WALLET_SECURE_SEND) + await checkBalance(E2E_TEST_WALLET, 10, refillTokens) + await checkBalance(E2E_TEST_WALLET_SECURE_SEND, 10, refillTokens) })() diff --git a/e2e/scripts/utils.ts b/e2e/scripts/utils.ts index cc94f0eb6a0..ac9adf45283 100644 --- a/e2e/scripts/utils.ts +++ b/e2e/scripts/utils.ts @@ -4,10 +4,10 @@ export const dotenv = require('dotenv') export const web3 = new Web3('https://alfajores-forno.celo-testnet.org') export const kit = ContractKit.newKitFromWeb3(web3) -export async function checkBalance(address: string, minBalance = 10) { - let balanceObject = await getBalance(address) - for (const balance in balanceObject) { - if (balanceObject[balance as keyof typeof balanceObject] < minBalance) { +export async function checkBalance(address: string, minBalance = 10, tokenSymbols?: string[]) { + const balance = (await getBalance(address)) ?? {} + for (const [tokenSymbol, tokenBalance] of Object.entries(balance)) { + if ((!tokenSymbols || tokenSymbols.includes(tokenSymbol)) && tokenBalance < minBalance) { throw new Error( `${balance} balance of ${address} is below ${minBalance}. Please refill from the faucet https://celo.org/developers/faucet or run ./fund-e2e-accounts.ts if a Valora Dev.` ) From f8bcb0a54a3c0bb79e119afc4945e85e0350a2b9 Mon Sep 17 00:00:00 2001 From: Kathy Luo Date: Tue, 21 Nov 2023 13:00:28 +0100 Subject: [PATCH 9/9] chore: cleanup --- e2e/scripts/check-e2e-wallet-balance.ts | 2 +- e2e/scripts/consts.ts | 1 + e2e/scripts/fund-e2e-accounts.ts | 21 ++++++++++++--------- e2e/scripts/utils.ts | 10 ++++++++-- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/e2e/scripts/check-e2e-wallet-balance.ts b/e2e/scripts/check-e2e-wallet-balance.ts index 58639c34d6c..2d448961a3c 100644 --- a/e2e/scripts/check-e2e-wallet-balance.ts +++ b/e2e/scripts/check-e2e-wallet-balance.ts @@ -7,5 +7,5 @@ import { checkBalance, getBalance } from './utils' console.log(E2E_TEST_WALLET_SECURE_SEND) console.table(await getBalance(E2E_TEST_WALLET_SECURE_SEND)) - await checkBalance(E2E_TEST_WALLET_SECURE_SEND, 2) + await checkBalance(E2E_TEST_WALLET_SECURE_SEND) })() diff --git a/e2e/scripts/consts.ts b/e2e/scripts/consts.ts index d57d5a0b369..7fb65ff556f 100644 --- a/e2e/scripts/consts.ts +++ b/e2e/scripts/consts.ts @@ -1,3 +1,4 @@ export const E2E_TEST_WALLET = '0x6131a6d616a4be3737b38988847270a64bc10caa' export const E2E_TEST_WALLET_SECURE_SEND = '0x86b8f44386cb2d457db79c3dab8cf42f9d8a3fc0' export const E2E_TEST_FAUCET = '0xe5F5363e31351C38ac82DBAdeaD91Fd5a7B08846' +export const REFILL_TOKENS = ['CELO', 'cUSD', 'cEUR'] diff --git a/e2e/scripts/fund-e2e-accounts.ts b/e2e/scripts/fund-e2e-accounts.ts index 6006cb94a41..40827d60606 100644 --- a/e2e/scripts/fund-e2e-accounts.ts +++ b/e2e/scripts/fund-e2e-accounts.ts @@ -1,7 +1,12 @@ import { newKitFromWeb3, StableToken } from '@celo/contractkit' import dotenv from 'dotenv' import Web3 from 'web3' -import { E2E_TEST_FAUCET, E2E_TEST_WALLET, E2E_TEST_WALLET_SECURE_SEND } from './consts' +import { + E2E_TEST_FAUCET, + E2E_TEST_WALLET, + E2E_TEST_WALLET_SECURE_SEND, + REFILL_TOKENS, +} from './consts' import { checkBalance, getBalance } from './utils' dotenv.config({ path: `${__dirname}/../.env` }) @@ -11,8 +16,6 @@ const kit = newKitFromWeb3(web3) const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! ;(async () => { - const refillTokens = ['CELO', 'cUSD', 'cEUR'] - const walletsToBeFunded = [E2E_TEST_WALLET, E2E_TEST_WALLET_SECURE_SEND] const walletBalances = await Promise.all(walletsToBeFunded.map(getBalance)) for (let i = 0; i < walletsToBeFunded.length; i++) { @@ -40,15 +43,15 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! // Balance Faucet let totalTokenHoldings = 0 // the absolute number of faucet tokens the faucet is holding Object.entries(faucetTokenBalances).forEach(([tokenSymbol, tokenBalance]) => { - if (refillTokens.includes(tokenSymbol)) { + if (REFILL_TOKENS.includes(tokenSymbol)) { totalTokenHoldings += tokenBalance } }) - const targetFaucetTokenBalance = totalTokenHoldings / refillTokens.length + const targetFaucetTokenBalance = totalTokenHoldings / REFILL_TOKENS.length // Ensure that the faucet has enough balance for each refill tokens for (const [tokenSymbol, tokenBalance] of Object.entries(faucetTokenBalances)) { - if (!refillTokens.includes(tokenSymbol)) { + if (!REFILL_TOKENS.includes(tokenSymbol)) { continue } @@ -174,7 +177,7 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! for (let i = 0; i < walletsToBeFunded.length; i++) { const walletAddress = walletsToBeFunded[i] const walletBalance = walletBalances[i] - for (const tokenSymbol of refillTokens) { + for (const tokenSymbol of REFILL_TOKENS) { if (walletBalance && walletBalance[tokenSymbol] < 200) { console.log(`Sending ${amountToSend} ${tokenSymbol} to ${walletAddress}`) let tx: any @@ -213,6 +216,6 @@ const valoraTestFaucetSecret = process.env['TEST_FAUCET_SECRET']! console.log('Valora Test Facuet:', E2E_TEST_FAUCET) console.table(await getBalance(E2E_TEST_FAUCET)) - await checkBalance(E2E_TEST_WALLET, 10, refillTokens) - await checkBalance(E2E_TEST_WALLET_SECURE_SEND, 10, refillTokens) + await checkBalance(E2E_TEST_WALLET) + await checkBalance(E2E_TEST_WALLET_SECURE_SEND) })() diff --git a/e2e/scripts/utils.ts b/e2e/scripts/utils.ts index ac9adf45283..fff5bff4d3a 100644 --- a/e2e/scripts/utils.ts +++ b/e2e/scripts/utils.ts @@ -1,13 +1,19 @@ +import { REFILL_TOKENS } from './consts' + export const Web3 = require('web3') export const ContractKit = require('@celo/contractkit') export const dotenv = require('dotenv') export const web3 = new Web3('https://alfajores-forno.celo-testnet.org') export const kit = ContractKit.newKitFromWeb3(web3) -export async function checkBalance(address: string, minBalance = 10, tokenSymbols?: string[]) { +export async function checkBalance( + address: string, + minBalance = 10, + tokenSymbols: string[] = REFILL_TOKENS +) { const balance = (await getBalance(address)) ?? {} for (const [tokenSymbol, tokenBalance] of Object.entries(balance)) { - if ((!tokenSymbols || tokenSymbols.includes(tokenSymbol)) && tokenBalance < minBalance) { + if (tokenSymbols.includes(tokenSymbol) && tokenBalance < minBalance) { throw new Error( `${balance} balance of ${address} is below ${minBalance}. Please refill from the faucet https://celo.org/developers/faucet or run ./fund-e2e-accounts.ts if a Valora Dev.` )