From 4849b31f7a7e7fa3a989b56ecdd00dc5540ce7eb Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Thu, 22 Feb 2018 16:43:31 +0100 Subject: [PATCH 01/14] Create an integration file for voting component --- test/integration/voting.test.js | 147 ++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 test/integration/voting.test.js diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js new file mode 100644 index 0000000000..2546a71806 --- /dev/null +++ b/test/integration/voting.test.js @@ -0,0 +1,147 @@ +import { step } from 'mocha-steps'; +import { expect } from 'chai'; +import { mount } from 'enzyme'; +import sinon from 'sinon'; +// import thunk from 'redux-thunk'; +import { prepareStore, renderWithRouter } from '../utils/applicationInit'; +import middleware from '../../src/store/middlewares'; +import accounts from '../constants/accounts'; +import actionTypes from '../../src/constants/actions'; +import accountReducer from '../../src/store/reducers/account'; +import votingReducer from '../../src/store/reducers/voting'; +import peersReducer from '../../src/store/reducers/peers'; +import { accountLoggedIn } from '../../src/actions/account'; +import * as delegateApi from '../../src/utils/api/delegate'; +import Voting from '../../src/components/voting'; + +const delegates = [ + { + address: '10839494368003872009L', + approval: 32.82, + missedblocks: 658, + producedblocks: 37236, + productivity: 98.26, + publicKey: 'b002f58531c074c7190714523eec08c48db8c7cfc0c943097db1a2e82ed87f84', + rank: 1, + rate: 1, + username: 'thepool', + vote: '3883699551759500', + }, + { + address: '14593474056247442712L', + approval: 32.08, + missedblocks: 283, + producedblocks: 38035, + productivity: 99.26, + publicKey: 'ec111c8ad482445cfe83d811a7edd1f1d2765079c99d7d958cca1354740b7614', + rank: 2, + rate: 2, + username: 'liskpool_com_01', + vote: '3796476912180144', + }, + { + address: '13943256167405531820L', + approval: 32.03, + missedblocks: 164, + producedblocks: 38088, + productivity: 99.57, + publicKey: '00de7d28ec3f55f42329667f08352d0d90faa3d2d4e62c883d86d1d7b083dd7c', + rank: 3, + rate: 3, + username: 'iii.element.iii', + vote: '3789594637157356', + }, +]; + +const realAccount = { + ...accounts.genesis, + delegate: {}, + multisignatures: [], + u_multisignatures: [], + unconfirmedBalance: '0', +}; + +const peers = { + defaultPeers: [ + 'node01.lisk.io', + 'node02.lisk.io', + ], + defaultSSLPeers: [ + 'node01.lisk.io', + 'node02.lisk.io', + ], + defaultTestnetPeers: [ + 'testnet.lisk.io', + ], + options: { + name: 'Testnet', + testnet: true, + ssl: true, + port: 443, + code: 1, + }, + ssl: true, + randomPeer: true, + testnet: true, + bannedPeers: [], + currentPeer: 'testnet.lisk.io', + port: 443, + nethash: { + 'Content-Type': 'application/json', + nethash: 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + broadhash: 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + os: 'lisk-js-api', + version: '1.0.0', + minVersion: '>=0.5.0', + port: 443, + }, +}; + +describe('@integration test of Voting', () => { + let store; + let wrapper; + let clock; + + + let listDelegatesApiStub; + let listAccountDelegatesStub; + + beforeEach(() => { + listDelegatesApiStub = sinon.stub(delegateApi, 'listDelegates'); + listAccountDelegatesStub = sinon.stub(delegateApi, 'listAccountDelegates'); + clock = sinon.useFakeTimers({ + toFake: ['setTimeout', 'clearTimeout', 'Date'], + }); + }); + afterEach(() => { + listDelegatesApiStub.restore(); + listAccountDelegatesStub.restore(); + clock.restore(); + }); + step('Given user is login in', () => { + store = prepareStore({ + account: accountReducer, + voting: votingReducer, + peers: peersReducer, + }, middleware); + + store.dispatch(accountLoggedIn(realAccount)); + store.dispatch({ + data: peers, + type: actionTypes.activePeerSet, + }); + listDelegatesApiStub.returnsPromise() + .resolves({ delegates, success: true, totalCount: 20 }); + listAccountDelegatesStub.returnsPromise() + .resolves({ delegates: [delegates[0]], success: true }); + + wrapper = mount(renderWithRouter(Voting, store)); + expect(store.getState().account).to.be.an('Object'); + expect(store.getState().voting).to.be.an('Object'); + expect(store.getState().peers).to.be.an('Object'); + }); + + step('When user doesn\'t vote to any delegates next button should be disabled', () => { + expect(wrapper.find('button.next').props().disabled).to.be.equal(true); + }); +}); From 383758fa7bd1805fc55bcdec88a3ce843b4b53f2 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Fri, 23 Feb 2018 17:42:19 +0100 Subject: [PATCH 02/14] Add result-box-header class to resultBox header --- src/components/resultBox/resultBox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/resultBox/resultBox.js b/src/components/resultBox/resultBox.js index 2b3b376d34..a19897b90e 100644 --- a/src/components/resultBox/resultBox.js +++ b/src/components/resultBox/resultBox.js @@ -25,7 +25,7 @@ class ResultBox extends React.Component { : } -

{this.props.title}

+

{this.props.title}

From 542c5072ce9273303b7ad5e349ec9781620f5a07 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Fri, 23 Feb 2018 17:50:06 +0100 Subject: [PATCH 03/14] Add more scenarios to voting integration --- test/integration/voting.test.js | 222 +++++++++++++++++++++----------- 1 file changed, 146 insertions(+), 76 deletions(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index 2546a71806..460df686cb 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -1,18 +1,26 @@ import { step } from 'mocha-steps'; +import thunk from 'redux-thunk'; import { expect } from 'chai'; import { mount } from 'enzyme'; -import sinon from 'sinon'; +import { stub, match } from 'sinon'; // import thunk from 'redux-thunk'; import { prepareStore, renderWithRouter } from '../utils/applicationInit'; -import middleware from '../../src/store/middlewares'; import accounts from '../constants/accounts'; -import actionTypes from '../../src/constants/actions'; +import transactionReducer from '../../src/store/reducers/transactions'; import accountReducer from '../../src/store/reducers/account'; import votingReducer from '../../src/store/reducers/voting'; -import peersReducer from '../../src/store/reducers/peers'; import { accountLoggedIn } from '../../src/actions/account'; import * as delegateApi from '../../src/utils/api/delegate'; +import * as accountAPI from '../../src/utils/api/account'; import Voting from '../../src/components/voting'; +import peersReducer from '../../src/store/reducers/peers'; +import loginMiddleware from '../../src/store/middlewares/login'; +import accountMiddleware from '../../src/store/middlewares/account'; +import peerMiddleware from '../../src/store/middlewares/peers'; +import transactionsMiddleware from '../../src/store/middlewares/transactions'; +import { activePeerSet } from '../../src/actions/peers'; +import networks from './../../src/constants/networks'; +import getNetwork from './../../src/utils/getNetwork'; const delegates = [ { @@ -53,7 +61,7 @@ const delegates = [ }, ]; -const realAccount = { +const account = { ...accounts.genesis, delegate: {}, multisignatures: [], @@ -61,87 +69,149 @@ const realAccount = { unconfirmedBalance: '0', }; -const peers = { - defaultPeers: [ - 'node01.lisk.io', - 'node02.lisk.io', - ], - defaultSSLPeers: [ - 'node01.lisk.io', - 'node02.lisk.io', - ], - defaultTestnetPeers: [ - 'testnet.lisk.io', - ], - options: { - name: 'Testnet', - testnet: true, - ssl: true, - port: 443, - code: 1, - }, - ssl: true, - randomPeer: true, - testnet: true, - bannedPeers: [], - currentPeer: 'testnet.lisk.io', - port: 443, - nethash: { - 'Content-Type': 'application/json', - nethash: 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', - broadhash: 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', - os: 'lisk-js-api', - version: '1.0.0', - minVersion: '>=0.5.0', - port: 443, - }, +let store; +let wrapper; +let listDelegatesApiStub; +let listAccountDelegatesStub; +let voteApiStub; +let accountAPIStub; +let localStorageStub; + +const loginProcess = (votes = []) => { + accountAPIStub = stub(accountAPI, 'getAccount'); + localStorageStub = stub(localStorage, 'getItem'); + localStorageStub.withArgs('accounts').returns(JSON.stringify([{}, {}])); + listDelegatesApiStub = stub(delegateApi, 'listDelegates'); + listAccountDelegatesStub = stub(delegateApi, 'listAccountDelegates'); + voteApiStub = stub(delegateApi, 'vote'); + store = prepareStore({ + account: accountReducer, + peers: peersReducer, + voting: votingReducer, + transactions: transactionReducer, + }, [ + thunk, + accountMiddleware, + loginMiddleware, + transactionsMiddleware, + peerMiddleware, + ]); + + accountAPIStub.withArgs(match.any).returnsPromise().resolves({ ...account }); + store.dispatch(activePeerSet({ network: getNetwork(networks.mainnet.code) })); + accountAPIStub.withArgs(match.any).returnsPromise().resolves({ ...account }); + store.dispatch(accountLoggedIn(account)); + + listDelegatesApiStub.returnsPromise() + .resolves({ delegates, success: true, totalCount: 20 }); + listAccountDelegatesStub.returnsPromise() + .resolves({ delegates: votes, success: true }); + + wrapper = mount(renderWithRouter(Voting, store)); + expect(store.getState().account).to.be.an('Object'); + expect(store.getState().voting).to.be.an('Object'); + expect(store.getState().peers).to.be.an('Object'); +}; + +const restoreApiMocks = () => { + listDelegatesApiStub.restore(); + listAccountDelegatesStub.restore(); + voteApiStub.restore(); + accountAPIStub.restore(); + localStorageStub.restore(); }; describe('@integration test of Voting', () => { - let store; - let wrapper; - let clock; + describe('Scenario: should allow to select delegates in the "Voting" and vote for them', () => { + step('I\'m logged in as "genesis"', () => { loginProcess(); }); + + step('And next button should be disabled', () => { + expect(wrapper.find('button.next').props().disabled).to.be.equal(true); + }); + step('When I vote to delegates and next button should be enabled', () => { + wrapper.find('.delegate-list input').at(0).simulate('change', { target: { value: 'true' } }); + wrapper.find('.delegate-list input').at(1).simulate('change', { target: { value: 'true' } }); + const selectionHeader = wrapper.find('.selection h4').text(); + expect(selectionHeader).to.be.equal('2'); + expect(wrapper.find('button.next').props().disabled).to.be.equal(false); + }); - let listDelegatesApiStub; - let listAccountDelegatesStub; + step('Then I must be able to go to next step', () => { + expect(wrapper.find('button.confirm').exists()).to.be.equal(false); + wrapper.find('button.next').simulate('click'); + expect(wrapper.find('button.confirm').exists()).to.be.equal(true); + }); - beforeEach(() => { - listDelegatesApiStub = sinon.stub(delegateApi, 'listDelegates'); - listAccountDelegatesStub = sinon.stub(delegateApi, 'listAccountDelegates'); - clock = sinon.useFakeTimers({ - toFake: ['setTimeout', 'clearTimeout', 'Date'], + step('Then I confirm my votes', () => { + const expectedValue = 'Votes submitted'; + voteApiStub.returnsPromise() + .resolves({ + transactionId: 12341234123432412, + account, + }); + wrapper.find('button.confirm').simulate('click'); + expect(wrapper.find('h2.result-box-header').text()).to.be.equal(expectedValue); + expect(wrapper.find('p.result-box-message').exists()).to.be.equal(true); + restoreApiMocks(); }); }); - afterEach(() => { - listDelegatesApiStub.restore(); - listAccountDelegatesStub.restore(); - clock.restore(); - }); - step('Given user is login in', () => { - store = prepareStore({ - account: accountReducer, - voting: votingReducer, - peers: peersReducer, - }, middleware); - - store.dispatch(accountLoggedIn(realAccount)); - store.dispatch({ - data: peers, - type: actionTypes.activePeerSet, + + describe('Scenario: should allow me to filter my votes', () => { + step('I\'m logged in as "genesis"', () => { loginProcess([delegates[0]]); }); + + step('And I should see 3 rows', () => { + expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(3); + }); + + step('When I click filter-voted I should see 1 rows', () => { + wrapper.find('li.filter-voted').simulate('click'); + expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(1); + }); + + step('When I click filter-not-voted I should see 2 rows', () => { + wrapper.find('li.filter-not-voted').simulate('click'); + expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(2); + }); + + step('When I click filter-all I should see all votes again', () => { + wrapper.find('li.filter-all').simulate('click'); + expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(3); + restoreApiMocks(); }); - listDelegatesApiStub.returnsPromise() - .resolves({ delegates, success: true, totalCount: 20 }); - listAccountDelegatesStub.returnsPromise() - .resolves({ delegates: [delegates[0]], success: true }); - - wrapper = mount(renderWithRouter(Voting, store)); - expect(store.getState().account).to.be.an('Object'); - expect(store.getState().voting).to.be.an('Object'); - expect(store.getState().peers).to.be.an('Object'); }); - step('When user doesn\'t vote to any delegates next button should be disabled', () => { - expect(wrapper.find('button.next').props().disabled).to.be.equal(true); + describe('Scenario: should allow to select delegates in the "Voting" and unvote them', () => { + step('I\'m logged in as "genesis"', () => { loginProcess([delegates[0]]); }); + + step('And next button should be disabled', () => { + expect(wrapper.find('button.next').props().disabled).to.be.equal(true); + }); + + step('When I remove my vote my delegates and next button should be enabled', () => { + wrapper.find('.delegate-list input').at(0).simulate('change', { target: { value: 'false' } }); + const selectionHeader = wrapper.find('.selection h4').text(); + expect(selectionHeader).to.be.equal('1'); + expect(wrapper.find('button.next').props().disabled).to.be.equal(false); + }); + + step('Then I must be able to go to next step', () => { + expect(wrapper.find('button.confirm').exists()).to.be.equal(false); + wrapper.find('button.next').simulate('click'); + expect(wrapper.find('button.confirm').exists()).to.be.equal(true); + }); + + step('Then I confirm my votes', () => { + const expectedValue = 'Votes submitted'; + voteApiStub.returnsPromise() + .resolves({ + transactionId: 12341234123432412, + account, + }); + wrapper.find('button.confirm').simulate('click'); + expect(wrapper.find('h2.result-box-header').text()).to.be.equal(expectedValue); + expect(wrapper.find('p.result-box-message').exists()).to.be.equal(true); + restoreApiMocks(); + }); }); }); From 6bba03d7bffbad2d2fed5e98933d4d996d18f17c Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Fri, 23 Feb 2018 17:51:58 +0100 Subject: [PATCH 04/14] Remove a pending scenario in voting e2e test --- test/e2e/voting.feature | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/e2e/voting.feature b/test/e2e/voting.feature index e9546dba99..be0c9d63c8 100644 --- a/test/e2e/voting.feature +++ b/test/e2e/voting.feature @@ -85,16 +85,6 @@ Feature: Voting page standby_2[789] """ - @integration - @pending - Scenario: should allow to select delegates in the "Vote" dialog and vote for them - Given I'm logged in as "delegate candidate" - When I click "voting" menu - And I click "vote button" - And Search twice for "genesis_7" in vote dialog - And I click "submit button" - Then I should see alert dialog with title "Success" and text "Your votes were successfully submitted. It can take several seconds before they are processed." - @integration @pending Scenario: should not allow to vote if not enough funds for the fee From 55b98c86e34a6102d9a617a8278830c82f7efd08 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Fri, 23 Feb 2018 17:54:20 +0100 Subject: [PATCH 05/14] Remove voteDialog integration test --- test/integration/voteDialog.test.js | 140 ---------------------------- 1 file changed, 140 deletions(-) delete mode 100644 test/integration/voteDialog.test.js diff --git a/test/integration/voteDialog.test.js b/test/integration/voteDialog.test.js deleted file mode 100644 index af3c3571f0..0000000000 --- a/test/integration/voteDialog.test.js +++ /dev/null @@ -1,140 +0,0 @@ -import { step } from 'mocha-steps'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import sinon from 'sinon'; -import { prepareStore, renderWithRouter } from '../utils/applicationInit'; -import accounts from '../constants/accounts'; -import actionTypes from '../../src/constants/actions'; -import accountReducer from '../../src/store/reducers/account'; -import votingReducer from '../../src/store/reducers/voting'; -import peersReducer from '../../src/store/reducers/peers'; -import { accountLoggedIn } from '../../src/actions/account'; -import { delegatesAdded } from '../../src/actions/voting'; -import * as delegateApi from '../../src/utils/api/delegate'; -import VoteDialog from '../../src/components/voteDialog'; - -const delegates = [ - { username: 'username1', publicKey: '123HG3452245L' }, - { username: 'username2', publicKey: '123HG3522345L' }, -]; -const unvotedDelegate = [ - { username: 'username3', publicKey: '123HG3522445L' }, - { username: 'username4', publicKey: '123HG3522545L' }, -]; - -const keyCodes = { - arrowDown: 40, - arrowUp: 38, - enter: 13, - escape: 27, -}; - -const realAccount = { - ...accounts.genesis, - delegate: {}, - multisignatures: [], - u_multisignatures: [], - unconfirmedBalance: '0', -}; - -const peers = { - defaultPeers: [ - 'node01.lisk.io', - 'node02.lisk.io', - ], - defaultSSLPeers: [ - 'node01.lisk.io', - 'node02.lisk.io', - ], - defaultTestnetPeers: [ - 'testnet.lisk.io', - ], - options: { - name: 'Testnet', - testnet: true, - ssl: true, - port: 443, - code: 1, - }, - ssl: true, - randomPeer: true, - testnet: true, - bannedPeers: [], - currentPeer: 'testnet.lisk.io', - port: 443, - nethash: { - 'Content-Type': 'application/json', - nethash: 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', - broadhash: 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', - os: 'lisk-js-api', - version: '1.0.0', - minVersion: '>=0.5.0', - port: 443, - }, -}; - -describe('@integration test of VoteDialog', () => { - let store; - let wrapper; - let clock; - - beforeEach(() => { - clock = sinon.useFakeTimers({ - toFake: ['setTimeout', 'clearTimeout', 'Date'], - }); - }); - afterEach(() => { - clock.restore(); - }); - - step('Given user is login in', () => { - store = prepareStore({ - account: accountReducer, - voting: votingReducer, - peers: peersReducer, - }); - - store.dispatch(accountLoggedIn(realAccount)); - store.dispatch({ - data: peers, - type: actionTypes.activePeerSet, - }); - wrapper = mount(renderWithRouter(VoteDialog, store)); - expect(store.getState().account).to.be.an('Object'); - expect(store.getState().voting).to.be.an('Object'); - expect(store.getState().peers).to.be.an('Object'); - }); - - step('When user doesn\'t vote to any delegates confirm button should be disabled', () => { - expect(wrapper.find('.primary-button button').props().disabled).to.be.equal(true); - }); - - step('Then user add an item to voteList and confirm button should become enabled', () => { - store.dispatch(delegatesAdded({ - list: delegates, - totalDelegates: 100, - refresh: true, - })); - expect(store.getState().voting.refresh).to.be.equal(true); - wrapper.update(); - const voteAutocompleteApiStub = sinon.stub(delegateApi, 'voteAutocomplete'); - voteAutocompleteApiStub.returnsPromise().resolves(unvotedDelegate); - // write a username - wrapper.find('.votedListSearch.vote-auto-complete input').simulate('change', { target: { value: 'user' } }); - clock.tick(400); - - // select it with arrow down - wrapper.find('.votedListSearch.vote-auto-complete input').simulate('keyDown', { keyCode: keyCodes.arrowDown }); - clock.tick(400); - wrapper.find('.votedListSearch.vote-auto-complete input').simulate('keyDown', { keyCode: keyCodes.enter }); - wrapper.update(); - expect(wrapper.find('.primary-button button').props().disabled).to.be.equal(false); - voteAutocompleteApiStub.restore(); - }); - - step('When user deletes all items form voteList confirm button should become disabled', () => { - wrapper.find('.vote-list span').last().simulate('click'); - wrapper.update(); - expect(wrapper.find('.primary-button button').props().disabled).to.be.equal(true); - }); -}); From c8476fbee4415495820b6dae33d53c58faace2cb Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Mon, 26 Feb 2018 13:53:54 +0100 Subject: [PATCH 06/14] Use chai-enzyme in voting integration tests --- test/integration/voting.test.js | 98 +++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index 460df686cb..15835a7f5d 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -113,6 +113,9 @@ const loginProcess = (votes = []) => { expect(store.getState().peers).to.be.an('Object'); }; +/** + * restore all Api mocks + */ const restoreApiMocks = () => { listDelegatesApiStub.restore(); listAccountDelegatesStub.restore(); @@ -121,38 +124,59 @@ const restoreApiMocks = () => { localStorageStub.restore(); }; +/** + * + * @param {string} index - index of the delegate in the list + * @param {boolean} value - new value of the input + */ +const voteToDelegates = (index, value) => { + wrapper.find('.delegate-list input').at(index) + .simulate('change', { target: { value } }); +}; + +const goToConfirmation = () => { + expect(wrapper.find('button.confirm')).to.be.not.present(); + wrapper.find('button.next').simulate('click'); + expect(wrapper.find('button.confirm')).to.be.present(); +}; + describe('@integration test of Voting', () => { describe('Scenario: should allow to select delegates in the "Voting" and vote for them', () => { step('I\'m logged in as "genesis"', () => { loginProcess(); }); step('And next button should be disabled', () => { - expect(wrapper.find('button.next').props().disabled).to.be.equal(true); + expect(wrapper.find('button.next')).to.have.prop('disabled', true); }); step('When I vote to delegates and next button should be enabled', () => { - wrapper.find('.delegate-list input').at(0).simulate('change', { target: { value: 'true' } }); - wrapper.find('.delegate-list input').at(1).simulate('change', { target: { value: 'true' } }); - const selectionHeader = wrapper.find('.selection h4').text(); - expect(selectionHeader).to.be.equal('2'); - expect(wrapper.find('button.next').props().disabled).to.be.equal(false); + voteToDelegates(0, true); + voteToDelegates(1, true); }); - step('Then I must be able to go to next step', () => { - expect(wrapper.find('button.confirm').exists()).to.be.equal(false); - wrapper.find('button.next').simulate('click'); - expect(wrapper.find('button.confirm').exists()).to.be.equal(true); + step('Then next button should be enabled', () => { + expect(wrapper.find('button.next')).to.have.prop('disabled', false); }); - step('Then I confirm my votes', () => { - const expectedValue = 'Votes submitted'; + step('And selectionHeader should be equal to "2"', () => { + const selectionHeader = wrapper.find('.selection h4'); + expect(selectionHeader).to.have.text('2'); + }); + + step('Then I go to confirmation step', () => { goToConfirmation(); }); + + step('When I click on confirm button', () => { voteApiStub.returnsPromise() .resolves({ transactionId: 12341234123432412, account, }); wrapper.find('button.confirm').simulate('click'); - expect(wrapper.find('h2.result-box-header').text()).to.be.equal(expectedValue); - expect(wrapper.find('p.result-box-message').exists()).to.be.equal(true); + }); + + step('Then I should see result box', () => { + const expectedValue = 'Votes submitted'; + expect(wrapper.find('h2.result-box-header')).to.have.text(expectedValue); + expect(wrapper.find('p.result-box-message')).to.be.present(); restoreApiMocks(); }); }); @@ -164,18 +188,27 @@ describe('@integration test of Voting', () => { expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(3); }); - step('When I click filter-voted I should see 1 rows', () => { + step('When I click filter-voted', () => { wrapper.find('li.filter-voted').simulate('click'); + }); + + step('Then I should see 1 rows', () => { expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(1); }); - step('When I click filter-not-voted I should see 2 rows', () => { + step('When I click filter-not-voted', () => { wrapper.find('li.filter-not-voted').simulate('click'); + }); + + step('Then I should see 2 rows', () => { expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(2); }); step('When I click filter-all I should see all votes again', () => { wrapper.find('li.filter-all').simulate('click'); + }); + + step('Then I should see all votes again', () => { expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(3); restoreApiMocks(); }); @@ -185,32 +218,37 @@ describe('@integration test of Voting', () => { step('I\'m logged in as "genesis"', () => { loginProcess([delegates[0]]); }); step('And next button should be disabled', () => { - expect(wrapper.find('button.next').props().disabled).to.be.equal(true); + expect(wrapper.find('button.next')).to.have.prop('disabled', true); }); - step('When I remove my vote my delegates and next button should be enabled', () => { - wrapper.find('.delegate-list input').at(0).simulate('change', { target: { value: 'false' } }); - const selectionHeader = wrapper.find('.selection h4').text(); - expect(selectionHeader).to.be.equal('1'); - expect(wrapper.find('button.next').props().disabled).to.be.equal(false); + step('When I remove my vote', () => { + voteToDelegates(0, 'false'); }); - step('Then I must be able to go to next step', () => { - expect(wrapper.find('button.confirm').exists()).to.be.equal(false); - wrapper.find('button.next').simulate('click'); - expect(wrapper.find('button.confirm').exists()).to.be.equal(true); + step('Then next button should be enabled', () => { + expect(wrapper.find('button.next')).to.have.prop('disabled', false); }); - step('Then I confirm my votes', () => { - const expectedValue = 'Votes submitted'; + step('And selectionHeader should be equal to "1"', () => { + const selectionHeader = wrapper.find('.selection h4'); + expect(selectionHeader).to.have.text('1'); + }); + + step('Then I go to confirmation step', () => { goToConfirmation(); }); + + step('When I click on confirm button', () => { voteApiStub.returnsPromise() .resolves({ transactionId: 12341234123432412, account, }); wrapper.find('button.confirm').simulate('click'); - expect(wrapper.find('h2.result-box-header').text()).to.be.equal(expectedValue); - expect(wrapper.find('p.result-box-message').exists()).to.be.equal(true); + }); + + step('Then I should see result box', () => { + const expectedValue = 'Votes submitted'; + expect(wrapper.find('h2.result-box-header')).to.have.text(expectedValue); + expect(wrapper.find('p.result-box-message')).to.be.present(); restoreApiMocks(); }); }); From 63300decd9fb730a3817716fbeb5916cccf20270 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Mon, 26 Feb 2018 13:55:12 +0100 Subject: [PATCH 07/14] Fix a bug in voting integration tests --- test/integration/voting.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index 15835a7f5d..0144ddbbea 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -222,7 +222,7 @@ describe('@integration test of Voting', () => { }); step('When I remove my vote', () => { - voteToDelegates(0, 'false'); + voteToDelegates(0, false); }); step('Then next button should be enabled', () => { From 8a994e2188c28bacfdb04208fce6f77724364b3c Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Mon, 26 Feb 2018 20:58:25 +0100 Subject: [PATCH 08/14] Create Utils class in mountHelper --- test/utils/mountHelpers.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/utils/mountHelpers.js b/test/utils/mountHelpers.js index 42ae4f555b..5c6e162e88 100644 --- a/test/utils/mountHelpers.js +++ b/test/utils/mountHelpers.js @@ -2,6 +2,7 @@ import { spy } from 'sinon'; import { mount } from 'enzyme'; import configureMockStore from 'redux-mock-store'; import PropTypes from 'prop-types'; +import { expect } from 'chai'; import i18n from '../../src/i18n'; @@ -33,3 +34,32 @@ export const mountWithContext = (component, { storeState = {}, location = {} }) }; return mount(component, options); }; + + +export class Utils { + constructor(input) { + this.wrapper = input; + } + + clickOnElement(query) { + this.wrapper.find(query).simulate('click'); + } + goToConfirmation() { + expect(this.wrapper.find('button.confirm')).to.be.not.present(); + this.wrapper.find('button.next').simulate('click'); + expect(this.wrapper.find('button.confirm')).to.be.present(); + } + checkDisableInput(query, status = '') { + if (status === 'not') { + expect(this.wrapper.find(query)).to.not.be.disabled(); + } else { + expect(this.wrapper.find(query)).to.be.disabled(); + } + } + haveLengthOf(query, length) { + expect(this.wrapper).to.have.exactly(length).descendants(query); + } + haveTextOf(query, text) { + expect(this.wrapper.find(query)).to.have.text(text); + } +} From 75f3281b92708815ac2934108007b8bf26150850 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Mon, 26 Feb 2018 20:58:58 +0100 Subject: [PATCH 09/14] Use Utils class in voting integration test --- test/integration/voting.test.js | 146 ++++++++++---------------------- 1 file changed, 43 insertions(+), 103 deletions(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index 0144ddbbea..d39449508e 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -5,6 +5,7 @@ import { mount } from 'enzyme'; import { stub, match } from 'sinon'; // import thunk from 'redux-thunk'; import { prepareStore, renderWithRouter } from '../utils/applicationInit'; +import { Utils } from '../utils/mountHelpers'; import accounts from '../constants/accounts'; import transactionReducer from '../../src/store/reducers/transactions'; import accountReducer from '../../src/store/reducers/account'; @@ -76,7 +77,11 @@ let listAccountDelegatesStub; let voteApiStub; let accountAPIStub; let localStorageStub; +let helper; +/** + * required steps for login + */ const loginProcess = (votes = []) => { accountAPIStub = stub(accountAPI, 'getAccount'); localStorageStub = stub(localStorage, 'getItem'); @@ -108,6 +113,7 @@ const loginProcess = (votes = []) => { .resolves({ delegates: votes, success: true }); wrapper = mount(renderWithRouter(Voting, store)); + helper = new Utils(wrapper); expect(store.getState().account).to.be.an('Object'); expect(store.getState().voting).to.be.an('Object'); expect(store.getState().peers).to.be.an('Object'); @@ -134,6 +140,15 @@ const voteToDelegates = (index, value) => { .simulate('change', { target: { value } }); }; +const confirmVotes = () => { + voteApiStub.returnsPromise() + .resolves({ + transactionId: 12341234123432412, + account, + }); + wrapper.find('button.confirm').simulate('click'); +}; + const goToConfirmation = () => { expect(wrapper.find('button.confirm')).to.be.not.present(); wrapper.find('button.next').simulate('click'); @@ -142,114 +157,39 @@ const goToConfirmation = () => { describe('@integration test of Voting', () => { describe('Scenario: should allow to select delegates in the "Voting" and vote for them', () => { - step('I\'m logged in as "genesis"', () => { loginProcess(); }); - - step('And next button should be disabled', () => { - expect(wrapper.find('button.next')).to.have.prop('disabled', true); - }); - - step('When I vote to delegates and next button should be enabled', () => { - voteToDelegates(0, true); - voteToDelegates(1, true); - }); - - step('Then next button should be enabled', () => { - expect(wrapper.find('button.next')).to.have.prop('disabled', false); - }); - - step('And selectionHeader should be equal to "2"', () => { - const selectionHeader = wrapper.find('.selection h4'); - expect(selectionHeader).to.have.text('2'); - }); - - step('Then I go to confirmation step', () => { goToConfirmation(); }); - - step('When I click on confirm button', () => { - voteApiStub.returnsPromise() - .resolves({ - transactionId: 12341234123432412, - account, - }); - wrapper.find('button.confirm').simulate('click'); - }); - - step('Then I should see result box', () => { - const expectedValue = 'Votes submitted'; - expect(wrapper.find('h2.result-box-header')).to.have.text(expectedValue); - expect(wrapper.find('p.result-box-message')).to.be.present(); - restoreApiMocks(); - }); + step('I\'m logged in as "genesis"', loginProcess); + step('And next button should be disabled', () => helper.checkDisableInput('button.next')); + step('When I click checkbox on list item no. 0', () => voteToDelegates(0, true)); + step('When I click checkbox on list item no. 1', () => voteToDelegates(1, true)); + step('Then next button should be enabled', () => helper.checkDisableInput('button.next', 'not')); + step('And selectionHeader should be equal to "2"', () => helper.haveTextOf('.selection h4', 2)); + step('Then I go to confirmation step', goToConfirmation); + step('When I click on confirm button', confirmVotes); + step('Then I should see result box', () => helper.haveTextOf('h2.result-box-header', 'Votes submitted')); + step('Then I restore Api mocks', restoreApiMocks); }); describe('Scenario: should allow me to filter my votes', () => { - step('I\'m logged in as "genesis"', () => { loginProcess([delegates[0]]); }); - - step('And I should see 3 rows', () => { - expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(3); - }); - - step('When I click filter-voted', () => { - wrapper.find('li.filter-voted').simulate('click'); - }); - - step('Then I should see 1 rows', () => { - expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(1); - }); - - step('When I click filter-not-voted', () => { - wrapper.find('li.filter-not-voted').simulate('click'); - }); - - step('Then I should see 2 rows', () => { - expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(2); - }); - - step('When I click filter-all I should see all votes again', () => { - wrapper.find('li.filter-all').simulate('click'); - }); - - step('Then I should see all votes again', () => { - expect(wrapper.find('ul.delegate-row')).to.have.lengthOf(3); - restoreApiMocks(); - }); + step('I\'m logged in as "genesis"', () => loginProcess([delegates[0]])); + step('And I should see 3 rows', () => helper.haveLengthOf('ul.delegate-row', 3)); + step('When I click filter-voted', () => helper.clickOnElement('li.filter-voted')); + step('Then I should see 1 rows', () => helper.haveLengthOf('ul.delegate-row', 1)); + step('When I click filter-not-voted', () => helper.clickOnElement('li.filter-not-voted')); + step('Then I should see 2 rows', () => helper.haveLengthOf('ul.delegate-row', 2)); + step('When I click filter-all', () => helper.clickOnElement('li.filter-all')); + step('Then I should see all votes again', () => helper.haveLengthOf('ul.delegate-row', 3)); + step('Then I restore Api mocks', restoreApiMocks); }); describe('Scenario: should allow to select delegates in the "Voting" and unvote them', () => { - step('I\'m logged in as "genesis"', () => { loginProcess([delegates[0]]); }); - - step('And next button should be disabled', () => { - expect(wrapper.find('button.next')).to.have.prop('disabled', true); - }); - - step('When I remove my vote', () => { - voteToDelegates(0, false); - }); - - step('Then next button should be enabled', () => { - expect(wrapper.find('button.next')).to.have.prop('disabled', false); - }); - - step('And selectionHeader should be equal to "1"', () => { - const selectionHeader = wrapper.find('.selection h4'); - expect(selectionHeader).to.have.text('1'); - }); - - step('Then I go to confirmation step', () => { goToConfirmation(); }); - - step('When I click on confirm button', () => { - voteApiStub.returnsPromise() - .resolves({ - transactionId: 12341234123432412, - account, - }); - wrapper.find('button.confirm').simulate('click'); - }); - - step('Then I should see result box', () => { - const expectedValue = 'Votes submitted'; - expect(wrapper.find('h2.result-box-header')).to.have.text(expectedValue); - expect(wrapper.find('p.result-box-message')).to.be.present(); - restoreApiMocks(); - }); + step('I\'m logged in as "genesis"', loginProcess.bind(null, [delegates[0]])); + step('And next button should be disabled', () => helper.checkDisableInput('button.next')); + step('When I click checkbox on list item no. 0', () => voteToDelegates(0, false)); + step('Then next button should be enabled', () => helper.checkDisableInput('button.next', 'not')); + step('And selectionHeader should be equal to "2"', () => helper.haveTextOf('.selection h4', 1)); + step('Then I go to confirmation step', goToConfirmation); + step('When I click on confirm button', confirmVotes); + step('Then I should see result box', () => helper.haveTextOf('h2.result-box-header', 'Votes submitted')); + step('Then I restore Api mocks', restoreApiMocks); }); }); From 4bea22439d1c1b0ef2c6676fa51941a3604645d4 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Tue, 27 Feb 2018 12:22:41 +0100 Subject: [PATCH 10/14] Move utils class to genericStepDefinition.js --- test/utils/genericStepDefinition.js | 44 +++++++++++++++++++++++++++++ test/utils/mountHelpers.js | 29 ------------------- 2 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 test/utils/genericStepDefinition.js diff --git a/test/utils/genericStepDefinition.js b/test/utils/genericStepDefinition.js new file mode 100644 index 0000000000..2ae44a7202 --- /dev/null +++ b/test/utils/genericStepDefinition.js @@ -0,0 +1,44 @@ + +import { expect } from 'chai'; + +export default class GenericStepDefinition { + constructor(input) { + this.wrapper = input; + } + /** + * simulate click on a dom query + * @param {String} query - dom query that we need to simulate clink on it + */ + clickOnElement(query) { + this.wrapper.find(query).simulate('click'); + } + /** + * check that dom query entry is disable or enable + * if value of status is equal to 'not' query shouldn't be disabled + * @param {String} query - dom query that we need to check that is disable or not + * @param {String} status - possible values are 'not' and '' + */ + checkDisableInput(query, status = '') { + if (status === 'not') { + expect(this.wrapper.find(query)).to.not.be.disabled(); + } else { + expect(this.wrapper.find(query)).to.be.disabled(); + } + } + /** + * + * @param {String} query - dom query that we need to check length of that + * @param {Integer} length + */ + haveLengthOf(query, length) { + expect(this.wrapper).to.have.exactly(length).descendants(query); + } + /** + * + * @param {String} query - dom query that we need to check text of that + * @param {String} text - expect text of the dom query entry + */ + haveTextOf(query, text) { + expect(this.wrapper.find(query)).to.have.text(text); + } +} diff --git a/test/utils/mountHelpers.js b/test/utils/mountHelpers.js index 5c6e162e88..363e1bec55 100644 --- a/test/utils/mountHelpers.js +++ b/test/utils/mountHelpers.js @@ -2,7 +2,6 @@ import { spy } from 'sinon'; import { mount } from 'enzyme'; import configureMockStore from 'redux-mock-store'; import PropTypes from 'prop-types'; -import { expect } from 'chai'; import i18n from '../../src/i18n'; @@ -35,31 +34,3 @@ export const mountWithContext = (component, { storeState = {}, location = {} }) return mount(component, options); }; - -export class Utils { - constructor(input) { - this.wrapper = input; - } - - clickOnElement(query) { - this.wrapper.find(query).simulate('click'); - } - goToConfirmation() { - expect(this.wrapper.find('button.confirm')).to.be.not.present(); - this.wrapper.find('button.next').simulate('click'); - expect(this.wrapper.find('button.confirm')).to.be.present(); - } - checkDisableInput(query, status = '') { - if (status === 'not') { - expect(this.wrapper.find(query)).to.not.be.disabled(); - } else { - expect(this.wrapper.find(query)).to.be.disabled(); - } - } - haveLengthOf(query, length) { - expect(this.wrapper).to.have.exactly(length).descendants(query); - } - haveTextOf(query, text) { - expect(this.wrapper.find(query)).to.have.text(text); - } -} From a6f7ffdf7e7da606e91f486a75f7c7024330e3e6 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Tue, 27 Feb 2018 12:23:25 +0100 Subject: [PATCH 11/14] Use genericStepDefinition instead of Utils in voting integration test --- test/integration/voting.test.js | 75 ++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index d39449508e..fd6e1e57e5 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -5,7 +5,7 @@ import { mount } from 'enzyme'; import { stub, match } from 'sinon'; // import thunk from 'redux-thunk'; import { prepareStore, renderWithRouter } from '../utils/applicationInit'; -import { Utils } from '../utils/mountHelpers'; +import GenericStepDefinition from '../utils/genericStepDefinition'; import accounts from '../constants/accounts'; import transactionReducer from '../../src/store/reducers/transactions'; import accountReducer from '../../src/store/reducers/account'; @@ -79,6 +79,32 @@ let accountAPIStub; let localStorageStub; let helper; +/** + * extend GenericStepDefinition and add some specific function to it for testing voting + */ +class Helper extends GenericStepDefinition { + constructor(input) { + super(input); + this.wrapper = input; + } + + /** + * + * @param {String} index - index of the delegate in the list + * @param {Boolean} value - new value of the input + */ + voteToDelegates(index, value) { + this.wrapper.find('.delegate-list input').at(index) + .simulate('change', { target: { value } }); + } + + goToConfirmation() { + expect(this.wrapper.find('button.confirm')).to.be.not.present(); + this.wrapper.find('button.next').simulate('click'); + expect(this.wrapper.find('button.confirm')).to.be.present(); + } +} + /** * required steps for login */ @@ -112,8 +138,14 @@ const loginProcess = (votes = []) => { listAccountDelegatesStub.returnsPromise() .resolves({ delegates: votes, success: true }); + voteApiStub.returnsPromise() + .resolves({ + transactionId: 12341234123432412, + account, + }); + wrapper = mount(renderWithRouter(Voting, store)); - helper = new Utils(wrapper); + helper = new Helper(wrapper); expect(store.getState().account).to.be.an('Object'); expect(store.getState().voting).to.be.an('Object'); expect(store.getState().peers).to.be.an('Object'); @@ -130,41 +162,16 @@ const restoreApiMocks = () => { localStorageStub.restore(); }; -/** - * - * @param {string} index - index of the delegate in the list - * @param {boolean} value - new value of the input - */ -const voteToDelegates = (index, value) => { - wrapper.find('.delegate-list input').at(index) - .simulate('change', { target: { value } }); -}; - -const confirmVotes = () => { - voteApiStub.returnsPromise() - .resolves({ - transactionId: 12341234123432412, - account, - }); - wrapper.find('button.confirm').simulate('click'); -}; - -const goToConfirmation = () => { - expect(wrapper.find('button.confirm')).to.be.not.present(); - wrapper.find('button.next').simulate('click'); - expect(wrapper.find('button.confirm')).to.be.present(); -}; - describe('@integration test of Voting', () => { describe('Scenario: should allow to select delegates in the "Voting" and vote for them', () => { step('I\'m logged in as "genesis"', loginProcess); step('And next button should be disabled', () => helper.checkDisableInput('button.next')); - step('When I click checkbox on list item no. 0', () => voteToDelegates(0, true)); - step('When I click checkbox on list item no. 1', () => voteToDelegates(1, true)); + step('When I click checkbox on list item no. 0', () => helper.voteToDelegates(0, true)); + step('When I click checkbox on list item no. 1', () => helper.voteToDelegates(1, true)); step('Then next button should be enabled', () => helper.checkDisableInput('button.next', 'not')); step('And selectionHeader should be equal to "2"', () => helper.haveTextOf('.selection h4', 2)); - step('Then I go to confirmation step', goToConfirmation); - step('When I click on confirm button', confirmVotes); + step('Then I go to confirmation step', () => helper.goToConfirmation()); + step('When I click on confirm button', () => helper.clickOnElement('button.confirm')); step('Then I should see result box', () => helper.haveTextOf('h2.result-box-header', 'Votes submitted')); step('Then I restore Api mocks', restoreApiMocks); }); @@ -184,11 +191,11 @@ describe('@integration test of Voting', () => { describe('Scenario: should allow to select delegates in the "Voting" and unvote them', () => { step('I\'m logged in as "genesis"', loginProcess.bind(null, [delegates[0]])); step('And next button should be disabled', () => helper.checkDisableInput('button.next')); - step('When I click checkbox on list item no. 0', () => voteToDelegates(0, false)); + step('When I click checkbox on list item no. 0', () => helper.voteToDelegates(0, false)); step('Then next button should be enabled', () => helper.checkDisableInput('button.next', 'not')); step('And selectionHeader should be equal to "2"', () => helper.haveTextOf('.selection h4', 1)); - step('Then I go to confirmation step', goToConfirmation); - step('When I click on confirm button', confirmVotes); + step('Then I go to confirmation step', () => helper.goToConfirmation()); + step('When I click on confirm button', () => helper.clickOnElement('button.confirm')); step('Then I should see result box', () => helper.haveTextOf('h2.result-box-header', 'Votes submitted')); step('Then I restore Api mocks', restoreApiMocks); }); From c83ec74f76767d36b3c5c40c12e11ba21b67cc7c Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Tue, 27 Feb 2018 12:24:55 +0100 Subject: [PATCH 12/14] Fix a bug in voting integration test --- test/integration/voting.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index fd6e1e57e5..5528243853 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -189,7 +189,7 @@ describe('@integration test of Voting', () => { }); describe('Scenario: should allow to select delegates in the "Voting" and unvote them', () => { - step('I\'m logged in as "genesis"', loginProcess.bind(null, [delegates[0]])); + step('I\'m logged in as "genesis"', () => loginProcess([delegates[0]])); step('And next button should be disabled', () => helper.checkDisableInput('button.next')); step('When I click checkbox on list item no. 0', () => helper.voteToDelegates(0, false)); step('Then next button should be enabled', () => helper.checkDisableInput('button.next', 'not')); From 76c1acf93ca7b35537e2dbe0dfe056deaadb6385 Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Tue, 27 Feb 2018 14:59:03 +0100 Subject: [PATCH 13/14] Remove some unnecessary voting e2e tests --- test/e2e/voting.feature | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/test/e2e/voting.feature b/test/e2e/voting.feature index be0c9d63c8..10ce6d1c60 100644 --- a/test/e2e/voting.feature +++ b/test/e2e/voting.feature @@ -24,14 +24,6 @@ Feature: Voting page Then I should see 0 instances of "delegate row" And I should see text "No delegates found." in "empty message" element - @integration - Scenario: should allow to view my votes - Given I'm logged in as "genesis" - And I wait 0.1 seconds - When I go to "main/voting/" - And I click "filter voted" - Then I should see 100 instances of "delegate row" - @testnet Scenario: should allow to select delegates in the "Voting" tab and vote for them Given I'm logged in as "delegate candidate" @@ -58,19 +50,7 @@ Feature: Voting page And I click "confirm" And I wait 0.5 seconds Then I should see text "You’re votes are being processed and will be confirmed. It may take up to 10 minutes to be secured in the blockchain." in "result box message" element - - @integration - Scenario: should allow to remove votes form delegates - Given I'm logged in as "genesis" - And I wait 0.1 seconds - When I go to "main/voting/" - And I click checkbox on list item no. 3 - And I click checkbox on list item no. 5 - And I click "next" - And I click "confirm" - And I wait 0.5 seconds - Then I should see text "You’re votes are being processed and will be confirmed. It may take up to 10 minutes to be secured in the blockchain." in "result box message" element - + Scenario: should allow to select delegates by URL Given I'm logged in as "delegate candidate" When I go to "/main/voting/vote?votes=standby_27,standby_28,standby_29,nonexisting_22&unvotes=standby_33" @@ -84,13 +64,3 @@ Feature: Voting page standby_2[789] standby_2[789] """ - - @integration - @pending - Scenario: should not allow to vote if not enough funds for the fee - Given I'm logged in as "empty account" - When I go to "main/voting/" - And I click checkbox on list item no. 3 - And I click "vote button" - Then I should see "Insufficient funds for 1 LSK fee" error message - And "submit button" should be disabled From a4dbcd917635083f6ca5cd4ddab096c0bfb9486b Mon Sep 17 00:00:00 2001 From: yasharAyari Date: Tue, 27 Feb 2018 14:59:37 +0100 Subject: [PATCH 14/14] Fix a bug in voting.test.js --- test/integration/voting.test.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/integration/voting.test.js b/test/integration/voting.test.js index 5528243853..b4ccc7f3bd 100644 --- a/test/integration/voting.test.js +++ b/test/integration/voting.test.js @@ -83,11 +83,6 @@ let helper; * extend GenericStepDefinition and add some specific function to it for testing voting */ class Helper extends GenericStepDefinition { - constructor(input) { - super(input); - this.wrapper = input; - } - /** * * @param {String} index - index of the delegate in the list