mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
daa20b4b63
* Add missing test descriptions * Fix async tests that expect a rejection These tests expected the function under test to return a rejected promise, and had assertions to be run in the `catch` clause. However, the tests would still pass if the function didn't reject, with the assertions never being run. The tests have been updated to fail if the function doesn't throw. * Handle ignored promise rejection In the case where `forceUpdateMetamaskState` rejects, the function `setSeedPhraseBackedUp` would never resolve. It has been updated to pass along the rejection instead. * Return after rejecting promise in action A few actions would continue after encountering an error, resulting in errors being compounded. Instead all actions will now return after encountering an error (which it looks like was the intention in these cases anyway).
364 lines
11 KiB
JavaScript
364 lines
11 KiB
JavaScript
const path = require('path')
|
|
const assert = require('assert')
|
|
const webdriver = require('selenium-webdriver')
|
|
const { By } = webdriver
|
|
const {
|
|
delay,
|
|
buildChromeWebDriver,
|
|
buildFirefoxWebdriver,
|
|
installWebExt,
|
|
getExtensionIdChrome,
|
|
getExtensionIdFirefox,
|
|
} = require('./func')
|
|
const {
|
|
checkBrowserForConsoleErrors,
|
|
closeAllWindowHandlesExcept,
|
|
findElement,
|
|
findElements,
|
|
openNewPage,
|
|
switchToWindowWithTitle,
|
|
verboseReportOnFailure,
|
|
waitUntilXWindowHandles,
|
|
} = require('./helpers')
|
|
const fetchMockResponses = require('./fetch-mocks.js')
|
|
|
|
|
|
describe('Using MetaMask with an existing account', function () {
|
|
let extensionId
|
|
let driver
|
|
|
|
const testSeedPhrase = 'forum vessel pink push lonely enact gentle tail admit parrot grunt dress'
|
|
const regularDelayMs = 1000
|
|
const largeDelayMs = regularDelayMs * 2
|
|
|
|
const button = async (x) => {
|
|
const buttoncheck = x
|
|
await buttoncheck.click()
|
|
await delay(largeDelayMs)
|
|
const [results] = await findElements(driver, By.css('#results'))
|
|
const resulttext = await results.getText()
|
|
var parsedData = JSON.parse(resulttext)
|
|
|
|
return (parsedData)
|
|
|
|
}
|
|
|
|
this.timeout(0)
|
|
this.bail(true)
|
|
|
|
before(async function () {
|
|
let extensionUrl
|
|
switch (process.env.SELENIUM_BROWSER) {
|
|
case 'chrome': {
|
|
const extensionPath = path.resolve('dist/chrome')
|
|
driver = buildChromeWebDriver(extensionPath)
|
|
extensionId = await getExtensionIdChrome(driver)
|
|
await delay(regularDelayMs)
|
|
extensionUrl = `chrome-extension://${extensionId}/home.html`
|
|
break
|
|
}
|
|
case 'firefox': {
|
|
const extensionPath = path.resolve('dist/firefox')
|
|
driver = buildFirefoxWebdriver()
|
|
await installWebExt(driver, extensionPath)
|
|
await delay(regularDelayMs)
|
|
extensionId = await getExtensionIdFirefox(driver)
|
|
extensionUrl = `moz-extension://${extensionId}/home.html`
|
|
break
|
|
}
|
|
}
|
|
// Depending on the state of the application built into the above directory (extPath) and the value of
|
|
// METAMASK_DEBUG we will see different post-install behaviour and possibly some extra windows. Here we
|
|
// are closing any extraneous windows to reset us to a single window before continuing.
|
|
const [tab1] = await driver.getAllWindowHandles()
|
|
await closeAllWindowHandlesExcept(driver, [tab1])
|
|
await driver.switchTo().window(tab1)
|
|
await driver.get(extensionUrl)
|
|
})
|
|
|
|
beforeEach(async function () {
|
|
await driver.executeScript(
|
|
'window.origFetch = window.fetch.bind(window);' +
|
|
'window.fetch = ' +
|
|
'(...args) => { ' +
|
|
'if (args[0] === "https://ethgasstation.info/json/ethgasAPI.json") { return ' +
|
|
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.ethGasBasic + '\')) }); } else if ' +
|
|
'(args[0] === "https://ethgasstation.info/json/predictTable.json") { return ' +
|
|
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.ethGasPredictTable + '\')) }); } else if ' +
|
|
'(args[0].match(/chromeextensionmm/)) { return ' +
|
|
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.metametrics + '\')) }); } else if ' +
|
|
'(args[0] === "https://dev.blockscale.net/api/gasexpress.json") { return ' +
|
|
'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.gasExpress + '\')) }); } ' +
|
|
'return window.origFetch(...args); };' +
|
|
'function cancelInfuraRequest(requestDetails) {' +
|
|
'console.log("Canceling: " + requestDetails.url);' +
|
|
'return {' +
|
|
'cancel: true' +
|
|
'};' +
|
|
' }' +
|
|
'window.chrome && window.chrome.webRequest && window.chrome.webRequest.onBeforeRequest.addListener(' +
|
|
'cancelInfuraRequest,' +
|
|
'{urls: ["https://*.infura.io/*"]},' +
|
|
'["blocking"]' +
|
|
');'
|
|
)
|
|
})
|
|
|
|
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('First time flow starting from an existing seed phrase', () => {
|
|
it('clicks the continue button on the welcome screen', async () => {
|
|
await findElement(driver, By.css('.welcome-page__header'))
|
|
const welcomeScreenBtn = await findElement(driver, By.css('.first-time-flow__button'))
|
|
welcomeScreenBtn.click()
|
|
await delay(largeDelayMs)
|
|
})
|
|
|
|
it('clicks the "Import Wallet" option', async () => {
|
|
const customRpcButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Import 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('imports a seed phrase', async () => {
|
|
const [seedTextArea] = await findElements(driver, By.css('textarea.first-time-flow__textarea'))
|
|
await seedTextArea.sendKeys(testSeedPhrase)
|
|
await delay(regularDelayMs)
|
|
|
|
const [password] = await findElements(driver, By.id('password'))
|
|
await password.sendKeys('correct horse battery staple')
|
|
const [confirmPassword] = await findElements(driver, By.id('confirm-password'))
|
|
confirmPassword.sendKeys('correct horse battery staple')
|
|
|
|
const tosCheckBox = await findElement(driver, By.css('.first-time-flow__checkbox'))
|
|
await tosCheckBox.click()
|
|
|
|
const [importButton] = await findElements(driver, By.xpath(`//button[contains(text(), 'Import')]`))
|
|
await importButton.click()
|
|
await delay(regularDelayMs)
|
|
})
|
|
|
|
it('clicks through the success screen', async () => {
|
|
await findElement(driver, By.xpath(`//div[contains(text(), 'Congratulations')]`))
|
|
const doneButton = await findElement(driver, By.css('button.first-time-flow__button'))
|
|
await doneButton.click()
|
|
await delay(regularDelayMs)
|
|
})
|
|
})
|
|
|
|
|
|
describe('opens dapp', () => {
|
|
|
|
it('switches to mainnet', async () => {
|
|
const networkDropdown = await findElement(driver, By.css('.network-name'))
|
|
await networkDropdown.click()
|
|
await delay(regularDelayMs)
|
|
|
|
const [mainnet] = await findElements(driver, By.xpath(`//span[contains(text(), 'Main Ethereum Network')]`))
|
|
await mainnet.click()
|
|
await delay(largeDelayMs * 2)
|
|
})
|
|
|
|
it('connects to dapp', async () => {
|
|
await openNewPage(driver, 'http://127.0.0.1:8080/')
|
|
await delay(regularDelayMs)
|
|
|
|
await waitUntilXWindowHandles(driver, 3)
|
|
const windowHandles = await driver.getAllWindowHandles()
|
|
|
|
const extension = windowHandles[0]
|
|
const popup = await switchToWindowWithTitle(driver, 'MetaMask Notification', windowHandles)
|
|
const dapp = windowHandles.find(handle => handle !== extension && handle !== popup)
|
|
|
|
await delay(regularDelayMs)
|
|
const approveButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Connect')]`))
|
|
await approveButton.click()
|
|
|
|
await driver.switchTo().window(dapp)
|
|
await delay(regularDelayMs)
|
|
})
|
|
})
|
|
|
|
describe('testing web3 methods', async () => {
|
|
|
|
|
|
it('testing hexa methods', async () => {
|
|
|
|
|
|
var List = await driver.findElements(By.className('hexaNumberMethods'))
|
|
|
|
for (let i = 0; i < List.length; i++) {
|
|
try {
|
|
|
|
var parsedData = await button(List[i])
|
|
console.log(parsedData)
|
|
var result = parseInt(parsedData.result, 16)
|
|
|
|
assert.equal((typeof result === 'number'), true)
|
|
await delay(regularDelayMs)
|
|
} catch (err) {
|
|
console.log(err)
|
|
assert(false)
|
|
|
|
}
|
|
}
|
|
})
|
|
|
|
it('testing booleanMethods', async () => {
|
|
|
|
var List = await driver.findElements(By.className('booleanMethods'))
|
|
|
|
for (let i = 0; i < List.length; i++) {
|
|
try {
|
|
|
|
var parsedData = await button(List[i])
|
|
console.log(parsedData)
|
|
var result = parsedData.result
|
|
|
|
assert.equal(result, false)
|
|
await delay(regularDelayMs)
|
|
} catch (err) {
|
|
console.log(err)
|
|
assert(false)
|
|
|
|
|
|
}
|
|
}
|
|
|
|
})
|
|
|
|
it('testing transactionMethods', async () => {
|
|
|
|
var List = await driver.findElements(By.className('transactionMethods'))
|
|
|
|
for (let i = 0; i < List.length; i++) {
|
|
try {
|
|
|
|
var parsedData = await button(List[i])
|
|
|
|
console.log(parsedData.result.blockHash)
|
|
|
|
var result = []
|
|
result.push(parseInt(parsedData.result.blockHash, 16))
|
|
result.push(parseInt(parsedData.result.blockNumber, 16))
|
|
result.push(parseInt(parsedData.result.gas, 16))
|
|
result.push(parseInt(parsedData.result.gasPrice, 16))
|
|
result.push(parseInt(parsedData.result.hash, 16))
|
|
result.push(parseInt(parsedData.result.input, 16))
|
|
result.push(parseInt(parsedData.result.nonce, 16))
|
|
result.push(parseInt(parsedData.result.r, 16))
|
|
result.push(parseInt(parsedData.result.s, 16))
|
|
result.push(parseInt(parsedData.result.v, 16))
|
|
result.push(parseInt(parsedData.result.to, 16))
|
|
result.push(parseInt(parsedData.result.value, 16))
|
|
|
|
|
|
result.forEach((value) => {
|
|
assert.equal((typeof value === 'number'), true)
|
|
})
|
|
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
assert(false)
|
|
|
|
|
|
}
|
|
}
|
|
|
|
})
|
|
|
|
it('testing blockMethods', async () => {
|
|
|
|
var List = await driver.findElements(By.className('blockMethods'))
|
|
|
|
for (let i = 0; i < List.length; i++) {
|
|
try {
|
|
|
|
var parsedData = await button(List[i])
|
|
console.log(JSON.stringify(parsedData) + i)
|
|
|
|
console.log(parsedData.result.parentHash)
|
|
|
|
var result = parseInt(parsedData.result.parentHash, 16)
|
|
|
|
assert.equal((typeof result === 'number'), true)
|
|
await delay(regularDelayMs)
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
assert(false)
|
|
|
|
|
|
}
|
|
}
|
|
})
|
|
|
|
it('testing methods', async () => {
|
|
|
|
var List = await driver.findElements(By.className('methods'))
|
|
var parsedData
|
|
var result
|
|
|
|
for (let i = 0; i < List.length; i++) {
|
|
try {
|
|
|
|
if (i === 2) {
|
|
|
|
parsedData = await button(List[i])
|
|
console.log(parsedData.result.blockHash)
|
|
|
|
result = parseInt(parsedData.result.blockHash, 16)
|
|
|
|
assert.equal((typeof result === 'number' || (result === 0)), true)
|
|
await delay(regularDelayMs)
|
|
} else {
|
|
parsedData = await button(List[i])
|
|
console.log(parsedData.result)
|
|
|
|
result = parseInt(parsedData.result, 16)
|
|
|
|
assert.equal((typeof result === 'number' || (result === 0)), true)
|
|
await delay(regularDelayMs)
|
|
}
|
|
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err)
|
|
assert(false)
|
|
|
|
|
|
}
|
|
}
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|