diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 95c9efeeb..7a70937a3 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -785,6 +785,9 @@ "noWebcamFound": { "message": "Your computer's webcam was not found. Please try again." }, + "ofTextNofM": { + "message": "of" + }, "oldUI": { "message": "Old UI" }, @@ -932,6 +935,9 @@ "restoreAccountWithSeed": { "message": "Restore your Account with Seed Phrase" }, + "requestsAwaitingAcknowledgement": { + "message": "requests waiting to be acknowledged" + }, "required": { "message": "Required" }, diff --git a/app/images/double-arrow.svg b/app/images/double-arrow.svg new file mode 100644 index 000000000..a31a0550b --- /dev/null +++ b/app/images/double-arrow.svg @@ -0,0 +1,13 @@ + + \ No newline at end of file diff --git a/app/images/single-arrow.svg b/app/images/single-arrow.svg new file mode 100644 index 000000000..399da72d6 --- /dev/null +++ b/app/images/single-arrow.svg @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/app/scripts/background.js b/app/scripts/background.js index 078e84928..a6fc5ed78 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -440,6 +440,7 @@ function triggerUi () { const currentlyActiveMetamaskTab = Boolean(tabs.find(tab => openMetamaskTabsIDs[tab.id])) if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) { notificationManager.showPopup() + notificationIsOpen = true } }) } diff --git a/development/states/navigate-txs.json b/development/states/navigate-txs.json new file mode 100644 index 000000000..d8b8dc67f --- /dev/null +++ b/development/states/navigate-txs.json @@ -0,0 +1,323 @@ +{ + "metamask": { + "isInitialized": true, + "isUnlocked": true, + "isAccountMenuOpen": false, + "isMascara": false, + "isPopup": false, + "rpcTarget": "https://rawtestrpc.metamask.io/", + "identities": { + "0x8cf82b5aa41ff2282427be151dd328568684007a": { + "address": "0x8cf82b5aa41ff2282427be151dd328568684007a", + "name": "Account 3" + }, + "0xbe1a00e10ec68b154adb84e8119167146a71c9a2": { + "address": "0xbe1a00e10ec68b154adb84e8119167146a71c9a2", + "name": "Account 2" + }, + "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2": { + "address": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "name": "Account 1" + } + }, + "unapprovedTxs": { + "2389644572638771": { + "estimatedGas": "0x8544", + "gasLimitSpecified": true, + "gasPriceSpecified": true, + "history": [], + "id": 2389644572638771, + "loadingDefaults": false, + "metamaskNetworkId": "4", + "origin": "MetaMask", + "status": "unapproved", + "time": 1538844175144, + "txParams": { + "data": "0xa9059cbb000000000000000000000000be1a00e10ec68b154adb84e8119167146a71c9a20000000000000000000000000000000000000000000000000000000000000000", + "from": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "gas": "0x8544", + "gasPrice": "0x3b9aca00", + "to": "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a", + "value": "0x0" + }, + "type": "standard" + }, + "2389644572638772": { + "estimatedGas": "0x5208", + "gasLimitSpecified": true, + "gasPriceSpecified": true, + "history": [], + "id": 2389644572638772, + "loadingDefaults": false, + "metamaskNetworkId": "4", + "origin": "MetaMask", + "status": "unapproved", + "time": 1538844178492, + "txParams": { + "from": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "gas": "0x5208", + "gasPrice": "0x3b9aca00", + "to": "0xbe1a00e10ec68b154adb84e8119167146a71c9a2", + "value": "0x0" + }, + "type": "standard" + }, + "2389644572638773": { + "estimatedGas": { + "length": 1, + "negative": 0, + "red": null, + "words": [ + 34061, + null + ] + }, + "gasLimitSpecified": false, + "gasPriceSpecified": true, + "history": [], + "id": 2389644572638773, + "loadingDefaults": false, + "metamaskNetworkId": "4", + "origin": "localhost", + "status": "unapproved", + "time": 1538844204724, + "txParams": { + "data": "0xdfb29935000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000155468697320697320746865206970667320686173680000000000000000000000", + "from": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "gas": "0xc793", + "gasPrice": "0x3b9aca00", + "to": "0xb7ec370c889b3b48ec537e0b2c887faedceb254a", + "value": "0x0" + }, + "type": "standard" + }, + "2389644572638774": { + "estimatedGas": "0x38f53", + "gasLimitSpecified": true, + "gasPriceSpecified": false, + "history": [], + "id": 2389644572638774, + "loadingDefaults": false, + "metamaskNetworkId": "4", + "origin": "remix.ethereum.org", + "status": "unapproved", + "time": 1538844223352, + "txParams": { + "data": "0x608060405234801561001057600080fd5b506102a7806100206000396000f30060806040526004361061004b5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663d13319c48114610050578063dfb29935146100da575b600080fd5b34801561005c57600080fd5b50610065610135565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561009f578181015183820152602001610087565b50505050905090810190601f1680156100cc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100e657600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101339436949293602493928401919081908401838280828437509497506101cc9650505050505050565b005b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156101c15780601f10610196576101008083540402835291602001916101c1565b820191906000526020600020905b8154815290600101906020018083116101a457829003601f168201915b505050505090505b90565b80516101df9060009060208401906101e3565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061022457805160ff1916838001178555610251565b82800160010185558215610251579182015b82811115610251578251825591602001919060010190610236565b5061025d929150610261565b5090565b6101c991905b8082111561025d57600081556001016102675600a165627a7a72305820cf4282c534b8f2faad947d592afa109b907e4e6b2f52335b361b69c24fedb9580029", + "from": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "gas": "0x38f53", + "gasPrice": "0x3b9aca00", + "value": "0x0" + }, + "type": "standard" + } + }, + "noActiveNotices": true, + "frequentRpcList": [], + "addressBook": [], + "selectedTokenAddress": null, + "contractExchangeRates": {}, + "tokenExchangeRates": {}, + "tokens": [ + { + "address": "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a", + "decimals": 9, + "symbol": "DGD" + } + ], + "pendingTokens": {}, + "send": { + "gasLimit": null, + "gasPrice": null, + "gasTotal": null, + "tokenBalance": null, + "from": "", + "to": "", + "amount": "0x0", + "memo": "", + "errors": {}, + "editingTransactionId": null, + "forceGasMin": null + }, + "coinOptions": {}, + "useBlockie": false, + "featureFlags": { + "betaUI": true, + "skipAnnounceBetaUI": true + }, + "isRevealingSeedWords": false, + "welcomeScreenSeen": false, + "currentLocale": "en", + "preferences": { + "useETHAsPrimaryCurrency": true + }, + "provider": { + "type": "rinkeby" + }, + "network": "4", + "accounts": { + "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2": { + "address": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "balance": "0x36aabfb2a0190c00" + }, + "0xbe1a00e10ec68b154adb84e8119167146a71c9a2": { + "address": "0xbe1a00e10ec68b154adb84e8119167146a71c9a2", + "balance": "0x7b3ef08c294a000" + }, + "0x8cf82b5aa41ff2282427be151dd328568684007a": { + "address": "0x8cf82b5aa41ff2282427be151dd328568684007a", + "balance": "0x0" + } + }, + "currentBlockGasLimit": "0x731e25", + "selectedAddressTxList": [], + "computedBalances": {}, + "unapprovedMsgs": {}, + "unapprovedMsgCount": 0, + "unapprovedPersonalMsgs": {}, + "unapprovedPersonalMsgCount": 0, + "unapprovedTypedMessages": {}, + "unapprovedTypedMessagesCount": 0, + "keyringTypes": [ + "Simple Key Pair", + "HD Key Tree", + "Trezor Hardware", + "Ledger Hardware" + ], + "keyrings": [ + { + "type": "HD Key Tree", + "accounts": [ + "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "0xbe1a00e10ec68b154adb84e8119167146a71c9a2", + "0x8cf82b5aa41ff2282427be151dd328568684007a" + ] + } + ], + "currentAccountTab": "history", + "accountTokens": { + "0x8cf82b5aa41ff2282427be151dd328568684007a": {}, + "0xbe1a00e10ec68b154adb84e8119167146a71c9a2": {}, + "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2": { + "rinkeby": [ + { + "address": "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a", + "decimals": 9, + "symbol": "DGD" + }, + { + "address": "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", + "decimals": 18, + "symbol": "DAI" + } + ] + } + }, + "assetImages": { + "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359": null, + "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a": null + }, + "suggestedTokens": {}, + "lostIdentities": {}, + "seedWords": null, + "forgottenPassword": false, + "selectedAddress": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "recentBlocks": [], + "currentCurrency": "usd", + "conversionRate": 225.23, + "conversionDate": 1538859376, + "shapeShiftTxList": [], + "infuraNetworkStatus": { + "kovan": "ok", + "mainnet": "ok", + "rinkeby": "ok", + "ropsten": "ok" + }, + "lostAccounts": [] + }, + "appState": { + "shouldClose": false, + "menuOpen": false, + "modal": { + "open": false, + "modalState": { + "name": null, + "props": {} + }, + "previousModalState": { + "name": null + } + }, + "sidebar": { + "isOpen": false, + "transitionName": "", + "type": "" + }, + "alertOpen": false, + "alertMessage": null, + "qrCodeData": null, + "networkDropdownOpen": false, + "currentView": { + "name": "confTx", + "context": 0 + }, + "accountDetail": { + "subview": "transactions" + }, + "transForward": false, + "isLoading": false, + "warning": null, + "buyView": {}, + "isMouseUser": true, + "gasIsLoading": false, + "networkNonce": "0x92", + "defaultHdPaths": { + "trezor": "m/44'/60'/0'/0", + "ledger": "m/44'/60'/0'/0/0" + } + }, + "localeMessages": {}, + "send": { + "fromDropdownOpen": false, + "toDropdownOpen": false, + "errors": {} + }, + "confirmTransaction": { + "txData": { + "estimatedGas": "0x38f53", + "gasLimitSpecified": true, + "gasPriceSpecified": false, + "history": [], + "id": 2389644572638774, + "loadingDefaults": false, + "metamaskNetworkId": "4", + "origin": "remix.ethereum.org", + "status": "unapproved", + "time": 1538844223352, + "txParams": { + "data": "0x608060405234801561001057600080fd5b506102a7806100206000396000f30060806040526004361061004b5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663d13319c48114610050578063dfb29935146100da575b600080fd5b34801561005c57600080fd5b50610065610135565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561009f578181015183820152602001610087565b50505050905090810190601f1680156100cc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100e657600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101339436949293602493928401919081908401838280828437509497506101cc9650505050505050565b005b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156101c15780601f10610196576101008083540402835291602001916101c1565b820191906000526020600020905b8154815290600101906020018083116101a457829003601f168201915b505050505090505b90565b80516101df9060009060208401906101e3565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061022457805160ff1916838001178555610251565b82800160010185558215610251579182015b82811115610251578251825591602001919060010190610236565b5061025d929150610261565b5090565b6101c991905b8082111561025d57600081556001016102675600a165627a7a72305820cf4282c534b8f2faad947d592afa109b907e4e6b2f52335b361b69c24fedb9580029", + "from": "0xe2f12a09ba1098312a7d1cad7581ed253ca5f4b2", + "gas": "0x38f53", + "gasPrice": "0x3b9aca00", + "value": "0x0" + }, + "type": "standard" + }, + "tokenData": {}, + "methodData": {}, + "tokenProps": { + "tokenDecimals": "", + "tokenSymbol": "" + }, + "fiatTransactionAmount": "0", + "fiatTransactionFee": "0.05", + "fiatTransactionTotal": "0.05", + "ethTransactionAmount": "0", + "ethTransactionFee": "0.000233", + "ethTransactionTotal": "0.000233", + "hexGasTotal": "0xd42f28057e00", + "nonce": "", + "toSmartContract": false, + "fetchingData": false + } +} \ No newline at end of file diff --git a/test/e2e/beta/from-import-beta-ui.spec.js b/test/e2e/beta/from-import-beta-ui.spec.js index d2c3f8958..77a61a73e 100644 --- a/test/e2e/beta/from-import-beta-ui.spec.js +++ b/test/e2e/beta/from-import-beta-ui.spec.js @@ -159,6 +159,7 @@ describe('Using MetaMask with an existing account', function () { it('clicks through the ToS', async () => { // terms of use + await delay(largeDelayMs) const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled() assert.equal(canClickThrough, false, 'disabled continue button') const bottomOfTos = await findElement(driver, By.linkText('Attributions')) diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js index 3bfa1eaf2..2b5c8ee18 100644 --- a/test/e2e/beta/metamask-beta-ui.spec.js +++ b/test/e2e/beta/metamask-beta-ui.spec.js @@ -484,6 +484,142 @@ describe('MetaMask', function () { }) }) + describe('Navigate transactions', () => { + it('adds multiple transactions', async () => { + await delay(regularDelayMs) + + await waitUntilXWindowHandles(driver, 2) + const windowHandles = await driver.getAllWindowHandles() + const extension = windowHandles[0] + const dapp = windowHandles[1] + + await driver.switchTo().window(dapp) + await delay(regularDelayMs) + + const send3eth = await findElement(driver, By.xpath(`//button[contains(text(), 'Send')]`), 10000) + await send3eth.click() + await delay(regularDelayMs) + + const contractDeployment = await findElement(driver, By.xpath(`//button[contains(text(), 'Deploy Contract')]`), 10000) + await contractDeployment.click() + await delay(regularDelayMs) + + await send3eth.click() + await contractDeployment.click() + await delay(regularDelayMs) + + await driver.switchTo().window(extension) + await delay(regularDelayMs) + + const transactions = await findElements(driver, By.css('.transaction-list-item')) + await transactions[3].click() + await delay(regularDelayMs) + }) + + it('navigates the transactions', async () => { + let navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + assert.equal(navigateTxButtons.length, 4, 'navigation button present') + + await navigateTxButtons[2].click() + let navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + let navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('2'), true, 'changed transaction right') + + navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + await navigateTxButtons[2].click() + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('3'), true, 'changed transaction right') + + navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + await navigateTxButtons[2].click() + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('4'), true, 'changed transaction right') + + navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + await navigateTxButtons[0].click() + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('1'), true, 'navigate to first transaction') + + navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + await navigateTxButtons[3].click() + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.split('4').length, 3, 'navigate to last transaction') + + navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + await navigateTxButtons[1].click() + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('3'), true, 'changed transaction left') + + navigateTxButtons = await findElements(driver, By.css('.confirm-page-container-navigation__arrow')) + await navigateTxButtons[1].click() + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('2'), true, 'changed transaction left') + }) + + it('adds a transaction while confirm screen is in focus', async () => { + let navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + let navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('2'), true, 'second transaction in focus') + + const windowHandles = await driver.getAllWindowHandles() + const extension = windowHandles[0] + const dapp = windowHandles[1] + + await driver.switchTo().window(dapp) + await delay(regularDelayMs) + + const send3eth = await findElement(driver, By.xpath(`//button[contains(text(), 'Send')]`), 10000) + await send3eth.click() + await delay(regularDelayMs) + + await driver.switchTo().window(extension) + await delay(regularDelayMs) + + navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('3'), true, 'correct transaction in focus') + }) + + it('confirms a transaction', async () => { + const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000) + await confirmButton.click() + await delay(regularDelayMs) + + const navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + const navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('4'), true, 'transaction confirmed') + }) + + it('rejects a transaction', async () => { + const rejectButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Reject')]`), 10000) + await rejectButton.click() + await delay(regularDelayMs) + + const navigationElement = await findElement(driver, By.css('.confirm-page-container-navigation')) + const navigationText = await navigationElement.getText() + assert.equal(navigationText.includes('3'), true, 'transaction rejected') + }) + + it('rejects the rest of the transactions', async () => { + const rejectAllButton = await findElement(driver, By.xpath(`//a[contains(text(), 'Reject 3')]`), 10000) + await rejectAllButton.click() + await delay(regularDelayMs) + + const rejectButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Reject All')]`), 10000) + await rejectButton.click() + await delay(largeDelayMs * 2) + + const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item')) + assert.equal(confirmedTxes.length, 3, '3 transactions present') + }) + }) + describe('Deploy contract and call contract methods', () => { let extension let dapp @@ -531,7 +667,7 @@ describe('MetaMask', function () { driver.wait(async () => { const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item')) - return confirmedTxes.length === 3 + return confirmedTxes.length === 4 }, 10000) const txAction = await findElements(driver, By.css('.transaction-list-item__action')) @@ -588,7 +724,7 @@ describe('MetaMask', function () { driver.wait(async () => { const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item')) - return confirmedTxes.length === 4 + return confirmedTxes.length === 5 }, 10000) const txValues = await findElements(driver, By.css('.transaction-list-item__amount--primary')) @@ -620,7 +756,7 @@ describe('MetaMask', function () { driver.wait(async () => { const confirmedTxes = await findElements(driver, By.css('.transaction-list__completed-transactions .transaction-list-item')) - return confirmedTxes.length === 5 + return confirmedTxes.length === 6 }, 10000) const txValues = await findElement(driver, By.css('.transaction-list-item__amount--primary')) @@ -634,9 +770,9 @@ describe('MetaMask', function () { const balance = await findElement(driver, By.css('.transaction-view-balance__primary-balance')) await delay(regularDelayMs) if (process.env.SELENIUM_BROWSER !== 'firefox') { - await driver.wait(until.elementTextMatches(balance, /^92.*\s*ETH.*$/), 10000) + await driver.wait(until.elementTextMatches(balance, /^89.*\s*ETH.*$/), 10000) const tokenAmount = await balance.getText() - assert.ok(/^92.*\s*ETH.*$/.test(tokenAmount)) + assert.ok(/^89.*\s*ETH.*$/.test(tokenAmount)) await delay(regularDelayMs) } }) diff --git a/test/integration/lib/navigate-txs.js b/test/integration/lib/navigate-txs.js new file mode 100644 index 000000000..0679d6b00 --- /dev/null +++ b/test/integration/lib/navigate-txs.js @@ -0,0 +1,87 @@ +const reactTriggerChange = require('react-trigger-change') +const { + timeout, + queryAsync, +} = require('../../lib/util') + +QUnit.module('navigate txs') + +QUnit.test('successful navigate', (assert) => { + const done = assert.async() + runNavigateTxsFlowTest(assert) + .then(done) + .catch(err => { + assert.notOk(err, `Error was thrown: ${err.stack}`) + done() + }) +}) + +async function runNavigateTxsFlowTest (assert, done) { + const selectState = await queryAsync($, 'select') + + selectState.val('navigate txs') + reactTriggerChange(selectState[0]) + + // Confirm navigation buttons present + let navigateTxButtons = await queryAsync($, '.confirm-page-container-navigation__arrow') + assert.ok(navigateTxButtons[0], 'navigation button present') + assert.ok(navigateTxButtons[1], 'navigation button present') + assert.ok(navigateTxButtons[2], 'navigation button present') + assert.ok(navigateTxButtons[3], 'navigation button present') + + // Verify number of transactions present + let trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.includes('1'), true, 'starts on first') + + // Verify correct route + let summaryAction = await queryAsync($, '.confirm-page-container-summary__action') + assert.equal(summaryAction[0].innerText, 'CONTRACT DEPLOYMENT', 'correct route') + + // Click navigation button + navigateTxButtons[2].click() + await timeout(2000) + + // Verify transaction changed to num 2 and routed correctly + trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.includes('2'), true, 'changed transaction right') + summaryAction = await queryAsync($, '.confirm-page-container-summary__action') + // assert.equal(summaryAction[0].innerText, 'CONFIRM', 'correct route') + + // Click navigation button + navigateTxButtons = await queryAsync($, '.confirm-page-container-navigation__arrow') + navigateTxButtons[2].click() + + // Verify transation changed to num 3 and routed correctly + trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.includes('3'), true, 'changed transaction right') + summaryAction = await queryAsync($, '.confirm-page-container-summary__action') + assert.equal(summaryAction[0].innerText, 'CONFIRM', 'correct route') + + // Click navigation button + navigateTxButtons = await queryAsync($, '.confirm-page-container-navigation__arrow') + navigateTxButtons[2].click() + + // Verify transation changed to num 4 and routed correctly + trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.split('4').length, 3, '4 transactions present') + summaryAction = await queryAsync($, '.confirm-page-container-summary__action') + assert.equal(summaryAction[0].innerText, 'TRANSFER', 'correct route') + + // Verify left arrow is working correctly + navigateTxButtons = await queryAsync($, '.confirm-page-container-navigation__arrow') + navigateTxButtons[1].click() + trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.includes('3'), true, 'changed transaction left') + + // Verify navigate to last transaction is working correctly + navigateTxButtons = await queryAsync($, '.confirm-page-container-navigation__arrow') + navigateTxButtons[3].click() + trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.split('4').length, 3, 'navigate to last transaction') + + // Verify navigate to first transaction is working correctly + navigateTxButtons = await queryAsync($, '.confirm-page-container-navigation__arrow') + navigateTxButtons[0].click() + trxNum = await queryAsync($, '.confirm-page-container-navigation') + assert.equal(trxNum[0].innerText.includes('1'), true, 'navigate to first transaction') +} diff --git a/ui/app/components/confirm-page-container/confirm-page-container-header/index.scss b/ui/app/components/confirm-page-container/confirm-page-container-header/index.scss index 43e1e4427..be77edbdf 100644 --- a/ui/app/components/confirm-page-container/confirm-page-container-header/index.scss +++ b/ui/app/components/confirm-page-container/confirm-page-container-header/index.scss @@ -7,7 +7,7 @@ display: flex; justify-content: space-between; border-bottom: 1px solid $geyser; - padding: 13px 13px 13px 24px; + padding: 4px 13px 4px 13px; flex: 0 0 auto; } diff --git a/ui/app/components/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js b/ui/app/components/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js new file mode 100755 index 000000000..8327f997b --- /dev/null +++ b/ui/app/components/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js @@ -0,0 +1,69 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const ConfirmPageContainerNavigation = props => { + const { onNextTx, totalTx, positionOfCurrentTx, nextTxId, prevTxId, showNavigation, firstTx, lastTx, ofText, requestsWaitingText } = props + + return ( +