@ -1,7 +1,7 @@
const path = require ( 'path' )
const assert = require ( 'assert' )
const webdriver = require ( 'selenium-webdriver' )
const { By , Key } = webdriver
const { By , Key , until } = webdriver
const {
delay ,
buildChromeWebDriver ,
@ -11,9 +11,12 @@ const {
getExtensionIdFirefox ,
} = require ( '../func' )
const {
findElement ,
findElements ,
checkBrowserForConsoleErrors ,
loadExtension ,
verboseReportOnFailure ,
openNewPage ,
} = require ( './helpers' )
describe ( 'MetaMask' , function ( ) {
@ -22,10 +25,9 @@ describe('MetaMask', function () {
let tokenAddress
const testSeedPhrase = 'phrase upgrade clock rough situate wedding elder clever doctor stamp excess tent'
const tinyDelayMs = 5 00
const tinyDelayMs = 10 00
const regularDelayMs = tinyDelayMs * 2
const largeDelayMs = regularDelayMs * 2
const waitingNewPageDelayMs = regularDelayMs * 10
this . timeout ( 0 )
this . bail ( true )
@ -60,7 +62,7 @@ describe('MetaMask', function () {
}
}
if ( this . currentTest . state === 'failed' ) {
await verboseReportOnFailure ( this . currentTest )
await verboseReportOnFailure ( driver , this . currentTest )
}
} )
@ -69,37 +71,52 @@ describe('MetaMask', function () {
} )
describe ( 'New UI setup' , async function ( ) {
let networkSelector
it ( 'switches to first tab' , async function ( ) {
const [ firstTab ] = await driver . getAllWindowHandles ( )
await driver . switchTo ( ) . window ( firstTab )
await delay ( regularDelayMs )
try {
networkSelector = await findElement ( driver , By . css ( '#network_component' ) )
} catch ( e ) {
await loadExtension ( driver , extensionId )
}
await delay ( regularDelayMs )
} )
it ( 'use the local network' , async function ( ) {
const [ networkSelector ] = await driver . findElements ( By . css ( '#network_component' ) )
await networkSelector . click ( )
await delay ( regularDelayMs )
const [ localhost ] = await driver . findElements ( By . xpath ( ` //li[contains(text(), 'Localhost')] ` ) )
const localhost = await findElement ( driver , By . xpath ( ` //li[contains(text(), 'Localhost')] ` ) )
await localhost . click ( )
await delay ( regularDelayMs )
} )
it ( 'selects the new UI option' , async ( ) => {
const button = await driver . findElement ( By . xpath ( "//p[contains(text(), 'Try Beta Version')]" ) )
const button = await findElement ( driver , By . xpath ( "//p[contains(text(), 'Try Beta Version')]" ) )
await button . click ( )
await delay ( regularDelayMs )
// Close all other tabs
const [ oldUi , infoPage , newUi ] = await driver . getAllWindowHandles ( )
const [ oldUi , tab1 , tab2 ] = await driver . getAllWindowHandles ( )
await driver . switchTo ( ) . window ( oldUi )
await driver . close ( )
await driver . switchTo ( ) . window ( infoPage )
await driver . switchTo ( ) . window ( tab1 )
const tab1Url = await driver . getCurrentUrl ( )
if ( tab1Url . match ( /metamask.io/ ) ) {
await driver . switchTo ( ) . window ( tab1 )
await driver . close ( )
await driver . switchTo ( ) . window ( newUi )
await driver . switchTo ( ) . window ( tab2 )
} else if ( tab2 ) {
await driver . switchTo ( ) . window ( tab2 )
await driver . close ( )
await driver . switchTo ( ) . window ( tab1 )
}
await delay ( regularDelayMs )
const [ continueBtn ] = await driver . findElements ( By . css ( '.welcome-screen__button' ) )
const continueBtn = await findElement ( driver , By . css ( '.welcome-screen__button' ) )
await continueBtn . click ( )
await delay ( regularDelayMs )
} )
@ -107,9 +124,9 @@ describe('MetaMask', function () {
describe ( 'Going through the first time flow' , ( ) => {
it ( 'accepts a secure password' , async ( ) => {
const [ passwordBox ] = await driver . findElements ( By . css ( '.create-password #create-password' ) )
const [ passwordBoxConfirm ] = await driver . findElements ( By . css ( '.create-password #confirm-password' ) )
const [ button ] = await driver . findElements ( By . css ( '.create-password button' ) )
const passwordBox = await findElement ( driver , By . css ( '.create-password #create-password' ) )
const passwordBoxConfirm = await findElement ( driver , By . css ( '.create-password #confirm-password' ) )
const button = await findElement ( driver , By . css ( '.create-password button' ) )
await passwordBox . sendKeys ( 'correct horse battery staple' )
await passwordBoxConfirm . sendKeys ( 'correct horse battery staple' )
@ -118,102 +135,141 @@ describe('MetaMask', function () {
} )
it ( 'clicks through the unique image screen' , async ( ) => {
const [ nextScreen ] = await driver . findElements ( By . css ( '.unique-image button' ) )
const nextScreen = await findElement ( driver , By . css ( '.unique-image button' ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
} )
it ( 'clicks through the privacy notice' , async ( ) => {
const [ nextScreen ] = await driver . findElements ( By . css ( '.tou button' ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
it ( 'clicks through the ToS' , async ( ) => {
// terms of use
const canClickThrough = await driver . findElement ( By . css ( '.tou button' ) ) . isEnabled ( )
assert . equal ( canClickThrough , false , 'disabled continue button' )
const [ bottomOfTos ] = await driver . findElements ( By . linkText ( 'Attributions' ) )
const bottomOfTos = await findElement ( driver , By . linkText ( 'Attributions' ) )
await driver . executeScript ( 'arguments[0].scrollIntoView(true)' , bottomOfTos )
await delay ( regularDelayMs )
const [ acceptTos ] = await driver . findElements ( By . css ( '.tou button' ) )
const acceptTos = await findElement ( driver , By . css ( '.tou button' ) )
driver . wait ( until . elementIsEnabled ( acceptTos ) )
await acceptTos . click ( )
await delay ( regularDelayMs )
} )
it ( 'clicks through the privacy notice' , async ( ) => {
// privacy notice
const nextScreen = await findElement ( driver , By . css ( '.tou button' ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
} )
it ( 'clicks through the phishing notice' , async ( ) => {
// phishing notice
const noticeElement = await driver . findElement ( By . css ( '.markdown' ) )
await driver . executeScript ( 'arguments[0].scrollTop = arguments[0].scrollHeight' , noticeElement )
await delay ( regularDelayMs )
const nextScreen = await findElement ( driver , By . css ( '.tou button' ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
} )
let seedPhrase
it ( 'reveals the seed phrase' , async ( ) => {
const [ revealSeedPhrase ] = await driver . findElements ( By . css ( '.backup-phrase__secret-blocker' ) )
await revealSeedPhrase . click ( )
const byRevealButton = By . css ( '.backup-phrase__secret-blocker .backup-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 ( '.backup-phrase__secret-words' ) ) . getText ( )
assert . equal ( seedPhrase . split ( ' ' ) . length , 12 )
await delay ( regularDelayMs )
const [ nextScreen ] = await driver . findElements ( By . css ( '.backup-phrase button' ) )
const nextScreen = await findElement ( driver , By . css ( '.backup-phrase button' ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
} )
it ( 'can retype the seed phrase' , async ( ) => {
const words = seedPhrase . split ( ' ' )
async function retypeSeedPhrase ( words ) {
try {
const word0 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 0 ] } ')] ` ) , 10000 )
const [ word0 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 0 ] } ')] ` ) )
await word0 . click ( )
await delay ( tinyDelayMs )
const [ word1 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 1 ] } ')] ` ) )
const word1 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 1 ] } ')] ` ) , 10000 )
await word1 . click ( )
await delay ( tinyDelayMs )
const [ word2 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 2 ] } ')] ` ) )
const word2 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 2 ] } ')] ` ) , 10000 )
await word2 . click ( )
await delay ( tinyDelayMs )
const [ word3 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 3 ] } ')] ` ) )
const word3 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 3 ] } ')] ` ) , 10000 )
await word3 . click ( )
await delay ( tinyDelayMs )
const [ word4 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 4 ] } ')] ` ) )
const word4 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 4 ] } ')] ` ) , 10000 )
await word4 . click ( )
await delay ( tinyDelayMs )
const [ word5 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 5 ] } ')] ` ) )
const word5 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 5 ] } ')] ` ) , 10000 )
await word5 . click ( )
await delay ( tinyDelayMs )
const [ word6 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 6 ] } ')] ` ) )
const word6 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 6 ] } ')] ` ) , 10000 )
await word6 . click ( )
await delay ( tinyDelayMs )
const [ word7 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 7 ] } ')] ` ) )
const word7 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 7 ] } ')] ` ) , 10000 )
await word7 . click ( )
await delay ( tinyDelayMs )
const [ word8 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 8 ] } ')] ` ) )
const word8 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 8 ] } ')] ` ) , 10000 )
await word8 . click ( )
await delay ( tinyDelayMs )
const [ word9 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 9 ] } ')] ` ) )
const word9 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 9 ] } ')] ` ) , 10000 )
await word9 . click ( )
await delay ( tinyDelayMs )
const [ word10 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 10 ] } ')] ` ) )
const word10 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 10 ] } ')] ` ) , 10000 )
await word10 . click ( )
await delay ( tinyDelayMs )
const [ word11 ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), ' ${ words [ 11 ] } ')] ` ) )
const word11 = await findElement ( driver , By . xpath ( ` //button[contains(text(), ' ${ words [ 11 ] } ')] ` ) , 10000 )
await word11 . click ( )
await delay ( tinyDelayMs )
} catch ( e ) {
await loadExtension ( driver , extensionId )
await retypeSeedPhrase ( words )
}
}
it ( 'can retype the seed phrase' , async ( ) => {
const words = seedPhrase . split ( ' ' )
const [ confirm ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await retypeSeedPhrase ( words )
const confirm = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirm . click ( )
await delay ( regularDelayMs )
} )
it ( 'clicks through the deposit modal' , async ( ) => {
const [ closeModal ] = await driver . findElements ( By . css ( '.page-container__header-close' ) )
const byBuyModal = By . css ( 'span .modal' )
const buyModal = await driver . wait ( until . elementLocated ( byBuyModal ) )
const closeModal = await findElement ( driver , By . css ( '.page-container__header-close' ) )
await closeModal . click ( )
await driver . wait ( until . stalenessOf ( buyModal ) )
await delay ( regularDelayMs )
} )
} )
@ -224,8 +280,12 @@ describe('MetaMask', function () {
await driver . findElement ( By . css ( '.qr-wrapper' ) ) . isDisplayed ( )
await delay ( regularDelayMs )
const accountModal = await driver . findElement ( By . css ( 'span .modal' ) )
await driver . executeScript ( "document.querySelector('.account-modal-close').click()" )
await delay ( regularDelayMs * 4 )
await driver . wait ( until . stalenessOf ( accountModal ) )
await delay ( regularDelayMs )
} )
} )
@ -234,7 +294,7 @@ describe('MetaMask', function () {
await driver . findElement ( By . css ( '.account-menu__icon' ) ) . click ( )
await delay ( regularDelayMs )
const [ logoutButton ] = await driver . findElements ( By . css ( '.account-menu__logout-button' ) )
const logoutButton = await findElement ( driver , By . css ( '.account-menu__logout-button' ) )
assert . equal ( await logoutButton . getText ( ) , 'Log out' )
await logoutButton . click ( )
await delay ( regularDelayMs )
@ -252,23 +312,23 @@ describe('MetaMask', function () {
await driver . findElement ( By . css ( '.account-menu__icon' ) ) . click ( )
await delay ( regularDelayMs )
const [ createAccount ] = await driver . findElements ( By . xpath ( ` //div[contains(text(), 'Create Account')] ` ) )
const createAccount = await findElement ( driver , By . xpath ( ` //div[contains(text(), 'Create Account')] ` ) )
await createAccount . click ( )
await delay ( regularDelayMs )
} )
it ( 'set account name' , async ( ) => {
const [ accountName ] = await driver . findElements ( By . css ( '.new-account-create-form input' ) )
const accountName = await findElement ( driver , By . css ( '.new-account-create-form input' ) )
await accountName . sendKeys ( '2nd account' )
await delay ( regularDelayMs )
const [ create ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Create')] ` ) )
const create = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Create')] ` ) )
await create . click ( )
await delay ( regularDelayMs )
} )
it ( 'should correct account name' , async ( ) => {
const [ accountName ] = await driver . findElements ( By . css ( '.account-name' ) )
const accountName = await findElement ( driver , By . css ( '.account-name' ) )
assert . equal ( await accountName . getText ( ) , '2nd account' )
await delay ( regularDelayMs )
} )
@ -279,19 +339,19 @@ describe('MetaMask', function () {
await driver . findElement ( By . css ( '.account-menu__icon' ) ) . click ( )
await delay ( regularDelayMs )
const [ logoutButton ] = await driver . findElements ( By . css ( '.account-menu__logout-button' ) )
const logoutButton = await findElement ( driver , By . css ( '.account-menu__logout-button' ) )
assert . equal ( await logoutButton . getText ( ) , 'Log out' )
await logoutButton . click ( )
await delay ( regularDelayMs )
} )
it ( 'imports seed phrase' , async ( ) => {
const [ restoreSeedLink ] = await driver . findElements ( By . css ( '.unlock-page__link--import' ) )
const restoreSeedLink = await findElement ( driver , By . css ( '.unlock-page__link--import' ) )
assert . equal ( await restoreSeedLink . getText ( ) , 'Import using account seed phrase' )
await restoreSeedLink . click ( )
await delay ( regularDelayMs )
const [ seedTextArea ] = await driver . findElements ( By . css ( 'textarea' ) )
const seedTextArea = await findElement ( driver , By . css ( 'textarea' ) )
await seedTextArea . sendKeys ( testSeedPhrase )
await delay ( regularDelayMs )
@ -302,7 +362,7 @@ describe('MetaMask', function () {
} )
it ( 'balance renders' , async ( ) => {
const balance = await driver . findElement ( By . css ( '.balance-display .token-amount' ) )
const balance = await findElement ( driver , By . css ( '.balance-display .token-amount' ) )
const tokenAmount = await balance . getText ( )
assert . equal ( tokenAmount , '100.000 ETH' )
await delay ( regularDelayMs )
@ -311,56 +371,60 @@ describe('MetaMask', function () {
describe ( 'Send ETH from inside MetaMask' , ( ) => {
it ( 'starts to send a transaction' , async function ( ) {
const [ sendButton ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Send')] ` ) )
const sendButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Send')] ` ) )
await sendButton . click ( )
await delay ( regularDelayMs )
const [ inputAddress ] = await driver . findElements ( By . css ( 'input[placeholder="Recipient Address"]' ) )
const [ inputAmount ] = await driver . findElements ( By . css ( '.currency-display__input' ) )
const inputAddress = await findElement ( driver , By . css ( 'input[placeholder="Recipient Address"]' ) )
const inputAmount = await findElement ( driver , By . css ( '.currency-display__input' ) )
await inputAddress . sendKeys ( '0x2f318C334780961FB129D2a6c30D0763d9a5C970' )
await inputAmount . sendKeys ( '1' )
// Set the gas limit
const [ configureGas ] = await driver . findElements ( By . css ( '.send-v2__gas-fee-display button' ) )
const configureGas = await findElement ( driver , By . css ( '.send-v2__gas-fee-display button' ) )
await configureGas . click ( )
await delay ( regularDelayMs )
const [ save ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Save')] ` ) )
const gasModal = await driver . findElement ( By . css ( 'span .modal' ) )
const save = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Save')] ` ) )
await save . click ( )
await driver . wait ( until . stalenessOf ( gasModal ) )
await delay ( regularDelayMs )
// Continue to next screen
const [ nextScreen ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
const nextScreen = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
} )
it ( 'confirms the transaction' , async function ( ) {
const [ confirmButton ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
} )
it ( 'finds the transaction in the transactions list' , async function ( ) {
const transactions = await driver . findElements ( By . css ( '.tx-list-item' ) )
const transactions = await findElements ( driver , By . css ( '.tx-list-item' ) )
assert . equal ( transactions . length , 1 )
const txValues = await driver . findElements ( By . css ( '.tx-list-value' ) )
assert . equal ( txValues . length , 1 )
assert . equal ( await txValues [ 0 ] . getText ( ) , '1 ETH' )
const txValues = await findElement ( driver , By . css ( '.tx-list-value' ) )
await driver . wait ( until . elementTextMatches ( txValues , /1\sETH/ ) , 10000 )
} )
} )
describe ( 'Send ETH from Faucet' , ( ) => {
it ( 'starts a send transaction inside Faucet' , async ( ) => {
await driver . executeScript ( 'window.open("https://faucet.metamask.io")' )
await delay ( waitingNewPageDelayMs )
await openNewPage ( driver , 'https://faucet.metamask.io' )
const [ extension , faucet ] = await driver . getAllWindowHandles ( )
await driver . switchTo ( ) . window ( faucet )
const faucetPageTitle = await findElement ( driver , By . css ( '.container-fluid' ) )
await driver . wait ( until . elementTextMatches ( faucetPageTitle , /MetaMask/ ) )
await delay ( regularDelayMs )
const [ send1eth ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), '10 ether')] ` ) )
const send1eth = await findElement ( driver , By . xpath ( ` //button[contains(text(), '10 ether')] ` ) , 14000 )
await send1eth . click ( )
await delay ( regularDelayMs )
@ -368,7 +432,7 @@ describe('MetaMask', function () {
await loadExtension ( driver , extensionId )
await delay ( regularDelayMs )
const [ confirmButton ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) , 14000 )
await confirmButton . click ( )
await delay ( regularDelayMs )
@ -383,59 +447,146 @@ describe('MetaMask', function () {
} )
} )
describe ( 'Add existing token using search' , ( ) => {
it ( 'clicks on the Add Token button' , async ( ) => {
const [ addToken ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Add Token')] ` ) )
await addToken . click ( )
describe ( 'Deploy contract and call contract methods' , ( ) => {
let extension
let contractTestPage
it ( 'confirms a deploy contract transaction' , async ( ) => {
await openNewPage ( driver , 'http://127.0.0.1:8080/' ) ;
[ extension , contractTestPage ] = await driver . getAllWindowHandles ( )
await delay ( regularDelayMs )
const deployContractButton = await findElement ( driver , By . css ( '#deployButton' ) )
await deployContractButton . click ( )
await delay ( regularDelayMs )
await driver . switchTo ( ) . window ( extension )
await delay ( regularDelayMs )
const txListItem = await findElement ( driver , By . css ( '.tx-list-item' ) )
await txListItem . click ( )
await delay ( regularDelayMs )
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
const txStatuses = await findElements ( driver , By . css ( '.tx-list-status' ) )
await driver . wait ( until . elementTextMatches ( txStatuses [ 0 ] , /Confirmed/ ) )
const txAccounts = await findElements ( driver , By . css ( '.tx-list-account' ) )
assert . equal ( await txAccounts [ 0 ] . getText ( ) , 'Contract Deployment' )
} )
it ( 'can pick a token from the existing options' , async ( ) => {
const [ tokenSearch ] = await driver . findElements ( By . css ( 'input.add-token__input' ) )
await tokenSearch . sendKeys ( 'BAT' )
it ( 'calls and confirms a contract method where ETH is sent' , async ( ) => {
await driver . switchTo ( ) . window ( contractTestPage )
await delay ( regularDelayMs )
const [ token ] = await driver . findElements ( By . xpath ( "//div[contains(text(), 'BAT')]" ) )
await token . click ( )
const depositButton = await findElement ( driver , By . css ( '#depositButton' ) )
await depositBut ton. click ( )
await delay ( regularDelayMs )
const [ nextScreen ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
await nextScreen . click ( )
await driver . switchTo ( ) . window ( extension )
await delay ( regularDelayMs )
const [ addTokens ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Add Tokens')] ` ) )
await addTokens . click ( )
await delay ( largeDelayMs )
const txListItem = await findElement ( driver , By . css ( '.tx-list-item' ) )
await txListItem . click ( )
await delay ( regularDelayMs )
// Set the gas limit
const configureGas = await findElement ( driver , By . css ( '.sliders-icon-container' ) )
await configureGas . click ( )
await delay ( regularDelayMs )
const gasModal = await driver . findElement ( By . css ( 'span .modal' ) )
await driver . wait ( until . elementLocated ( By . css ( '.send-v2__customize-gas__title' ) ) )
const [ gasPriceInput , gasLimitInput ] = await findElements ( driver , By . css ( '.customize-gas-input' ) )
await gasPriceInput . clear ( )
await gasPriceInput . sendKeys ( '10' )
await gasLimitInput . clear ( )
await gasLimitInput . sendKeys ( '60001' )
const save = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Save')] ` ) )
await save . click ( )
await delay ( regularDelayMs )
await driver . wait ( until . stalenessOf ( gasModal ) )
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
const txStatuses = await findElements ( driver , By . css ( '.tx-list-status' ) )
await driver . wait ( until . elementTextMatches ( txStatuses [ 0 ] , /Confirmed/ ) )
const txValues = await findElement ( driver , By . css ( '.tx-list-value' ) )
await driver . wait ( until . elementTextMatches ( txValues , /3\sETH/ ) , 10000 )
const txAccounts = await findElements ( driver , By . css ( '.tx-list-account' ) )
const firstTxAddress = await txAccounts [ 0 ] . getText ( )
assert ( firstTxAddress . match ( /^0x\w{8}\.{3}\w{4}$/ ) )
} )
it ( 'renders the balance for the chosen token' , async ( ) => {
const balance = await driver . findElement ( By . css ( '.tx-view .balance-display .token-amount' ) )
it ( 'calls and confirms a contract method where ETH is received' , async ( ) => {
await driver . switchTo ( ) . window ( contractTestPage )
await delay ( regularDelayMs )
const withdrawButton = await findElement ( driver , By . css ( '#withdrawButton' ) )
await withdrawButton . click ( )
await delay ( regularDelayMs )
await driver . switchTo ( ) . window ( extension )
await delay ( regularDelayMs )
const txListItem = await findElement ( driver , By . css ( '.tx-list-item' ) )
await txListItem . click ( )
await delay ( regularDelayMs )
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
const txStatuses = await findElements ( driver , By . css ( '.tx-list-status' ) )
await driver . wait ( until . elementTextMatches ( txStatuses [ 0 ] , /Confirmed/ ) )
const txValues = await findElement ( driver , By . css ( '.tx-list-value' ) )
await driver . wait ( until . elementTextMatches ( txValues , /0\sETH/ ) , 10000 )
await driver . switchTo ( ) . window ( contractTestPage )
await driver . close ( )
await driver . switchTo ( ) . window ( extension )
} )
it ( 'renders the correct ETH balance' , async ( ) => {
const balance = await findElement ( driver , By . css ( '.tx-view .balance-display .token-amount' ) )
await driver . wait ( until . elementTextMatches ( balance , /^86.*ETH.*$/ ) , 10000 )
const tokenAmount = await balance . getText ( )
assert . equal ( tokenAmount , '0BAT' )
assert . ok ( /^86.*ETH.*$/ . test ( tokenAmount ) )
await delay ( regularDelayMs )
} )
} )
describe ( 'Add a custom token from TokenFactory' , ( ) => {
it ( 'creates a new token' , async ( ) => {
await driver . executeScript ( 'window.open("https://tokenfactory.surge.sh/#/factory")' )
await delay ( waitingNewPageDelayMs )
openNewPage ( driver , 'https://tokenfactory.surge.sh/#/factory' )
await delay ( regularDelayMs * 10 )
const [ extension , tokenFactory ] = await driver . getAllWindowHandles ( )
await driver . switchTo ( ) . window ( tokenFactory )
const [
totalSupply ,
tokenName ,
tokenDecimal ,
tokenSymbol ,
] = await driver . findElements ( By . css ( 'input' ) )
] = await findElements ( driver , By . css ( '.form-control ' ) )
await totalSupply . sendKeys ( '100' )
await tokenName . sendKeys ( 'Test' )
await tokenDecimal . sendKeys ( '0' )
await tokenSymbol . sendKeys ( 'TST' )
const [ createToken ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Create Token')] ` ) )
const createToken = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Create Token')] ` ) )
await createToken . click ( )
await delay ( regularDelayMs )
@ -443,48 +594,261 @@ describe('MetaMask', function () {
await loadExtension ( driver , extensionId )
await delay ( regularDelayMs )
const [ confirmButton ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
await driver . switchTo ( ) . window ( tokenFactory )
await delay ( regularDelayMs )
const tokenContactAddress = await driver . findElement ( By . css ( 'div > div > div:nth-child(2) > span:nth-child(3)' ) )
tokenAddress = await tokenContactAddress . getText ( )
await driver . close ( )
await driver . switchTo ( ) . window ( extension )
await loadExtension ( driver , extensionId )
await driver . switchTo ( ) . window ( extension )
await delay ( regularDelayMs )
} )
it ( 'clicks on the Add Token button' , async ( ) => {
const [ addToken ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Add Token')] ` ) )
const addToken = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Add Token')] ` ) )
await addToken . click ( )
await delay ( regularDelayMs )
} )
it ( 'picks the newly created Test token' , async ( ) => {
const [ addCustomToken ] = await driver . findElements ( By . xpath ( "//div[contains(text(), 'Custom Token')]" ) )
const addCustomToken = await findElement ( driver , By . xpath ( "//div[contains(text(), 'Custom Token')]" ) )
await addCustomToken . click ( )
await delay ( regularDelayMs )
const [ newTokenAddress ] = await driver . findElements ( By . css ( '.add-token__add-custom-form input ' ) )
const newTokenAddress = await findElement ( driver , By . css ( '#custom-address ' ) )
await newTokenAddress . sendKeys ( tokenAddress )
await delay ( regularDelayMs )
const [ nextScreen ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
const nextScreen = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
const [ addTokens ] = await driver . findElements ( By . xpath ( ` //button[contains(text(), 'Add Tokens')] ` ) )
const addTokens = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Add Tokens')] ` ) )
await addTokens . click ( )
await delay ( regularDelayMs )
} )
it ( 'renders the balance for the new token' , async ( ) => {
const [ balance ] = await driver . findElements ( By . css ( '.tx-view .balance-display .token-amount' ) )
const balance = await findElement ( driver , By . css ( '.tx-view .balance-display .token-amount' ) )
await driver . wait ( until . elementTextMatches ( balance , /^100\s*TST\s*$/ ) )
const tokenAmount = await balance . getText ( )
assert . equal ( tokenAmount , '100TST' )
assert . ok ( /^100\s*TST\s*$/ . test ( tokenAmount ) )
await delay ( regularDelayMs )
} )
} )
describe ( 'Send token from inside MetaMask' , ( ) => {
let gasModal
it ( 'starts to send a transaction' , async function ( ) {
const sendButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Send')] ` ) )
await sendButton . click ( )
await delay ( regularDelayMs )
const inputAddress = await findElement ( driver , By . css ( 'input[placeholder="Recipient Address"]' ) )
const inputAmount = await findElement ( driver , By . css ( '.currency-display__input' ) )
await inputAddress . sendKeys ( '0x2f318C334780961FB129D2a6c30D0763d9a5C970' )
await inputAmount . sendKeys ( '50' )
// Set the gas limit
const configureGas = await findElement ( driver , By . css ( '.send-v2__gas-fee-display button' ) )
await configureGas . click ( )
await delay ( regularDelayMs )
gasModal = await driver . findElement ( By . css ( 'span .modal' ) )
} )
it ( 'customizes gas' , async ( ) => {
await driver . wait ( until . elementLocated ( By . css ( '.send-v2__customize-gas__title' ) ) )
const save = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Save')] ` ) )
await save . click ( )
await delay ( regularDelayMs )
} )
it ( 'transitions to the confirm screen' , async ( ) => {
await driver . wait ( until . stalenessOf ( gasModal ) )
// Continue to next screen
const nextScreen = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
} )
it ( 'submits the transaction' , async function ( ) {
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
} )
it ( 'finds the transaction in the transactions list' , async function ( ) {
const transactions = await findElements ( driver , By . css ( '.tx-list-item' ) )
assert . equal ( transactions . length , 1 )
const txValues = await findElements ( driver , By . css ( '.tx-list-value' ) )
assert . equal ( txValues . length , 1 )
// test cancelled on firefox until https://github.com/mozilla/geckodriver/issues/906 is resolved,
// or possibly until we use latest version of firefox in the tests
if ( process . env . SELENIUM _BROWSER !== 'firefox' ) {
await driver . wait ( until . elementTextMatches ( txValues [ 0 ] , /50\sTST/ ) , 10000 )
}
const txStatuses = await findElements ( driver , By . css ( '.tx-list-status' ) )
const tx = await driver . wait ( until . elementTextMatches ( txStatuses [ 0 ] , /Confirmed|Failed/ ) , 10000 )
assert . equal ( await tx . getText ( ) , 'Confirmed' )
} )
} )
describe ( 'Send a custom token from TokenFactory' , ( ) => {
let gasModal
it ( 'sends an already created token' , async ( ) => {
openNewPage ( driver , ` https://tokenfactory.surge.sh/#/token/ ${ tokenAddress } ` )
const [ extension ] = await driver . getAllWindowHandles ( )
const [
transferToAddress ,
transferToAmount ,
] = await findElements ( driver , By . css ( '.form-control' ) )
await transferToAddress . sendKeys ( '0x2f318C334780961FB129D2a6c30D0763d9a5C970' )
await transferToAmount . sendKeys ( '26' )
const transferAmountButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Transfer Amount')] ` ) )
await transferAmountButton . click ( )
await delay ( regularDelayMs )
const [ , , popup ] = await driver . getAllWindowHandles ( )
await driver . switchTo ( ) . window ( popup )
await driver . close ( )
await driver . switchTo ( ) . window ( extension )
await delay ( regularDelayMs )
const [ txListItem ] = await findElements ( driver , By . css ( '.tx-list-item' ) )
await txListItem . click ( )
await delay ( regularDelayMs )
// Set the gas limit
const configureGas = await driver . wait ( until . elementLocated ( By . css ( '.send-v2__gas-fee-display button' ) ) )
await configureGas . click ( )
await delay ( regularDelayMs )
gasModal = await driver . findElement ( By . css ( 'span .modal' ) )
} )
it ( 'customizes gas' , async ( ) => {
await driver . wait ( until . elementLocated ( By . css ( '.send-v2__customize-gas__title' ) ) )
const [ gasPriceInput , gasLimitInput ] = await findElements ( driver , By . css ( '.customize-gas-input' ) )
await gasPriceInput . clear ( )
await delay ( tinyDelayMs )
await gasPriceInput . sendKeys ( '10' )
await delay ( tinyDelayMs )
await gasLimitInput . clear ( )
await delay ( tinyDelayMs )
await gasLimitInput . sendKeys ( Key . chord ( Key . CONTROL , 'a' ) )
await gasLimitInput . sendKeys ( '60000' )
await gasLimitInput . sendKeys ( Key . chord ( Key . CONTROL , 'e' ) )
// Needed for different behaviour of input in different versions of firefox
const gasLimitInputValue = await gasLimitInput . getAttribute ( 'value' )
if ( gasLimitInputValue === '600001' ) {
await gasLimitInput . sendKeys ( Key . BACK _SPACE )
}
const save = await findElement ( driver , By . css ( '.send-v2__customize-gas__save' ) )
await save . click ( )
await driver . wait ( until . stalenessOf ( gasModal ) )
const gasFeeInput = await findElement ( driver , By . css ( '.currency-display__input' ) )
assert . equal ( await gasFeeInput . getAttribute ( 'value' ) , 0.0006 )
} )
it ( 'submits the transaction' , async function ( ) {
const confirmButton = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Confirm')] ` ) )
await confirmButton . click ( )
await delay ( regularDelayMs )
} )
it ( 'finds the transaction in the transactions list' , async function ( ) {
const transactions = await findElements ( driver , By . css ( '.tx-list-item' ) )
assert . equal ( transactions . length , 2 )
const txValues = await findElements ( driver , By . css ( '.tx-list-value' ) )
await driver . wait ( until . elementTextMatches ( txValues [ 0 ] , /26\sTST/ ) )
const txStatuses = await findElements ( driver , By . css ( '.tx-list-status' ) )
await driver . wait ( until . elementTextMatches ( txStatuses [ 0 ] , /Confirmed/ ) )
const walletBalance = await findElement ( driver , By . css ( '.wallet-balance' ) )
await walletBalance . click ( )
const tokenListItems = await findElements ( driver , By . css ( '.token-list-item' ) )
await tokenListItems [ 0 ] . click ( )
// test cancelled on firefox until https://github.com/mozilla/geckodriver/issues/906 is resolved,
// or possibly until we use latest version of firefox in the tests
if ( process . env . SELENIUM _BROWSER !== 'firefox' ) {
const tokenBalanceAmount = await findElement ( driver , By . css ( '.token-balance__amount' ) )
assert . equal ( await tokenBalanceAmount . getText ( ) , '24' )
}
} )
} )
describe ( 'Hide token' , ( ) => {
it ( 'hides the token when clicked' , async ( ) => {
const [ hideTokenEllipsis ] = await findElements ( driver , By . css ( '.token-list-item__ellipsis' ) )
await hideTokenEllipsis . click ( )
const byTokenMenuDropdownOption = By . css ( '.menu__item--clickable' )
const tokenMenuDropdownOption = await driver . wait ( until . elementLocated ( byTokenMenuDropdownOption ) )
await tokenMenuDropdownOption . click ( )
const confirmHideModal = await findElement ( driver , By . css ( 'span .modal' ) )
const byHideTokenConfirmationButton = By . css ( '.hide-token-confirmation__button' )
const hideTokenConfirmationButton = await driver . wait ( until . elementLocated ( byHideTokenConfirmationButton ) )
await hideTokenConfirmationButton . click ( )
await driver . wait ( until . stalenessOf ( confirmHideModal ) )
} )
} )
describe ( 'Add existing token using search' , ( ) => {
it ( 'clicks on the Add Token button' , async ( ) => {
const addToken = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Add Token')] ` ) )
await addToken . click ( )
await delay ( regularDelayMs )
} )
it ( 'can pick a token from the existing options' , async ( ) => {
const tokenSearch = await findElement ( driver , By . css ( '#search-tokens' ) )
await tokenSearch . sendKeys ( 'BAT' )
await delay ( regularDelayMs )
const token = await findElement ( driver , By . xpath ( "//span[contains(text(), 'BAT')]" ) )
await token . click ( )
await delay ( regularDelayMs )
const nextScreen = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Next')] ` ) )
await nextScreen . click ( )
await delay ( regularDelayMs )
const addTokens = await findElement ( driver , By . xpath ( ` //button[contains(text(), 'Add Tokens')] ` ) )
await addTokens . click ( )
await delay ( largeDelayMs )
} )
it ( 'renders the balance for the chosen token' , async ( ) => {
const balance = await findElement ( driver , By . css ( '.tx-view .balance-display .token-amount' ) )
await driver . wait ( until . elementTextMatches ( balance , /0\sBAT/ ) )
await delay ( regularDelayMs )
} )
} )