aboutsummaryrefslogtreecommitdiffstats
path: root/test/e2e/firefox/metamask.spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/e2e/firefox/metamask.spec.js')
-rw-r--r--test/e2e/firefox/metamask.spec.js320
1 files changed, 320 insertions, 0 deletions
diff --git a/test/e2e/firefox/metamask.spec.js b/test/e2e/firefox/metamask.spec.js
new file mode 100644
index 000000000..a5d286235
--- /dev/null
+++ b/test/e2e/firefox/metamask.spec.js
@@ -0,0 +1,320 @@
+const fs = require('fs')
+const mkdirp = require('mkdirp')
+const path = require('path')
+const assert = require('assert')
+const pify = require('pify')
+const webdriver = require('selenium-webdriver')
+const Command = require('selenium-webdriver/lib/command').Command
+const By = webdriver.By
+const { delay, buildFirefoxWebdriver } = require('../func')
+
+describe('', function () {
+ let driver, seedPhase, accountAddress, tokenAddress, extensionId
+
+ this.timeout(0)
+
+ before(async function () {
+ const extPath = path.resolve('dist/firefox')
+ driver = buildFirefoxWebdriver()
+ installWebExt(driver, extPath)
+ await delay(1000)
+ })
+
+ afterEach(async function () {
+ if (this.currentTest.state === 'failed') {
+ await verboseReportOnFailure(this.currentTest)
+ }
+ })
+
+ after(async function () {
+ await driver.quit()
+ })
+
+ describe('Setup', function () {
+
+ it('switches to Firefox addon list', async function () {
+ await driver.get('about:debugging#addons')
+ await delay(1000)
+ })
+
+ it(`selects MetaMask's extension id and opens it in the current tab`, async function () {
+ const tabs = await driver.getAllWindowHandles()
+ await driver.switchTo().window(tabs[0])
+ extensionId = await driver.findElement(By.css('dd.addon-target-info-content:nth-child(6) > span:nth-child(1)')).getText()
+ await driver.get(`moz-extension://${extensionId}/popup.html`)
+ await delay(500)
+ })
+
+ it('sets provider type to localhost', async function () {
+ await setProviderType('localhost')
+ await delay(300)
+ })
+ })
+
+ describe('Account Creation', () => {
+
+ it('matches MetaMask title', async () => {
+ const title = await driver.getTitle()
+ assert.equal(title, 'MetaMask', 'title matches MetaMask')
+ })
+
+ it('shows privacy notice', async () => {
+ const privacy = await driver.findElement(By.css('.terms-header')).getText()
+ assert.equal(privacy, 'PRIVACY NOTICE', 'shows privacy notice')
+ await driver.findElement(By.css('button')).click()
+ await delay(300)
+ })
+
+ it('show terms of use', async () => {
+ await delay(300)
+ const terms = await driver.findElement(By.css('.terms-header')).getText()
+ assert.equal(terms, 'TERMS OF USE', 'shows terms of use')
+ await delay(300)
+ })
+
+ it('checks if the TOU button is disabled', async () => {
+ const button = await driver.findElement(By.css('button')).isEnabled()
+ assert.equal(button, false, 'disabled continue button')
+ const element = await driver.findElement(By.linkText('Attributions'))
+ await driver.executeScript('arguments[0].scrollIntoView(true)', element)
+ await delay(300)
+ })
+
+ it('allows the button to be clicked when scrolled to the bottom of TOU', async () => {
+ const button = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.flex-column.flex-center.flex-grow > button'))
+ await delay(300)
+ const buttonEnabled = await button.isEnabled()
+ assert.equal(buttonEnabled, true, 'enabled continue button')
+ await delay(200)
+ await button.click()
+ })
+
+ it('accepts password with length of eight', async () => {
+ const passwordBox = await driver.findElement(By.id('password-box'))
+ const passwordBoxConfirm = await driver.findElement(By.id('password-box-confirm'))
+ const button = await driver.findElements(By.css('button'))
+
+ await passwordBox.sendKeys('123456789')
+ await passwordBoxConfirm.sendKeys('123456789')
+ await button[0].click()
+ await delay(500)
+ })
+
+ it('shows value was created and seed phrase', async () => {
+ await delay(300)
+ seedPhase = await driver.findElement(By.css('.twelve-word-phrase')).getText()
+ const continueAfterSeedPhrase = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > button:nth-child(4)'))
+ assert.equal(await continueAfterSeedPhrase.getText(), `I'VE COPIED IT SOMEWHERE SAFE`)
+ await continueAfterSeedPhrase.click()
+ await delay(300)
+ })
+
+ it('shows account address', async function () {
+ accountAddress = await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > div > div:nth-child(1) > flex-column > div.flex-row > div')).getText()
+ })
+
+ it('logs out of the vault', async () => {
+ await driver.findElement(By.css('.sandwich-expando')).click()
+ await delay(500)
+ const logoutButton = await driver.findElement(By.css('#app-content > div > div:nth-child(3) > span > div > li:nth-child(3)'))
+ assert.equal(await logoutButton.getText(), 'Log Out')
+ await logoutButton.click()
+ })
+
+ it('accepts 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('shows QR code option', async () => {
+ await delay(300)
+ await driver.findElement(By.css('.fa-ellipsis-h')).click()
+ await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div > div:nth-child(1) > flex-column > div.name-label > div > span > i > div > div > li:nth-child(3)')).click()
+ await delay(300)
+ })
+
+ it('checks QR code address is the same as account details address', async () => {
+ const QRaccountAddress = await driver.findElement(By.css('.ellip-address')).getText()
+ assert.equal(accountAddress.toLowerCase(), QRaccountAddress)
+ await driver.findElement(By.css('.fa-arrow-left')).click()
+ await delay(500)
+ })
+ })
+
+ describe('Import Ganache seed phrase', function () {
+ it('logs out', async function () {
+ await driver.findElement(By.css('.sandwich-expando')).click()
+ await delay(200)
+ const logOut = await driver.findElement(By.css('#app-content > div > div:nth-child(3) > span > div > li:nth-child(3)'))
+ assert.equal(await logOut.getText(), 'Log Out')
+ await logOut.click()
+ await delay(300)
+ })
+
+ it('restores from seed phrase', async function () {
+ const restoreSeedLink = await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > div.flex-row.flex-center.flex-grow > p'))
+ assert.equal(await restoreSeedLink.getText(), 'Restore from seed phrase')
+ await restoreSeedLink.click()
+ await delay(100)
+ })
+
+ it('adds seed phrase', async function () {
+ const testSeedPhrase = 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent'
+ const seedTextArea = await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > textarea'))
+ await seedTextArea.sendKeys(testSeedPhrase)
+
+ await driver.findElement(By.id('password-box')).sendKeys('123456789')
+ await driver.findElement(By.id('password-box-confirm')).sendKeys('123456789')
+ await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > div > button:nth-child(2)')).click()
+ await delay(500)
+ })
+
+ it('balance renders', async function () {
+ await delay(200)
+ const balance = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div > div.flex-row > div.ether-balance.ether-balance-amount > div > div > div:nth-child(1) > div:nth-child(1)'))
+ assert.equal(await balance.getText(), '100.000')
+ await delay(200)
+ })
+
+ it('sends transaction', async function () {
+ const sendButton = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div > div.flex-row > button:nth-child(4)'))
+ assert.equal(await sendButton.getText(), 'SEND')
+ await sendButton.click()
+ await delay(200)
+ })
+
+ it('adds recipient address and amount', async function () {
+ const sendTranscationScreen = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > h3:nth-child(2)')).getText()
+ assert.equal(sendTranscationScreen, 'SEND TRANSACTION')
+ const inputAddress = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(3) > div > input'))
+ const inputAmmount = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(4) > input'))
+ await inputAddress.sendKeys('0x2f318C334780961FB129D2a6c30D0763d9a5C970')
+ await inputAmmount.sendKeys('10')
+ await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > section:nth-child(4) > button')).click()
+ await delay(300)
+ })
+
+ it('confirms transaction', async function () {
+ await delay(300)
+ await driver.findElement(By.css('#pending-tx-form > div.flex-row.flex-space-around.conf-buttons > input')).click()
+ await delay(500)
+ })
+
+ it('finds the transaction in the transactions list', async function () {
+ const tranasactionAmount = await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > section > section > div > div > div > div.ether-balance.ether-balance-amount > div > div > div > div:nth-child(1)'))
+ assert.equal(await tranasactionAmount.getText(), '10.0')
+ })
+ })
+
+ describe('Token Factory', function () {
+
+ it('navigates to token factory', async function () {
+ await driver.get('http://tokenfactory.surge.sh/')
+ })
+
+ it('navigates to create token contract link', async function () {
+ const createToken = await driver.findElement(By.css('#bs-example-navbar-collapse-1 > ul > li:nth-child(3) > a'))
+ await createToken.click()
+ })
+
+ it('adds input for token', async function () {
+ const totalSupply = await driver.findElement(By.css('#main > div > div > div > div:nth-child(2) > div > div:nth-child(5) > input'))
+ const tokenName = await driver.findElement(By.css('#main > div > div > div > div:nth-child(2) > div > div:nth-child(6) > input'))
+ const tokenDecimal = await driver.findElement(By.css('#main > div > div > div > div:nth-child(2) > div > div:nth-child(7) > input'))
+ const tokenSymbol = await driver.findElement(By.css('#main > div > div > div > div:nth-child(2) > div > div:nth-child(8) > input'))
+ const createToken = await driver.findElement(By.css('#main > div > div > div > div:nth-child(2) > div > button'))
+
+ await totalSupply.sendKeys('100')
+ await tokenName.sendKeys('Test')
+ await tokenDecimal.sendKeys('0')
+ await tokenSymbol.sendKeys('TST')
+ await createToken.click()
+ await delay(1000)
+ })
+
+ it('confirms transaction in MetaMask popup', async function () {
+ const windowHandles = await driver.getAllWindowHandles()
+ await driver.switchTo().window(windowHandles[2])
+ const metamaskSubmit = await driver.findElement(By.css('#pending-tx-form > div.flex-row.flex-space-around.conf-buttons > input'))
+ await metamaskSubmit.click()
+ await delay(1000)
+ })
+
+ it('switches back to Token Factory to grab the token contract address', async function () {
+ const windowHandles = await driver.getAllWindowHandles()
+ await driver.switchTo().window(windowHandles[0])
+ const tokenContactAddress = await driver.findElement(By.css('#main > div > div > div > div:nth-child(2) > span:nth-child(3)'))
+ tokenAddress = await tokenContactAddress.getText()
+ await delay(500)
+ })
+
+ it('navigates back to MetaMask popup in the tab', async function () {
+ await driver.get(`moz-extension://${extensionId}/popup.html`)
+ await delay(700)
+ })
+ })
+
+ describe('Add Token', function () {
+ it('switches to the add token screen', async function () {
+ const tokensTab = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > section > div > div.inactiveForm.pointer'))
+ assert.equal(await tokensTab.getText(), 'TOKENS')
+ await tokensTab.click()
+ await delay(300)
+ })
+
+ it('navigates to the add token screen', async function () {
+ const addTokenButton = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > section > div.full-flex-height > div > button'))
+ assert.equal(await addTokenButton.getText(), 'ADD TOKEN')
+ await addTokenButton.click()
+ })
+
+ it('checks add token screen rendered', async function () {
+ const addTokenScreen = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.section-title.flex-row.flex-center > h2'))
+ assert.equal(await addTokenScreen.getText(), 'ADD TOKEN')
+ })
+
+ it('adds token parameters', async function () {
+ const tokenContractAddress = await driver.findElement(By.css('#token-address'))
+ await tokenContractAddress.sendKeys(tokenAddress)
+ await delay(300)
+ await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.flex-column.flex-justify-center.flex-grow.select-none > div > button')).click()
+ await delay(100)
+ })
+
+ it('checks the token balance', async function () {
+ const tokenBalance = await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > ol > li:nth-child(2) > h3'))
+ assert.equal(await tokenBalance.getText(), '100 TST')
+ })
+ })
+
+ async function setProviderType(type) {
+ await driver.executeScript('window.metamask.setProviderType(arguments[0])', type)
+ }
+
+ async function verboseReportOnFailure(test) {
+ const artifactDir = `./test-artifacts/firefox/${test.title}`
+ const filepathBase = `${artifactDir}/test-failure`
+ await pify(mkdirp)(artifactDir)
+ // capture screenshot
+ const screenshot = await driver.takeScreenshot()
+ await pify(fs.writeFile)(`${filepathBase}-screenshot.png`, screenshot, { encoding: 'base64' })
+ // capture dom source
+ const htmlSource = await driver.getPageSource()
+ await pify(fs.writeFile)(`${filepathBase}-dom.html`, htmlSource)
+ }
+
+})
+
+function installWebExt (driver, extension) {
+ const cmd = new Command('moz-install-web-ext')
+ .setParameter('path', path.resolve(extension))
+ .setParameter('temporary', true)
+
+ driver.getExecutor()
+ .defineCommand(cmd.getName(), 'POST', '/session/:sessionId/moz/addon/install')
+
+ return driver.schedule(cmd, 'installWebExt(' + extension + ')')
+}
+