1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00
metamask-extension/test/e2e/incremental-security.spec.js
Mark Stacey adb50d1357
Fix flaky e2e tests (#7307)
* Add a delay after connecting

This addresses an intermittent test failure where the MetaMask
Notification window cannot be found. It appears to be caused by the
Send button being clicked too soon after connecting to a dapp, before
the background has had a chance to process the approval. The premature
send is ignored and the window never appears.

This delay (2 seconds) should be sufficient time for the connection to
be processed. A later 5-second delay was also reduced to 2 seconds.

* Select onboarding buttons by button text

The onboarding buttons were being selected using the classname, which
was common to all onboarding buttons. This resulting in buttons being
selected just before a page transition, leading to an error about
the element reference being stale when a click was attempted.

The CSS class selectors have been replaced by text selectors, which
are more specific and shouldn't be at risk of resolving early. They're
also easier to read.

* Remove retypeSeedPhrase function

This function was used to re-type the seed phrase in the event that a
failure occurred when confirming the seed phrase. I'm not sure what
failure this was meant to address exactly, but this contingency hasn't
been needed for some time. We can tell that it hasn't been used because
it wasn't updated for the incremental account security changes, so it
couldn't have worked since then (it would have clicked the wrong
button).
2019-10-23 14:00:16 -03:00

218 lines
7.8 KiB
JavaScript

const assert = require('assert')
const webdriver = require('selenium-webdriver')
const { By, until } = webdriver
const {
delay,
} = require('./func')
const {
assertElementNotPresent,
checkBrowserForConsoleErrors,
findElement,
findElements,
openNewPage,
verboseReportOnFailure,
setupFetchMocking,
prepareExtensionForTesting,
} = require('./helpers')
const enLocaleMessages = require('../../app/_locales/en/messages.json')
describe('MetaMask', function () {
let driver
let publicAddress
const tinyDelayMs = 200
const regularDelayMs = tinyDelayMs * 2
const largeDelayMs = regularDelayMs * 2
this.timeout(0)
this.bail(true)
before(async function () {
const result = await prepareExtensionForTesting()
driver = result.driver
await setupFetchMocking(driver)
})
afterEach(async function () {
if (process.env.SELENIUM_BROWSER === 'chrome') {
const errors = await 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 verboseReportOnFailure(driver, this.currentTest)
}
})
after(async function () {
await driver.quit()
})
describe('Going through the first time flow, but skipping the seed phrase challenge', () => {
it('clicks the continue button on the welcome screen', async () => {
await findElement(driver, By.css('.welcome-page__header'))
const welcomeScreenBtn = await findElement(driver, By.xpath(`//button[contains(text(), '${enLocaleMessages.getStarted.message}')]`))
welcomeScreenBtn.click()
await delay(largeDelayMs)
})
it('clicks the "Create New Wallet" option', async () => {
const customRpcButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Create a Wallet')]`))
customRpcButton.click()
await delay(largeDelayMs)
})
it('clicks the "No thanks" option on the metametrics opt-in screen', async () => {
const optOutButton = await findElement(driver, By.css('.btn-default'))
optOutButton.click()
await delay(largeDelayMs)
})
it('accepts a secure password', async () => {
const passwordBox = await findElement(driver, By.css('.first-time-flow__form #create-password'))
const passwordBoxConfirm = await findElement(driver, By.css('.first-time-flow__form #confirm-password'))
const button = await findElement(driver, By.css('.first-time-flow__form button'))
await passwordBox.sendKeys('correct horse battery staple')
await passwordBoxConfirm.sendKeys('correct horse battery staple')
const tosCheckBox = await findElement(driver, By.css('.first-time-flow__checkbox'))
await tosCheckBox.click()
await button.click()
await delay(regularDelayMs)
})
it('skips the seed phrase challenge', async () => {
const button = await findElement(driver, By.xpath(`//button[contains(text(), '${enLocaleMessages.remindMeLater.message}')]`))
await button.click()
await delay(regularDelayMs)
const detailsButton = await findElement(driver, By.css('.account-details__details-button'))
await detailsButton.click()
await delay(regularDelayMs)
})
it('gets the current accounts address', async () => {
const addressInput = await findElement(driver, By.css('.qr-ellip-address'))
publicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal'))
await driver.executeScript("document.querySelector('.account-modal-close').click()")
await driver.wait(until.stalenessOf(accountModal))
await delay(regularDelayMs)
})
})
describe('send to current account from dapp with different provider', () => {
let extension
it('switches to dapp screen', async () => {
const windowHandles = await driver.getAllWindowHandles()
extension = windowHandles[0]
await openNewPage(driver, 'http://127.0.0.1:8080/')
await delay(regularDelayMs)
})
it('sends eth to the current account', async () => {
const addressInput = await findElement(driver, By.css('#address'))
await addressInput.sendKeys(publicAddress)
await delay(regularDelayMs)
const sendButton = await findElement(driver, By.css('#send'))
await sendButton.click()
const txStatus = await findElement(driver, By.css('#success'))
await driver.wait(until.elementTextMatches(txStatus, /Success/), 15000)
})
it('switches back to MetaMask', async () => {
await driver.switchTo().window(extension)
})
it('should have the correct amount of eth', async () => {
const balances = await findElements(driver, By.css('.currency-display-component__text'))
await driver.wait(until.elementTextMatches(balances[0], /1/), 15000)
const balance = await balances[0].getText()
assert.equal(balance, '1')
})
})
describe('backs up the seed phrase', () => {
it('should show a backup reminder', async () => {
const backupReminder = await findElements(driver, By.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 () => {
const backupButton = await findElement(driver, By.css('.home-notification__accept-button'))
await backupButton.click()
await delay(regularDelayMs)
})
let seedPhrase
it('reveals the seed phrase', async () => {
const byRevealButton = By.css('.reveal-seed-phrase__secret-blocker .reveal-seed-phrase__reveal-button')
await driver.wait(until.elementLocated(byRevealButton, 10000))
const revealSeedPhraseButton = await findElement(driver, byRevealButton, 10000)
await revealSeedPhraseButton.click()
await delay(regularDelayMs)
seedPhrase = await driver.findElement(By.css('.reveal-seed-phrase__secret-words')).getText()
assert.equal(seedPhrase.split(' ').length, 12)
await delay(regularDelayMs)
const nextScreen = await findElement(driver, By.xpath(`//button[contains(text(), '${enLocaleMessages.next.message}')]`))
await nextScreen.click()
await 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 findElement(driver, By.xpath(xpath), 10000)
await word0.click()
await delay(tinyDelayMs)
}
it('can retype the seed phrase', async () => {
const words = seedPhrase.split(' ')
for (const word of words) {
await clickWordAndWait(word)
}
const confirm = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`))
await confirm.click()
await delay(regularDelayMs)
})
it('can click through the success screen', async () => {
const confirm = await findElement(driver, By.xpath(`//button[contains(text(), 'All Done')]`))
await confirm.click()
await delay(regularDelayMs)
})
it('should have the correct amount of eth', async () => {
const balances = await findElements(driver, By.css('.currency-display-component__text'))
await driver.wait(until.elementTextMatches(balances[0], /1/), 15000)
const balance = await balances[0].getText()
assert.equal(balance, '1')
})
it('should not show a backup reminder', async () => {
await assertElementNotPresent(webdriver, driver, By.css('.backup-notification'))
})
})
})