const path = require ( 'path' )
const fs = require ( 'fs' )
const pify = require ( 'pify' )
const mkdirp = require ( 'mkdirp' )
const rimraf = require ( 'rimraf' )
const webdriver = require ( 'selenium-webdriver' )
const endOfStream = require ( 'end-of-stream' )
const GIFEncoder = require ( 'gifencoder' )
const pngFileStream = require ( 'png-file-stream' )
const sizeOfPng = require ( 'image-size/lib/types/png' )
const By = webdriver . By
const { delay , buildWebDriver } = require ( './func' )
const localesIndex = require ( '../../app/_locales/index.json' )
let driver
captureAllScreens ( ) . catch ( ( err ) => {
try {
console . error ( err )
verboseReportOnFailure ( )
driver . quit ( )
} catch ( err ) {
console . error ( err )
}
process . exit ( 1 )
} )
async function captureAllScreens ( ) {
let screenshotCount = 0
// common names
let button
let tabs
let element
await cleanScreenShotDir ( )
// setup selenium and install extension
const extPath = path . resolve ( 'dist/chrome' )
driver = buildWebDriver ( extPath )
await driver . get ( 'chrome://extensions-frame' )
const extensionId = 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")' )
await driver . get ( ` chrome-extension:// ${ extensionId } /home.html ` )
await delay ( 500 )
tabs = await driver . getAllWindowHandles ( )
await driver . switchTo ( ) . window ( tabs [ 0 ] )
await delay ( 1000 )
await setProviderType ( 'localhost' )
await delay ( 300 )
// click try new ui
await driver . findElement ( By . css ( '#app-content > div > div.app-primary.from-right > div > div.flex-row.flex-center.flex-grow > p' ) ) . click ( )
await delay ( 300 )
// close metamask homepage and extra home.html
tabs = await driver . getAllWindowHandles ( )
// metamask homepage is opened on prod, not dev
if ( tabs . length > 2 ) {
await driver . switchTo ( ) . window ( tabs [ 2 ] )
driver . close ( )
}
await driver . switchTo ( ) . window ( tabs [ 1 ] )
driver . close ( )
await driver . switchTo ( ) . window ( tabs [ 0 ] )
await delay ( 300 )
await captureLanguageScreenShots ( 'welcome-new-ui' )
// setup account
await delay ( 1000 )
await driver . findElement ( By . css ( 'body' ) ) . click ( )
await delay ( 300 )
await captureLanguageScreenShots ( 'welcome' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await captureLanguageScreenShots ( 'create password' )
const passwordBox = await driver . findElement ( By . css ( 'input#create-password' ) )
const passwordBoxConfirm = await driver . findElement ( By . css ( 'input#confirm-password' ) )
passwordBox . sendKeys ( '123456789' )
passwordBoxConfirm . sendKeys ( '123456789' )
await delay ( 500 )
await captureLanguageScreenShots ( 'choose-password-filled' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await delay ( 500 )
await captureLanguageScreenShots ( 'unique account image' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await delay ( 500 )
await captureLanguageScreenShots ( 'privacy note' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await delay ( 300 )
await captureLanguageScreenShots ( 'terms' )
await delay ( 300 )
element = driver . findElement ( By . linkText ( 'Attributions' ) )
await driver . executeScript ( 'arguments[0].scrollIntoView(true)' , element )
await delay ( 300 )
await captureLanguageScreenShots ( 'terms-scrolled' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await delay ( 300 )
await captureLanguageScreenShots ( 'secret backup phrase' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await delay ( 300 )
await captureLanguageScreenShots ( 'secret backup phrase' )
await driver . findElement ( By . css ( '.backup-phrase__reveal-button' ) ) . click ( )
await delay ( 300 )
await captureLanguageScreenShots ( 'secret backup phrase - reveal' )
await driver . findElement ( By . css ( 'button' ) ) . click ( )
await delay ( 300 )
await captureLanguageScreenShots ( 'confirm secret backup phrase' )
// finish up
console . log ( 'building gif...' )
await generateGif ( )
await driver . quit ( )
return
//
// await button.click()
// await delay(700)
// this.seedPhase = await driver.findElement(By.css('.twelve-word-phrase')).getText()
// await captureScreenShot('seed phrase')
//
// const continueAfterSeedPhrase = await driver.findElement(By.css('button'))
// await continueAfterSeedPhrase.click()
// await delay(300)
// await captureScreenShot('main screen')
//
// await driver.findElement(By.css('.sandwich-expando')).click()
// await delay(500)
// await captureScreenShot('menu')
// await driver.findElement(By.css('#app-content > div > div:nth-child(3) > span > div > li:nth-child(3)')).click()
// await captureScreenShot('main screen')
// 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 captureLanguageScreenShots ( label ) {
const nonEnglishLocales = localesIndex . filter ( localeMeta => localeMeta . code !== 'en' )
// take english shot
await captureScreenShot ( ` ${ label } (en) ` )
for ( let localeMeta of nonEnglishLocales ) {
// set locale and take shot
await setLocale ( localeMeta . code )
await delay ( 300 )
await captureScreenShot ( ` ${ label } ( ${ localeMeta . code } ) ` )
}
// return locale to english
await setLocale ( 'en' )
await delay ( 300 )
}
async function setLocale ( code ) {
await driver . executeScript ( 'window.metamask.updateCurrentLocale(arguments[0])' , code )
}
async function setProviderType ( type ) {
await driver . executeScript ( 'window.metamask.setProviderType(arguments[0])' , type )
}
// cleanup
await driver . quit ( )
async function cleanScreenShotDir ( ) {
await pify ( rimraf ) ( ` ./test-artifacts/screens/ ` )
}
async function captureScreenShot ( label ) {
const shotIndex = screenshotCount . toString ( ) . padStart ( 4 , '0' )
screenshotCount ++
const artifactDir = ` ./test-artifacts/screens/ `
await pify ( mkdirp ) ( artifactDir )
// capture screenshot
const screenshot = await driver . takeScreenshot ( )
await pify ( fs . writeFile ) ( ` ${ artifactDir } / ${ shotIndex } - ${ label } .png ` , screenshot , { encoding : 'base64' } )
}
async function generateGif ( ) {
// calculate screenshot size
const screenshot = await driver . takeScreenshot ( )
const pngBuffer = Buffer . from ( screenshot , 'base64' )
const size = sizeOfPng . calculate ( pngBuffer )
// read only the english pngs into gif
const encoder = new GIFEncoder ( size . width , size . height )
const stream = pngFileStream ( './test-artifacts/screens/* (en).png' )
. pipe ( encoder . createWriteStream ( { repeat : 0 , delay : 1000 , quality : 10 } ) )
. pipe ( fs . createWriteStream ( './test-artifacts/screens/walkthrough (en).gif' ) )
// wait for end
await pify ( endOfStream ) ( stream )
}
}
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 )
}