From 5b92dc4cf08570e81277e74c39973a919c6eba0b Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Thu, 20 Jan 2022 00:04:43 +0530 Subject: [PATCH] Adding e2e test for edit gas fee modal (#13303) --- test/e2e/fixtures/eip-1559-v2-dapp/state.json | 145 +++++++++ test/e2e/fixtures/eip-1559-v2/state.json | 214 ++++++++++++++ test/e2e/helpers.js | 45 +++ test/e2e/tests/edit-gas-fee.spec.js | 277 ++++++++++++++++++ test/e2e/tests/send-edit.spec.js | 8 +- .../edit-gas-fee-button.js | 5 +- .../edit-gas-item/edit-gas-item.js | 1 + .../actionable-message/actionable-message.js | 4 +- .../transaction-alerts/transaction-alerts.js | 1 + 9 files changed, 694 insertions(+), 6 deletions(-) create mode 100644 test/e2e/fixtures/eip-1559-v2-dapp/state.json create mode 100644 test/e2e/fixtures/eip-1559-v2/state.json create mode 100644 test/e2e/tests/edit-gas-fee.spec.js diff --git a/test/e2e/fixtures/eip-1559-v2-dapp/state.json b/test/e2e/fixtures/eip-1559-v2-dapp/state.json new file mode 100644 index 000000000..3e29d737e --- /dev/null +++ b/test/e2e/fixtures/eip-1559-v2-dapp/state.json @@ -0,0 +1,145 @@ +{ + "data": { + "AppStateController": { + "mkrMigrationReminderTimestamp": null, + "swapsWelcomeMessageHasBeenShown": true + }, + "CachedBalancesController": { + "cachedBalances": { + "4": {} + } + }, + "CurrencyController": { + "conversionDate": 1575697244.188, + "conversionRate": 149.61, + "currentCurrency": "usd", + "nativeCurrency": "ETH" + }, + "IncomingTransactionsController": { + "incomingTransactions": {}, + "incomingTxLastFetchedBlocksByNetwork": { + "goerli": null, + "kovan": null, + "mainnet": null, + "rinkeby": 5570536 + } + }, + "KeyringController": { + "vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" + }, + "NetworkController": { + "network": "1337", + "provider": { + "nickname": "Localhost 8545", + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "ticker": "ETH", + "type": "rpc" + } + }, + "NotificationController": { + "notifications": { + "1": { + "isShown": true + }, + "3": { + "isShown": true + }, + "5": { + "isShown": true + }, + "6": { + "isShown": true + }, + "8": { + "isShown": true + } + } + }, + "OnboardingController": { + "onboardingTabs": {}, + "seedPhraseBackedUp": false + }, + "PermissionsMetadata": { + "domainMetadata": { + "metamask.github.io": { + "icon": null, + "name": "M E T A M A S K M E S H T E S T" + } + }, + "permissionsHistory": {}, + "permissionsLog": [ + { + "id": 746677923, + "method": "eth_accounts", + "methodType": "restricted", + "origin": "metamask.github.io", + "request": { + "id": 746677923, + "jsonrpc": "2.0", + "method": "eth_accounts", + "origin": "metamask.github.io", + "params": [] + }, + "requestTime": 1575697241368, + "response": { + "id": 746677923, + "jsonrpc": "2.0", + "result": [] + }, + "responseTime": 1575697241370, + "success": true + } + ] + }, + "PreferencesController": { + "accountTokens": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "rinkeby": [], + "ropsten": [] + } + }, + "assetImages": {}, + "completedOnboarding": true, + "eip1559V2Enabled": true, + "currentLocale": "en", + "featureFlags": { + "showIncomingTransactions": true, + "transactionTime": false + }, + "firstTimeFlowType": "create", + "forgottenPassword": false, + "frequentRpcListDetail": [], + "identities": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "name": "Account 1" + } + }, + "knownMethodData": {}, + "lostIdentities": {}, + "metaMetricsId": null, + "participateInMetaMetrics": false, + "preferences": { + "useNativeCurrencyAsPrimaryCurrency": true + }, + "selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "suggestedTokens": {}, + "tokens": [], + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true + }, + "TransactionController": { + "transactions": {} + }, + "config": {}, + "firstTimeInfo": { + "date": 1575697234195, + "version": "7.7.0" + } + }, + "meta": { + "version": 40 + } +} diff --git a/test/e2e/fixtures/eip-1559-v2/state.json b/test/e2e/fixtures/eip-1559-v2/state.json new file mode 100644 index 000000000..452c896c3 --- /dev/null +++ b/test/e2e/fixtures/eip-1559-v2/state.json @@ -0,0 +1,214 @@ +{ + "data": { + "AppStateController": { + "mkrMigrationReminderTimestamp": null, + "swapsWelcomeMessageHasBeenShown": true + }, + "CachedBalancesController": { + "cachedBalances": { + "4": {} + } + }, + "CurrencyController": { + "conversionDate": 1575697244.188, + "conversionRate": 149.61, + "currentCurrency": "usd", + "nativeCurrency": "ETH" + }, + "IncomingTransactionsController": { + "incomingTransactions": {}, + "incomingTxLastFetchedBlocksByNetwork": { + "goerli": null, + "kovan": null, + "mainnet": null, + "rinkeby": 5570536 + } + }, + "KeyringController": { + "vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" + }, + "NetworkController": { + "network": "1337", + "provider": { + "nickname": "Localhost 8545", + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "ticker": "ETH", + "type": "rpc" + } + }, + "NotificationController": { + "notifications": { + "1": { + "isShown": true + }, + "3": { + "isShown": true + }, + "5": { + "isShown": true + }, + "6": { + "isShown": true + }, + "8": { + "isShown": true + } + } + }, + "OnboardingController": { + "onboardingTabs": {}, + "seedPhraseBackedUp": false + }, + "PermissionsMetadata": { + "domainMetadata": { + "metamask.github.io": { + "icon": null, + "name": "M E T A M A S K M E S H T E S T" + } + }, + "permissionsHistory": {}, + "permissionsLog": [ + { + "id": 746677923, + "method": "eth_accounts", + "methodType": "restricted", + "origin": "metamask.github.io", + "request": { + "id": 746677923, + "jsonrpc": "2.0", + "method": "eth_accounts", + "origin": "metamask.github.io", + "params": [] + }, + "requestTime": 1575697241368, + "response": { + "id": 746677923, + "jsonrpc": "2.0", + "result": [] + }, + "responseTime": 1575697241370, + "success": true + } + ] + }, + "PreferencesController": { + "accountTokens": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "rinkeby": [], + "ropsten": [] + } + }, + "assetImages": {}, + "completedOnboarding": true, + "eip1559V2Enabled": true, + "currentLocale": "en", + "featureFlags": { + "showIncomingTransactions": true, + "transactionTime": false + }, + "firstTimeFlowType": "create", + "forgottenPassword": false, + "frequentRpcListDetail": [], + "identities": { + "0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { + "address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "name": "Account 1" + } + }, + "knownMethodData": {}, + "lostIdentities": {}, + "metaMetricsId": null, + "participateInMetaMetrics": false, + "preferences": { + "useNativeCurrencyAsPrimaryCurrency": true + }, + "selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "suggestedTokens": {}, + "tokens": [], + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true + }, + "TransactionController": { + "transactions": { + "4046084157914634": { + "chainId": "0x539", + "primaryTransaction": { + "chainId": "0x539", + "id": 4046084157914634, + "loadingDefaults": true, + "metamaskNetworkId": "1337", + "origin": "metamask", + "status": "unapproved", + "time": 1617228030067, + "txParams": { + "from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "gas": "0x61a8", + "maxFeePerGas": "0x59682f0c", + "maxPriorityFeePerGas": "0x59682f00", + "type": "0x2", + "to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970", + "value": "0x1e87F85809dc0000" + }, + "type": "sentEther" + }, + "history": [ + { + "chainId": "0x539", + "id": 4046084157914634, + "loadingDefaults": true, + "metamaskNetworkId": "1337", + "origin": "metamask", + "status": "unapproved", + "time": 1617228030067, + "txParams": { + "from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "gas": "0x61a8", + "maxFeePerGas": "0x59682f0c", + "maxPriorityFeePerGas": "0x59682f00", + "type": "0x2", + "to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970", + "value": "0x1e87F85809dc0000" + }, + "type": "simpleSend" + }, + [ + { + "note": "Added new unapproved transaction.", + "op": "replace", + "path": "/loadingDefaults", + "timestamp": 1617228030069, + "value": false + } + ] + ], + "id": 4046084157914634, + "loadingDefaults": false, + "metamaskNetworkId": "1337", + "origin": "metamask", + "status": "unapproved", + "time": 1617228030067, + "txParams": { + "from": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", + "gas": "0x61a8", + "maxFeePerGas": "0x59682f0c", + "maxPriorityFeePerGas": "0x59682f00", + "type": "0x2", + "to": "0x2f318C334780961FB129D2a6c30D0763d9a5C970", + "value": "0x1e87F85809dc0000" + }, + "type": "simpleSend" + } + } + }, + "config": {}, + "firstTimeInfo": { + "date": 1575697234195, + "version": "7.7.0" + } + }, + "meta": { + "version": 40 + } +} diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 76d0976b4..6b662f1a6 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -149,10 +149,55 @@ async function withFixtures(options, testSuite) { } } +/** + * @param {*} driver - selinium driver + * @param {*} handlesCount - total count of windows that should be loaded + * @returns handles - an object with window handles, properties in object represent windows: + * 1. extension: metamask extension window + * 2. dapp: test-app window + * 3. popup: metsmask extension popup window + */ +const getWindowHandles = async (driver, handlesCount) => { + await driver.waitUntilXWindowHandles(handlesCount); + const windowHandles = await driver.getAllWindowHandles(); + + const extension = windowHandles[0]; + const dapp = await driver.switchToWindowWithTitle( + 'E2E Test Dapp', + windowHandles, + ); + const popup = windowHandles.find( + (handle) => handle !== extension && handle !== dapp, + ); + return { extension, dapp, popup }; +}; + +const connectDappWithExtensionPopup = async (driver) => { + await driver.openNewPage(`http://127.0.0.1:${dappPort}/`); + await driver.delay(regularDelayMs); + await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.delay(regularDelayMs); + + const windowHandles = await getWindowHandles(driver, 3); + + // open extension popup and confirm connect + await driver.switchToWindow(windowHandles.popup); + await driver.delay(largeDelayMs); + await driver.clickElement({ text: 'Next', tag: 'button' }); + await driver.clickElement({ text: 'Connect', tag: 'button' }); + + // send from dapp + await driver.waitUntilXWindowHandles(2); + await driver.switchToWindow(windowHandles.dapp); + await driver.delay(regularDelayMs); +}; + module.exports = { + getWindowHandles, convertToHexValue, tinyDelayMs, regularDelayMs, largeDelayMs, withFixtures, + connectDappWithExtensionPopup, }; diff --git a/test/e2e/tests/edit-gas-fee.spec.js b/test/e2e/tests/edit-gas-fee.spec.js new file mode 100644 index 000000000..9c43c9e79 --- /dev/null +++ b/test/e2e/tests/edit-gas-fee.spec.js @@ -0,0 +1,277 @@ +const { strict: assert } = require('assert'); +const { + convertToHexValue, + connectDappWithExtensionPopup, + getWindowHandles, + largeDelayMs, + withFixtures, + regularDelayMs, +} = require('../helpers'); + +if (process.env.EIP_1559_V2 === '1') { + describe('Editing Confirm Transaction', function () { + it('allows selecting high, medium, low gas estimates on edit gas fee popover', async function () { + const ganacheOptions = { + hardfork: 'london', + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], + }; + await withFixtures( + { + fixtures: 'eip-1559-v2', + ganacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + const transactionAmounts = await driver.findElements( + '.currency-display-component__text', + ); + const transactionAmount = transactionAmounts[0]; + assert.equal(await transactionAmount.getText(), '2.2'); + + // update estimates to high + await driver.clickElement('[data-testid="edit-gas-fee-button"]'); + await driver.delay(regularDelayMs); + await driver.clickElement('[data-testid="edit-gas-fee-item-high"]'); + await driver.delay(regularDelayMs); + await driver.waitForSelector({ text: '🦍' }); + await driver.waitForSelector({ + text: 'Aggressive', + }); + + // update estimates to medium + await driver.clickElement('[data-testid="edit-gas-fee-button"]'); + await driver.delay(regularDelayMs); + await driver.clickElement('[data-testid="edit-gas-fee-item-medium"]'); + await driver.delay(regularDelayMs); + await driver.waitForSelector({ text: '🦊' }); + await driver.waitForSelector({ + text: 'Market', + }); + + // update estimates to low + await driver.clickElement('[data-testid="edit-gas-fee-button"]'); + await driver.delay(regularDelayMs); + await driver.clickElement('[data-testid="edit-gas-fee-item-low"]'); + await driver.delay(regularDelayMs); + await driver.waitForSelector({ text: '🐢' }); + await driver.waitForSelector({ + text: 'Low', + }); + await driver.waitForSelector('[data-testid="low-gas-fee-alert"]'); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.delay(regularDelayMs); + + await driver.clickElement('[data-testid="home__activity-tab"]'); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .transaction-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '.transaction-list-item__primary-currency', + ); + assert.equal(txValues.length, 1); + assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); + }, + ); + }); + + it('allows accessing advance gas fee popover from edit gas fee popover', async function () { + const ganacheOptions = { + hardfork: 'london', + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], + }; + await withFixtures( + { + fixtures: 'eip-1559-v2', + ganacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + const transactionAmounts = await driver.findElements( + '.currency-display-component__text', + ); + const transactionAmount = transactionAmounts[0]; + assert.equal(await transactionAmount.getText(), '2.2'); + + // update estimates to high + await driver.clickElement('[data-testid="edit-gas-fee-button"]'); + await driver.delay(regularDelayMs); + await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); + await driver.delay(regularDelayMs); + + // enter max fee + const maxBaseFee = await driver.findElement( + '[data-testid="base-fee-input"]', + ); + await maxBaseFee.clear(); + await maxBaseFee.sendKeys('8'); + await driver.delay(regularDelayMs); + + // enter priority fee + const priorityFee = await driver.findElement( + '[data-testid="priority-fee-input"]', + ); + await priorityFee.clear(); + await priorityFee.sendKeys('8'); + await driver.delay(regularDelayMs); + + // save default values + await driver.clickElement('input[type="checkbox"]'); + await driver.delay(regularDelayMs); + + // edit gas limit + await driver.clickElement('[data-testid="advanced-gas-fee-edit"]'); + await driver.delay(regularDelayMs); + const gasLimit = await driver.findElement( + '[data-testid="gas-limit-input"]', + ); + await gasLimit.clear(); + await gasLimit.sendKeys('100000'); + await driver.delay(regularDelayMs); + + // Submit gas fee changes + await driver.clickElement({ text: 'Save', tag: 'button' }); + + // has correct updated value on the confirm screen the transaction + const editedTransactionAmounts = await driver.findElements( + '.transaction-detail-item__row .transaction-detail-item__detail-values .currency-display-component__text:last-of-type', + ); + const editedTransactionAmount = editedTransactionAmounts[0]; + assert.equal(await editedTransactionAmount.getText(), '0.0008'); + + const editedTransactionFee = editedTransactionAmounts[1]; + assert.equal(await editedTransactionFee.getText(), '2.2008'); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.delay(regularDelayMs); + + await driver.clickElement('[data-testid="home__activity-tab"]'); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .transaction-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '.transaction-list-item__primary-currency', + ); + assert.equal(txValues.length, 1); + assert.ok(/-2.2\s*ETH/u.test(await txValues[0].getText())); + }, + ); + }); + + it('should use dapp suggested estimates for transaction coming from dapp', async function () { + const ganacheOptions = { + hardfork: 'london', + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], + }; + await withFixtures( + { + fixtures: 'eip-1559-v2-dapp', + ganacheOptions, + title: this.test.title, + dapp: true, + }, + async ({ driver }) => { + await driver.navigate(); + + // login to extension + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + // open dapp and connect + await connectDappWithExtensionPopup(driver); + await driver.clickElement({ text: 'Send', tag: 'button' }); + + // check transaction in extension popup + const windowHandles = await getWindowHandles(driver, 3); + await driver.switchToWindow(windowHandles.popup); + await driver.delay(largeDelayMs); + await driver.waitForSelector({ text: '🌐' }); + await driver.waitForSelector({ + text: 'Site suggested', + }); + + await driver.clickElement('[data-testid="edit-gas-fee-button"]'); + await driver.delay(regularDelayMs); + await driver.clickElement( + '[data-testid="edit-gas-fee-item-dappSuggested"]', + ); + await driver.delay(regularDelayMs); + + const transactionAmounts = await driver.findElements( + '.currency-display-component__text', + ); + const transactionAmount = transactionAmounts[0]; + assert.equal(await transactionAmount.getText(), '3'); + + // has correct updated value on the confirm screen the transaction + const editedTransactionAmounts = await driver.findElements( + '.transaction-detail-item__row .transaction-detail-item__detail-values .currency-display-component__text:last-of-type', + ); + const editedTransactionAmount = editedTransactionAmounts[0]; + assert.equal(await editedTransactionAmount.getText(), '0.00042'); + + const editedTransactionFee = editedTransactionAmounts[1]; + assert.equal(await editedTransactionFee.getText(), '3.00042'); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + await driver.delay(regularDelayMs); + + // transaction should correct values in activity tab + await driver.switchToWindow(windowHandles.extension); + await driver.clickElement('[data-testid="home__activity-tab"]'); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .transaction-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '.transaction-list-item__primary-currency', + ); + assert.equal(txValues.length, 1); + assert.ok(/-3\s*ETH/u.test(await txValues[0].getText())); + }, + ); + }); + }); +} diff --git a/test/e2e/tests/send-edit.spec.js b/test/e2e/tests/send-edit.spec.js index 05562add9..f63796d53 100644 --- a/test/e2e/tests/send-edit.spec.js +++ b/test/e2e/tests/send-edit.spec.js @@ -145,7 +145,7 @@ describe('Editing Confirm Transaction', function () { ); await maxBaseFee.clear(); await maxBaseFee.sendKeys('8'); - await driver.delay(largeDelayMs); + await driver.delay(regularDelayMs); // enter priority fee const priorityFee = await driver.findElement( @@ -153,7 +153,7 @@ describe('Editing Confirm Transaction', function () { ); await priorityFee.clear(); await priorityFee.sendKeys('8'); - await driver.delay(largeDelayMs); + await driver.delay(regularDelayMs); // edit gas limit const gasLimit = await driver.findElement( @@ -161,11 +161,11 @@ describe('Editing Confirm Transaction', function () { ); await gasLimit.clear(); await gasLimit.sendKeys('100000'); - await driver.delay(largeDelayMs); + await driver.delay(regularDelayMs); // save default values await driver.clickElement('input[type="checkbox"]'); - await driver.delay(largeDelayMs); + await driver.delay(regularDelayMs); // Submit gas fee changes await driver.clickElement({ text: 'Save', tag: 'button' }); diff --git a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js index f8791918e..468624408 100644 --- a/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js +++ b/ui/components/app/edit-gas-fee-button/edit-gas-fee-button.js @@ -48,7 +48,10 @@ export default function EditGasFeeButton({ userAcknowledgedGasMissing }) { return (
-