From be08cfec0c07ff8f4108f2d29b77885b30d61ae7 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 15 Jan 2020 15:34:15 -0400 Subject: [PATCH] Wait until element is clickable before clicking in e2e tests (#7823) * Wait until element is clickable before clicking in e2e tests A new `findClickableElement` has been added to the webdriver to allow finding an element and blocking until it's both visible and enabled. This is now used by the pre-existing `clickElement` method as well. All cases where something is clicked in the e2e tests have been updated to use one of these methods, to ensure we don't run into intermittent failures when loading screens take longer than usual. --- test/e2e/address-book.spec.js | 69 ++-- test/e2e/ethereum-on.spec.js | 40 +-- test/e2e/from-import-ui.spec.js | 107 +++---- test/e2e/incremental-security.spec.js | 46 +-- test/e2e/metamask-responsive-ui.spec.js | 65 ++-- test/e2e/metamask-ui.spec.js | 405 ++++++++---------------- test/e2e/permissions.spec.js | 50 +-- test/e2e/send-edit.spec.js | 45 +-- test/e2e/signature-request.spec.js | 21 +- test/e2e/threebox.spec.js | 76 ++--- test/e2e/web3.spec.js | 40 +-- test/e2e/webdriver/driver.js | 29 +- 12 files changed, 347 insertions(+), 646 deletions(-) diff --git a/test/e2e/address-book.spec.js b/test/e2e/address-book.spec.js index 1ce1635f8..8b6ef3310 100644 --- a/test/e2e/address-book.spec.js +++ b/test/e2e/address-book.spec.js @@ -55,35 +55,29 @@ describe('MetaMask', function () { describe('Going through the first time flow', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Create New Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) it('accepts a secure password', async () => { const passwordBox = await driver.findElement(By.css('.first-time-flow__form #create-password')) const passwordBoxConfirm = await driver.findElement(By.css('.first-time-flow__form #confirm-password')) - const button = await driver.findElement(By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() - - await button.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) + await driver.clickElement(By.css('.first-time-flow__form button')) await driver.delay(regularDelayMs) }) @@ -91,8 +85,7 @@ describe('MetaMask', function () { it('reveals the seed phrase', async () => { const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') - const revealSeedPhraseButton = await driver.findElement(byRevealButton, 10000) - await revealSeedPhraseButton.click() + await driver.clickElement(byRevealButton) await driver.delay(regularDelayMs) const revealedSeedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')) @@ -100,16 +93,13 @@ describe('MetaMask', function () { assert.equal(seedPhrase.split(' ').length, 12) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) await driver.delay(regularDelayMs) }) async function clickWordAndWait (word) { const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` - const word0 = await driver.findElement(By.xpath(xpath)) - - await word0.click() + await driver.clickElement(By.xpath(xpath)) await driver.delay(tinyDelayMs) } @@ -120,33 +110,30 @@ describe('MetaMask', function () { await clickWordAndWait(word) } - const confirm = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirm.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) }) describe('Import seed phrase', () => { it('logs out of the vault', async () => { - const accountMenu = await driver.findElement(By.css('.account-menu__icon')) - await accountMenu.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const logoutButton = await driver.findElement(By.css('.account-menu__logout-button')) + const logoutButton = await driver.findClickableElement(By.css('.account-menu__logout-button')) assert.equal(await logoutButton.getText(), 'Log out') await logoutButton.click() await driver.delay(regularDelayMs) }) it('imports seed phrase', async () => { - const restoreSeedLink = await driver.findElement(By.css('.unlock-page__link--import')) + const restoreSeedLink = await driver.findClickableElement(By.css('.unlock-page__link--import')) assert.equal(await restoreSeedLink.getText(), 'Import using account seed phrase') await restoreSeedLink.click() await driver.delay(regularDelayMs) @@ -160,8 +147,7 @@ describe('MetaMask', function () { await passwordInputs[0].sendKeys('correct horse battery staple') await passwordInputs[1].sendKeys('correct horse battery staple') - const restoreButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.restore.message}')]`)) - await restoreButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.restore.message}')]`)) await driver.delay(regularDelayMs) }) @@ -174,24 +160,21 @@ describe('MetaMask', function () { describe('Adds an entry to the address book and sends eth to that address', () => { it('starts a send transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970') await driver.delay(regularDelayMs) - const addToAddressBookButton = await driver.findElement(By.css('.dialog.send__dialog.dialog--message')) - await addToAddressBookButton.click() + await driver.clickElement(By.css('.dialog.send__dialog.dialog--message')) const addressBookAddModal = await driver.findElement(By.css('span .modal')) await driver.findElement(By.css('.add-to-address-book-modal')) const addressBookInput = await driver.findElement(By.css('.add-to-address-book-modal__input')) await addressBookInput.sendKeys('Test Name 1') await driver.delay(tinyDelayMs) - const addressBookSaveButton = await driver.findElement(By.css('.add-to-address-book-modal__footer .btn-primary')) - await addressBookSaveButton.click() + await driver.clickElement(By.css('.add-to-address-book-modal__footer .btn-primary')) await driver.wait(until.stalenessOf(addressBookAddModal)) @@ -203,14 +186,12 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs * 2) }) @@ -227,16 +208,14 @@ describe('MetaMask', function () { describe('Sends to an address book entry', () => { it('starts a send transaction by clicking address book entry', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) - const recipientRow = await driver.findElement(By.css('.send__select-recipient-wrapper__group-item')) const recipientRowTitle = await driver.findElement(By.css('.send__select-recipient-wrapper__group-item__title')) const recipientRowTitleString = await recipientRowTitle.getText() assert.equal(recipientRowTitleString, 'Test Name 1') - await recipientRow.click() + await driver.clickElement(By.css('.send__select-recipient-wrapper__group-item')) await driver.delay(regularDelayMs) const inputAmount = await driver.findElement(By.css('.unit-input__input')) @@ -244,14 +223,12 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs * 2) }) diff --git a/test/e2e/ethereum-on.spec.js b/test/e2e/ethereum-on.spec.js index 0347bee9e..30bacf16a 100644 --- a/test/e2e/ethereum-on.spec.js +++ b/test/e2e/ethereum-on.spec.js @@ -54,45 +54,37 @@ describe('MetaMask', function () { describe('Going through the first time flow, but skipping the seed phrase challenge', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Create New Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) it('accepts a secure password', async () => { const passwordBox = await driver.findElement(By.css('.first-time-flow__form #create-password')) const passwordBoxConfirm = await driver.findElement(By.css('.first-time-flow__form #confirm-password')) - const button = await driver.findElement(By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() - - await button.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) + await driver.clickElement(By.css('.first-time-flow__form button')) await driver.delay(largeDelayMs) }) it('skips the seed phrase challenge', async () => { - const button = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`)) - await button.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`)) await driver.delay(regularDelayMs) - const detailsButton = await driver.findElement(By.css('.account-details__details-button')) - await detailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.delay(regularDelayMs) }) @@ -101,8 +93,7 @@ describe('MetaMask', function () { publicAddress = await addressInput.getAttribute('value') const accountModal = await driver.findElement(By.css('span .modal')) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.wait(until.stalenessOf(accountModal)) await driver.delay(regularDelayMs) @@ -119,8 +110,7 @@ describe('MetaMask', function () { await driver.openNewPage('http://127.0.0.1:8080/') await driver.delay(regularDelayMs) - const connectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Connect')]`)) - await connectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.delay(regularDelayMs) @@ -135,11 +125,9 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) - const accountButton = await driver.findElement(By.css('.permissions-connect-choose-account__account')) - await accountButton.click() + await driver.clickElement(By.css('.permissions-connect-choose-account__account')) - const submitButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Submit')]`)) - await submitButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) await driver.switchToWindow(dapp) @@ -155,12 +143,10 @@ describe('MetaMask', function () { it('changes the network', async () => { await driver.switchToWindow(extension) - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) - const ropstenButton = await driver.findElement(By.xpath(`//span[contains(text(), 'Ropsten')]`)) - await ropstenButton.click() + await driver.clickElement(By.xpath(`//span[contains(text(), 'Ropsten')]`)) await driver.delay(largeDelayMs) }) diff --git a/test/e2e/from-import-ui.spec.js b/test/e2e/from-import-ui.spec.js index d5fa0684c..fa8e117a2 100644 --- a/test/e2e/from-import-ui.spec.js +++ b/test/e2e/from-import-ui.spec.js @@ -59,20 +59,17 @@ describe('Using MetaMask with an existing account', function () { describe('First time flow starting from an existing seed phrase', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Import Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) @@ -86,46 +83,39 @@ describe('Using MetaMask with an existing account', function () { const [confirmPassword] = await driver.findElements(By.id('confirm-password')) confirmPassword.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - const [importButton] = await driver.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) }) describe('Show account information', () => { it('shows the correct account address', async () => { - const accountDetailsButton = await driver.findElement(By.css('.account-details__details-button')) - await accountDetailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.findVisibleElement(By.css('.qr-wrapper')) await driver.delay(regularDelayMs) const [address] = await driver.findElements(By.css('input.qr-ellip-address')) assert.equal(await address.getAttribute('value'), testAddress) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.delay(largeDelayMs) }) it('shows a QR code for the account', async () => { - const accountDetailsButton = await driver.findElement(By.css('.account-details__details-button')) - await accountDetailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.findVisibleElement(By.css('.qr-wrapper')) const detailModal = await driver.findElement(By.css('span .modal')) await driver.delay(regularDelayMs) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.wait(until.stalenessOf(detailModal)) await driver.delay(regularDelayMs) }) @@ -133,11 +123,10 @@ describe('Using MetaMask with an existing account', function () { describe('Log out and log back in', () => { it('logs out of the account', async () => { - const accountIdenticon = await driver.findElement(By.css('.account-menu__icon .identicon')) - await accountIdenticon.click() + await driver.clickElement(By.css('.account-menu__icon .identicon')) await driver.delay(regularDelayMs) - const [logoutButton] = await driver.findElements(By.css('.account-menu__logout-button')) + const logoutButton = await driver.findClickableElement(By.css('.account-menu__logout-button')) assert.equal(await logoutButton.getText(), 'Log out') await logoutButton.click() await driver.delay(regularDelayMs) @@ -153,22 +142,18 @@ describe('Using MetaMask with an existing account', function () { describe('Add an account', () => { it('switches to localhost', async () => { - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) - const [localhost] = await driver.findElements(By.xpath(`//span[contains(text(), 'Localhost')]`)) - await localhost.click() + await driver.clickElement(By.xpath(`//span[contains(text(), 'Localhost')]`)) await driver.delay(largeDelayMs) }) it('choose Create Account from the account menu', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const [createAccount] = await driver.findElements(By.xpath(`//div[contains(text(), 'Create Account')]`)) - await createAccount.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Create Account')]`)) await driver.delay(regularDelayMs) }) @@ -177,8 +162,7 @@ describe('Using MetaMask with an existing account', function () { await accountName.sendKeys('2nd account') await driver.delay(regularDelayMs) - const [createButton] = await driver.findElements(By.xpath(`//button[contains(text(), 'Create')]`)) - await createButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create')]`)) await driver.delay(regularDelayMs) }) @@ -191,20 +175,17 @@ describe('Using MetaMask with an existing account', function () { describe('Switch back to original account', () => { it('chooses the original account from the account menu', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const [originalAccountMenuItem] = await driver.findElements(By.css('.account-menu__name')) - await originalAccountMenuItem.click() + await driver.clickElement(By.css('.account-menu__name')) await driver.delay(regularDelayMs) }) }) describe('Send ETH from inside MetaMask', () => { it('starts a send transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -214,25 +195,21 @@ describe('Using MetaMask with an existing account', function () { await inputAmount.sendKeys('1') // Set the gas limit - const configureGas = await driver.findElement(By.css('.advanced-gas-options-btn')) - await configureGas.click() + await driver.clickElement(By.css('.advanced-gas-options-btn')) await driver.delay(regularDelayMs) const gasModal = await driver.findElement(By.css('span .modal')) - const save = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await save.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.wait(until.stalenessOf(gasModal)) await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) @@ -250,12 +227,10 @@ describe('Using MetaMask with an existing account', function () { describe('Imports an account with private key', () => { it('choose Create Account from the account menu', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const [importAccount] = await driver.findElements(By.xpath(`//div[contains(text(), 'Import Account')]`)) - await importAccount.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Import Account')]`)) await driver.delay(regularDelayMs) }) @@ -263,8 +238,7 @@ describe('Using MetaMask with an existing account', function () { const privateKeyInput = await driver.findElement(By.css('#private-key-box')) await privateKeyInput.sendKeys(testPrivateKey2) await driver.delay(regularDelayMs) - const importButtons = await driver.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButtons[0].click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver.delay(regularDelayMs) }) @@ -283,12 +257,10 @@ describe('Using MetaMask with an existing account', function () { describe('Imports and removes an account', () => { it('choose Create Account from the account menu', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const [importAccount] = await driver.findElements(By.xpath(`//div[contains(text(), 'Import Account')]`)) - await importAccount.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Import Account')]`)) await driver.delay(regularDelayMs) }) @@ -296,8 +268,7 @@ describe('Using MetaMask with an existing account', function () { const privateKeyInput = await driver.findElement(By.css('#private-key-box')) await privateKeyInput.sendKeys(testPrivateKey3) await driver.delay(regularDelayMs) - const importButtons = await driver.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButtons[0].click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver.delay(regularDelayMs) }) @@ -306,23 +277,20 @@ describe('Using MetaMask with an existing account', function () { assert.equal(await accountName.getText(), 'Account 5') await driver.delay(regularDelayMs) - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) const accountListItems = await driver.findElements(By.css('.account-menu__account')) assert.equal(accountListItems.length, 5) - const removeAccountIcons = await driver.findElements(By.css('.remove-account-icon')) - await removeAccountIcons[1].click() + await driver.clickElement(By.css('.account-menu__account:last-of-type > .remove-account-icon')) await driver.delay(tinyDelayMs) await driver.findElement(By.css('.confirm-remove-account__account')) }) it('should remove the account', async () => { - const removeButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Remove')]`)) - await removeButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Remove')]`)) await driver.delay(regularDelayMs) @@ -337,17 +305,14 @@ describe('Using MetaMask with an existing account', function () { describe('Connects to a Hardware wallet', () => { it('choose Connect Hardware Wallet from the account menu', async () => { - const [connectAccount] = await driver.findElements(By.xpath(`//div[contains(text(), 'Connect Hardware Wallet')]`)) - await connectAccount.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Connect Hardware Wallet')]`)) await driver.delay(regularDelayMs) }) it('should open the TREZOR Connect popup', async () => { - const trezorButton = await driver.findElements(By.css('.hw-connect__btn')) - await trezorButton[1].click() + await driver.clickElement(By.css('.hw-connect__btn:nth-of-type(2)')) await driver.delay(regularDelayMs) - const connectButtons = await driver.findElements(By.xpath(`//button[contains(text(), 'Connect')]`)) - await connectButtons[0].click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.delay(regularDelayMs) const allWindows = await driver.getAllWindowHandles() assert.equal(allWindows.length, 2) diff --git a/test/e2e/incremental-security.spec.js b/test/e2e/incremental-security.spec.js index f3708c1e1..197c94152 100644 --- a/test/e2e/incremental-security.spec.js +++ b/test/e2e/incremental-security.spec.js @@ -59,45 +59,38 @@ describe('MetaMask', function () { describe('Going through the first time flow, but skipping the seed phrase challenge', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Create New Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) it('accepts a secure password', async () => { const passwordBox = await driver.findElement(By.css('.first-time-flow__form #create-password')) const passwordBoxConfirm = await driver.findElement(By.css('.first-time-flow__form #confirm-password')) - const button = await driver.findElement(By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - await button.click() + await driver.clickElement(By.css('.first-time-flow__form button')) await driver.delay(regularDelayMs) }) it('skips the seed phrase challenge', async () => { - const button = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`)) - await button.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`)) await driver.delay(regularDelayMs) - const detailsButton = await driver.findElement(By.css('.account-details__details-button')) - await detailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.delay(regularDelayMs) }) @@ -107,8 +100,7 @@ describe('MetaMask', function () { const accountModal = await driver.findElement(By.css('span .modal')) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.wait(until.stalenessOf(accountModal)) await driver.delay(regularDelayMs) @@ -132,8 +124,7 @@ describe('MetaMask', function () { await addressInput.sendKeys(publicAddress) await driver.delay(regularDelayMs) - const sendButton = await driver.findElement(By.css('#send')) - await sendButton.click() + await driver.clickElement(By.css('#send')) const txStatus = await driver.findElement(By.css('#success')) await driver.wait(until.elementTextMatches(txStatus, /Success/), 15000) @@ -159,8 +150,7 @@ describe('MetaMask', function () { }) it('should take the user to the seedphrase backup screen', async () => { - const backupButton = await driver.findElement(By.css('.home-notification__accept-button')) - await backupButton.click() + await driver.clickElement(By.css('.home-notification__accept-button')) await driver.delay(regularDelayMs) }) @@ -168,8 +158,7 @@ describe('MetaMask', function () { it('reveals the seed phrase', async () => { const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') - const revealSeedPhraseButton = await driver.findElement(byRevealButton) - await revealSeedPhraseButton.click() + await driver.clickElement(byRevealButton) await driver.delay(regularDelayMs) const revealedSeedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')) @@ -177,16 +166,13 @@ describe('MetaMask', function () { assert.equal(seedPhrase.split(' ').length, 12) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) await driver.delay(regularDelayMs) }) async function clickWordAndWait (word) { const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` - const word0 = await driver.findElement(By.xpath(xpath)) - - await word0.click() + await driver.clickElement(By.xpath(xpath)) await driver.delay(tinyDelayMs) } @@ -197,14 +183,12 @@ describe('MetaMask', function () { await clickWordAndWait(word) } - const confirm = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirm.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) it('can click through the success screen', async () => { - const confirm = await driver.findElement(By.xpath(`//button[contains(text(), 'All Done')]`)) - await confirm.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'All Done')]`)) await driver.delay(regularDelayMs) }) diff --git a/test/e2e/metamask-responsive-ui.spec.js b/test/e2e/metamask-responsive-ui.spec.js index 8f991579c..b06c11f8e 100644 --- a/test/e2e/metamask-responsive-ui.spec.js +++ b/test/e2e/metamask-responsive-ui.spec.js @@ -49,35 +49,30 @@ describe('MetaMask', function () { describe('Going through the first time flow', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Create New Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "I agree" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-primary')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-primary')) await driver.delay(largeDelayMs) }) it('accepts a secure password', async () => { const passwordBox = await driver.findElement(By.css('.first-time-flow__form #create-password')) const passwordBoxConfirm = await driver.findElement(By.css('.first-time-flow__form #confirm-password')) - const button = await driver.findElement(By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - await button.click() + await driver.clickElement(By.css('.first-time-flow__form button')) await driver.delay(regularDelayMs) }) @@ -85,8 +80,7 @@ describe('MetaMask', function () { it('reveals the seed phrase', async () => { const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') - const revealSeedPhraseButton = await driver.findElement(byRevealButton) - await revealSeedPhraseButton.click() + await driver.clickElement(byRevealButton) await driver.delay(regularDelayMs) const revealedSeedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')) @@ -94,16 +88,13 @@ describe('MetaMask', function () { assert.equal(seedPhrase.split(' ').length, 12) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) await driver.delay(regularDelayMs) }) async function clickWordAndWait (word) { const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` - const word0 = await driver.findElement(By.xpath(xpath)) - - await word0.click() + await driver.clickElement(By.xpath(xpath)) await driver.delay(tinyDelayMs) } @@ -114,23 +105,20 @@ describe('MetaMask', function () { await clickWordAndWait(word) } - const confirm = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirm.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) }) describe('Show account information', () => { it('show account details dropdown menu', async () => { - const openInBrowser = await driver.findElement(By.css('div.menu-bar__open-in-browser')) - await openInBrowser.click() + await driver.clickElement(By.css('div.menu-bar__open-in-browser')) const options = await driver.findElements(By.css('div.menu.account-details-dropdown div.menu__item')) assert.equal(options.length, 4) // HD Wallet type does not have to show the Remove Account option await driver.delay(regularDelayMs) @@ -139,18 +127,17 @@ describe('MetaMask', function () { describe('Import seed phrase', () => { it('logs out of the vault', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const logoutButton = await driver.findElement(By.css('.account-menu__logout-button')) + const logoutButton = await driver.findClickableElement(By.css('.account-menu__logout-button')) assert.equal(await logoutButton.getText(), 'Log out') await logoutButton.click() await driver.delay(regularDelayMs) }) it('imports seed phrase', async () => { - const restoreSeedLink = await driver.findElement(By.css('.unlock-page__link--import')) + const restoreSeedLink = await driver.findClickableElement(By.css('.unlock-page__link--import')) assert.equal(await restoreSeedLink.getText(), 'Import using account seed phrase') await restoreSeedLink.click() await driver.delay(regularDelayMs) @@ -164,18 +151,15 @@ describe('MetaMask', function () { await passwordInputs[0].sendKeys('correct horse battery staple') await passwordInputs[1].sendKeys('correct horse battery staple') - const restoreButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.restore.message}')]`)) - await restoreButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.restore.message}')]`)) await driver.delay(regularDelayMs) }) it('switches to localhost', async () => { - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) - const [localhost] = await driver.findElements(By.xpath(`//span[contains(text(), 'Localhost')]`)) - await localhost.click() + await driver.clickElement(By.xpath(`//span[contains(text(), 'Localhost')]`)) await driver.delay(largeDelayMs * 2) }) @@ -188,8 +172,7 @@ describe('MetaMask', function () { describe('Send ETH from inside MetaMask', () => { it('starts to send a transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -205,28 +188,24 @@ describe('MetaMask', function () { it('opens and closes the gas modal', async function () { // Set the gas limit - const configureGas = await driver.findElement(By.css('.advanced-gas-options-btn')) - await configureGas.click() + await driver.clickElement(By.css('.advanced-gas-options-btn')) await driver.delay(regularDelayMs) const gasModal = await driver.findElement(By.css('span .modal')) - const save = await driver.findElement(By.css('.page-container__header-close-text')) - await save.click() + await driver.clickElement(By.css('.page-container__header-close-text')) await driver.wait(until.stalenessOf(gasModal), 10000) await driver.delay(regularDelayMs) }) it('clicks through to the confirm screen', async function () { // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs) }) diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index c2bfdb55a..3433d68ed 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -50,35 +50,30 @@ describe('MetaMask', function () { describe('Going through the first time flow', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Create New Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) it('accepts a secure password', async () => { const passwordBox = await driver.findElement(By.css('.first-time-flow__form #create-password')) const passwordBoxConfirm = await driver.findElement(By.css('.first-time-flow__form #confirm-password')) - const button = await driver.findElement(By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - await button.click() + await driver.clickElement(By.css('.first-time-flow__form button')) await driver.delay(regularDelayMs) }) @@ -87,8 +82,7 @@ describe('MetaMask', function () { it('reveals the seed phrase', async () => { const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button') await driver.findElement(byRevealButton) - const revealSeedPhraseButton = await driver.findElement(byRevealButton) - await revealSeedPhraseButton.click() + await driver.clickElement(byRevealButton) await driver.delay(regularDelayMs) const revealedSeedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')) @@ -96,16 +90,13 @@ describe('MetaMask', function () { assert.equal(seedPhrase.split(' ').length, 12) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`)) await driver.delay(regularDelayMs) }) async function clickWordAndWait (word) { const xpath = `//div[contains(@class, 'confirm-seed-phrase__seed-word--shuffled') and not(contains(@class, 'confirm-seed-phrase__seed-word--selected')) and contains(text(), '${word}')]` - const word0 = await driver.findElement(By.xpath(xpath)) - - await word0.click() + await driver.clickElement(By.xpath(xpath)) await driver.delay(tinyDelayMs) } @@ -116,29 +107,25 @@ describe('MetaMask', function () { await clickWordAndWait(word) } - const confirm = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirm.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) }) describe('Show account information', () => { it('shows the QR code for the account', async () => { - const accountDetailsButton = await driver.findElement(By.css('.account-details__details-button')) - await accountDetailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.findVisibleElement(By.css('.qr-wrapper')) await driver.delay(regularDelayMs) const accountModal = await driver.findElement(By.css('span .modal')) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.wait(until.stalenessOf(accountModal)) await driver.delay(regularDelayMs) @@ -147,11 +134,10 @@ describe('MetaMask', function () { describe('Log out an log back in', () => { it('logs out of the account', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const logoutButton = await driver.findElement(By.css('.account-menu__logout-button')) + const logoutButton = await driver.findClickableElement(By.css('.account-menu__logout-button')) assert.equal(await logoutButton.getText(), 'Log out') await logoutButton.click() await driver.delay(regularDelayMs) @@ -167,12 +153,10 @@ describe('MetaMask', function () { describe('Add account', () => { it('choose Create Account from the account menu', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const createAccount = await driver.findElement(By.xpath(`//div[contains(text(), 'Create Account')]`)) - await createAccount.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Create Account')]`)) await driver.delay(regularDelayMs) }) @@ -181,8 +165,7 @@ describe('MetaMask', function () { await accountName.sendKeys('2nd account') await driver.delay(regularDelayMs) - const create = await driver.findElement(By.xpath(`//button[contains(text(), 'Create')]`)) - await create.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create')]`)) await driver.delay(largeDelayMs) }) @@ -195,18 +178,17 @@ describe('MetaMask', function () { describe('Import seed phrase', () => { it('logs out of the vault', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const logoutButton = await driver.findElement(By.css('.account-menu__logout-button')) + const logoutButton = await driver.findClickableElement(By.css('.account-menu__logout-button')) assert.equal(await logoutButton.getText(), 'Log out') await logoutButton.click() await driver.delay(regularDelayMs) }) it('imports seed phrase', async () => { - const restoreSeedLink = await driver.findElement(By.css('.unlock-page__link--import')) + const restoreSeedLink = await driver.findClickableElement(By.css('.unlock-page__link--import')) assert.equal(await restoreSeedLink.getText(), 'Import using account seed phrase') await restoreSeedLink.click() await driver.delay(regularDelayMs) @@ -220,8 +202,7 @@ describe('MetaMask', function () { await passwordInputs[0].sendKeys('correct horse battery staple') await passwordInputs[1].sendKeys('correct horse battery staple') - const restoreButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.restore.message}')]`)) - await restoreButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.restore.message}')]`)) await driver.delay(regularDelayMs) }) @@ -234,8 +215,7 @@ describe('MetaMask', function () { describe('Send ETH from inside MetaMask using default gas', () => { it('starts a send transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -256,7 +236,7 @@ describe('MetaMask', function () { await driver.assertElementNotPresent(By.css('.send-v2__error-amount')) - const amountMax = await driver.findElement(By.css('.send-v2__amount-max')) + const amountMax = await driver.findClickableElement(By.css('.send-v2__amount-max')) await amountMax.click() assert.equal(await inputAmount.isEnabled(), false) @@ -276,14 +256,12 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs * 2) }) @@ -300,8 +278,7 @@ describe('MetaMask', function () { describe('Send ETH from inside MetaMask using fast gas option', () => { it('starts a send transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -314,19 +291,16 @@ describe('MetaMask', function () { assert.equal(inputValue, '1') // Set the gas price - const fastGas = await driver.findElement(By.xpath(`//button/div/div[contains(text(), "Fast")]`)) - await fastGas.click() + await driver.clickElement(By.xpath(`//button/div/div[contains(text(), "Fast")]`)) await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs) }) @@ -343,8 +317,7 @@ describe('MetaMask', function () { describe('Send ETH from inside MetaMask using advanced gas modal', () => { it('starts a send transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -357,19 +330,16 @@ describe('MetaMask', function () { assert.equal(inputValue, '1') // Set the gas limit - const configureGas = await driver.findElement(By.css('.advanced-gas-options-btn')) - await configureGas.click() + await driver.clickElement(By.css('.advanced-gas-options-btn')) await driver.delay(regularDelayMs) const gasModal = await driver.findElement(By.css('span .modal')) - const save = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await save.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.wait(until.stalenessOf(gasModal)) await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) @@ -378,8 +348,7 @@ describe('MetaMask', function () { const transactionAmount = transactionAmounts[0] assert.equal(await transactionAmount.getText(), '1') - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs) }) @@ -401,33 +370,27 @@ describe('MetaMask', function () { let dapp it('goes to the settings screen', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const settingsButton = await driver.findElement(By.xpath(`//div[contains(text(), 'Settings')]`)) - await settingsButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Settings')]`)) // await driver.findElement(By.css('.tab-bar')) - const advancedTab = await driver.findElement(By.xpath(`//div[contains(text(), 'Advanced')]`)) - await advancedTab.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Advanced')]`)) await driver.delay(regularDelayMs) - const showConversionToggle = await driver.findElement(By.css('[data-testid="advanced-setting-show-testnet-conversion"] .settings-page__content-item-col > div > div')) - await showConversionToggle.click() + await driver.clickElement(By.css('[data-testid="advanced-setting-show-testnet-conversion"] .settings-page__content-item-col > div > div')) const advancedGasTitle = await driver.findElement(By.xpath(`//span[contains(text(), 'Advanced gas controls')]`)) await driver.scrollToElement(advancedGasTitle) - const advancedGasToggle = await driver.findElement(By.css('[data-testid="advanced-setting-advanced-gas-inline"] .settings-page__content-item-col > div > div')) - await advancedGasToggle.click() + await driver.clickElement(By.css('[data-testid="advanced-setting-advanced-gas-inline"] .settings-page__content-item-col > div > div')) windowHandles = await driver.getAllWindowHandles() extension = windowHandles[0] await driver.closeAllWindowHandlesExcept([extension]) - const metamaskHomeButton = await driver.findElement(By.css('.app-header__logo-container')) - await metamaskHomeButton.click() + await driver.clickElement(By.css('.app-header__logo-container')) await driver.delay(largeDelayMs) }) @@ -436,8 +399,7 @@ describe('MetaMask', function () { await driver.openNewPage('http://127.0.0.1:8080/') await driver.delay(regularDelayMs) - const connectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Connect')]`)) - await connectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.delay(regularDelayMs) @@ -452,11 +414,9 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) - const accountButton = await driver.findElement(By.css('.permissions-connect-choose-account__account')) - await accountButton.click() + await driver.clickElement(By.css('.permissions-connect-choose-account__account')) - const submitButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Submit')]`)) - await submitButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) await driver.switchToWindow(dapp) @@ -464,8 +424,7 @@ describe('MetaMask', function () { }) it('initiates a send from the dapp', async () => { - const send3eth = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`), 10000) - await send3eth.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`), 10000) await driver.delay(2000) windowHandles = await driver.getAllWindowHandles() @@ -491,8 +450,7 @@ describe('MetaMask', function () { await driver.delay(1000) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`), 10000) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`), 10000) await driver.delay(regularDelayMs) await driver.waitUntilXWindowHandles(2) @@ -500,39 +458,24 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) }) - let txValues - it('finds the transaction in the transactions list', async function () { await driver.wait(async () => { const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item')) return confirmedTxes.length === 4 }, 10000) - txValues = await driver.findElements(By.css('.transaction-list-item__amount--primary')) - await driver.wait(until.elementTextMatches(txValues[0], /-3\s*ETH/), 10000) + const txValue = await driver.findClickableElement(By.css('.transaction-list-item__amount--primary')) + await driver.wait(until.elementTextMatches(txValue, /-3\s*ETH/), 10000) }) it('the transaction has the expected gas price', async function () { - await driver.delay(largeDelayMs) - let txGasPriceLabels - let txGasPrices - try { - await txValues[0].click() - txGasPrices = await driver.findElements(By.css('.transaction-breakdown__value')) - txGasPriceLabels = await driver.findElements(By.css('.transaction-breakdown-row__title')) - txGasPrices = await driver.findElements(By.css('.transaction-breakdown__value')) - await driver.wait(until.elementTextMatches(txGasPrices[3], /^10$/), 10000) - } catch (e) { - console.log(e.message) - txValues = await driver.findElements(By.css('.transaction-list-item__amount--primary')) - await txValues[0].click() - txGasPriceLabels = await driver.findElements(By.css('.transaction-breakdown-row__title')) - txGasPrices = await driver.findElements(By.css('.transaction-breakdown__value')) - await driver.wait(until.elementTextMatches(txGasPrices[3], /^10$/), 10000) - } + const txValue = await driver.findClickableElement(By.css('.transaction-list-item__amount--primary')) + await txValue.click() + const txGasPrices = await driver.findElements(By.css('.transaction-breakdown__value')) + const txGasPriceLabels = await driver.findElements(By.css('.transaction-breakdown-row__title')) + await driver.wait(until.elementTextMatches(txGasPrices[3], /^10$/), 10000) assert(txGasPriceLabels[2]) - - await txValues[0].click() + await txValue.click() }) }) @@ -548,11 +491,11 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(largeDelayMs) - const send3eth = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) + const send3eth = await driver.findClickableElement(By.xpath(`//button[contains(text(), 'Send')]`)) await send3eth.click() await driver.delay(largeDelayMs) - const contractDeployment = await driver.findElement(By.xpath(`//button[contains(text(), 'Deploy Contract')]`)) + const contractDeployment = await driver.findClickableElement(By.xpath(`//button[contains(text(), 'Deploy Contract')]`)) await contractDeployment.click() await driver.delay(largeDelayMs) @@ -564,16 +507,8 @@ describe('MetaMask', function () { await driver.switchToWindow(extension) await driver.delay(regularDelayMs) - let transactions = await driver.findElements(By.css('.transaction-list-item')) - await transactions[0].click() - await driver.delay(regularDelayMs) - try { - transactions = await driver.findElements(By.css('.transaction-list-item')) - await transactions[0].click() - } catch (e) { - console.log(e) - } - await driver.delay(regularDelayMs) + await driver.clickElement(By.css('.transaction-list-item')) + await driver.delay(largeDelayMs) }) it('navigates the transactions', async () => { @@ -625,8 +560,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(regularDelayMs) - const send3eth = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await send3eth.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) await driver.switchToWindow(extension) @@ -639,8 +573,7 @@ describe('MetaMask', function () { it('rejects a transaction', async () => { await driver.delay(tinyDelayMs) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Reject')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Reject')]`)) await driver.delay(largeDelayMs * 2) const navigationElement = await driver.findElement(By.css('.confirm-page-container-navigation')) @@ -651,9 +584,7 @@ describe('MetaMask', function () { it('confirms a transaction', async () => { await driver.delay(tinyDelayMs / 2) - const rejectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await driver.delay(tinyDelayMs / 2) - await rejectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) const navigationElement = await driver.findElement(By.css('.confirm-page-container-navigation')) @@ -664,12 +595,10 @@ describe('MetaMask', function () { }) it('rejects the rest of the transactions', async () => { - const rejectAllButton = await driver.findElement(By.xpath(`//a[contains(text(), 'Reject 3')]`)) - await rejectAllButton.click() + await driver.clickElement(By.xpath(`//a[contains(text(), 'Reject 3')]`)) await driver.delay(regularDelayMs) - const rejectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Reject All')]`)) - await rejectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Reject All')]`)) await driver.delay(largeDelayMs * 2) const confirmedTxes = await driver.findElements(By.css('.transaction-list__completed-transactions .transaction-list-item')) @@ -689,21 +618,18 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(regularDelayMs) - const deployContractButton = await driver.findElement(By.css('#deployButton')) - await deployContractButton.click() + await driver.clickElement(By.css('#deployButton')) await driver.delay(regularDelayMs) await driver.switchToWindow(extension) await driver.delay(regularDelayMs) - const txListItem = await driver.findElement(By.xpath(`//div[contains(text(), 'Contract Deployment')]`)) - await txListItem.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Contract Deployment')]`)) await driver.delay(largeDelayMs) }) it('displays the contract creation data', async () => { - const dataTab = await driver.findElement(By.xpath(`//li[contains(text(), 'Data')]`)) - await dataTab.click() + await driver.clickElement(By.xpath(`//li[contains(text(), 'Data')]`)) await driver.delay(regularDelayMs) await driver.findElement(By.xpath(`//div[contains(text(), '127.0.0.1')]`)) @@ -712,14 +638,12 @@ describe('MetaMask', function () { const confirmDataText = await confirmDataDiv.getText() assert.equal(confirmDataText.match(/0x608060405234801561001057600080fd5b5033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff/)) - const detailsTab = await driver.findElement(By.xpath(`//li[contains(text(), 'Details')]`)) - await detailsTab.click() + await driver.clickElement(By.xpath(`//li[contains(text(), 'Details')]`)) await driver.delay(regularDelayMs) }) it('confirms a deploy contract transaction', async () => { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs) await driver.wait(async () => { @@ -739,8 +663,7 @@ describe('MetaMask', function () { let contractStatus = await driver.findElement(By.css('#contractStatus')) await driver.wait(until.elementTextMatches(contractStatus, /Deployed/), 15000) - const depositButton = await driver.findElement(By.css('#depositButton')) - await depositButton.click() + await driver.clickElement(By.css('#depositButton')) await driver.delay(largeDelayMs) contractStatus = await driver.findElement(By.css('#contractStatus')) @@ -750,20 +673,18 @@ describe('MetaMask', function () { await driver.delay(largeDelayMs * 2) await driver.findElements(By.css('.transaction-list-item')) - const [txListValue] = await driver.findElements(By.css('.transaction-list-item__amount--primary')) + const txListValue = await driver.findClickableElement(By.css('.transaction-list-item__amount--primary')) await driver.wait(until.elementTextMatches(txListValue, /-4\s*ETH/), 10000) await txListValue.click() await driver.delay(regularDelayMs) // Set the gas limit - const configureGas = await driver.findElement(By.css('.confirm-detail-row__header-text--edit')) - await configureGas.click() + await driver.clickElement(By.css('.confirm-detail-row__header-text--edit')) await driver.delay(regularDelayMs) const gasModal = await driver.findElement(By.css('span .modal')) await driver.delay(regularDelayMs) - const modalTabs = await driver.findElements(By.css('.page-container__tab')) - await modalTabs[1].click() + await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')) await driver.delay(regularDelayMs) const [gasPriceInput, gasLimitInput] = await driver.findElements(By.css('.advanced-gas-inputs__gas-edit-row__input')) @@ -784,14 +705,12 @@ describe('MetaMask', function () { await driver.delay(1000) - const save = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await save.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.delay(regularDelayMs) await driver.wait(until.stalenessOf(gasModal)) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) await driver.wait(async () => { @@ -807,19 +726,16 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(regularDelayMs) - const withdrawButton = await driver.findElement(By.css('#withdrawButton')) - await withdrawButton.click() + await driver.clickElement(By.css('#withdrawButton')) await driver.delay(regularDelayMs) await driver.switchToWindow(extension) await driver.delay(largeDelayMs * 2) - const txListItem = await driver.findElement(By.css('.transaction-list-item')) - await txListItem.click() + await driver.clickElement(By.css('.transaction-list-item')) await driver.delay(regularDelayMs) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) await driver.wait(async () => { @@ -854,8 +770,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(regularDelayMs * 2) - const createToken = await driver.findElement(By.xpath(`//button[contains(text(), 'Create Token')]`)) - await createToken.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create Token')]`)) await driver.delay(largeDelayMs) windowHandles = await driver.getAllWindowHandles() @@ -863,24 +778,20 @@ describe('MetaMask', function () { await driver.switchToWindow(popup) await driver.delay(regularDelayMs) - const configureGas = await driver.findElement(By.css('.confirm-detail-row__header-text--edit')) - await configureGas.click() + await driver.clickElement(By.css('.confirm-detail-row__header-text--edit')) await driver.delay(regularDelayMs) - const advancedTabButton = await driver.findElement(By.xpath(`//li[contains(text(), 'Advanced')]`)) - await advancedTabButton.click() + await driver.clickElement(By.xpath(`//li[contains(text(), 'Advanced')]`)) await driver.delay(tinyDelayMs) const [gasPriceInput, gasLimitInput] = await driver.findElements(By.css('.advanced-gas-inputs__gas-edit-row__input')) assert(gasPriceInput.getAttribute('value'), 20) assert(gasLimitInput.getAttribute('value'), 4700000) - const saveButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await saveButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.delay(regularDelayMs) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) await driver.switchToWindow(dapp) @@ -898,26 +809,22 @@ describe('MetaMask', function () { }) it('clicks on the Add Token button', async () => { - const addToken = await driver.findElement(By.xpath(`//div[contains(text(), 'Add Token')]`)) - await addToken.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Add Token')]`)) await driver.delay(regularDelayMs) }) it('picks the newly created Test token', async () => { - const addCustomToken = await driver.findElement(By.xpath("//li[contains(text(), 'Custom Token')]")) - await addCustomToken.click() + await driver.clickElement(By.xpath("//li[contains(text(), 'Custom Token')]")) await driver.delay(regularDelayMs) const newTokenAddress = await driver.findElement(By.css('#custom-address')) await newTokenAddress.sendKeys(tokenAddress) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) - const addTokens = await driver.findElement(By.xpath(`//button[contains(text(), 'Add Tokens')]`)) - await addTokens.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Add Tokens')]`)) await driver.delay(regularDelayMs) }) @@ -933,8 +840,7 @@ describe('MetaMask', function () { describe('Send token from inside MetaMask', () => { let gasModal it('starts to send a transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -944,8 +850,7 @@ describe('MetaMask', function () { await inputAmount.sendKeys('1') // Set the gas limit - const configureGas = await driver.findElement(By.css('.advanced-gas-options-btn')) - await configureGas.click() + await driver.clickElement(By.css('.advanced-gas-options-btn')) await driver.delay(regularDelayMs) gasModal = await driver.findElement(By.css('span .modal')) @@ -954,8 +859,7 @@ describe('MetaMask', function () { it('opens customize gas modal', async () => { await driver.findElement(By.css('.page-container__title')) - const save = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await save.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.delay(regularDelayMs) }) @@ -963,15 +867,12 @@ describe('MetaMask', function () { await driver.wait(until.stalenessOf(gasModal)) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await driver.wait(until.elementIsEnabled(nextScreen)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) it('displays the token transfer data', async () => { - const dataTab = await driver.findElement(By.xpath(`//li[contains(text(), 'Data')]`)) - await dataTab.click() + await driver.clickElement(By.xpath(`//li[contains(text(), 'Data')]`)) await driver.delay(regularDelayMs) const functionType = await driver.findElement(By.css('.confirm-page-container-content__function-type')) @@ -988,14 +889,12 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) assert(confirmDataText.match(/0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/)) - const detailsTab = await driver.findElement(By.xpath(`//li[contains(text(), 'Details')]`)) - await detailsTab.click() + await driver.clickElement(By.xpath(`//li[contains(text(), 'Details')]`)) await driver.delay(regularDelayMs) }) it('submits the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) @@ -1025,14 +924,13 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(tinyDelayMs) - const transferTokens = await driver.findElement(By.xpath(`//button[contains(text(), 'Transfer Tokens')]`)) - await transferTokens.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Transfer Tokens')]`)) await driver.switchToWindow(extension) await driver.delay(largeDelayMs) await driver.findElements(By.css('.transaction-list__pending-transactions')) - const [txListValue] = await driver.findElements(By.css('.transaction-list-item__amount--primary')) + const txListValue = await driver.findClickableElement(By.css('.transaction-list-item__amount--primary')) await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/), 10000) await txListValue.click() await driver.delay(regularDelayMs) @@ -1042,16 +940,14 @@ describe('MetaMask', function () { assert(await transactionAmount.getText(), '1.5 TST') // Set the gas limit - const configureGas = await driver.findElement(By.css('.confirm-detail-row__header-text--edit')) - await configureGas.click() + await driver.clickElement(By.css('.confirm-detail-row__header-text--edit')) await driver.delay(regularDelayMs) gasModal = await driver.findElement(By.css('span .modal')) }) it('customizes gas', async () => { - const modalTabs = await driver.findElements(By.css('.page-container__tab')) - await modalTabs[1].click() + await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')) await driver.delay(regularDelayMs) const [gasPriceInput, gasLimitInput] = await driver.findElements(By.css('.advanced-gas-inputs__gas-edit-row__input')) @@ -1070,8 +966,7 @@ describe('MetaMask', function () { await driver.delay(1000) - const save = await driver.findElement(By.css('.page-container__footer-button')) - await save.click() + await driver.clickElement(By.css('.page-container__footer-button')) await driver.wait(until.stalenessOf(gasModal)) const gasFeeInputs = await driver.findElements(By.css('.confirm-detail-row__primary')) @@ -1084,8 +979,7 @@ describe('MetaMask', function () { const tokenAmountText = await tokenAmount.getText() assert.equal(tokenAmountText, '1.5 TST') - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) @@ -1100,11 +994,9 @@ describe('MetaMask', function () { const txStatuses = await driver.findElements(By.css('.transaction-list-item__action')) await driver.wait(until.elementTextMatches(txStatuses[0], /Sent\sToken/), 10000) - const walletBalance = await driver.findElement(By.css('.wallet-balance')) - await walletBalance.click() + await driver.clickElement(By.css('.wallet-balance')) - const tokenListItems = await driver.findElements(By.css('.token-list-item')) - await tokenListItems[0].click() + await driver.clickElement(By.css('.token-list-item')) await driver.delay(1000) const tokenBalanceAmount = await driver.findElements(By.css('.transaction-view-balance__primary-balance')) @@ -1124,8 +1016,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(tinyDelayMs) - const approveTokens = await driver.findElement(By.xpath(`//button[contains(text(), 'Approve Tokens')]`)) - await approveTokens.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Approve Tokens')]`)) await driver.switchToWindow(extension) await driver.delay(regularDelayMs) @@ -1135,16 +1026,14 @@ describe('MetaMask', function () { return pendingTxes.length === 1 }, 10000) - const [txListItem] = await driver.findElements(By.css('.transaction-list-item')) const [txListValue] = await driver.findElements(By.css('.transaction-list-item__amount--primary')) await driver.wait(until.elementTextMatches(txListValue, /-7\s*TST/)) - await txListItem.click() + await driver.clickElement(By.css('.transaction-list-item')) await driver.delay(regularDelayMs) }) it('displays the token approval data', async () => { - const fullTxDataButton = await driver.findElement(By.css('.confirm-approve-content__view-full-tx-button')) - await fullTxDataButton.click() + await driver.clickElement(By.css('.confirm-approve-content__view-full-tx-button')) await driver.delay(regularDelayMs) const functionType = await driver.findElement(By.css('.confirm-approve-content__data .confirm-approve-content__small-text')) @@ -1157,16 +1046,14 @@ describe('MetaMask', function () { }) it('opens the gas edit modal', async () => { - const editButtons = await driver.findElements(By.css('.confirm-approve-content__small-blue-text.cursor-pointer')) - await editButtons[0].click() + await driver.clickElement(By.css('.confirm-approve-content__small-blue-text.cursor-pointer')) await driver.delay(regularDelayMs) gasModal = await driver.findElement(By.css('span .modal')) }) it('customizes gas', async () => { - const modalTabs = await driver.findElements(By.css('.page-container__tab')) - await modalTabs[1].click() + await driver.clickElement(By.css('.page-container__tab:nth-of-type(2)')) await driver.delay(regularDelayMs) const [gasPriceInput, gasLimitInput] = await driver.findElements(By.css('.advanced-gas-inputs__gas-edit-row__input')) @@ -1185,8 +1072,7 @@ describe('MetaMask', function () { await driver.delay(1000) - const save = await driver.findElement(By.css('.page-container__footer-button')) - await save.click() + await driver.clickElement(By.css('.page-container__footer-button')) await driver.wait(until.stalenessOf(gasModal)) const gasFeeInEth = await driver.findElement(By.css('.confirm-approve-content__transaction-details-content__secondary-fee')) @@ -1194,13 +1080,13 @@ describe('MetaMask', function () { }) it('edits the permission', async () => { - const editButtons = await driver.findElements(By.css('.confirm-approve-content__small-blue-text.cursor-pointer')) + const editButtons = await driver.findClickableElements(By.css('.confirm-approve-content__small-blue-text.cursor-pointer')) await editButtons[1].click() await driver.delay(regularDelayMs) const permissionModal = await driver.findElement(By.css('span .modal')) - const radioButtons = await driver.findElements(By.css('.edit-approval-permission__edit-section__radio-button')) + const radioButtons = await driver.findClickableElements(By.css('.edit-approval-permission__edit-section__radio-button')) await radioButtons[1].click() const customInput = await driver.findElement(By.css('input')) @@ -1208,8 +1094,7 @@ describe('MetaMask', function () { await customInput.sendKeys('5') await driver.delay(regularDelayMs) - const saveButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await saveButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.delay(regularDelayMs) await driver.wait(until.stalenessOf(permissionModal)) @@ -1220,8 +1105,7 @@ describe('MetaMask', function () { }) it('submits the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) @@ -1248,8 +1132,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) - const transferTokens = await driver.findElement(By.xpath(`//button[contains(text(), 'Transfer Tokens Without Gas')]`)) - await transferTokens.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Transfer Tokens Without Gas')]`)) await driver.switchToWindow(extension) await driver.delay(regularDelayMs) @@ -1259,17 +1142,15 @@ describe('MetaMask', function () { return pendingTxes.length === 1 }, 10000) - const [txListItem] = await driver.findElements(By.css('.transaction-list-item')) const [txListValue] = await driver.findElements(By.css('.transaction-list-item__amount--primary')) await driver.wait(until.elementTextMatches(txListValue, /-1.5\s*TST/)) - await txListItem.click() + await driver.clickElement(By.css('.transaction-list-item')) await driver.delay(regularDelayMs) }) it('submits the transaction', async function () { await driver.delay(largeDelayMs * 2) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(largeDelayMs * 2) }) @@ -1297,8 +1178,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(tinyDelayMs) - const transferTokens = await driver.findElement(By.xpath(`//button[contains(text(), 'Approve Tokens Without Gas')]`)) - await transferTokens.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Approve Tokens Without Gas')]`)) await driver.switchToWindow(extension) await driver.delay(regularDelayMs) @@ -1308,16 +1188,14 @@ describe('MetaMask', function () { return pendingTxes.length === 1 }, 10000) - const [txListItem] = await driver.findElements(By.css('.transaction-list-item')) const [txListValue] = await driver.findElements(By.css('.transaction-list-item__amount--primary')) await driver.wait(until.elementTextMatches(txListValue, /-7\s*TST/)) - await txListItem.click() + await driver.clickElement(By.css('.transaction-list-item')) await driver.delay(regularDelayMs) }) it('shows the correct recipient', async function () { - const fullTxDataButton = await driver.findElement(By.css('.confirm-approve-content__view-full-tx-button')) - await fullTxDataButton.click() + await driver.clickElement(By.css('.confirm-approve-content__view-full-tx-button')) await driver.delay(regularDelayMs) const permissionInfo = await driver.findElements(By.css('.confirm-approve-content__medium-text')) @@ -1327,8 +1205,7 @@ describe('MetaMask', function () { it('submits the transaction', async function () { await driver.delay(1000) - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) @@ -1347,19 +1224,15 @@ describe('MetaMask', function () { describe('Hide token', () => { it('hides the token when clicked', async () => { - const [hideTokenEllipsis] = await driver.findElements(By.css('.token-list-item__ellipsis')) - await hideTokenEllipsis.click() + await driver.clickElement(By.css('.token-list-item__ellipsis')) const byTokenMenuDropdownOption = By.css('.menu__item--clickable') - const tokenMenuDropdownOption = await driver.findElement(byTokenMenuDropdownOption) - - await tokenMenuDropdownOption.click() + await driver.clickElement(byTokenMenuDropdownOption) const confirmHideModal = await driver.findElement(By.css('span .modal')) const byHideTokenConfirmationButton = By.css('.hide-token-confirmation__button') - const hideTokenConfirmationButton = await driver.findElement(byHideTokenConfirmationButton) - await hideTokenConfirmationButton.click() + await driver.clickElement(byHideTokenConfirmationButton) await driver.wait(until.stalenessOf(confirmHideModal)) }) @@ -1367,8 +1240,7 @@ describe('MetaMask', function () { describe('Add existing token using search', () => { it('clicks on the Add Token button', async () => { - const addToken = await driver.findElement(By.xpath(`//div[contains(text(), 'Add Token')]`)) - await addToken.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Add Token')]`)) await driver.delay(regularDelayMs) }) @@ -1377,16 +1249,13 @@ describe('MetaMask', function () { await tokenSearch.sendKeys('BAT') await driver.delay(regularDelayMs) - const token = await driver.findElement(By.xpath("//span[contains(text(), 'BAT')]")) - await token.click() + await driver.clickElement(By.xpath("//span[contains(text(), 'BAT')]")) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) - const addTokens = await driver.findElement(By.xpath(`//button[contains(text(), 'Add Tokens')]`)) - await addTokens.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Add Tokens')]`)) await driver.delay(largeDelayMs) }) @@ -1407,12 +1276,10 @@ describe('MetaMask', function () { customRpcUrls.forEach(customRpcUrl => { it(`creates custom RPC: ${customRpcUrl}`, async () => { - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) - const customRpcButton = await driver.findElement(By.xpath(`//span[contains(text(), 'Custom RPC')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//span[contains(text(), 'Custom RPC')]`)) await driver.delay(regularDelayMs) await driver.findElement(By.css('.settings-page__sub-header-text')) @@ -1422,25 +1289,21 @@ describe('MetaMask', function () { await customRpcInput.clear() await customRpcInput.sendKeys(customRpcUrl) - const customRpcSave = await driver.findElement(By.css('.network-form__footer .btn-secondary')) - await customRpcSave.click() + await driver.clickElement(By.css('.network-form__footer .btn-secondary')) await driver.delay(largeDelayMs * 2) }) }) it('selects another provider', async () => { - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) - const customRpcButton = await driver.findElement(By.xpath(`//span[contains(text(), 'Main Ethereum Network')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//span[contains(text(), 'Main Ethereum Network')]`)) await driver.delay(largeDelayMs * 2) }) it('finds all recent RPCs in history', async () => { - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) // only recent 3 are found and in correct order (most recent at the top) @@ -1450,20 +1313,18 @@ describe('MetaMask', function () { }) it('deletes a custom RPC', async () => { - const networkListItems = await driver.findElements(By.css('.networks-tab__networks-list-name')) + const networkListItems = await driver.findClickableElements(By.css('.networks-tab__networks-list-name')) const lastNetworkListItem = networkListItems[networkListItems.length - 1] await lastNetworkListItem.click() await driver.delay(100) - const deleteButton = await driver.findElement(By.css('.btn-danger')) - await deleteButton.click() + await driver.clickElement(By.css('.btn-danger')) await driver.delay(regularDelayMs) const confirmDeleteNetworkModal = await driver.findElement(By.css('span .modal')) const byConfirmDeleteNetworkButton = By.css('.button.btn-danger.modal-container__footer-button') - const confirmDeleteNetworkButton = await driver.findElement(byConfirmDeleteNetworkButton) - await confirmDeleteNetworkButton.click() + await driver.clickElement(byConfirmDeleteNetworkButton) await driver.wait(until.stalenessOf(confirmDeleteNetworkModal)) diff --git a/test/e2e/permissions.spec.js b/test/e2e/permissions.spec.js index 780a8f5d7..3f3d323b1 100644 --- a/test/e2e/permissions.spec.js +++ b/test/e2e/permissions.spec.js @@ -54,45 +54,38 @@ describe('MetaMask', function () { describe('Going through the first time flow, but skipping the seed phrase challenge', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Create New Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Create a Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) it('accepts a secure password', async () => { const passwordBox = await driver.findElement(By.css('.first-time-flow__form #create-password')) const passwordBoxConfirm = await driver.findElement(By.css('.first-time-flow__form #confirm-password')) - const button = await driver.findElement(By.css('.first-time-flow__form button')) await passwordBox.sendKeys('correct horse battery staple') await passwordBoxConfirm.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - await button.click() + await driver.clickElement(By.css('.first-time-flow__form button')) await driver.delay(largeDelayMs) }) it('skips the seed phrase challenge', async () => { - const button = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`)) - await button.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`)) await driver.delay(regularDelayMs) - const detailsButton = await driver.findElement(By.css('.account-details__details-button')) - await detailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.delay(regularDelayMs) }) @@ -101,8 +94,7 @@ describe('MetaMask', function () { publicAddress = await addressInput.getAttribute('value') const accountModal = await driver.findElement(By.css('span .modal')) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.wait(until.stalenessOf(accountModal)) await driver.delay(regularDelayMs) @@ -118,8 +110,7 @@ describe('MetaMask', function () { await driver.openNewPage('http://127.0.0.1:8080/') await driver.delay(regularDelayMs) - const connectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Connect')]`)) - await connectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.waitUntilXWindowHandles(3) const windowHandles = await driver.getAllWindowHandles() @@ -132,11 +123,9 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) - const accountButton = await driver.findElement(By.css('.permissions-connect-choose-account__account')) - await accountButton.click() + await driver.clickElement(By.css('.permissions-connect-choose-account__account')) - const submitButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Submit')]`)) - await submitButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) await driver.switchToWindow(extension) @@ -144,12 +133,11 @@ describe('MetaMask', function () { }) it('shows connected sites', async () => { - const connectedSites = await driver.findElement(By.xpath(`//button[contains(text(), 'Connected Sites')]`)) - await connectedSites.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connected Sites')]`)) await driver.findElement(By.css('.connected-sites__title')) - const domains = await driver.findElements(By.css('.connected-sites-list__domain')) + const domains = await driver.findClickableElements(By.css('.connected-sites-list__domain')) assert.equal(domains.length, 1) const domainName = await driver.findElement(By.css('.connected-sites-list__domain-name')) @@ -165,8 +153,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(regularDelayMs) - const getAccountsButton = await driver.findElement(By.xpath(`//button[contains(text(), 'eth_accounts')]`)) - await getAccountsButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'eth_accounts')]`)) const getAccountsResult = await driver.findElement(By.css('#getAccountsResult')) assert.equal((await getAccountsResult.getText()).toLowerCase(), publicAddress.toLowerCase()) @@ -175,13 +162,11 @@ describe('MetaMask', function () { it('can disconnect all accounts', async () => { await driver.switchToWindow(extension) - const disconnectAllButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Disconnect All')]`)) - await disconnectAllButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Disconnect All')]`)) const disconnectModal = await driver.findElement(By.css('span .modal')) - const disconnectAllModalButton = await driver.findElement(By.css('.disconnect-all-modal .btn-danger')) - await disconnectAllModalButton.click() + await driver.clickElement(By.css('.disconnect-all-modal .btn-danger')) await driver.wait(until.stalenessOf(disconnectModal)) await driver.delay(regularDelayMs) @@ -191,8 +176,7 @@ describe('MetaMask', function () { await driver.switchToWindow(dapp) await driver.delay(regularDelayMs) - const getAccountsButton = await driver.findElement(By.xpath(`//button[contains(text(), 'eth_accounts')]`)) - await getAccountsButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'eth_accounts')]`)) const getAccountsResult = await driver.findElement(By.css('#getAccountsResult')) assert.equal(await getAccountsResult.getText(), 'Not able to get accounts') diff --git a/test/e2e/send-edit.spec.js b/test/e2e/send-edit.spec.js index 1f8ed96bb..eb4473f60 100644 --- a/test/e2e/send-edit.spec.js +++ b/test/e2e/send-edit.spec.js @@ -56,20 +56,17 @@ describe('Using MetaMask with an existing account', function () { describe('First time flow starting from an existing seed phrase', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Import Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) @@ -83,26 +80,22 @@ describe('Using MetaMask with an existing account', function () { const [confirmPassword] = await driver.findElements(By.id('confirm-password')) confirmPassword.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - const [importButton] = await driver.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) }) describe('Send ETH from inside MetaMask', () => { it('starts a send transaction', async function () { - const sendButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Send')]`)) - await sendButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Send')]`)) await driver.delay(regularDelayMs) const inputAddress = await driver.findElement(By.css('input[placeholder="Search, public address (0x), or ENS"]')) @@ -112,8 +105,7 @@ describe('Using MetaMask with an existing account', function () { await inputAmount.sendKeys('1') // Set the gas limit - const configureGas = await driver.findElement(By.css('.advanced-gas-options-btn')) - await configureGas.click() + await driver.clickElement(By.css('.advanced-gas-options-btn')) await driver.delay(regularDelayMs) const gasModal = await driver.findElement(By.css('span .modal')) @@ -138,14 +130,12 @@ describe('Using MetaMask with an existing account', function () { await driver.delay(1000) - const save = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await save.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.wait(until.stalenessOf(gasModal)) await driver.delay(regularDelayMs) // Continue to next screen - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) @@ -159,8 +149,7 @@ describe('Using MetaMask with an existing account', function () { }) it('edits the transaction', async function () { - const editButton = await driver.findElement(By.css('.confirm-page-container-header__back-button')) - await editButton.click() + await driver.clickElement(By.css('.confirm-page-container-header__back-button')) await driver.delay(regularDelayMs) @@ -171,8 +160,7 @@ describe('Using MetaMask with an existing account', function () { await driver.delay(50) await inputAmount.sendKeys('2.2') - const configureGas = await driver.findElement(By.css('.advanced-gas-options-btn')) - await configureGas.click() + await driver.clickElement(By.css('.advanced-gas-options-btn')) await driver.delay(regularDelayMs) const gasModal = await driver.findElement(By.css('span .modal')) @@ -196,13 +184,11 @@ describe('Using MetaMask with an existing account', function () { await driver.delay(1000) - const save = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await save.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.wait(until.stalenessOf(gasModal)) await driver.delay(regularDelayMs) - const nextScreen = await driver.findElement(By.xpath(`//button[contains(text(), 'Next')]`)) - await nextScreen.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Next')]`)) await driver.delay(regularDelayMs) }) @@ -216,8 +202,7 @@ describe('Using MetaMask with an existing account', function () { }) it('confirms the transaction', async function () { - const confirmButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) - await confirmButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Confirm')]`)) await driver.delay(regularDelayMs) }) diff --git a/test/e2e/signature-request.spec.js b/test/e2e/signature-request.spec.js index f401d8aae..35526b973 100644 --- a/test/e2e/signature-request.spec.js +++ b/test/e2e/signature-request.spec.js @@ -69,8 +69,7 @@ describe('MetaMask', function () { await driver.openNewPage('http://127.0.0.1:8080/') await driver.delay(regularDelayMs) - const connectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Connect')]`)) - await connectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.delay(regularDelayMs) @@ -85,19 +84,16 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs) - const accountButton = await driver.findElement(By.css('.permissions-connect-choose-account__account')) - await accountButton.click() + await driver.clickElement(By.css('.permissions-connect-choose-account__account')) - const submitButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Submit')]`)) - await submitButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Submit')]`)) await driver.waitUntilXWindowHandles(2) await driver.switchToWindow(dapp) }) it('creates a sign typed data signature request', async () => { - const signTypedMessage = await driver.findElement(By.xpath(`//button[contains(text(), 'Sign')]`), 10000) - await signTypedMessage.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Sign')]`), 10000) await driver.delay(largeDelayMs) await driver.delay(regularDelayMs) @@ -117,8 +113,7 @@ describe('MetaMask', function () { }) it('signs the transaction', async () => { - const signButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Sign')]`), 10000) - await signButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Sign')]`), 10000) await driver.delay(regularDelayMs) extension = windowHandles[0] @@ -126,16 +121,14 @@ describe('MetaMask', function () { }) it('gets the current accounts address', async () => { - const detailsButton = await driver.findElement(By.css('.account-details__details-button')) - await detailsButton.click() + await driver.clickElement(By.css('.account-details__details-button')) await driver.delay(regularDelayMs) const addressInput = await driver.findElement(By.css('.qr-ellip-address')) const newPublicAddress = await addressInput.getAttribute('value') const accountModal = await driver.findElement(By.css('span .modal')) - const accountModalClose = await driver.findElement(By.css('.account-modal-close')) - await accountModalClose.click() + await driver.clickElement(By.css('.account-modal-close')) await driver.wait(until.stalenessOf(accountModal)) await driver.delay(regularDelayMs) diff --git a/test/e2e/threebox.spec.js b/test/e2e/threebox.spec.js index 9167bdb5e..664ad2084 100644 --- a/test/e2e/threebox.spec.js +++ b/test/e2e/threebox.spec.js @@ -59,20 +59,17 @@ describe('MetaMask', function () { describe('First time flow starting from an existing seed phrase', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Import Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) @@ -86,18 +83,15 @@ describe('MetaMask', function () { const [confirmPassword] = await driver.findElements(By.id('confirm-password')) confirmPassword.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - const [importButton] = await driver.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) @@ -110,41 +104,32 @@ describe('MetaMask', function () { describe('turns on threebox syncing', () => { it('goes to the settings screen', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const settingsButton = await driver.findElement(By.xpath(`//div[contains(text(), 'Settings')]`)) - await settingsButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Settings')]`)) }) it('turns on threebox syncing', async () => { - const advancedButton = await driver.findElement(By.xpath(`//div[contains(text(), 'Advanced')]`)) - await advancedButton.click() - - const threeBoxToggleButton = await driver.findElement(By.css('[data-testid="advanced-setting-3box"] .toggle-button div')) - await threeBoxToggleButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Advanced')]`)) + await driver.clickElement(By.css('[data-testid="advanced-setting-3box"] .toggle-button div')) }) }) describe('updates settings and address book', () => { it('adds an address to the contact list', async () => { - const generalButton = await driver.findElement(By.xpath(`//div[contains(text(), 'General')]`)) - await generalButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'General')]`)) }) it('turns on use of blockies', async () => { - const toggleButton = await driver.findElement(By.css('.toggle-button > div')) - await toggleButton.click() + await driver.clickElement(By.css('.toggle-button > div')) }) it('adds an address to the contact list', async () => { - const contactsButton = await driver.findElement(By.xpath(`//div[contains(text(), 'Contacts')]`)) - await contactsButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Contacts')]`)) - const addressBookAddButton = await driver.findElement(By.css('.address-book-add-button__button')) - await addressBookAddButton.click() + await driver.clickElement(By.css('.address-book-add-button__button')) await driver.delay(tinyDelayMs) const addAddressInputs = await driver.findElements(By.css('input')) @@ -156,8 +141,7 @@ describe('MetaMask', function () { await driver.delay(largeDelayMs * 2) - const saveButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Save')]`)) - await saveButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Save')]`)) await driver.findElement(By.xpath(`//div[contains(text(), 'Test User Name 11')]`)) await driver.delay(regularDelayMs) @@ -181,20 +165,17 @@ describe('MetaMask', function () { describe('First time flow starting from an existing seed phrase', () => { it('clicks the continue button on the welcome screen', async () => { await driver2.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver2.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver2.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver2.delay(largeDelayMs) }) it('clicks the "Import Wallet" option', async () => { - const customRpcButton = await driver2.findElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) - await customRpcButton.click() + await driver2.clickElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) await driver2.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver2.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver2.clickElement(By.css('.btn-default')) await driver2.delay(largeDelayMs) }) @@ -208,18 +189,15 @@ describe('MetaMask', function () { const [confirmPassword] = await driver2.findElements(By.id('confirm-password')) confirmPassword.sendKeys('correct horse battery staple') - const tosCheckBox = await driver2.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver2.clickElement(By.css('.first-time-flow__checkbox')) - const [importButton] = await driver2.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButton.click() + await driver2.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver2.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver2.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver2.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver2.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver2.delay(regularDelayMs) }) @@ -232,18 +210,15 @@ describe('MetaMask', function () { describe('restores 3box data', () => { it('confirms the 3box restore notification', async () => { - const restoreButton = await driver2.findElement(By.css('.home-notification__accept-button')) - await restoreButton.click() + await driver2.clickElement(By.css('.home-notification__accept-button')) }) // TODO: Fix tests from here forward; they're using the wrong driver it('goes to the settings screen', async () => { - const accountMenuButton = await driver.findElement(By.css('.account-menu__icon')) - await accountMenuButton.click() + await driver.clickElement(By.css('.account-menu__icon')) await driver.delay(regularDelayMs) - const settingsButton = await driver.findElement(By.xpath(`//div[contains(text(), 'Settings')]`)) - await settingsButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Settings')]`)) }) it('finds the blockies toggle turned on', async () => { @@ -254,8 +229,7 @@ describe('MetaMask', function () { }) it('finds the restored address in the contact list', async () => { - const contactsButton = await driver.findElement(By.xpath(`//div[contains(text(), 'Contacts')]`)) - await contactsButton.click() + await driver.clickElement(By.xpath(`//div[contains(text(), 'Contacts')]`)) await driver.delay(regularDelayMs) await driver.findElement(By.xpath(`//div[contains(text(), 'Test User Name 11')]`)) diff --git a/test/e2e/web3.spec.js b/test/e2e/web3.spec.js index 0f2c25262..8312101b5 100644 --- a/test/e2e/web3.spec.js +++ b/test/e2e/web3.spec.js @@ -55,20 +55,17 @@ describe('Using MetaMask with an existing account', function () { describe('First time flow starting from an existing seed phrase', () => { it('clicks the continue button on the welcome screen', async () => { await driver.findElement(By.css('.welcome-page__header')) - const welcomeScreenBtn = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) - await welcomeScreenBtn.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`)) await driver.delay(largeDelayMs) }) it('clicks the "Import Wallet" option', async () => { - const customRpcButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) - await customRpcButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import Wallet')]`)) await driver.delay(largeDelayMs) }) it('clicks the "No thanks" option on the metametrics opt-in screen', async () => { - const optOutButton = await driver.findElement(By.css('.btn-default')) - await optOutButton.click() + await driver.clickElement(By.css('.btn-default')) await driver.delay(largeDelayMs) }) @@ -82,18 +79,15 @@ describe('Using MetaMask with an existing account', function () { const [confirmPassword] = await driver.findElements(By.id('confirm-password')) confirmPassword.sendKeys('correct horse battery staple') - const tosCheckBox = await driver.findElement(By.css('.first-time-flow__checkbox')) - await tosCheckBox.click() + await driver.clickElement(By.css('.first-time-flow__checkbox')) - const [importButton] = await driver.findElements(By.xpath(`//button[contains(text(), 'Import')]`)) - await importButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Import')]`)) await driver.delay(regularDelayMs) }) it('clicks through the success screen', async () => { await driver.findElement(By.xpath(`//div[contains(text(), 'Congratulations')]`)) - const doneButton = await driver.findElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) - await doneButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), '${enLocaleMessages.endOfFlowMessage10.message}')]`)) await driver.delay(regularDelayMs) }) }) @@ -102,12 +96,10 @@ describe('Using MetaMask with an existing account', function () { describe('opens dapp', () => { it('switches to mainnet', async () => { - const networkDropdown = await driver.findElement(By.css('.network-name')) - await networkDropdown.click() + await driver.clickElement(By.css('.network-name')) await driver.delay(regularDelayMs) - const [mainnet] = await driver.findElements(By.xpath(`//span[contains(text(), 'Main Ethereum Network')]`)) - await mainnet.click() + await driver.clickElement(By.xpath(`//span[contains(text(), 'Main Ethereum Network')]`)) await driver.delay(largeDelayMs * 2) }) @@ -115,8 +107,7 @@ describe('Using MetaMask with an existing account', function () { await driver.openNewPage('http://127.0.0.1:8080/') await driver.delay(regularDelayMs) - const connectButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Connect')]`)) - await connectButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.delay(regularDelayMs) @@ -128,8 +119,7 @@ describe('Using MetaMask with an existing account', function () { const dapp = windowHandles.find(handle => handle !== extension && handle !== popup) await driver.delay(regularDelayMs) - const approveButton = await driver.findElement(By.xpath(`//button[contains(text(), 'Connect')]`)) - await approveButton.click() + await driver.clickElement(By.xpath(`//button[contains(text(), 'Connect')]`)) await driver.switchToWindow(dapp) await driver.delay(regularDelayMs) @@ -142,7 +132,7 @@ describe('Using MetaMask with an existing account', function () { it('testing hexa methods', async () => { - const List = await driver.findElements(By.className('hexaNumberMethods')) + const List = await driver.findClickableElements(By.className('hexaNumberMethods')) for (let i = 0; i < List.length; i++) { try { @@ -163,7 +153,7 @@ describe('Using MetaMask with an existing account', function () { it('testing booleanMethods', async () => { - const List = await driver.findElements(By.className('booleanMethods')) + const List = await driver.findClickableElement(By.className('booleanMethods')) for (let i = 0; i < List.length; i++) { try { @@ -186,7 +176,7 @@ describe('Using MetaMask with an existing account', function () { it('testing transactionMethods', async () => { - const List = await driver.findElements(By.className('transactionMethods')) + const List = await driver.findClickableElement(By.className('transactionMethods')) for (let i = 0; i < List.length; i++) { try { @@ -228,7 +218,7 @@ describe('Using MetaMask with an existing account', function () { it('testing blockMethods', async () => { - const List = await driver.findElements(By.className('blockMethods')) + const List = await driver.findClickableElement(By.className('blockMethods')) for (let i = 0; i < List.length; i++) { try { @@ -254,7 +244,7 @@ describe('Using MetaMask with an existing account', function () { it('testing methods', async () => { - const List = await driver.findElements(By.className('methods')) + const List = await driver.findClickableElement(By.className('methods')) let parsedData let result diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index 9ac1063b7..3774189bf 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -38,12 +38,35 @@ class Driver { return element } - findElements (locator) { - return this.driver.wait(until.elementsLocated(locator), this.timeout) + async findClickableElement (locator) { + const element = await this.findElement(locator) + await Promise.all([ + this.driver.wait(until.elementIsVisible(element), this.timeout), + this.driver.wait(until.elementIsEnabled(element), this.timeout), + ]) + return element + } + + async findElements (locator) { + return await this.driver.wait(until.elementsLocated(locator), this.timeout) + } + + async findClickableElements (locator) { + const elements = await this.findElements(locator) + await Promise.all(elements + .reduce((acc, element) => { + acc.push( + this.driver.wait(until.elementIsVisible(element), this.timeout), + this.driver.wait(until.elementIsEnabled(element), this.timeout), + ) + return acc + }, []) + ) + return elements } async clickElement (locator) { - const element = await this.findElement(locator) + const element = await this.findClickableElement(locator) await element.click() }