From c254e1459841489e0cd2585a62ba6f9c2f2c5bf8 Mon Sep 17 00:00:00 2001 From: Niranjana Binoy <43930900+NiranjanaBinoy@users.noreply.github.com> Date: Thu, 22 Apr 2021 14:03:47 -0400 Subject: [PATCH] Refactoring from-import-ui.spec.js to use fixtures (#10907) --- test/e2e/fixtures/import-ui/state.json | 238 ++++++++++++++++ test/e2e/from-import-ui.spec.js | 363 ------------------------- test/e2e/run-all.sh | 6 - test/e2e/tests/from-import-ui.spec.js | 297 ++++++++++++++++++++ 4 files changed, 535 insertions(+), 369 deletions(-) create mode 100644 test/e2e/fixtures/import-ui/state.json delete mode 100644 test/e2e/from-import-ui.spec.js create mode 100644 test/e2e/tests/from-import-ui.spec.js diff --git a/test/e2e/fixtures/import-ui/state.json b/test/e2e/fixtures/import-ui/state.json new file mode 100644 index 000000000..34f2e1152 --- /dev/null +++ b/test/e2e/fixtures/import-ui/state.json @@ -0,0 +1,238 @@ +{ + "data": { + "config": {}, + "PreferencesController": { + "frequentRpcListDetail": [ + { + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "ticker": "ETH", + "nickname": "Localhost 8545", + "rpcPrefs": {} + } + ], + "accountTokens": { + "0x0cc5261ab8ce458dc977078a3623e2badd27afd3": { + "0x539": [] + }, + "0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": {}, + "0xd38d853771fb546bd8b18b2f3638491bc0b0e906": { + "0x539": [] + } + }, + "accountHiddenTokens": { + "0x0cc5261ab8ce458dc977078a3623e2badd27afd3": { + "0x539": [] + }, + "0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": {}, + "0xd38d853771fb546bd8b18b2f3638491bc0b0e906": { + "0x539": [] + } + }, + "assetImages": {}, + "tokens": [], + "hiddenTokens": [], + "suggestedTokens": {}, + "useBlockie": false, + "useNonceField": false, + "usePhishDetect": true, + "featureFlags": { + "showIncomingTransactions": true + }, + "knownMethodData": {}, + "firstTimeFlowType": "import", + "currentLocale": "en", + "identities": { + "0x0cc5261ab8ce458dc977078a3623e2badd27afd3": { + "name": "Account 1", + "address": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3", + "lastSelected": 1618940443499 + }, + "0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": { + "name": "Account 2", + "address": "0x3ed0ee22e0685ebbf07b2360a8331693c413cc59" + }, + "0xd38d853771fb546bd8b18b2f3638491bc0b0e906": { + "name": "2nd account", + "address": "0xd38d853771fb546bd8b18b2f3638491bc0b0e906", + "lastSelected": 1618940443010 + } + }, + "lostIdentities": {}, + "forgottenPassword": false, + "preferences": { + "showFiatInTestnets": false, + "useNativeCurrencyAsPrimaryCurrency": true, + "hideZeroBalanceTokens": false + }, + "completedOnboarding": true, + "ipfsGateway": "dweb.link", + "infuraBlocked": false, + "selectedAddress": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3" + }, + "firstTimeInfo": { + "version": "9.3.0", + "date": 1617927806790 + }, + "NetworkController": { + "provider": { + "ticker": "ETH", + "type": "rpc", + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "nickname": "Localhost 8545" + }, + "previousProviderStore": { + "ticker": "ETH", + "type": "rpc", + "rpcUrl": "http://localhost:8545", + "chainId": "0x539", + "nickname": "Localhost 8545" + }, + "network": "1337" + }, + "CurrencyController": { + "conversionDate": 1618940438.187, + "conversionRate": 2254.54, + "currentCurrency": "usd", + "nativeCurrency": "ETH", + "usdConversionRate": 2254.54 + }, + "CachedBalancesController": { + "cachedBalances": { + "0x539": { + "0x0cc5261ab8ce458dc977078a3623e2badd27afd3": "0x14cffbeaf5a7d3000", + "0x3ed0ee22e0685ebbf07b2360a8331693c413cc59": "0x0", + "0xd38d853771fb546bd8b18b2f3638491bc0b0e906": "0x0" + } + } + }, + "MetaMetricsController": { + "participateInMetaMetrics": false, + "metaMetricsId": null, + "metaMetricsSendCount": 1 + }, + "PermissionsController": { + "permissionsRequests": [], + "permissionsDescriptions": {}, + "domains": {} + }, + "TransactionController": { + "transactions": { + "1374812123920442": { + "id": 1374812123920442, + "time": 1618940444708, + "status": "confirmed", + "metamaskNetworkId": "1337", + "chainId": "0x539", + "loadingDefaults": false, + "txParams": { + "from": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3", + "to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970", + "nonce": "0x0", + "value": "0xde0b6b3a7640000", + "gas": "0x5208", + "gasPrice": "0x363fe1da00" + }, + "origin": "metamask", + "type": "sentEther", + "history": [], + "nonceDetails": { + "params": { + "highestLocallyConfirmed": 0, + "highestSuggested": 0, + "nextNetworkNonce": 0 + }, + "local": { + "name": "local", + "nonce": 0, + "details": { + "startPoint": 0, + "highest": 0 + } + }, + "network": { + "name": "network", + "nonce": 0, + "details": { + "blockNumber": "0x5", + "baseCount": 0 + } + } + }, + "r": "0x035de1d588f67547bd9c7bb9b34a8330c10085155e42af0017986911ca922e61", + "s": "0x36c3c12a323121afe6d63bc8c5929766d385e2e7b7fc892ecd0f10a7ec4ab59e", + "v": "0x0a95", + "rawTx": "0xf86e8085363fe1da00825208942f318c334780961fb129d2a6c30d0763d9a5c970880de0b6b3a764000080820a95a0035de1d588f67547bd9c7bb9b34a8330c10085155e42af0017986911ca922e61a036c3c12a323121afe6d63bc8c5929766d385e2e7b7fc892ecd0f10a7ec4ab59e", + "hash": "0xaba403a1dff459d7549b57369cfdd323c70fc79a307ed8f9cae811ddd6883a74", + "submittedTime": 1618940445208, + "txReceipt": { + "transactionHash": "0xaba403a1dff459d7549b57369cfdd323c70fc79a307ed8f9cae811ddd6883a74", + "transactionIndex": { + "negative": 0, + "words": [0, null], + "length": 1, + "red": null + }, + "blockHash": "0x734618e63369e7ea10872e68cec4d400d77c55ed525cbc295802d00d7b4bd1d2", + "blockNumber": { + "negative": 0, + "words": [6, null], + "length": 1, + "red": null + }, + "from": "0x0cc5261ab8ce458dc977078a3623e2badd27afd3", + "to": "0x2f318c334780961fb129d2a6c30d0763d9a5c970", + "gasUsed": "5208", + "cumulativeGasUsed": { + "negative": 0, + "words": [21000, null], + "length": 1, + "red": null + }, + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + } + } + }, + "KeyringController": { + "vault": "{\"data\":\"Ot+BTtJPag0xubdiv1nO9bsSvTHivHCd6CD7Lxgb1McYw3VqMjgp5rPMZmblJ1lscuMxyiqp99G52uXO9S0em6F9htpa+t/wn6qubRKTTNG9fxNzQrKXRDNhdgfYckVk5VAZ4fgl2iMZcRDvS8H/+gucVKJ33Sl6mXyPofdexXhWDCU6uR2YecnfaIum9cL2u/GqOMPE3jxzy0Wip0x2Jyp3QOKhvu8A3GIjzagLOaQ7a1APdl8=\",\"iv\":\"lbsyPeGYWU6U1+jvmW9UHg==\",\"salt\":\"Zmbhpskwxe4rYfXtELBvlcvW4HISPBATRmMqzsnZPMg=\"}" + }, + "AlertController": { + "alertEnabledness": { + "unconnectedAccount": true, + "web3ShimUsage": true + }, + "unconnectedAccountAlertShownOrigins": {}, + "web3ShimUsageOrigins": {} + }, + "OnboardingController": { + "seedPhraseBackedUp": true, + "onboardingTabs": {} + }, + "AddressBookController": { + "addressBook": { + "0x539": { + "0x2f318C334780961FB129D2a6c30D0763d9a5C970": { + "address": "0x2f318C334780961FB129D2a6c30D0763d9a5C970", + "chainId": "0x539", + "isEns": false, + "memo": "", + "name": "" + } + } + } + }, + "AppStateController": { + "connectedStatusPopoverHasBeenShown": true, + "swapsWelcomeMessageHasBeenShown": false, + "defaultHomeActiveTabName": "Activity" + } + }, + "meta": { + "version": 57 + } +} diff --git a/test/e2e/from-import-ui.spec.js b/test/e2e/from-import-ui.spec.js deleted file mode 100644 index 286c00294..000000000 --- a/test/e2e/from-import-ui.spec.js +++ /dev/null @@ -1,363 +0,0 @@ -const assert = require('assert'); -const enLocaleMessages = require('../../app/_locales/en/messages.json'); -const { regularDelayMs, largeDelayMs } = require('./helpers'); -const { buildWebDriver } = require('./webdriver'); -const Ganache = require('./ganache'); - -const ganacheServer = new Ganache(); - -describe('Using MetaMask with an existing account', function () { - let driver; - - const testSeedPhrase = - 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'; - const testAddress = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3'; - const testPrivateKey2 = - '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6'; - const testPrivateKey3 = - 'F4EC2590A0C10DE95FBF4547845178910E40F5035320C516A18C117DE02B5669'; - - this.timeout(0); - this.bail(true); - - before(async function () { - await ganacheServer.start({ - accounts: [ - { - secretKey: - '0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9', - balance: 25000000000000000000, - }, - ], - }); - const result = await buildWebDriver(); - driver = result.driver; - await driver.navigate(); - }); - - afterEach(async function () { - if (process.env.SELENIUM_BROWSER === 'chrome') { - const errors = await driver.checkBrowserForConsoleErrors(driver); - if (errors.length) { - const errorReports = errors.map((err) => err.message); - const errorMessage = `Errors found in browser console:\n${errorReports.join( - '\n', - )}`; - console.error(new Error(errorMessage)); - } - } - if (this.currentTest.state === 'failed') { - await driver.verboseReportOnFailure(this.currentTest.title); - } - }); - - after(async function () { - await ganacheServer.quit(); - await driver.quit(); - }); - - describe('First time flow starting from an existing seed phrase', function () { - it('clicks the continue button on the welcome screen', async function () { - await driver.findElement('.welcome-page__header'); - await driver.clickElement({ - text: enLocaleMessages.getStarted.message, - tag: 'button', - }); - await driver.delay(largeDelayMs); - }); - - it('clicks the "Import Wallet" option', async function () { - await driver.clickElement({ text: 'Import wallet', tag: 'button' }); - await driver.delay(largeDelayMs); - }); - - it('clicks the "No thanks" option on the metametrics opt-in screen', async function () { - await driver.clickElement('.btn-default'); - await driver.delay(largeDelayMs); - }); - - it('imports a seed phrase', async function () { - await driver.fill( - 'input[placeholder="Paste seed phrase from clipboard"]', - testSeedPhrase, - ); - await driver.delay(regularDelayMs); - - await driver.fill('#password', 'correct horse battery staple'); - await driver.fill('#confirm-password', 'correct horse battery staple'); - - await driver.clickElement('.first-time-flow__terms'); - - await driver.clickElement({ text: 'Import', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('clicks through the success screen', async function () { - await driver.findElement({ text: 'Congratulations', tag: 'div' }); - await driver.clickElement({ - text: enLocaleMessages.endOfFlowMessage10.message, - tag: 'button', - }); - await driver.delay(regularDelayMs); - }); - }); - - describe('Show account information', function () { - it('shows the correct account address', async function () { - await driver.clickElement('[data-testid="account-options-menu-button"]'); - await driver.clickElement( - '[data-testid="account-options-menu__account-details"]', - ); - await driver.findVisibleElement('.qr-code__wrapper'); - await driver.delay(regularDelayMs); - - const [address] = await driver.findElements('.readonly-input__input'); - assert.equal(await address.getAttribute('value'), testAddress); - - await driver.clickElement('.account-modal__close'); - await driver.delay(largeDelayMs); - }); - - it('shows a QR code for the account', async function () { - await driver.clickElement('[data-testid="account-options-menu-button"]'); - await driver.clickElement( - '[data-testid="account-options-menu__account-details"]', - ); - await driver.findVisibleElement('.qr-code__wrapper'); - // wait for details modal to be visible - const detailsModal = await driver.findVisibleElement('span .modal'); - await driver.delay(regularDelayMs); - - await driver.clickElement('.account-modal__close'); - // wait for details modal to be removed from DOM - await detailsModal.waitForElementState('hidden'); - await driver.delay(regularDelayMs); - }); - }); - - describe('Lock and unlock', function () { - it('logs out of the account', async function () { - await driver.clickElement('.account-menu__icon .identicon'); - await driver.delay(regularDelayMs); - - const lockButton = await driver.findClickableElement( - '.account-menu__lock-button', - ); - assert.equal(await lockButton.getText(), 'Lock'); - await lockButton.click(); - await driver.delay(regularDelayMs); - }); - - it('accepts the account password after lock', async function () { - await driver.fill('#password', 'correct horse battery staple'); - await driver.press('#password', driver.Key.ENTER); - await driver.delay(largeDelayMs); - }); - }); - - describe('Add an account', function () { - it('switches to localhost', async function () { - await driver.clickElement('.network-display'); - await driver.delay(regularDelayMs); - - await driver.clickElement({ text: 'Localhost', tag: 'span' }); - await driver.delay(largeDelayMs); - }); - - it('choose Create Account from the account menu', async function () { - await driver.clickElement('.account-menu__icon'); - await driver.delay(regularDelayMs); - - await driver.clickElement({ text: 'Create Account', tag: 'div' }); - await driver.delay(regularDelayMs); - }); - - it('set account name', async function () { - await driver.fill('.new-account-create-form input', '2nd account'); - await driver.delay(regularDelayMs); - - await driver.clickElement({ text: 'Create', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('should show the correct account name', async function () { - const accountName = await driver.findElement('.selected-account__name'); - assert.equal(await accountName.getText(), '2nd account'); - await driver.delay(regularDelayMs); - }); - }); - - describe('Switch back to original account', function () { - it('chooses the original account from the account menu', async function () { - await driver.clickElement('.account-menu__icon'); - await driver.delay(regularDelayMs); - - await driver.clickElement('.account-menu__name'); - await driver.delay(regularDelayMs); - }); - }); - - describe('Send ETH from inside MetaMask', function () { - it('starts a send transaction', async function () { - await driver.clickElement('[data-testid="eth-overview-send"]'); - await driver.delay(regularDelayMs); - - await driver.fill( - 'input[placeholder="Search, public address (0x), or ENS"]', - '0x2f318C334780961FB129D2a6c30D0763d9a5C970', - ); - - await driver.fill('.unit-input__input', '1'); - - // Set the gas limit - await driver.clickElement('.advanced-gas-options-btn'); - await driver.delay(regularDelayMs); - - // wait for gas modal to be visible - const gasModal = await driver.findVisibleElement('span .modal'); - await driver.clickElement({ text: 'Save', tag: 'button' }); - // wait for gas modal to be removed from DOM - await gasModal.waitForElementState('hidden'); - - // Continue to next screen - await driver.clickElement({ text: 'Next', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('confirms the transaction', async function () { - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('finds the transaction in the transactions list', async function () { - await driver.clickElement('[data-testid="home__activity-tab"]'); - await driver.wait(async () => { - const confirmedTxes = await driver.findElements( - '.transaction-list__completed-transactions .transaction-list-item', - ); - return confirmedTxes.length === 1; - }, 10000); - - const txValues = await driver.findElements( - '.transaction-list-item__primary-currency', - ); - assert.equal(txValues.length, 1); - assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); - }); - }); - - describe('Imports an account with private key', function () { - it('choose Create Account from the account menu', async function () { - await driver.clickElement('.account-menu__icon'); - await driver.delay(regularDelayMs); - - await driver.clickElement({ text: 'Import Account', tag: 'div' }); - await driver.delay(regularDelayMs); - }); - - it('enter private key', async function () { - await driver.fill('#private-key-box', testPrivateKey2); - await driver.delay(regularDelayMs); - await driver.clickElement({ text: 'Import', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('should show the correct account name', async function () { - const accountName = await driver.findElement('.selected-account__name'); - assert.equal(await accountName.getText(), 'Account 4'); - await driver.delay(regularDelayMs); - }); - - it('should show the imported label', async function () { - await driver.clickElement('.account-menu__icon'); - - // confirm 4th account is account 4, as expected - const accountMenuItemSelector = '.account-menu__account:nth-child(4)'; - const accountName = await driver.findElement( - `${accountMenuItemSelector} .account-menu__name`, - ); - assert.equal(await accountName.getText(), 'Account 4'); - // confirm label is present on the same menu item - const importedLabel = await driver.findElement( - `${accountMenuItemSelector} .keyring-label`, - ); - assert.equal(await importedLabel.getText(), 'IMPORTED'); - }); - }); - - describe('Imports and removes an account', function () { - it('choose Create Account from the account menu', async function () { - await driver.clickElement({ text: 'Import Account', tag: 'div' }); - await driver.delay(regularDelayMs); - }); - - it('enter private key', async function () { - await driver.fill('#private-key-box', testPrivateKey3); - await driver.delay(regularDelayMs); - await driver.clickElement({ text: 'Import', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('should see new account in account menu', async function () { - const accountName = await driver.findElement('.selected-account__name'); - assert.equal(await accountName.getText(), 'Account 5'); - await driver.delay(regularDelayMs); - - await driver.clickElement('.account-menu__icon'); - await driver.delay(regularDelayMs); - - const accountListItems = await driver.findElements( - '.account-menu__account', - ); - assert.equal(accountListItems.length, 5); - - await driver.clickPoint('.account-menu__icon', 0, 0); - }); - - it('should open the remove account modal', async function () { - await driver.clickElement('[data-testid="account-options-menu-button"]'); - - await driver.clickElement( - '[data-testid="account-options-menu__remove-account"]', - ); - - await driver.findElement('.confirm-remove-account__account'); - }); - - it('should remove the account', async function () { - await driver.clickElement({ text: 'Remove', tag: 'button' }); - - await driver.delay(regularDelayMs); - - const accountName = await driver.findElement('.selected-account__name'); - assert.equal(await accountName.getText(), 'Account 1'); - await driver.delay(regularDelayMs); - - await driver.clickElement('.account-menu__icon'); - - const accountListItems = await driver.findElements( - '.account-menu__account', - ); - assert.equal(accountListItems.length, 4); - }); - }); - - describe('Connects to a Hardware wallet', function () { - it('choose Connect Hardware Wallet from the account menu', async function () { - await driver.clickElement({ - text: 'Connect Hardware Wallet', - tag: 'div', - }); - await driver.delay(regularDelayMs); - }); - - it('should open the TREZOR Connect popup', async function () { - await driver.clickElement('.hw-connect__btn:nth-of-type(2)'); - await driver.delay(regularDelayMs); - await driver.clickElement({ text: 'Connect', tag: 'button' }); - await driver.delay(regularDelayMs); - const allWindows = await driver.getAllWindowHandles(); - assert.equal(allWindows.length, 2); - }); - }); -}); diff --git a/test/e2e/run-all.sh b/test/e2e/run-all.sh index b0b0ca486..41846efdd 100755 --- a/test/e2e/run-all.sh +++ b/test/e2e/run-all.sh @@ -35,12 +35,6 @@ retry concurrently --kill-others \ 'yarn dapp' \ 'mocha test/e2e/metamask-ui.spec' -retry concurrently --kill-others \ - --names 'e2e' \ - --prefix '[{time}][{name}]' \ - --success first \ - 'mocha test/e2e/from-import-ui.spec' - retry concurrently --kill-others \ --names 'sendwithprivatedapp,e2e' \ --prefix '[{time}][{name}]' \ diff --git a/test/e2e/tests/from-import-ui.spec.js b/test/e2e/tests/from-import-ui.spec.js new file mode 100644 index 000000000..d9e72d55c --- /dev/null +++ b/test/e2e/tests/from-import-ui.spec.js @@ -0,0 +1,297 @@ +const { strict: assert } = require('assert'); +const { withFixtures, regularDelayMs } = require('../helpers'); +const enLocaleMessages = require('../../../app/_locales/en/messages.json'); + +describe('Metamask Import UI', function () { + it('Importing wallet using seed phrase', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9', + balance: 25000000000000000000, + }, + ], + }; + const testSeedPhrase = + 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'; + const testAddress = '0x0Cc5261AB8cE458dc977078A3623E2BaDD27afD3'; + + await withFixtures( + { + fixtures: 'onboarding', + ganacheOptions, + title: this.test.title, + failOnConsoleError: false, + }, + async ({ driver }) => { + await driver.navigate(); + + // clicks the continue button on the welcome screen + await driver.findElement('.welcome-page__header'); + await driver.clickElement({ + text: enLocaleMessages.getStarted.message, + tag: 'button', + }); + + // clicks the "Import Wallet" option + await driver.clickElement({ text: 'Import wallet', tag: 'button' }); + + // clicks the "No thanks" option on the metametrics opt-in screen + await driver.clickElement('.btn-default'); + + // Import seed phrase + await driver.fill( + 'input[placeholder="Paste seed phrase from clipboard"]', + testSeedPhrase, + ); + + await driver.fill('#password', 'correct horse battery staple'); + await driver.fill('#confirm-password', 'correct horse battery staple'); + + await driver.clickElement('.first-time-flow__terms'); + + await driver.clickElement({ text: 'Import', tag: 'button' }); + + // clicks through the success screen + await driver.findElement({ text: 'Congratulations', tag: 'div' }); + await driver.clickElement({ + text: enLocaleMessages.endOfFlowMessage10.message, + tag: 'button', + }); + + // Show account information + await driver.clickElement( + '[data-testid="account-options-menu-button"]', + ); + await driver.clickElement( + '[data-testid="account-options-menu__account-details"]', + ); + await driver.findVisibleElement('.qr-code__wrapper'); + // shows a QR code for the account + const detailsModal = await driver.findVisibleElement('span .modal'); + // shows the correct account address + const [address] = await driver.findElements('.readonly-input__input'); + assert.equal(await address.getAttribute('value'), testAddress); + + await driver.clickElement('.account-modal__close'); + await detailsModal.waitForElementState('hidden'); + + // logs out of the account + await driver.clickElement('.account-menu__icon .identicon'); + const lockButton = await driver.findClickableElement( + '.account-menu__lock-button', + ); + assert.equal(await lockButton.getText(), 'Lock'); + await lockButton.click(); + + // accepts the account password after lock + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + // Create a new account + // switches to locakhost + await driver.clickElement('.network-display'); + await driver.clickElement({ text: 'Localhost', tag: 'span' }); + + // choose Create Account from the account menu + await driver.clickElement('.account-menu__icon'); + await driver.clickElement({ text: 'Create Account', tag: 'div' }); + + // set account name + await driver.fill('.new-account-create-form input', '2nd account'); + await driver.delay(regularDelayMs); + await driver.clickElement({ text: 'Create', tag: 'button' }); + + // should show the correct account name + const accountName = await driver.findElement('.selected-account__name'); + assert.equal(await accountName.getText(), '2nd account'); + + // Switch back to original account + // chooses the original account from the account menu + await driver.clickElement('.account-menu__icon'); + await driver.clickElement('.account-menu__name'); + + // Send ETH from inside MetaMask + // starts a send transaction + await driver.clickElement('[data-testid="eth-overview-send"]'); + await driver.fill( + 'input[placeholder="Search, public address (0x), or ENS"]', + '0x2f318C334780961FB129D2a6c30D0763d9a5C970', + ); + await driver.fill('.unit-input__input', '1'); + + // Set the gas limit + await driver.clickElement('.advanced-gas-options-btn'); + + // wait for gas modal to be visible + const gasModal = await driver.findVisibleElement('span .modal'); + await driver.clickElement({ text: 'Save', tag: 'button' }); + // wait for gas modal to be removed from DOM + await gasModal.waitForElementState('hidden'); + + // Continue to next screen + await driver.clickElement({ text: 'Next', tag: 'button' }); + + // confirms the transaction + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // finds the transaction in the transactions list + await driver.clickElement('[data-testid="home__activity-tab"]'); + await driver.wait(async () => { + const confirmedTxes = await driver.findElements( + '.transaction-list__completed-transactions .transaction-list-item', + ); + return confirmedTxes.length === 1; + }, 10000); + + const txValues = await driver.findElements( + '.transaction-list-item__primary-currency', + ); + assert.equal(txValues.length, 1); + assert.ok(/-1\s*ETH/u.test(await txValues[0].getText())); + }, + ); + }); + + it('Import Account using private key', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9', + balance: 25000000000000000000, + }, + ], + }; + const testPrivateKey1 = + '14abe6f4aab7f9f626fe981c864d0adeb5685f289ac9270c27b8fd790b4235d6'; + const testPrivateKey2 = + 'F4EC2590A0C10DE95FBF4547845178910E40F5035320C516A18C117DE02B5669'; + + await withFixtures( + { + fixtures: 'import-ui', + ganacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + // Imports an account with private key + // choose Create Account from the account menu + await driver.clickElement('.account-menu__icon'); + await driver.clickElement({ text: 'Import Account', tag: 'div' }); + + // enter private key', + await driver.fill('#private-key-box', testPrivateKey1); + await driver.clickElement({ text: 'Import', tag: 'button' }); + + // should show the correct account name + const importedAccountName = await driver.findElement( + '.selected-account__name', + ); + assert.equal(await importedAccountName.getText(), 'Account 4'); + + // should show the imported label + await driver.clickElement('.account-menu__icon'); + // confirm 4th account is account 4, as expected + const accountMenuItemSelector = '.account-menu__account:nth-child(4)'; + const fourthAccountName = await driver.findElement( + `${accountMenuItemSelector} .account-menu__name`, + ); + assert.equal(await fourthAccountName.getText(), 'Account 4'); + // confirm label is present on the same menu item + const importedLabel = await driver.findElement( + `${accountMenuItemSelector} .keyring-label`, + ); + assert.equal(await importedLabel.getText(), 'IMPORTED'); + + // Imports and removes an account + // choose Create Account from the account menu + await driver.clickElement({ text: 'Import Account', tag: 'div' }); + // enter private key + await driver.fill('#private-key-box', testPrivateKey2); + await driver.clickElement({ text: 'Import', tag: 'button' }); + + // should see new account in account menu + const importedAccount2Name = await driver.findElement( + '.selected-account__name', + ); + assert.equal(await importedAccount2Name.getText(), 'Account 5'); + await driver.clickElement('.account-menu__icon'); + const accountListItems = await driver.findElements( + '.account-menu__account', + ); + assert.equal(accountListItems.length, 5); + + await driver.clickPoint('.account-menu__icon', 0, 0); + + // should open the remove account modal + await driver.clickElement( + '[data-testid="account-options-menu-button"]', + ); + await driver.clickElement( + '[data-testid="account-options-menu__remove-account"]', + ); + await driver.findElement('.confirm-remove-account__account'); + + // should remove the account + await driver.clickElement({ text: 'Remove', tag: 'button' }); + + const currentActiveAccountName = await driver.findElement( + '.selected-account__name', + ); + assert.equal(await currentActiveAccountName.getText(), 'Account 1'); + await driver.delay(regularDelayMs); + await driver.clickElement('.account-menu__icon'); + + const accountListItemsAgfterRemoval = await driver.findElements( + '.account-menu__account', + ); + assert.equal(accountListItemsAgfterRemoval.length, 4); + }, + ); + }); + it('Connects to a Hardware wallet', async function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9', + balance: 25000000000000000000, + }, + ], + }; + + await withFixtures( + { + fixtures: 'import-ui', + ganacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + // choose Connect Hardware Wallet from the account menu + await driver.clickElement('.account-menu__icon'); + await driver.clickElement({ + text: 'Connect Hardware Wallet', + tag: 'div', + }); + await driver.delay(regularDelayMs); + + // should open the TREZOR Connect popup + await driver.clickElement('.hw-connect__btn:nth-of-type(2)'); + await driver.clickElement({ text: 'Connect', tag: 'button' }); + await driver.waitUntilXWindowHandles(2); + const allWindows = await driver.getAllWindowHandles(); + assert.equal(allWindows.length, 2); + }, + ); + }); +});