Merge branch 'tokens-send' of github.com:poanetwork/metamask-extension into tokens-send

This commit is contained in:
Victor Baranov 2018-09-28 18:18:56 +03:00
commit f837af2bac
3 changed files with 259 additions and 48 deletions

View File

@ -326,14 +326,14 @@ SendTransactionScreen.prototype.onSubmit = async function () {
let message let message
if (isNaN(input) || input === '') { if (isNaN(input) || input === '') {
message = 'Invalid tokens\' amount.' message = 'Invalid token\'s amount.'
return this.props.dispatch(actions.displayWarning(message)) return this.props.dispatch(actions.displayWarning(message))
} }
if (parts[1]) { if (parts[1]) {
var decimal = parts[1] var decimal = parts[1]
if (decimal.length > 18) { if (decimal.length > 18) {
message = 'Tokens\' amount is too precise.' message = 'Token\'s amount is too precise.'
return this.props.dispatch(actions.displayWarning(message)) return this.props.dispatch(actions.displayWarning(message))
} }
} }
@ -343,7 +343,7 @@ SendTransactionScreen.prototype.onSubmit = async function () {
const tokensValueWithDec = new BigNumber(calcTokenAmountWithDec(input, token.decimals)) const tokensValueWithDec = new BigNumber(calcTokenAmountWithDec(input, token.decimals))
if (tokensValueWithDec.gt(token.balance)) { if (tokensValueWithDec.gt(token.balance)) {
message = 'Insufficient tokens\' balance.' message = 'Insufficient token\'s balance.'
return this.props.dispatch(actions.displayWarning(message)) return this.props.dispatch(actions.displayWarning(message))
} }

View File

@ -8,9 +8,11 @@ module.exports = {
token: { token: {
menu: By.id('token-cell_dropdown_0'), menu: By.id('token-cell_dropdown_0'),
items: By.className('dropdown-menu-item'), items: By.className('dropdown-menu-item'),
view: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(2)'), send: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(2)'),
copy: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(3)'), view: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(3)'),
remove: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(4)'), copy: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(4)'),
remove: By.css('#token-cell_dropdown_0 > div > div > li:nth-child(5)'),
sendText: 'Send',
viewText: 'View token on block explorer', viewText: 'View token on block explorer',
copyText: 'Copy address to clipboard', copyText: 'Copy address to clipboard',
removeText: 'Remove', removeText: 'Remove',
@ -25,6 +27,7 @@ module.exports = {
}, },
account: { account: {
account1: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(2) > span'), account1: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(2) > span'),
account2: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(3) > span'),
menu: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div'), menu: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div'),
delete: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(4) > div.remove'), delete: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(4) > div.remove'),
createAccount: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(3) > span'), createAccount: By.css('#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(3) > span'),
@ -43,6 +46,29 @@ module.exports = {
}, },
}, },
screens: { screens: {
sendTokens: {
error: By.className('error flex-center'),
errorText: {
invalidAmount: 'Invalid token\'s amount',
address: 'Recipient address is invalid',
largeAmount: 'Insufficient token\'s balance',
tooPrecise: 'Token\'s amount is too precise',
negativeAmount: 'Can not send negative amounts of ETH',
},
title: By.className('flex-center'),
balance: By.className('hide-text-overflow token-balance__amount'),
symbol: By.className('token-balance__symbol'),
field: {
address: By.name('address'),
addressPlaceholder: 'Recipient Address',
amount: By.name('amount'),
amountPlaceholder: 'Amount',
},
button: {
next: By.xpath('//*[@id="app-content"]/div/div[4]/div/section[2]/button'),
arrow: By.className('fa fa-arrow-left fa-lg cursor-pointer'),
},
},
yourPR: { yourPR: {
key: By.css('#app-content > div > div.app-primary.from-right > div > div.privateKey > div.flex-row > p'), key: By.css('#app-content > div > div.app-primary.from-right > div > div.privateKey > div.flex-row > p'),
copy: By.className('clipboard cursor-pointer'), copy: By.className('clipboard cursor-pointer'),
@ -120,14 +146,17 @@ module.exports = {
titleText: 'Delete Custom RPC', titleText: 'Delete Custom RPC',
}, },
confirmTransaction: { confirmTransaction: {
buttons: { title: By.className('flex-row flex-center'),
amount: By.css('#pending-tx-form > div:nth-child(1) > div.table-box > div:nth-child(2) > div.ether-balance.ether-balance-amount > div > div > div > div:nth-child(1)'),
symbol: By.css('#pending-tx-form > div:nth-child(1) > div.table-box > div:nth-child(2) > div.ether-balance.ether-balance-amount > div > div > div > div:nth-child(2)'),
button: {
submit: By.css('#pending-tx-form > div.flex-row.flex-space-around.conf-buttons > input'), submit: By.css('#pending-tx-form > div.flex-row.flex-space-around.conf-buttons > input'),
}, },
}, },
sendTransaction: { sendTransaction: {
title: By.css('#app-content > div > div.app-primary.from-right > div > h3:nth-child(2)'), title: By.css('#app-content > div > div.app-primary.from-right > div > h3:nth-child(2)'),
titleText: 'Send Transaction', titleText: 'Send Transaction',
fields: { field: {
address: By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(3) > div > input'), address: By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(3) > div > input'),
amount: By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(4) > input'), amount: By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(4) > input'),
}, },
@ -179,7 +208,8 @@ module.exports = {
}, },
main: { main: {
identicon: By.className('identicon-wrapper select-none'), identicon: By.className('identicon-wrapper select-none'),
accountName: By.className('sizing-input'), fieldAccountName: By.className('sizing-input'),
accountName: By.css('#app-content > div > div.app-primary.from-left > div > div > div:nth-child(1) > flex-column > div.name-label > div > div > h2'),
edit: By.className('edit-text'), edit: By.className('edit-text'),
iconCopy: By.className('clipboard cursor-pointer white'), iconCopy: By.className('clipboard cursor-pointer white'),
transactionList: By.css('#app-content > div > div.app-primary.from-left > div > section > section > div > div > div > div.ether-balance.ether-balance-amount > div > div > div > div:nth-child(1)'), transactionList: By.css('#app-content > div > div.app-primary.from-left > div > section > section > div > div > div > div.ether-balance.ether-balance-amount > div > div > div > div:nth-child(1)'),
@ -199,7 +229,7 @@ module.exports = {
tokens: { tokens: {
menu: By.className('inactiveForm pointer'), menu: By.className('inactiveForm pointer'),
token: By.className('token-cell'), token: By.className('token-cell'),
balance: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > ol > li:nth-child(2) > h3'), balance: By.css('#token-cell_0 > h3'),
amount: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > span'), amount: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > span'),
textNoTokens: 'No tokens found', textNoTokens: 'No tokens found',
textYouOwn1token: 'You own 1 token', textYouOwn1token: 'You own 1 token',

View File

@ -133,13 +133,13 @@ describe('Metamask popup page', async function () {
await menu.click() await menu.click()
const field = await waitUntilShowUp(screens.main.edit) const field = await waitUntilShowUp(screens.main.edit)
await field.click() await field.click()
const accountName = await waitUntilShowUp(screens.main.accountName) const accountName = await waitUntilShowUp(screens.main.fieldAccountName)
assert.notEqual(accountName, false, '\'Account name\' change dialog isn\'t opened') assert.notEqual(accountName, false, '\'Account name\' change dialog isn\'t opened')
assert.equal(await accountName.getAttribute('value'), 'Account 1', 'incorrect placeholder') assert.equal(await accountName.getAttribute('value'), 'Account 1', 'incorrect placeholder')
}) })
it('fill out new account\'s name', async () => { it('fill out new account\'s name', async () => {
const field = await waitUntilShowUp(screens.main.accountName) const field = await waitUntilShowUp(screens.main.fieldAccountName)
await field.clear() await field.clear()
await field.sendKeys(newAccountName) await field.sendKeys(newAccountName)
}) })
@ -149,7 +149,7 @@ describe('Metamask popup page', async function () {
assert.equal(await button.getText(), 'Save', 'button has incorrect name') assert.equal(await button.getText(), 'Save', 'button has incorrect name')
assert.notEqual(button, true, 'button \'Save\' does not present') assert.notEqual(button, true, 'button \'Save\' does not present')
await click(button) await click(button)
const accountName = await waitUntilShowUp(screens.main.accountName, 10) const accountName = await waitUntilShowUp(screens.main.fieldAccountName, 10)
assert.equal(accountName, false, '\'Account name\' change dialog isn\'t opened') assert.equal(accountName, false, '\'Account name\' change dialog isn\'t opened')
}) })
@ -586,8 +586,8 @@ describe('Metamask popup page', async function () {
it('adds recipient address and amount', async function () { it('adds recipient address and amount', async function () {
const sendTranscationScreen = await waitUntilShowUp(screens.sendTransaction.title) const sendTranscationScreen = await waitUntilShowUp(screens.sendTransaction.title)
assert.equal(await sendTranscationScreen.getText(), screens.sendTransaction.titleText, 'Transaction screen has incorrect titlr') assert.equal(await sendTranscationScreen.getText(), screens.sendTransaction.titleText, 'Transaction screen has incorrect titlr')
const inputAddress = await waitUntilShowUp(screens.sendTransaction.fields.address) const inputAddress = await waitUntilShowUp(screens.sendTransaction.field.address)
const inputAmmount = await waitUntilShowUp(screens.sendTransaction.fields.amount) const inputAmmount = await waitUntilShowUp(screens.sendTransaction.field.amount)
await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')
await inputAmmount.sendKeys('10') await inputAmmount.sendKeys('10')
const button = await waitUntilShowUp(screens.sendTransaction.buttonNext) const button = await waitUntilShowUp(screens.sendTransaction.buttonNext)
@ -596,7 +596,7 @@ describe('Metamask popup page', async function () {
}) })
it('confirms transaction', async function () { it('confirms transaction', async function () {
const button = await waitUntilShowUp(screens.confirmTransaction.buttons.submit) const button = await waitUntilShowUp(screens.confirmTransaction.button.submit)
assert.equal(await button.getAttribute('value'), 'Submit', 'button has incorrect name') assert.equal(await button.getAttribute('value'), 'Submit', 'button has incorrect name')
await click(button) await click(button)
}) })
@ -921,7 +921,7 @@ describe('Metamask popup page', async function () {
it('confirms transaction in MetaMask popup', async function () { it('confirms transaction in MetaMask popup', async function () {
const windowHandles = await driver.getAllWindowHandles() const windowHandles = await driver.getAllWindowHandles()
await driver.switchTo().window(windowHandles[windowHandles.length - 1]) await driver.switchTo().window(windowHandles[windowHandles.length - 1])
const button = await waitUntilShowUp(screens.confirmTransaction.buttons.submit) const button = await waitUntilShowUp(screens.confirmTransaction.button.submit)
await click(button) await click(button)
}) })
@ -946,6 +946,9 @@ describe('Metamask popup page', async function () {
it('navigates to the add token screen', async function () { it('navigates to the add token screen', async function () {
await waitUntilShowUp(screens.main.identicon) await waitUntilShowUp(screens.main.identicon)
const tab = await waitUntilShowUp(screens.main.tokens.menu)
await tab.click()
const addTokenButton = await waitUntilShowUp(screens.main.tokens.buttonAdd) const addTokenButton = await waitUntilShowUp(screens.main.tokens.buttonAdd)
assert.equal(await addTokenButton.getText(), screens.main.tokens.buttonAddText) assert.equal(await addTokenButton.getText(), screens.main.tokens.buttonAddText)
await click(addTokenButton) await click(addTokenButton)
@ -957,7 +960,7 @@ describe('Metamask popup page', async function () {
}) })
it('adds token parameters', async function () { it('adds token parameters', async function () {
const tab = await waitUntilShowUp(screens.addToken.tab.custom) const tab = await waitUntilShowUp(screens.addToken.tab.custom, 30)
if (!await waitUntilShowUp(screens.addToken.custom.fields.contractAddress)) await tab.click() if (!await waitUntilShowUp(screens.addToken.custom.fields.contractAddress)) await tab.click()
const tokenContractAddress = await waitUntilShowUp(screens.addToken.custom.fields.contractAddress) const tokenContractAddress = await waitUntilShowUp(screens.addToken.custom.fields.contractAddress)
await tokenContractAddress.sendKeys(tokenAddress) await tokenContractAddress.sendKeys(tokenAddress)
@ -987,6 +990,50 @@ describe('Metamask popup page', async function () {
await switchToFirstPage() await switchToFirstPage()
}) })
}) })
describe('Token menu', function () {
it('token menu is displayed and clickable ', async function () {
const menu = await waitUntilShowUp(menus.token.menu)
await menu.click()
})
it('link \'View on blockexplorer...\' leads to correct page ', async function () {
const menu = await waitUntilShowUp(menus.token.view)
assert.notEqual(menu, false, 'item isn\'t displayed')
assert.equal(await menu.getText(), menus.token.viewText, 'incorrect name')
await menu.click()
await switchToLastPage()
const title = await driver.getCurrentUrl()
assert.equal(title.includes('https://etherscan.io/token/'), true, 'link leads to wrong page')
await switchToFirstPage()
})
it('item \'Copy\' is displayed and clickable ', async function () {
let menu = await waitUntilShowUp(menus.token.menu)
await menu.click()
const item = await waitUntilShowUp(menus.token.copy)
assert.notEqual(item, false, 'item isn\'t displayed')
assert.equal(await item.getText(), menus.token.copyText, 'incorrect name')
await item.click()
menu = await waitUntilShowUp(menus.token.menu, 10)
assert.notEqual(menu, false, 'menu wasn\'t closed')
})
it('item \'Remove\' is displayed', async function () {
const menu = await waitUntilShowUp(menus.token.menu)
await menu.click()
const item = await waitUntilShowUp(menus.token.remove)
assert.notEqual(item, false, 'item isn\'t displayed')
assert.equal(await item.getText(), menus.token.removeText, 'incorrect name')
})
it('item \'Send \' is displayed', async function () {
const item = await waitUntilShowUp(menus.token.send)
assert.notEqual(item, false, 'item isn\'t displayed')
assert.equal(await item.getText(), menus.token.sendText, 'incorrect name')
await waitUntilShowUp(menus.token.menu)
})
})
describe('Check support of token per network basis ', async function () { describe('Check support of token per network basis ', async function () {
@ -1081,44 +1128,178 @@ describe('Metamask popup page', async function () {
}) })
}) })
describe('Token menu', function () { describe('Transfer tokens', function () {
it('token menu is displayed and clickable ', async function () { const account2 = '0x2f318C334780961FB129D2a6c30D0763d9a5C970'
const menu = await waitUntilShowUp(menus.token.menu) const invalidAddress = '0xkqjefwblknnecwe'
await menu.click() const invalidAmount = 'eeeee'
}) const largeAmount = '123'
const preciseAmount = '0.123456789123456789123'
it('link \'View on blockexplorer...\' leads to correct page ', async function () { const negativeAmount = '-1'
const menu = await waitUntilShowUp(menus.token.view) it('switch to account 1 ', async function () {
assert.notEqual(menu, false, 'item isn\'t displayed') const accountMenu = await waitUntilShowUp(menus.account.menu)
assert.equal(await menu.getText(), menus.token.viewText, 'incorrect name') await accountMenu.click()
await menu.click() const item = await waitUntilShowUp(menus.account.account1)
await switchToLastPage()
const title = await driver.getCurrentUrl()
assert.equal(title.includes('https://etherscan.io/token/'), true, 'link leads to wrong page')
await switchToFirstPage()
})
it('item \'Copy\' is displayed and clickable ', async function () {
let menu = await waitUntilShowUp(menus.token.menu)
await menu.click()
const item = await waitUntilShowUp(menus.token.copy)
assert.notEqual(item, false, 'item isn\'t displayed')
assert.equal(await item.getText(), menus.token.copyText, 'incorrect name')
await item.click() await item.click()
menu = await waitUntilShowUp(menus.token.menu, 10) await delay(2000)
assert.notEqual(menu, false, 'menu wasn\'t closed') const accountName = await waitUntilShowUp(screens.main.accountName)
assert.equal(await accountName.getText(), 'Account 1', 'account name incorrect')
}) })
it('item \'Remove\' is displayed', async function () { it('open screen \'Transfer tokens\' ', async function () {
const menu = await waitUntilShowUp(menus.token.menu) const menu = await waitUntilShowUp(menus.token.menu)
await menu.click() await menu.click()
const item = await waitUntilShowUp(menus.token.remove) const item = await waitUntilShowUp(menus.token.send)
assert.notEqual(item, false, 'item isn\'t displayed') await item.click()
assert.equal(await item.getText(), menus.token.removeText, 'incorrect name') })
it('field \'Amount\' is displayed and has correct placeholder ', async function () {
const item = await waitUntilShowUp(screens.sendTokens.field.amount)
assert.equal(await item.getAttribute('placeholder'), screens.sendTokens.field.amountPlaceholder, 'placeholder is incorrect')
})
it('field \'Address\' is displayed and has correct placeholder ', async function () {
const item = await waitUntilShowUp(screens.sendTokens.field.address)
assert.equal(await item.getAttribute('placeholder'), screens.sendTokens.field.addressPlaceholder, 'placeholder is incorrect')
})
it('token\'s balance is correct ', async function () {
const item = await waitUntilShowUp(screens.sendTokens.balance)
assert.equal(await item.getText(), '100', 'token\'s balance is incorrect')
})
it('token\'s symbol is correct ', async function () {
const item = await waitUntilShowUp(screens.sendTokens.symbol)
assert.equal(await item.getText(), 'TST', 'token\'s symbol is incorrect')
})
it('error message if invalid token\'s amount', async function () {
const button = await waitUntilShowUp(screens.sendTokens.button.next)
assert.equal(await button.getText(), 'Next', 'button \'Next\' has incorrect name')
await click(button)
const error = await waitUntilShowUp(screens.sendTokens.error)
assert.equal(await error.getText(), screens.sendTokens.errorText.invalidAmount, ' error message is incorrect')
})
it('error message if invalid address', async function () {
const amount = await waitUntilShowUp(screens.sendTokens.field.amount)
await amount.sendKeys('1')
const address = await waitUntilShowUp(screens.sendTokens.field.address)
await address.sendKeys(invalidAddress)
const button = await waitUntilShowUp(screens.sendTokens.button.next)
await click(button)
await click(button)
await delay(2000)
const error = await waitUntilShowUp(screens.sendTokens.error)
assert.equal(await error.getText(), screens.sendTokens.errorText.address, ' error message is incorrect')
})
it('error message if amount is large', async function () {
const amount = await waitUntilShowUp(screens.sendTokens.field.amount)
await amount.sendKeys(largeAmount)
const address = await waitUntilShowUp(screens.sendTokens.field.address)
await clearField(address)
await address.sendKeys(account2)
const button = await waitUntilShowUp(screens.sendTokens.button.next)
await click(button)
await click(button)
await delay(2000)
const error = await waitUntilShowUp(screens.sendTokens.error)
assert.equal(await error.getText(), screens.sendTokens.errorText.largeAmount, ' error message is incorrect')
})
it('error message if amount is invalid', async function () {
const amount = await waitUntilShowUp(screens.sendTokens.field.amount)
await clearField(amount)
await amount.sendKeys(invalidAmount)
const button = await waitUntilShowUp(screens.sendTokens.button.next)
await click(button)
await click(button)
await delay(2000)
const error = await waitUntilShowUp(screens.sendTokens.error)
assert.equal(await error.getText(), screens.sendTokens.errorText.invalidAmount, ' error message is incorrect')
})
it.skip('error message if amount is too precise', async function () {
const amount = await waitUntilShowUp(screens.sendTokens.field.amount)
await clearField(amount)
await amount.sendKeys(preciseAmount)
const button = await waitUntilShowUp(screens.sendTokens.button.next)
await click(button)
await click(button)
await delay(2000)
const error = await waitUntilShowUp(screens.sendTokens.error)
assert.equal(await error.getText(), screens.sendTokens.errorText.tooPrecise, ' error message is incorrect')
})
it('error message if amount is negative', async function () {
const amount = await waitUntilShowUp(screens.sendTokens.field.amount)
await clearField(amount)
await amount.sendKeys(negativeAmount)
const button = await waitUntilShowUp(screens.sendTokens.button.next)
await click(button)
await click(button)
await delay(2000)
const error = await waitUntilShowUp(screens.sendTokens.error)
assert.equal(await error.getText(), screens.sendTokens.errorText.negativeAmount, ' error message is incorrect')
})
it('\'Confirm transaction\' screen is opened if address and amount are correct', async function () {
const amount = await waitUntilShowUp(screens.sendTokens.field.amount)
await clearField(amount)
await amount.sendKeys('5')
const button = await waitUntilShowUp(screens.sendTokens.button.next)
await click(button)
const buttonSubmit = await waitUntilShowUp(screens.confirmTransaction.button.submit)
assert.notEqual(buttonSubmit, false, 'incorrect screen was opened')
})
it('\'Confirm transaction\' screen: token\'s amount is correct', async function () {
const amount = await waitUntilShowUp(screens.confirmTransaction.amount)
assert.equal(await amount.getText(), '5.000', ' amount is incorrect')
})
it('\'Confirm transaction\' screen: token\'s symbol is correct', async function () {
const symbol = await waitUntilShowUp(screens.confirmTransaction.symbol)
assert.equal(await symbol.getText(), 'TST', ' symbol is incorrect')
})
it('submit transaction', async function () {
await driver.navigate().refresh()
const button = await waitUntilShowUp(screens.confirmTransaction.button.submit)
await click(button)
const list = await waitUntilShowUp(screens.main.transactionList)
assert.notEqual(list, false, ' main screen isn\'t opened')
})
it('correct amount substracted from sender\'s tokens balance', async function () {
const tab = await waitUntilShowUp(screens.main.tokens.menu)
await tab.click()
await driver.navigate().refresh()
await delay(5000)
await driver.navigate().refresh()
await delay(5000)
await driver.navigate().refresh()
await delay(5000)
const balance = await waitUntilShowUp(screens.main.tokens.balance)
assert.equal(await balance.getText(), '95 TST', 'balance is incorrect')
})
it('switch to account 2 ', async function () {
const accountMenu = await waitUntilShowUp(menus.account.menu)
await accountMenu.click()
const item = await waitUntilShowUp(menus.account.account2)
await item.click()
await delay(2000)
const accountName = await waitUntilShowUp(screens.main.accountName)
assert.equal(await accountName.getText(), 'Account 2', 'account name incorrect')
})
it('receiver got correct amount of tokens', async function () {
const balance = await waitUntilShowUp(screens.main.tokens.balance)
assert.equal(await balance.getText(), '5 TST', 'balance is incorrect')
}) })
}) })
describe('Remove token , provider is localhost', function () { describe('Remove token , provider is localhost', function () {
it('remove option opens \'Remove token\' screen ', async function () { it('remove option opens \'Remove token\' screen ', async function () {