aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/base.conf.js2
-rw-r--r--test/e2e/func.js18
-rw-r--r--test/e2e/metamask.spec.js122
-rw-r--r--test/integration/lib/add-token.js39
-rw-r--r--test/integration/lib/confirm-sig-requests.js6
-rw-r--r--test/integration/lib/mascara-first-time.js6
-rw-r--r--test/integration/lib/send-new-ui.js9
-rw-r--r--test/unit/migrations/022-test.js32
-rw-r--r--test/unit/migrations/023-test.js99
-rw-r--r--test/unit/tx-state-manager-test.js6
10 files changed, 308 insertions, 31 deletions
diff --git a/test/base.conf.js b/test/base.conf.js
index adb5357e8..e2e9d44ba 100644
--- a/test/base.conf.js
+++ b/test/base.conf.js
@@ -19,11 +19,13 @@ module.exports = function(config) {
'test/integration/jquery-3.1.0.min.js',
{ pattern: 'dist/chrome/images/**/*.*', watched: false, included: false, served: true },
{ pattern: 'dist/chrome/fonts/**/*.*', watched: false, included: false, served: true },
+ { pattern: 'dist/chrome/_locales/**/*.*', watched: false, included: false, served: true },
],
proxies: {
'/images/': '/base/dist/chrome/images/',
'/fonts/': '/base/dist/chrome/fonts/',
+ '/_locales/': '/base/dist/chrome/_locales/',
},
// test results reporter to use
diff --git a/test/e2e/func.js b/test/e2e/func.js
new file mode 100644
index 000000000..733225565
--- /dev/null
+++ b/test/e2e/func.js
@@ -0,0 +1,18 @@
+require('chromedriver')
+const webdriver = require('selenium-webdriver')
+
+exports.delay = function delay (time) {
+ return new Promise(resolve => setTimeout(resolve, time))
+}
+
+
+exports.buildWebDriver = function buildWebDriver (extPath) {
+ return new webdriver.Builder()
+ .withCapabilities({
+ chromeOptions: {
+ args: [`load-extension=${extPath}`],
+ },
+ })
+ .forBrowser('chrome')
+ .build()
+}
diff --git a/test/e2e/metamask.spec.js b/test/e2e/metamask.spec.js
new file mode 100644
index 000000000..c73ba2b41
--- /dev/null
+++ b/test/e2e/metamask.spec.js
@@ -0,0 +1,122 @@
+const path = require('path')
+const assert = require('assert')
+const webdriver = require('selenium-webdriver')
+const By = webdriver.By
+const { delay, buildWebDriver } = require('./func')
+
+describe('Metamask popup page', function () {
+ let driver
+ this.seedPhase
+ this.accountAddress
+ this.timeout(0)
+
+ before(async function () {
+ const extPath = path.resolve('dist/chrome')
+ driver = buildWebDriver(extPath)
+ await driver.get('chrome://extensions-frame')
+ const elems = await driver.findElements(By.className('extension-list-item-wrapper'))
+ const extensionId = await elems[1].getAttribute('id')
+ await driver.get(`chrome-extension://${extensionId}/popup.html`)
+ await delay(500)
+ })
+
+ after(async function () {
+ await driver.quit()
+ })
+
+ describe('#onboarding', () => {
+ it('should open Metamask.io', async function () {
+ const tabs = await driver.getAllWindowHandles()
+ await driver.switchTo().window(tabs[0])
+ await delay(300)
+ })
+
+ it('should match title', async () => {
+ const title = await driver.getTitle()
+ assert.equal(title, 'MetaMask Plugin', 'title matches MetaMask Plugin')
+ })
+
+ it('should show privacy notice', async () => {
+ const privacy = await driver.findElement(By.className(
+ 'terms-header'
+ )).getText()
+ assert.equal(privacy, 'PRIVACY NOTICE', 'shows privacy notice')
+ driver.findElement(By.css(
+ 'button'
+ )).click()
+ })
+
+ it('should show terms of use', async () => {
+ await delay(300)
+ const terms = await driver.findElement(By.className(
+ 'terms-header'
+ )).getText()
+ assert.equal(terms, 'TERMS OF USE', 'shows terms of use')
+ })
+
+ it('should be unable to continue without scolling throught the terms of use', async () => {
+ const button = await driver.findElement(By.css(
+ 'button'
+ )).isEnabled()
+ assert.equal(button, false, 'disabled continue button')
+ const element = driver.findElement(By.linkText(
+ 'Attributions'
+ ))
+ await driver.executeScript('arguments[0].scrollIntoView(true)', element)
+ })
+
+ it('should be able to continue when scrolled to the bottom of terms of use', async () => {
+ const button = await driver.findElement(By.css('button'))
+ const buttonEnabled = await button.isEnabled()
+ await delay(500)
+ assert.equal(buttonEnabled, true, 'enabled continue button')
+ await button.click()
+ })
+
+ it('should accept password with length of eight', async () => {
+ await delay(300)
+ const passwordBox = await driver.findElement(By.id('password-box'))
+ const passwordBoxConfirm = await driver.findElement(By.id('password-box-confirm'))
+ const button = driver.findElement(By.css('button'))
+
+ passwordBox.sendKeys('123456789')
+ passwordBoxConfirm.sendKeys('123456789')
+ await delay(500)
+ await button.click()
+ })
+
+ it('should show value was created and seed phrase', async () => {
+ await delay(700)
+ this.seedPhase = await driver.findElement(By.className('twelve-word-phrase')).getText()
+ const continueAfterSeedPhrase = await driver.findElement(By.css('button'))
+ await continueAfterSeedPhrase.click()
+ })
+
+ it('should show lock account', async () => {
+ await delay(300)
+ await driver.findElement(By.className('sandwich-expando')).click()
+ await delay(500)
+ await driver.findElement(By.xpath('//*[@id="app-content"]/div/div[3]/span/div/li[2]')).click()
+ })
+
+ it('should accept account password after lock', async () => {
+ await delay(500)
+ await driver.findElement(By.id('password-box')).sendKeys('123456789')
+ await driver.findElement(By.css('button')).click()
+ await delay(500)
+ })
+
+ it('should show QR code', async () => {
+ await delay(300)
+ await driver.findElement(By.className('fa-ellipsis-h')).click()
+ await driver.findElement(By.xpath('//*[@id="app-content"]/div/div[4]/div/div/div[1]/flex-column/div[1]/div/span/i/div/div/li[2]')).click()
+ await delay(300)
+ })
+
+ it('should show the account address', async () => {
+ this.accountAddress = await driver.findElement(By.className('ellip-address')).getText()
+ await driver.findElement(By.className('fa-arrow-left')).click()
+ await delay(500)
+ })
+ })
+})
diff --git a/test/integration/lib/add-token.js b/test/integration/lib/add-token.js
index 42ed28dca..cc04beb21 100644
--- a/test/integration/lib/add-token.js
+++ b/test/integration/lib/add-token.js
@@ -26,7 +26,7 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok($('.token-list-item').length === 0, 'no tokens added')
// Go to Add Token screen
- let addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button')
+ let addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click()
@@ -34,26 +34,26 @@ async function runAddTokenFlowTest (assert, done) {
let addTokenWrapper = await queryAsync($, '.add-token__wrapper')
assert.ok(addTokenWrapper[0], 'add token wrapper renders')
- let addTokenTitle = await queryAsync($, '.add-token__title')
- assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct')
+ let addTokenTitle = await queryAsync($, '.add-token__header__title')
+ assert.equal(addTokenTitle[0].textContent, 'Add Tokens', 'add token title is correct')
// Cancel Add Token
- const cancelAddTokenButton = await queryAsync($, 'button.btn-cancel.add-token__button')
+ const cancelAddTokenButton = await queryAsync($, 'button.btn-secondary--lg.add-token__cancel-button')
assert.ok(cancelAddTokenButton[0], 'cancel add token button present')
cancelAddTokenButton.click()
assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view')
// Return to Add Token Screen
- addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button')
+ addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click()
// Verify Add Token Screen
addTokenWrapper = await queryAsync($, '.add-token__wrapper')
- addTokenTitle = await queryAsync($, '.add-token__title')
+ addTokenTitle = await queryAsync($, '.add-token__header__title')
assert.ok(addTokenWrapper[0], 'add token wrapper renders')
- assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct')
+ assert.equal(addTokenTitle[0].textContent, 'Add Tokens', 'add token title is correct')
// Search for token
const searchInput = await queryAsync($, 'input.add-token__input')
@@ -68,7 +68,7 @@ async function runAddTokenFlowTest (assert, done) {
tokenWrapper[0].click()
// Click Next button
- let nextButton = await queryAsync($, 'button.btn-clear.add-token__button')
+ let nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click()
@@ -78,8 +78,8 @@ async function runAddTokenFlowTest (assert, done) {
'Would you like to add these tokens?',
'confirm add token rendered'
)
- assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found')
- $('button.btn-clear.add-token__button')[0].click()
+ assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
+ $('button.btn-primary--lg')[0].click()
// Verify added token image
let heroBalance = await queryAsync($, '.hero-balance')
@@ -87,13 +87,15 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added')
// Return to Add Token Screen
- addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button')
+ addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click()
- const addCustom = await queryAsync($, '.add-token__add-custom')
- assert.ok(addCustom[0], 'add custom token button present')
- addCustom[0].click()
+ const addTokenTabs = await queryAsync($, '.add-token__header__tabs__tab')
+ assert.equal(addTokenTabs.length, 2, 'expected number of tabs')
+ assert.equal(addTokenTabs[1].textContent, 'Custom Token', 'Custom Token tab present')
+ assert.ok(addTokenTabs[1], 'add custom token tab present')
+ addTokenTabs[1].click()
// Input token contract address
const customInput = await queryAsync($, 'input.add-token__add-custom-input')
@@ -101,14 +103,15 @@ async function runAddTokenFlowTest (assert, done) {
reactTriggerChange(customInput[0])
// Click Next button
- nextButton = await queryAsync($, 'button.btn-clear.add-token__button')
+ nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click()
// Verify symbol length error since contract address won't return symbol
const errorMessage = await queryAsync($, '.add-token__add-custom-error-message')
assert.ok(errorMessage[0], 'error rendered')
- $('button.btn-cancel.add-token__button')[0].click()
+
+ $('button.btn-secondary--lg')[0].click()
// // Confirm Add token
// assert.equal(
@@ -116,8 +119,8 @@ async function runAddTokenFlowTest (assert, done) {
// 'Would you like to add these tokens?',
// 'confirm add token rendered'
// )
- // assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found')
- // $('button.btn-clear.add-token__button')[0].click()
+ // assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
+ // $('button.btn-primary--lg')[0].click()
// // Verify added token image
// heroBalance = await queryAsync($, '.hero-balance')
diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js
index 9737a2283..f1116d1a6 100644
--- a/test/integration/lib/confirm-sig-requests.js
+++ b/test/integration/lib/confirm-sig-requests.js
@@ -27,7 +27,7 @@ async function runConfirmSigRequestsTest(assert, done) {
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
- let confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button')
+ let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@@ -39,7 +39,7 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
- confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button')
+ confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@@ -49,7 +49,7 @@ async function runConfirmSigRequestsTest(assert, done) {
assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
assert.equal(confirmSigRowValue[1].textContent, '1337')
- confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button')
+ confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
const txView = await queryAsync($, '.tx-view')
diff --git a/test/integration/lib/mascara-first-time.js b/test/integration/lib/mascara-first-time.js
index bcbc94ff6..564852585 100644
--- a/test/integration/lib/mascara-first-time.js
+++ b/test/integration/lib/mascara-first-time.js
@@ -57,9 +57,9 @@ async function runFirstTimeUsageTest (assert, done) {
;(await findAsync(app, '.first-time-flow__button')).click()
// Deposit Ether Screen
- const buyEthTitle = (await findAsync(app, '.buy-ether__title'))[0]
- assert.equal(buyEthTitle.textContent, 'Deposit Ether', 'deposit ether screen')
- ;(await findAsync(app, '.buy-ether__do-it-later')).click()
+ const depositEthTitle = (await findAsync(app, '.page-container__title'))[0]
+ assert.equal(depositEthTitle.textContent, 'Deposit Ether', 'deposit ether screen')
+ ;(await findAsync(app, '.page-container__header-close')).click()
const menu = (await findAsync(app, '.account-menu__icon'))[0]
menu.click()
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index 46e0ef0e4..163f3658c 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -21,13 +21,15 @@ global.ethQuery = {
sendTransaction: () => {},
}
+global.ethereumProvider = {}
+
async function runSendFlowTest(assert, done) {
console.log('*** start runSendFlowTest')
const selectState = await queryAsync($, 'select')
selectState.val('send new ui')
reactTriggerChange(selectState[0])
- const sendScreenButton = await queryAsync($, 'button.btn-clear.hero-balance-button')
+ const sendScreenButton = await queryAsync($, 'button.btn-primary.hero-balance-button')
assert.ok(sendScreenButton[1], 'send screen button present')
sendScreenButton[1].click()
@@ -120,14 +122,13 @@ async function runSendFlowTest(assert, done) {
'send gas field should show customized gas total converted to USD'
)
- const sendButton = await queryAsync($, 'button.btn-clear.page-container__footer-button')
+ const sendButton = await queryAsync($, 'button.btn-primary--lg.page-container__footer-button')
assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
sendButton[0].click()
await timeout()
selectState.val('send edit')
reactTriggerChange(selectState[0])
- await timeout(10000)
const confirmFromName = (await queryAsync($, '.sender-to-recipient__sender-name')).first()
assert.equal(confirmFromName[0].textContent, 'Send Account 2', 'confirm screen should show correct from name')
@@ -161,7 +162,7 @@ async function runSendFlowTest(assert, done) {
sendAmountFieldInputInEdit.val('1.0')
reactTriggerChange(sendAmountFieldInputInEdit[0])
- const sendButtonInEdit = await queryAsync($, '.btn-clear.page-container__footer-button')
+ const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
sendButtonInEdit[0].click()
diff --git a/test/unit/migrations/022-test.js b/test/unit/migrations/022-test.js
new file mode 100644
index 000000000..1333d929d
--- /dev/null
+++ b/test/unit/migrations/022-test.js
@@ -0,0 +1,32 @@
+const assert = require('assert')
+const migration22 = require('../../../app/scripts/migrations/022')
+const properTime = (new Date()).getTime()
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ { "status": "submitted" },
+ { "status": "submitted", "submittedTime": properTime },
+ {"status": "confirmed"},
+ ]
+ },
+ },
+}
+
+describe('storage is migrated successfully where transactions that are submitted have submittedTimes', () => {
+ it('should add submittedTime key on the txMeta if appropriate', (done) => {
+ migration22.migrate(storage)
+ .then((migratedData) => {
+ const [txMeta1, txMeta2, txMeta3] = migratedData.data.TransactionController.transactions
+ assert.equal(migratedData.meta.version, 22)
+ // should have written a submitted time
+ assert(txMeta1.submittedTime)
+ // should not have written a submitted time because it already has one
+ assert.equal(txMeta2.submittedTime, properTime)
+ // should not have written a submitted time
+ assert(!txMeta3.submittedTime)
+ done()
+ }).catch(done)
+ })
+})
diff --git a/test/unit/migrations/023-test.js b/test/unit/migrations/023-test.js
new file mode 100644
index 000000000..be432d9fa
--- /dev/null
+++ b/test/unit/migrations/023-test.js
@@ -0,0 +1,99 @@
+const assert = require('assert')
+const migration23 = require('../../../app/scripts/migrations/023')
+const properTime = (new Date()).getTime()
+const storage = {
+ "meta": {},
+ "data": {
+ "TransactionController": {
+ "transactions": [
+ ]
+ },
+ },
+}
+
+const transactions = []
+const transactions40 = []
+const transactions20 = []
+
+const txStates = [
+ 'unapproved',
+ 'approved',
+ 'signed',
+ 'submitted',
+ 'confirmed',
+ 'rejected',
+ 'failed',
+ 'dropped',
+]
+
+const deletableTxStates = [
+ 'confirmed',
+ 'rejected',
+ 'failed',
+ 'dropped',
+]
+
+let nonDeletableCount = 0
+
+let status
+while (transactions.length <= 100) {
+ status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]
+ if (!deletableTxStates.find((s) => s === status)) nonDeletableCount++
+ transactions.push({status})
+}
+
+while (transactions40.length < 40) {
+ status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]
+ transactions40.push({status})
+}
+
+while (transactions20.length < 20) {
+ status = txStates[Math.floor(Math.random() * Math.floor(txStates.length - 1))]
+ transactions20.push({status})
+}
+
+
+
+storage.data.TransactionController.transactions = transactions
+
+describe('storage is migrated successfully and the proper transactions are remove from state', () => {
+ it('should remove transactions that are unneeded', (done) => {
+ migration23.migrate(storage)
+ .then((migratedData) => {
+ let leftoverNonDeletableTxCount = 0
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ migratedTransactions.forEach((tx) => {
+ if (!deletableTxStates.find((s) => s === tx.status)) {
+ leftoverNonDeletableTxCount++
+ }
+ })
+ assert.equal(leftoverNonDeletableTxCount, nonDeletableCount, 'migration shouldnt delete transactions we want to keep')
+ assert((migratedTransactions.length >= 40), `should be equal or greater to 40 if they are non deletable states got ${migratedTransactions.length} transactions`)
+ done()
+ }).catch(done)
+ })
+
+ it('should not remove any transactions because 40 is the expectable limit', (done) => {
+ storage.meta.version = 22
+ storage.data.TransactionController.transactions = transactions40
+ migration23.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+
+ assert.equal(migratedTransactions.length, 40, 'migration shouldnt delete when at limit')
+ done()
+ }).catch(done)
+ })
+
+ it('should not remove any transactions because 20 txs is under the expectable limit', (done) => {
+ storage.meta.version = 22
+ storage.data.TransactionController.transactions = transactions20
+ migration23.migrate(storage)
+ .then((migratedData) => {
+ const migratedTransactions = migratedData.data.TransactionController.transactions
+ assert.equal(migratedTransactions.length, 20, 'migration shouldnt delete when under limit')
+ done()
+ }).catch(done)
+ })
+
+})
diff --git a/test/unit/tx-state-manager-test.js b/test/unit/tx-state-manager-test.js
index 220bf501f..a5ac13664 100644
--- a/test/unit/tx-state-manager-test.js
+++ b/test/unit/tx-state-manager-test.js
@@ -240,12 +240,12 @@ describe('TransactionStateManager', function () {
})
describe('#wipeTransactions', function () {
-
+
const specificAddress = '0xaa'
const otherAddress = '0xbb'
it('should remove only the transactions from a specific address', function () {
-
+
const txMetas = [
{ id: 0, status: 'unapproved', txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: currentNetworkId },
{ id: 1, status: 'confirmed', txParams: { from: otherAddress, to: specificAddress }, metamaskNetworkId: currentNetworkId },
@@ -268,7 +268,7 @@ describe('TransactionStateManager', function () {
{ id: 1, status: 'confirmed', txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: otherNetworkId },
{ id: 2, status: 'confirmed', txParams: { from: specificAddress, to: otherAddress }, metamaskNetworkId: otherNetworkId },
]
-
+
txMetas.forEach((txMeta) => txStateManager.addTx(txMeta, noop))
txStateManager.wipeTransactions(specificAddress)