commit
76ab5c04fa
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,314 @@ |
||||
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 until = require('selenium-webdriver/lib/until') |
||||
const By = webdriver.By |
||||
const { delay, buildChromeWebDriver } = require('../func') |
||||
|
||||
describe('Metamask popup page', function () { |
||||
let driver, accountAddress, tokenAddress, extensionId |
||||
|
||||
this.timeout(0) |
||||
|
||||
before(async function () { |
||||
const extPath = path.resolve('dist/chrome') |
||||
driver = buildChromeWebDriver(extPath) |
||||
await driver.get('chrome://extensions') |
||||
await delay(500) |
||||
}) |
||||
|
||||
afterEach(async function () { |
||||
if (this.currentTest.state === 'failed') { |
||||
await verboseReportOnFailure(this.currentTest) |
||||
} |
||||
}) |
||||
|
||||
after(async function () { |
||||
await driver.quit() |
||||
}) |
||||
|
||||
describe('Setup', function () { |
||||
|
||||
it('switches to Chrome extensions list', async function () { |
||||
const tabs = await driver.getAllWindowHandles() |
||||
await driver.switchTo().window(tabs[0]) |
||||
await delay(300) |
||||
}) |
||||
|
||||
it(`selects MetaMask's extension id and opens it in the current tab`, async function () { |
||||
extensionId = await getExtensionId() |
||||
await driver.get(`chrome-extension://${extensionId}/popup.html`) |
||||
await delay(500) |
||||
}) |
||||
|
||||
it('sets provider type to localhost', async function () { |
||||
await driver.wait(until.elementLocated(By.css('#app-content')), 300) |
||||
await setProviderType('localhost') |
||||
}) |
||||
}) |
||||
|
||||
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 () => { |
||||
await driver.wait(async () => { |
||||
const privacyHeader = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.flex-column.flex-center.flex-grow > h3')).getText() |
||||
assert.equal(privacyHeader, 'PRIVACY NOTICE', 'shows privacy notice')
|
||||
return privacyHeader === 'PRIVACY NOTICE' |
||||
}, 300) |
||||
await driver.findElement(By.css('button')).click() |
||||
}) |
||||
|
||||
it('show terms of use', async () => { |
||||
await driver.wait(async () => { |
||||
const terms = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div.flex-column.flex-center.flex-grow > h3')).getText() |
||||
assert.equal(terms, 'TERMS OF USE', 'shows terms of use') |
||||
return terms === 'TERMS OF USE' |
||||
}) |
||||
}) |
||||
|
||||
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')) |
||||
const buttonEnabled = await button.isEnabled() |
||||
assert.equal(buttonEnabled, true, 'enabled continue button') |
||||
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) |
||||
const seedPhrase = await driver.findElement(By.css('.twelve-word-phrase')).getText() |
||||
assert.equal(seedPhrase.split(' ').length, 12) |
||||
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(`chrome-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 getExtensionId () { |
||||
const extension = await driver.executeScript('return document.querySelector("extensions-manager").shadowRoot.querySelector("extensions-view-manager extensions-item-list").shadowRoot.querySelector("#container > div.items-container > extensions-item:nth-child(2)").getAttribute("id")') |
||||
return extension |
||||
} |
||||
|
||||
async function setProviderType (type) { |
||||
await driver.executeScript('window.metamask.setProviderType(arguments[0])', type) |
||||
} |
||||
|
||||
async function verboseReportOnFailure (test) { |
||||
const artifactDir = `./test-artifacts/chrome/${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) |
||||
} |
||||
|
||||
}) |
@ -0,0 +1,322 @@ |
||||
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, accountAddress, tokenAddress, extensionId |
||||
|
||||
this.timeout(0) |
||||
|
||||
before(async function () { |
||||
const extPath = path.resolve('dist/firefox') |
||||
driver = buildFirefoxWebdriver() |
||||
installWebExt(driver, extPath) |
||||
await delay(700) |
||||
}) |
||||
|
||||
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) |
||||
const seedPhrase = await driver.findElement(By.css('.twelve-word-phrase')).getText() |
||||
assert.equal(seedPhrase.split(' ').length, 12) |
||||
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) |
||||
}) |
||||
|
||||
// There is an issue with blank confirmation window, but the button is still there and the driver is able to clicked (?.?)
|
||||
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) |
||||
} |
||||
|
||||
}) |
||||
|
||||
async function installWebExt (driver, extension) { |
||||
const cmd = await new Command('moz-install-web-ext') |
||||
.setParameter('path', path.resolve(extension)) |
||||
.setParameter('temporary', true) |
||||
|
||||
await driver.getExecutor() |
||||
.defineCommand(cmd.getName(), 'POST', '/session/:sessionId/moz/addon/install') |
||||
|
||||
return await driver.schedule(cmd, 'installWebExt(' + extension + ')') |
||||
} |
||||
|
@ -1,145 +0,0 @@ |
||||
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 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.css('.extension-list-item-wrapper')) |
||||
const extensionId = await elems[1].getAttribute('id') |
||||
await driver.get(`chrome-extension://${extensionId}/popup.html`) |
||||
await delay(500) |
||||
}) |
||||
|
||||
afterEach(async function () { |
||||
if (this.currentTest.state === 'failed') { |
||||
await verboseReportOnFailure(this.currentTest) |
||||
} |
||||
}) |
||||
|
||||
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) |
||||
await setProviderType('localhost') |
||||
await delay(300) |
||||
}) |
||||
|
||||
it('should match title', async () => { |
||||
const title = await driver.getTitle() |
||||
assert.equal(title, 'MetaMask', 'title matches MetaMask') |
||||
}) |
||||
|
||||
it('should show privacy notice', async () => { |
||||
const privacy = await driver.findElement(By.css('.terms-header')).getText() |
||||
assert.equal(privacy, 'PRIVACY NOTICE', 'shows privacy notice') |
||||
driver.findElement(By.css('button')).click() |
||||
await delay(300) |
||||
}) |
||||
|
||||
it('should 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('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) |
||||
await delay(300) |
||||
}) |
||||
|
||||
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() |
||||
await delay(300) |
||||
}) |
||||
|
||||
it('should accept 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 = 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.css('.twelve-word-phrase')).getText() |
||||
const continueAfterSeedPhrase = await driver.findElement(By.css('button')) |
||||
await continueAfterSeedPhrase.click() |
||||
await delay(300) |
||||
}) |
||||
|
||||
it('should show lock account', async () => { |
||||
await driver.findElement(By.css('.sandwich-expando')).click() |
||||
await delay(500) |
||||
await driver.findElement(By.css('#app-content > div > div:nth-child(3) > span > div > li:nth-child(3)')).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 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('should show the account address', async () => { |
||||
this.accountAddress = await driver.findElement(By.css('.ellip-address')).getText() |
||||
await driver.findElement(By.css('.fa-arrow-left')).click() |
||||
await delay(500) |
||||
}) |
||||
}) |
||||
|
||||
async function setProviderType(type) { |
||||
await driver.executeScript('window.metamask.setProviderType(arguments[0])', type) |
||||
} |
||||
|
||||
async function verboseReportOnFailure(test) { |
||||
const artifactDir = `./test-artifacts/${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) |
||||
} |
||||
|
||||
}) |
Loading…
Reference in new issue