From d97a9e8acc9816c552120503f41a81718ae40a6d Mon Sep 17 00:00:00 2001 From: Niranjana Binoy <43930900+NiranjanaBinoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 11:02:29 -0400 Subject: [PATCH] Refactoring incremental-security.spec.js to use fixtures (#10917) --- package.json | 1 - test/e2e/helpers.js | 24 +- test/e2e/incremental-security.spec.js | 237 -------------------- test/e2e/run-all.sh | 6 - test/e2e/tests/incremental-security.spec.js | 175 +++++++++++++++ 5 files changed, 190 insertions(+), 253 deletions(-) delete mode 100644 test/e2e/incremental-security.spec.js create mode 100644 test/e2e/tests/incremental-security.spec.js diff --git a/package.json b/package.json index 72eeba7ad..b4d3b595c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'", "forwarder": "node ./development/static-server.js ./node_modules/@metamask/forwarder/dist/ --port 9010", "dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'", - "sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080", "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive './{app,shared}/**/*.test.js'", "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*.test.js", "test:unit:jest": "jest", diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index c8d1d7a59..38ab4d500 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -23,6 +23,7 @@ async function withFixtures(options, testSuite) { mockSegment, title, failOnConsoleError = true, + dappPath = undefined, } = options; const fixtureServer = new FixtureServer(); const ganacheServer = new Ganache(); @@ -36,15 +37,20 @@ async function withFixtures(options, testSuite) { await fixtureServer.start(); await fixtureServer.loadState(path.join(__dirname, 'fixtures', fixtures)); if (dapp) { - const dappDirectory = path.resolve( - __dirname, - '..', - '..', - 'node_modules', - '@metamask', - 'test-dapp', - 'dist', - ); + let dappDirectory; + if (dappPath) { + dappDirectory = path.resolve(__dirname, dappPath); + } else { + dappDirectory = path.resolve( + __dirname, + '..', + '..', + 'node_modules', + '@metamask', + 'test-dapp', + 'dist', + ); + } dappServer = createStaticServer(dappDirectory); dappServer.listen(dappPort); await new Promise((resolve, reject) => { diff --git a/test/e2e/incremental-security.spec.js b/test/e2e/incremental-security.spec.js deleted file mode 100644 index f03c0a9cc..000000000 --- a/test/e2e/incremental-security.spec.js +++ /dev/null @@ -1,237 +0,0 @@ -const assert = require('assert'); - -const enLocaleMessages = require('../../app/_locales/en/messages.json'); -const { tinyDelayMs, regularDelayMs, largeDelayMs } = require('./helpers'); -const { buildWebDriver } = require('./webdriver'); -const Ganache = require('./ganache'); - -const ganacheServer = new Ganache(); - -describe('MetaMask', function () { - let driver; - let publicAddress; - - this.timeout(0); - this.bail(true); - - before(async function () { - await ganacheServer.start({ - accounts: [ - { - secretKey: - '0x250F458997A364988956409A164BA4E16F0F99F916ACDD73ADCD3A1DE30CF8D1', - balance: 0, - }, - { - 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('Going through the first time flow, but skipping the seed phrase challenge', 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 "Create New Wallet" option', async function () { - await driver.clickElement({ text: 'Create a 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('accepts a secure password', async function () { - await driver.fill( - '.first-time-flow__form #create-password', - 'correct horse battery staple', - ); - await driver.fill( - '.first-time-flow__form #confirm-password', - 'correct horse battery staple', - ); - - await driver.clickElement('.first-time-flow__checkbox'); - - await driver.clickElement('.first-time-flow__form button'); - await driver.delay(regularDelayMs); - }); - - it('renders the seed phrase intro screen', async function () { - await driver.clickElement('.seed-phrase-intro__left button'); - await driver.delay(regularDelayMs); - }); - - it('skips the seed phrase challenge', async function () { - await driver.clickElement({ - text: enLocaleMessages.remindMeLater.message, - tag: 'button', - }); - await driver.delay(regularDelayMs); - - await driver.clickElement('[data-testid="account-options-menu-button"]'); - await driver.clickElement( - '[data-testid="account-options-menu__account-details"]', - ); - }); - - it('gets the current accounts address', async function () { - const addressInput = await driver.findElement('.readonly-input__input'); - publicAddress = await addressInput.getAttribute('value'); - - // wait for account modal to be visible - const accountModal = await driver.findVisibleElement('span .modal'); - - await driver.clickElement('.account-modal__close'); - - // wait for account modal to be removed from DOM - await accountModal.waitForElementState('hidden'); - await driver.delay(regularDelayMs); - }); - }); - - describe('send to current account from dapp with different provider', function () { - let extension; - - it('switches to dapp screen', async function () { - const windowHandles = await driver.getAllWindowHandles(); - extension = windowHandles[0]; - - await driver.openNewPage('http://127.0.0.1:8080/'); - await driver.delay(regularDelayMs); - }); - - it('sends eth to the current account', async function () { - await driver.fill('#address', publicAddress); - await driver.delay(regularDelayMs); - await driver.clickElement('#send'); - - await driver.waitForSelector( - { css: '#success', text: 'Success' }, - { timeout: 15000 }, - ); - }); - - it('switches back to MetaMask', async function () { - await driver.switchToWindow(extension); - }); - - it('should have the correct amount of eth', async function () { - const currencyDisplay = await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '1', - }); - const balance = await currencyDisplay.getText(); - - assert.strictEqual(balance, '1'); - }); - }); - - describe('backs up the seed phrase', function () { - it('should show a backup reminder', async function () { - const backupReminder = await driver.findElements({ - xpath: - "//div[contains(@class, 'home-notification__text') and contains(text(), 'Backup your Secret Recovery code to keep your wallet and funds secure')]", - }); - assert.equal(backupReminder.length, 1); - }); - - it('should take the user to the seedphrase backup screen', async function () { - await driver.clickElement('.home-notification__accept-button'); - await driver.delay(regularDelayMs); - }); - - let seedPhrase; - - it('reveals the seed phrase', async function () { - await driver.clickElement( - '.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button', - ); - await driver.delay(regularDelayMs); - - const revealedSeedPhrase = await driver.findElement( - '.reveal-seed-phrase__secret-words', - ); - seedPhrase = await revealedSeedPhrase.getText(); - assert.equal(seedPhrase.split(' ').length, 12); - await driver.delay(regularDelayMs); - - await driver.clickElement({ - text: enLocaleMessages.next.message, - tag: 'button', - }); - await driver.delay(regularDelayMs); - }); - - async function clickWordAndWait(word) { - await driver.clickElement( - `[data-testid="seed-phrase-sorted"] [data-testid="draggable-seed-${word}"]`, - ); - await driver.delay(tinyDelayMs); - } - - it('can retype the seed phrase', async function () { - const words = seedPhrase.split(' '); - - for (const word of words) { - await clickWordAndWait(word); - } - - await driver.clickElement({ text: 'Confirm', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('can click through the success screen', async function () { - await driver.clickElement({ text: 'All Done', tag: 'button' }); - await driver.delay(regularDelayMs); - }); - - it('should have the correct amount of eth', async function () { - const currencyDisplay = await driver.waitForSelector({ - css: '.currency-display-component__text', - text: '1', - }); - const balance = await currencyDisplay.getText(); - - assert.strictEqual(balance, '1'); - }); - - it('should not show a backup reminder', async function () { - await driver.assertElementNotPresent('.backup-notification'); - }); - }); -}); diff --git a/test/e2e/run-all.sh b/test/e2e/run-all.sh index 41846efdd..18c3443c9 100755 --- a/test/e2e/run-all.sh +++ b/test/e2e/run-all.sh @@ -35,9 +35,3 @@ retry concurrently --kill-others \ 'yarn dapp' \ 'mocha test/e2e/metamask-ui.spec' -retry concurrently --kill-others \ - --names 'sendwithprivatedapp,e2e' \ - --prefix '[{time}][{name}]' \ - --success first \ - 'yarn sendwithprivatedapp' \ - 'mocha test/e2e/incremental-security.spec' diff --git a/test/e2e/tests/incremental-security.spec.js b/test/e2e/tests/incremental-security.spec.js new file mode 100644 index 000000000..573330319 --- /dev/null +++ b/test/e2e/tests/incremental-security.spec.js @@ -0,0 +1,175 @@ +const { strict: assert } = require('assert'); +const { withFixtures, tinyDelayMs } = require('../helpers'); +const enLocaleMessages = require('../../../app/_locales/en/messages.json'); + +describe('Incremental Security', function () { + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x250F458997A364988956409A164BA4E16F0F99F916ACDD73ADCD3A1DE30CF8D1', + balance: 0, + }, + { + secretKey: + '0x53CB0AB5226EEBF4D872113D98332C1555DC304443BEE1CF759D15798D3C55A9', + balance: 25000000000000000000, + }, + ], + }; + it('Back up seed phrase from backup reminder', async function () { + await withFixtures( + { + dapp: true, + fixtures: 'onboarding', + ganacheOptions, + title: this.test.title, + failOnConsoleError: false, + dappPath: 'send-eth-with-private-key-test', + }, + async ({ driver }) => { + await driver.navigate(); + await driver.delay(tinyDelayMs); + + // 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 "Create New Wallet" option + await driver.clickElement({ text: 'Create a Wallet', tag: 'button' }); + + // clicks the "No thanks" option on the metametrics opt-in screen + await driver.clickElement('.btn-default'); + + // accepts a secure password + await driver.fill( + '.first-time-flow__form #create-password', + 'correct horse battery staple', + ); + await driver.fill( + '.first-time-flow__form #confirm-password', + 'correct horse battery staple', + ); + await driver.clickElement('.first-time-flow__checkbox'); + await driver.clickElement('.first-time-flow__form button'); + + // renders the seed phrase intro screen' + await driver.clickElement('.seed-phrase-intro__left button'); + + // skips the seed phrase challenge + await driver.clickElement({ + text: enLocaleMessages.remindMeLater.message, + tag: 'button', + }); + + await driver.clickElement( + '[data-testid="account-options-menu-button"]', + ); + await driver.clickElement( + '[data-testid="account-options-menu__account-details"]', + ); + + // gets the current accounts address + const addressInput = await driver.findElement('.readonly-input__input'); + const publicAddress = await addressInput.getAttribute('value'); + + // wait for account modal to be visible + const accountModal = await driver.findVisibleElement('span .modal'); + + await driver.clickElement('.account-modal__close'); + + // wait for account modal to be removed from DOM + await accountModal.waitForElementState('hidden'); + + // send to current account from dapp with different provider + const windowHandles = await driver.getAllWindowHandles(); + const extension = windowHandles[0]; + + // switched to Dapp + await driver.openNewPage('http://127.0.0.1:8080/'); + + // sends eth to the current account + await driver.fill('#address', publicAddress); + await driver.clickElement('#send'); + + await driver.waitForSelector( + { css: '#success', text: 'Success' }, + { timeout: 15000 }, + ); + + // switch to extension + await driver.switchToWindow(extension); + + // should have the correct amount of eth + let currencyDisplay = await driver.waitForSelector({ + css: '.currency-display-component__text', + text: '1', + }); + let balance = await currencyDisplay.getText(); + assert.strictEqual(balance, '1'); + + // backs up the seed phrase + // should show a backup reminder + const backupReminder = await driver.findElements({ + xpath: + "//div[contains(@class, 'home-notification__text') and contains(text(), 'Backup your Secret Recovery code to keep your wallet and funds secure')]", + }); + assert.equal(backupReminder.length, 1); + + // should take the user to the seedphrase backup screen + await driver.clickElement('.home-notification__accept-button'); + + // reveals the seed phrase + await driver.clickElement( + '.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button', + ); + + const revealedSeedPhrase = await driver.findElement( + '.reveal-seed-phrase__secret-words', + ); + const seedPhrase = await revealedSeedPhrase.getText(); + assert.equal(seedPhrase.split(' ').length, 12); + + await driver.clickElement({ + text: enLocaleMessages.next.message, + tag: 'button', + }); + + // selecting the words from seedphrase + async function clickWordAndWait(word) { + await driver.clickElement( + `[data-testid="seed-phrase-sorted"] [data-testid="draggable-seed-${word}"]`, + ); + await driver.delay(tinyDelayMs); + } + + // can retype the seed phrase + const words = seedPhrase.split(' '); + + for (const word of words) { + await clickWordAndWait(word); + } + + await driver.clickElement({ text: 'Confirm', tag: 'button' }); + + // can click through the success screen + await driver.clickElement({ text: 'All Done', tag: 'button' }); + + // should have the correct amount of eth + currencyDisplay = await driver.waitForSelector({ + css: '.currency-display-component__text', + text: '1', + }); + balance = await currencyDisplay.getText(); + + assert.strictEqual(balance, '1'); + + // should not show a backup reminder + await driver.assertElementNotPresent('.backup-notification'); + }, + ); + }); +});