diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index 0e7aa4a3d..7b5fe2d24 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -225,6 +225,7 @@ const importSRPOnboardingFlow = async (driver, seedPhrase, password) => { // metrics await driver.clickElement('[data-testid="metametrics-no-thanks"]'); + await driver.waitForSelector('.import-srp__actions'); // import with recovery phrase await driver.pasteIntoField( '[data-testid="import-srp__srp-word-0"]', @@ -488,6 +489,7 @@ const sendTransaction = async (driver, recipientAddress, quantity) => { await driver.clickElement('[data-testid="page-container-footer-next"]'); await driver.clickElement('[data-testid="page-container-footer-next"]'); await driver.clickElement('[data-testid="home__activity-tab"]'); + await driver.waitForElementNotPresent('.transaction-list-item--unconfirmed'); await driver.findElement('.transaction-list-item'); }; @@ -529,12 +531,28 @@ const locateAccountBalanceDOM = async (driver, ganacheServer) => { }); }; +const restartServiceWorker = async (driver) => { + const serviceWorkerElements = await driver.findElements({ + text: 'terminate', + tag: 'span', + }); + // 1st one is app-init.js; while 2nd one is service-worker.js + await serviceWorkerElements[1].click(); +}; + +async function waitForAccountRendered(driver) { + await driver.waitForSelector( + '[data-testid="eth-overview__primary-currency"]', + ); +} + module.exports = { DAPP_URL, DAPP_ONE_URL, SERVICE_WORKER_URL, TEST_SEED_PHRASE, TEST_SEED_PHRASE_TWO, + PRIVATE_KEY, getWindowHandles, convertToHexValue, tinyDelayMs, @@ -557,4 +575,6 @@ module.exports = { findAnotherAccountFromAccountList, assertAccountBalanceForDOM, locateAccountBalanceDOM, + restartServiceWorker, + waitForAccountRendered, }; diff --git a/test/e2e/mv3/phishing-warning-sw-restart.spec.js b/test/e2e/mv3/phishing-warning-sw-restart.spec.js index 4557a0e57..de01139fe 100644 --- a/test/e2e/mv3/phishing-warning-sw-restart.spec.js +++ b/test/e2e/mv3/phishing-warning-sw-restart.spec.js @@ -2,14 +2,21 @@ const { strict: assert } = require('assert'); const { withFixtures, mockPhishingDetection, - SERVICE_WORKER_URL, openDapp, defaultGanacheOptions, + assertAccountBalanceForDOM, + restartServiceWorker, + SERVICE_WORKER_URL, + regularDelayMs, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); describe('Phishing warning page', function () { + const driverOptions = { openDevToolsForTabs: true }; + it('should restore the transaction when service worker restarts', async function () { + let windowHandles; + await withFixtures( { dapp: true, @@ -17,35 +24,42 @@ describe('Phishing warning page', function () { ganacheOptions: defaultGanacheOptions, title: this.test.title, testSpecificMock: mockPhishingDetection, + driverOptions, }, - async ({ driver }) => { + async ({ driver, ganacheServer }) => { await driver.navigate(); // log in wallet await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - // Restart service worker - await driver.openNewPage(SERVICE_WORKER_URL); - - await driver.clickElement({ - text: 'Service workers', - tag: 'button', - }); - - await driver.clickElement({ - text: 'terminate', - tag: 'span', - }); - - // Open the dapp site and extension detect it as phishing warning page + // DAPP is detected as phishing page await openDapp(driver); - - await driver.switchToWindowWithTitle('MetaMask Phishing Detection'); const phishingPageHeader = await driver.findElements({ text: 'Deceptive site ahead', tag: 'h1', }); assert.ok(phishingPageHeader.length, 1); + + // Restart service worker + await driver.openNewPage(SERVICE_WORKER_URL); + await restartServiceWorker(driver); + + await driver.delay(regularDelayMs); + // wait until extension is reloaded + windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; + await driver.switchToWindow(extension); + await assertAccountBalanceForDOM(driver, ganacheServer); + + // Open the dapp site and extension detect it as phishing warning page + await openDapp(driver); + // - extension, dapp, service worker and new dapp + await driver.waitUntilXWindowHandles(4); + const newPhishingPageHeader = await driver.findElements({ + text: 'Deceptive site ahead', + tag: 'h1', + }); + assert.ok(newPhishingPageHeader.length, 1); }, ); }); diff --git a/test/e2e/tests/add-account.spec.js b/test/e2e/tests/add-account.spec.js index be1590879..38535b0f1 100644 --- a/test/e2e/tests/add-account.spec.js +++ b/test/e2e/tests/add-account.spec.js @@ -1,18 +1,23 @@ const { strict: assert } = require('assert'); const { TEST_SEED_PHRASE, - convertToHexValue, withFixtures, - regularDelayMs, completeImportSRPOnboardingFlow, sendTransaction, findAnotherAccountFromAccountList, + waitForAccountRendered, + convertToHexValue, + regularDelayMs, } = require('../helpers'); -const enLocaleMessages = require('../../../app/_locales/en/messages.json'); + const FixtureBuilder = require('../fixture-builder'); +const { shortenAddress } = require('../../../ui/helpers/utils/util'); describe('Add account', function () { const testPassword = 'correct horse battery staple'; + const firstAccount = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3'; + const secondAccount = '0x3ED0eE22E0685Ebbf07b2360A8331693c413CC59'; + const ganacheOptions = { accounts: [ { @@ -22,8 +27,6 @@ describe('Add account', function () { }, ], }; - const firstAccount = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3'; - const secondAccount = '0x3ED0eE22E0685Ebbf07b2360A8331693c413CC59'; it('should display correct new account name after create', async function () { await withFixtures( @@ -72,29 +75,39 @@ describe('Add account', function () { ); // Check address of 1st account - const firstAccountPublicAddress = await checkAccountDetails(driver); - assert.equal(firstAccountPublicAddress, firstAccount); - await driver.delay(regularDelayMs); + await waitForAccountRendered(driver); + const firstAccountPublicAddress = await retrieveShortenAccountAddress( + driver, + ); + assert.equal(firstAccountPublicAddress, shortenAddress(firstAccount)); - // Create a new account + // Create 2nd account await driver.clickElement('[data-testid="account-menu-icon"]'); await driver.clickElement( '[data-testid="multichain-account-menu-add-account"]', ); await driver.fill('.new-account-create-form input', '2nd account'); await driver.clickElement({ text: 'Create', tag: 'button' }); + await waitForAccountRendered(driver); // Check address of 2nd account - const secondAccountPublicAddress = await checkAccountDetails(driver); - assert.strictEqual(secondAccountPublicAddress, secondAccount); - await driver.delay(regularDelayMs); + const secondAccountPublicAddress = await retrieveShortenAccountAddress( + driver, + ); + assert.strictEqual( + secondAccountPublicAddress, + shortenAddress(secondAccount), + ); - // Give 2nd locally account some balance so it will not be removed after recovering SRP + // Log into the account with balance(account 1) + // and transfer some balance to 2nd account + // so they will not be removed after recovering SRP const accountOneSelector = await findAnotherAccountFromAccountList( driver, 1, 'Account 1', ); + await waitForAccountRendered(driver); await driver.clickElement(accountOneSelector); await sendTransaction(driver, secondAccount, '2.8'); @@ -102,41 +115,41 @@ describe('Add account', function () { await driver.clickElement( '[data-testid="account-options-menu-button"]', ); - await driver.delay(regularDelayMs); - await driver.clickElement('[data-testid="global-menu-lock"]'); await driver.delay(regularDelayMs); + await driver.waitForSelector('[data-testid="global-menu-lock"]'); + await driver.clickElement('[data-testid="global-menu-lock"]'); + await driver.waitForSelector('[data-testid="unlock-page"]'); // Recover via SRP in "forget password" option const restoreSeedLink = await driver.findClickableElement( '.unlock-page__link', ); - await restoreSeedLink.click(); - - await driver.delay(regularDelayMs); - await driver.pasteIntoField( '[data-testid="import-srp__srp-word-0"]', TEST_SEED_PHRASE, ); - await driver.fill('#password', 'correct horse battery staple'); await driver.fill('#confirm-password', 'correct horse battery staple'); - await driver.clickElement({ - text: enLocaleMessages.restore.message, - tag: 'button', - }); + + await driver.delay(regularDelayMs); + await driver.clickElement( + '[data-testid="create-new-vault-submit-button"]', + ); // Land in 1st account home page await driver.findElement('.home__main-view'); + await waitForAccountRendered(driver); // Check address of 1st account - const restoredFirstAccountPublicAddress = await checkAccountDetails( - driver, + const restoredFirstAccountPublicAddress = + await retrieveShortenAccountAddress(driver); + assert.equal( + restoredFirstAccountPublicAddress, + shortenAddress(firstAccount), ); - assert.equal(restoredFirstAccountPublicAddress, firstAccount); - await driver.delay(regularDelayMs); + // Check address of 2nd account const accountTwoSelector = await findAnotherAccountFromAccountList( driver, @@ -144,10 +157,13 @@ describe('Add account', function () { 'Account 2', ); await driver.clickElement(accountTwoSelector); - const restoredSecondAccountPublicAddress = await checkAccountDetails( - driver, + + const restoredSecondAccountPublicAddress = + await retrieveShortenAccountAddress(driver); + assert.equal( + restoredSecondAccountPublicAddress, + shortenAddress(secondAccount), ); - assert.equal(restoredSecondAccountPublicAddress, secondAccount); }, ); }); @@ -167,80 +183,71 @@ describe('Add account', function () { await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); - await driver.delay(regularDelayMs); + await waitForAccountRendered(driver); await driver.clickElement('[data-testid="account-menu-icon"]'); await driver.clickElement( '[data-testid="multichain-account-menu-add-account"]', ); + await driver.fill('.new-account-create-form input', '2nd account'); await driver.clickElement({ text: 'Create', tag: 'button' }); - // Open account menu again + // Wait for 2nd account to be created + await waitForAccountRendered(driver); + const secondAccountCreated = await driver.findElement( + '[data-testid="account-menu-icon"]', + ); + assert.equal(await secondAccountCreated.getText(), '2nd account'); + await driver.clickElement('[data-testid="account-menu-icon"]'); - // Show account list menu for second account + const menuItems = await driver.findElements( + '.multichain-account-list-item', + ); + assert.equal(menuItems.length, 2); + + // User cannot delete 2nd account generated from the SRP imported in onboarding await driver.clickElement( '.multichain-account-list-item--selected [data-testid="account-list-item-menu-button"]', ); + await driver.waitForElementNotPresent( + '[data-testid="account-list-menu-remove"]', + ); - const menuItems = await driver.findElements('.menu-item'); - assert.equal(menuItems.length, 2); - - // click out of menu + // Create 3rd account with private key await driver.clickElement('.menu__background'); - - // import with private key await driver.clickElement({ text: 'Import account', tag: 'button' }); - - // enter private key', await driver.fill('#private-key-box', testPrivateKey); await driver.clickElement({ text: 'Import', tag: 'button' }); - // should show the correct account name - const importedAccountName = await driver.findElement( + // Wait for 3rd account to be created + await waitForAccountRendered(driver); + const thirdAccountCreated = await driver.findElement( '[data-testid="account-menu-icon"]', ); - assert.equal(await importedAccountName.getText(), 'Account 3'); + assert.equal(await thirdAccountCreated.getText(), 'Account 3'); - // Open account menu again + // User can delete 3rd account imported with a private key await driver.clickElement('[data-testid="account-menu-icon"]'); - - // Show account list menu for second account + const importedMenuItems = await driver.findElements( + '.multichain-account-list-item', + ); + assert.equal(importedMenuItems.length, 3); await driver.clickElement( '.multichain-account-list-item--selected [data-testid="account-list-item-menu-button"]', ); - - const importedMenuItems = await driver.findElements('.menu-item'); - assert.equal(importedMenuItems.length, 3); - await driver.findElement('[data-testid="account-list-menu-remove"]'); }, ); }); }); -async function checkAccountDetails(driver) { - // Open account menu again - await driver.clickElement('[data-testid="account-menu-icon"]'); - - // Select account details for second account - await driver.clickElement( - '.multichain-account-list-item--selected [data-testid="account-list-item-menu-button"]', - ); - await driver.clickElement('[data-testid="account-list-menu-details"]'); - - await driver.findVisibleElement('.popover-bg'); - - // get the public address for the "second account" +async function retrieveShortenAccountAddress(driver) { + // get the shorten public address for account const accountDOM = await driver.waitForSelector( - '.qr-code .multichain-address-copy-button', + '.multichain-address-copy-button', ); - const accountAddress = await accountDOM.getText(); - - await driver.clickElement('button[aria-label="Close"]'); - await driver.waitForElementNotPresent('.popover-bg'); - - return accountAddress; + return await accountDOM.getText(); } diff --git a/test/e2e/tests/network-error.spec.js b/test/e2e/tests/network-error.spec.js index 31c47752b..beccd01f1 100644 --- a/test/e2e/tests/network-error.spec.js +++ b/test/e2e/tests/network-error.spec.js @@ -2,7 +2,7 @@ const { strict: assert } = require('assert'); const { convertToHexValue, withFixtures, - regularDelayMs, + assertAccountBalanceForDOM, } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); @@ -66,11 +66,12 @@ describe('Gas API fallback', function () { ganacheOptions, title: this.test.title, }, - async ({ driver }) => { + async ({ driver, ganacheServer }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); + await assertAccountBalanceForDOM(driver, ganacheServer); await driver.clickElement('[data-testid="eth-overview-send"]'); await driver.fill( @@ -83,7 +84,6 @@ describe('Gas API fallback', function () { await driver.clickElement({ text: 'Next', tag: 'button' }); - await driver.delay(regularDelayMs); await driver.findElement('.transaction-alerts'); const error = await driver.isElementPresent({ diff --git a/test/e2e/tests/send-eth.spec.js b/test/e2e/tests/send-eth.spec.js index 7b0c87708..0711c8750 100644 --- a/test/e2e/tests/send-eth.spec.js +++ b/test/e2e/tests/send-eth.spec.js @@ -318,7 +318,7 @@ describe('Send ETH from dapp using advanced gas controls', function () { }, title: this.test.title, }, - async ({ driver, ganacheServer }) => { + async ({ driver }) => { await driver.navigate(); await driver.fill('#password', 'correct horse battery staple'); await driver.press('#password', driver.Key.ENTER); @@ -361,8 +361,11 @@ describe('Send ETH from dapp using advanced gas controls', function () { await driver.waitUntilXWindowHandles(2); await driver.switchToWindow(extension); - // finds the transaction in the transactions list - await assertAccountBalanceForDOM(driver, ganacheServer); + // Identify the transaction in the transactions list + await driver.waitForSelector( + '[data-testid="eth-overview__primary-currency"]', + ); + await driver.clickElement('[data-testid="home__activity-tab"]'); await driver.waitForSelector( '.transaction-list__completed-transactions .transaction-list-item:nth-of-type(1)',