Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: re-enable secure send e2e test #4507

Merged
merged 12 commits into from
Nov 21, 2023
6 changes: 5 additions & 1 deletion e2e/scripts/check-e2e-wallet-balance.ts
Original file line number Diff line number Diff line change
@@ -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, 2)
})()
1 change: 1 addition & 0 deletions e2e/scripts/consts.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const E2E_TEST_WALLET = '0x6131a6d616a4be3737b38988847270a64bc10caa'
export const E2E_TEST_WALLET_SECURE_SEND = '0x86b8f44386cb2d457db79c3dab8cf42f9d8a3fc0'
export const E2E_TEST_FAUCET = '0xe5F5363e31351C38ac82DBAdeaD91Fd5a7B08846'
17 changes: 14 additions & 3 deletions e2e/scripts/fund-e2e-accounts.ts
Original file line number Diff line number Diff line change
@@ -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` })
Expand All @@ -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,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this gonna mix/overwrite balances between both accounts?
Where do we actually send to E2E_TEST_WALLET_SECURE_SEND?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol oops, this logic didn't make sense. i've updated the script, sorry about that

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(
Expand Down Expand Up @@ -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)
})()
8 changes: 1 addition & 7 deletions e2e/src/Send.spec.js
Original file line number Diff line number Diff line change
@@ -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)
})
136 changes: 71 additions & 65 deletions e2e/src/usecases/SecureSend.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,92 @@
import { reloadReactNative } from '../utils/retries'
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 = '+12057368924'
const LAST_ACCOUNT_CHARACTERS = 'FD08'
const AMOUNT_TO_SEND = '0.1'
const AMOUNT_TO_SEND = '0.01'

export default SecureSend = () => {
beforeEach(async () => {
await reloadReactNative()
})

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()

// 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()
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)
})

// Select the currency
await waitFor(element(by.id('cUSDBalance')))
.toBeVisible()
.withTimeout(30 * 1000)
await element(by.id('cUSDBalance')).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()

// Enter the amount and review
await inputNumberKeypad(AMOUNT_TO_SEND)
await element(by.id('Review')).tap()
await element(by.id('SearchInput')).tap()
await element(by.id('SearchInput')).replaceText(VERIFIED_PHONE_NUMBER)
await element(by.id('RecipientItem')).tap()

// hack: we shouldn't need this but the test fails without
await sleep(3000)
// Select the currency
await waitFor(element(by.id('cUSDTouchable'))).toBeVisible()
await element(by.id('cUSDTouchable')).tap()

// Click Edit if confirm account isn't served
try {
await element(by.id('accountEditButton')).tap()
} catch {}
// Enter the amount and review
await inputNumberKeypad(AMOUNT_TO_SEND)
await element(by.id('Review')).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()
// Use the last digits of the account to confirm the sender.
await waitFor(element(by.id('confirmAccountButton'))).toBeVisible()
await element(by.id('confirmAccountButton')).tap()
// 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
)

Comment on lines +66 to +68
Copy link
Member

@jeanregisser jeanregisser Nov 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't it need just the last 4 digits?
Oh, it's doing this lookup from the verified account itself.
Since we can't lookup numbers without being verified.

We'd need 2 other verified accounts, to another number to test that case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i understand correctly, the secure send screen either asks for the full address or the last 4 digits but this is depending on how "different" the possible addresses are. unfortunately we've mapped to 2 wallets and they both have a "0" in the last 4 digits of the address, so we've got the full text input.

idk if it is too important to test both the full text input and the 4 digits, i have 90% confidence that both flows are working if i know one of them is working. we can try to remap to another address, but this is Tom's burner number and he's out all week so would need to wait till he's back

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the current test is fine for now.

For posterity, the check for uniqueness of the last 4 digits is done as a whole, but also includes the user's own address:

// Adding user's address so they don't mistakenly verify with last 4 digits of their own address
if (last4DigitsAreUnique([userAddress, ...possibleAddresses])) {
return AddressValidationType.PARTIAL
}

It's not the fact that there are chars in common between them that causes PARTIAL vs FULL.

// Write a comment.
await addComment(randomContent)
// Scroll to see submit button
await scrollIntoView('Submit', 'KeyboardAwareScrollView', 50)
await element(by.id('ConfirmAccountButton')).tap()

// Wait for the confirm button to be clickable. If it takes too long this test
// will be flaky :(
await sleep(3000)
// Write a comment.
await addComment(randomContent)

// 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)
})
}
)
}
4 changes: 4 additions & 0 deletions e2e/src/usecases/Send.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)',
Expand Down
4 changes: 4 additions & 0 deletions e2e/src/utils/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions e2e/src/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to console.log something here, maybe Ignored error while waiting for phone verification screen, account likely already verified or something.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes done :)


// Assert on Wallet Home Screen
await dismissCashInBottomSheet()
Expand Down
31 changes: 0 additions & 31 deletions scripts/fund_e2e_account.sh

This file was deleted.

Loading