From 6e11da657558ad6ee9a3ea45b106f61a249a015e Mon Sep 17 00:00:00 2001 From: andreiklimenok Date: Wed, 10 Oct 2018 14:52:14 +0200 Subject: [PATCH] :white_check_mark: tests for transfer --- src/components/spinner/index.js | 2 +- src/components/timestamp/index.js | 2 +- src/components/transactions/transactionRow.js | 4 +- .../transactions/transactionType.js | 2 +- test/constants/urls.js | 8 + .../e2e/ex-protractor-cucumber/send.spec.js | 45 ----- test/cypress/e2e/login.spec.js | 2 +- test/cypress/e2e/registration.spec.js | 2 +- test/cypress/e2e/transfer.spec.js | 185 ++++++++++++++++++ test/cypress/{e2e => }/utils/chooseNetwork.js | 2 +- 10 files changed, 201 insertions(+), 53 deletions(-) create mode 100644 test/constants/urls.js create mode 100644 test/cypress/e2e/transfer.spec.js rename test/cypress/{e2e => }/utils/chooseNetwork.js (93%) diff --git a/src/components/spinner/index.js b/src/components/spinner/index.js index a1f0b990db9..312e515bf0c 100644 --- a/src/components/spinner/index.js +++ b/src/components/spinner/index.js @@ -2,7 +2,7 @@ import React from 'react'; import styles from './spinner.css'; const Spinner = () => ( - +
diff --git a/src/components/timestamp/index.js b/src/components/timestamp/index.js index 509e2559d53..6c94de65327 100644 --- a/src/components/timestamp/index.js +++ b/src/components/timestamp/index.js @@ -53,7 +53,7 @@ export const Time = translate()((props) => { export const DateFromTimestamp = translate()((props) => { moment.locale(i18n.language); const day = moment(_convertTimeFromFirstBlock(props.time)); - return ({day.format('ll')}); + return ({day.format('ll')}); }); export const TimeFromTimestamp = translate()((props) => { diff --git a/src/components/transactions/transactionRow.js b/src/components/transactions/transactionRow.js index 8d47361fb2b..f433cf86c4f 100644 --- a/src/components/transactions/transactionRow.js +++ b/src/components/transactions/transactionRow.js @@ -20,12 +20,12 @@ class TransactionRow extends React.Component { return (
-
+
-
+
{props.value.asset && props.value.asset.data ? {props.value.asset.data} : '-'} diff --git a/src/components/transactions/transactionType.js b/src/components/transactions/transactionType.js index 3d71184c40f..f45a24870cf 100644 --- a/src/components/transactions/transactionType.js +++ b/src/components/transactions/transactionType.js @@ -37,7 +37,7 @@ const TransactionType = (props) => { const address = props.address !== props.senderId ? props.senderId : props.recipientId; const template = type || props.showTransaction ? {type || t('Transaction')} : - {address}; + {address}; return template; }; diff --git a/test/constants/urls.js b/test/constants/urls.js new file mode 100644 index 00000000000..d621eb77cb1 --- /dev/null +++ b/test/constants/urls.js @@ -0,0 +1,8 @@ +const urls = { + dashboard: '/dashboard', + wallet: '/wallet', + help: '/help', + settings: '/settings', +}; + +export default urls; diff --git a/test/cypress/e2e/ex-protractor-cucumber/send.spec.js b/test/cypress/e2e/ex-protractor-cucumber/send.spec.js index e9da5582622..13b66ef80f1 100644 --- a/test/cypress/e2e/ex-protractor-cucumber/send.spec.js +++ b/test/cypress/e2e/ex-protractor-cucumber/send.spec.js @@ -1,17 +1,6 @@ import accounts from '../../../constants/accounts'; describe('Send dialog', () => { - it('should allow to send when enough funds and correct address form', () => { - cy.loginUI(accounts.genesis, 'test'); - cy.visit('/wallet'); - cy.get('.amount input').click().type('1'); - cy.get('.convertor').get('.converted-price').contains(/^\d{1,100}(\.\d{1,2})? USD$/); - cy.get('.recipient input').click().type('23495548317450503L'); - cy.get('.send-next-button').click(); - cy.get('.send-button').click(); - cy.get('.result-box-message').should('have.text', 'Transaction is being processed and will be confirmed. It may take up to 15 minutes to be secured in the blockchain.'); - }); - it('should be correct number of transactions in a table', () => { cy.loginUI(accounts.genesis, 'dev'); cy.get('.transactions-row').should('have.length', 5); @@ -20,38 +9,4 @@ describe('Send dialog', () => { cy.get('.transaction-results').scrollTo('bottom'); cy.get('.transactions-row').should('have.length', 50); }); - - it('should allow to send when using launch protocol', () => { - cy.loginUI(accounts.genesis, 'dev'); - cy.visit('/wallet?recipient=4995063339468361088L&amount=5'); - cy.get('.recipient input').should('have.value', '4995063339468361088L'); - cy.get('.amount input').should('have.value', '5'); - cy.get('.send-next-button').click(); - cy.get('.send-button').click(); - cy.get('.result-box-message').should('have.text', 'Transaction is being processed and will be confirmed. It may take up to 15 minutes to be secured in the blockchain.'); - }); - - it('should be able to init account if needed', () => { - cy.loginUI(accounts.genesis, 'dev'); - cy.visit('wallet'); - cy.get('.amount input').click().type('1'); - cy.get('.convertor').get('.converted-price').contains(/^\d{1,100}(\.\d{1,2})? USD$/); - cy.get('.recipient input').click().type('94495548317450502L'); - cy.get('.send-next-button').click(); - cy.get('.send-button').click(); - cy.wait(15000); - cy.reload(); - cy.loginUI(accounts['without initialization'], 'dev'); - cy.visit('wallet'); - cy.get('.account-initialization').get('.account-init-button').click(); - cy.get('.send-button').click(); - cy.get('.result-box-message').should('have.text', 'Transaction is being processed and will be confirmed. It may take up to 15 minutes to be secured in the blockchain.'); - cy.get('.okay-button').click(); - cy.get('.account-initialization').should('have.length', 0); - cy.wait(15000); - cy.visit('dashboard'); - cy.visit('wallet'); - cy.get('.account-initialization').should('have.length', 0); - cy.get('.transactions-row').should('have.length', 2); - }); }); diff --git a/test/cypress/e2e/login.spec.js b/test/cypress/e2e/login.spec.js index a6c86a55fd5..b0469c7ac94 100644 --- a/test/cypress/e2e/login.spec.js +++ b/test/cypress/e2e/login.spec.js @@ -2,7 +2,7 @@ import numeral from 'numeral'; import { fromRawLsk } from '../../../src/utils/lsk'; import accounts from '../../constants/accounts'; import networks from '../../constants/networks'; -import chooseNetwork from './utils/chooseNetwork'; +import chooseNetwork from '../utils/chooseNetwork'; const ss = { newAccountBtn: '.new-account-button', diff --git a/test/cypress/e2e/registration.spec.js b/test/cypress/e2e/registration.spec.js index b0d3ddb9ab4..1dcea0f00c4 100644 --- a/test/cypress/e2e/registration.spec.js +++ b/test/cypress/e2e/registration.spec.js @@ -1,5 +1,5 @@ import networks from '../../constants/networks'; -import chooseNetwork from './utils/chooseNetwork'; +import chooseNetwork from '../utils/chooseNetwork'; const ss = { networkStatus: '.network-status', diff --git a/test/cypress/e2e/transfer.spec.js b/test/cypress/e2e/transfer.spec.js new file mode 100644 index 00000000000..4ed215e8050 --- /dev/null +++ b/test/cypress/e2e/transfer.spec.js @@ -0,0 +1,185 @@ +import accounts from '../../constants/accounts'; +import networks from '../../constants/networks'; +import urls from '../../constants/urls'; + +const ss = { + sidebarMenuWalletBtn: '#transactions', + recipientInput: '.recipient input', + amountInput: '.amount input', + referenceInput: '.reference input', + convertorElement: '.convertor', + convertedPrice: '.converted-price', + nextButton: '.send-next-button', + sendButton: '.send-button', + secondPassphraseInput: '.second-passphrase input', + secondPassphraseNextBtn: '.second-passphrase-next', + resultMessage: '.result-box-message', + okayBtn: '.okay-button', + transactoinsTable: '.transaction-results', + transactionRow: '.transaactions-row', + accountInitializationMsg: '.account-initialization', + accountInitializationBtn: '.account-init-button', + spinner: '.spinner', + transactionAddress: '.transaction-address span', + transactionReference: '.transaction-reference', + transactionAmount: '#transactionAmount span', + headerBalance: '.balance span', +}; + +const msg = { + transferTxSuccess: 'Transaction is being processed and will be confirmed. It may take up to 15 minutes to be secured in the blockchain.', + accountInitializatoinAddress: 'Account initialization', +}; + +const txConfirmationTimeout = 11000; + +const checkWalletPageLoaded = () => cy.get(ss.recipientInput); + +const getRandomAddress = () => `23495548666${Math.floor((Math.random() * 899000) + 100000)}L`; +const getRandomAmount = () => Math.floor((Math.random() * 100) + 1); +const getRandomReference = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); + +const castBalanceStringToNumber = number => parseFloat(number.replace(/,/g, '')); + +describe('Wallet', () => { + let randomAddress; + let randomAmount; + let randomReference; + const transactionFee = 0.1; + + beforeEach(() => { + randomAddress = getRandomAddress(); + randomAmount = getRandomAmount(); + randomReference = getRandomReference(); + }); + + it(`Opens by url ${urls.wallet}`, () => { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit(urls.wallet); + cy.url().should('contain', 'wallet'); + checkWalletPageLoaded(); + }); + + it('Opens by sidebar button', () => { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit('/dashboard'); + cy.get(ss.sidebarMenuWalletBtn).click(); + cy.url().should('contain', 'wallet'); + checkWalletPageLoaded(); + }); + + it('Transfer tx with empty ref appears in activity pending -> approved,' + + 'Header balance is affected', function () { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit(urls.wallet); + cy.get(ss.headerBalance).invoke('text').as('balanceBeforeString'); + cy.get(ss.recipientInput).type(randomAddress); + cy.get(ss.amountInput).click().type(randomAmount); + cy.get(ss.nextButton).click(); + cy.get(ss.sendButton).click(); + cy.get(ss.resultMessage).should('have.text', msg.transferTxSuccess); + cy.get(ss.transactionRow).eq(0).as('tx'); + cy.get('@tx').find('.spinner'); + cy.get('@tx').find(ss.transactionAddress).should('have.text', randomAddress); + cy.get('@tx').find(ss.transactionReference).should('have.text', '-'); + cy.get('@tx').find(ss.transactionAmount).should('have.text', randomAmount.toString()); + cy.wait(txConfirmationTimeout); + cy.get('@tx').find(ss.spinner).should('not.exist'); + cy.get(ss.headerBalance).should((headerBalance) => { + const balanceAfter = castBalanceStringToNumber(headerBalance.text()); + const balanceBefore = castBalanceStringToNumber(this.balanceBeforeString); + expect(balanceAfter) + .to.be.equal(parseFloat((balanceBefore - (randomAmount + transactionFee)).toFixed(6))); + }); + }); + + it('Transfer tx with ref appears in dashboard activity pending -> approved', () => { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit(urls.wallet); + cy.get(ss.recipientInput).type(randomAddress); + cy.get(ss.referenceInput).click().type(randomReference); + cy.get(ss.amountInput).click().type(randomAmount); + cy.get(ss.nextButton).click(); + cy.get(ss.sendButton).click(); + cy.get(ss.resultMessage).should('have.text', msg.transferTxSuccess); + cy.visit(urls.dashboard); + cy.get(ss.transactionRow).eq(0).as('tx'); + cy.get('@tx').find(ss.spinner); + cy.get('@tx').find(ss.transactionAddress).should('have.text', randomAddress); + cy.get('@tx').find(ss.transactionReference).should('have.text', randomReference); + cy.get('@tx').find(ss.transactionAmount).should('have.text', randomAmount.toString()); + cy.wait(txConfirmationTimeout); + cy.get('@tx').find(ss.spinner).should('not.exist'); + }); + + it('Transfer tx with second passphrase', () => { + cy.autologin(accounts['second passphrase account'].passphrase, networks.devnet.node); + cy.visit(urls.wallet); + cy.get(ss.recipientInput).type(randomAddress); + cy.get(ss.referenceInput).click().type(randomReference); + cy.get(ss.amountInput).click().type(randomAmount); + cy.get(ss.nextButton).click(); + cy.get(ss.secondPassphraseInput).each(($el, index) => { + const passphraseWordsArray = accounts['second passphrase account'].secondPassphrase.split(' '); + cy.wrap($el).type(passphraseWordsArray[index]); + }); + cy.get(ss.secondPassphraseNextBtn).click(); + cy.get(ss.sendButton).click(); + cy.get(ss.resultMessage).should('have.text', msg.transferTxSuccess); + cy.get(ss.transactionRow).eq(0).as('tx'); + cy.get('@tx').find('.spinner'); + cy.get('@tx').find(ss.transactionAddress).should('have.text', randomAddress); + }); + + it('Transfer to myself appears as account initialization', () => { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit(urls.wallet); + cy.get(ss.recipientInput).type(accounts.genesis.address); + cy.get(ss.amountInput).click().type(randomAmount); + cy.get(ss.nextButton).click(); + cy.get(ss.sendButton).click(); + cy.get(ss.transactionRow).eq(0).find(ss.transactionAddress).should('have.text', msg.accountInitializatoinAddress); + }); + + it('Launch protocol link prefills recipient, amount and reference', () => { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit('/wallet?recipient=4995063339468361088L&amount=5&reference=test'); + cy.get(ss.recipientInput).should('have.value', '4995063339468361088L'); + cy.get(ss.amountInput).should('have.value', '5'); + cy.get(ss.referenceInput).should('have.value', 'test'); + }); + + it('Fiat converter shows amount in USD', () => { + cy.addLocalStorage('settings', 'currency', 'USD'); + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit('/wallet?recipient=4995063339468361088L&amount=5'); + cy.get(ss.convertedPrice).contains(/^\d{1,100}(\.\d{1,2})? USD$/); + }); + + it('Fiat converter shows amount in EUR', () => { + cy.addLocalStorage('settings', 'currency', 'EUR'); + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit('/wallet?recipient=4995063339468361088L&amount=5'); + cy.get(ss.convertedPrice).contains(/^\d{1,100}(\.\d{1,2})? EUR$/); + }); + + it('Should be able to init account when needed', () => { + cy.autologin(accounts.genesis.passphrase, networks.devnet.node); + cy.visit(urls.wallet); + cy.get(ss.recipientInput).type(accounts['without initialization'].address); + cy.get(ss.amountInput).click().type(randomAmount); + cy.get(ss.nextButton).click(); + cy.get(ss.sendButton).click(); + cy.wait(txConfirmationTimeout); + cy.autologin(accounts['without initialization'].passphrase, networks.devnet.node); + cy.reload(); + cy.visit(urls.wallet); + cy.get(ss.accountInitializationMsg).get(ss.accountInitializationBtn).click(); + cy.get(ss.sendButton).click(); + cy.get(ss.resultMessage).should('have.text', msg.transferTxSuccess); + cy.get(ss.accountInitializationMsg).should('not.exist'); + cy.wait(txConfirmationTimeout); + cy.reload(); + cy.get(ss.accountInitializationMsg).should('not.exist'); + }); +}); diff --git a/test/cypress/e2e/utils/chooseNetwork.js b/test/cypress/utils/chooseNetwork.js similarity index 93% rename from test/cypress/e2e/utils/chooseNetwork.js rename to test/cypress/utils/chooseNetwork.js index 5da6a7f227f..2c8558c693e 100644 --- a/test/cypress/e2e/utils/chooseNetwork.js +++ b/test/cypress/utils/chooseNetwork.js @@ -1,4 +1,4 @@ -import networks from '../../../constants/networks'; +import networks from '../../constants/networks'; const ss = { networkDropdown: '.network',