merge with develop branch
This commit is contained in:
commit
d14597f7e4
|
@ -24,10 +24,10 @@ workflows:
|
|||
requires:
|
||||
- prep-deps-npm
|
||||
- prep-build
|
||||
- test-e2e-firefox:
|
||||
requires:
|
||||
- prep-deps-npm
|
||||
- prep-build
|
||||
# - test-e2e-firefox:
|
||||
# requires:
|
||||
# - prep-deps-npm
|
||||
# - prep-build
|
||||
- test-unit:
|
||||
requires:
|
||||
- prep-deps-npm
|
||||
|
@ -52,7 +52,7 @@ workflows:
|
|||
- test-lint
|
||||
- test-unit
|
||||
- test-e2e-chrome
|
||||
- test-e2e-firefox
|
||||
# - test-e2e-firefox
|
||||
- test-integration-mascara-chrome
|
||||
- test-integration-mascara-firefox
|
||||
- test-integration-flat-chrome
|
||||
|
|
|
@ -52,6 +52,7 @@ const LedgerBridgeKeyring = require('eth-ledger-bridge-keyring')
|
|||
const EthQuery = require('eth-query')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
const sigUtil = require('eth-sig-util')
|
||||
const { importTypes } = require('../../old-ui/app/accounts/import/enums')
|
||||
const { LEDGER, TREZOR } = require('../../old-ui/app/components/connect-hardware/enum')
|
||||
|
||||
const { POA_CODE,
|
||||
|
@ -384,6 +385,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||
resetAccount: nodeify(this.resetAccount, this),
|
||||
changePassword: nodeify(this.changePassword, this),
|
||||
removeAccount: nodeify(this.removeAccount, this),
|
||||
updateABI: nodeify(this.updateABI, this),
|
||||
getContract: nodeify(this.getContract, this),
|
||||
importAccountWithStrategy: nodeify(this.importAccountWithStrategy, this),
|
||||
|
||||
|
@ -922,6 +924,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||
* Removes an account from state / storage.
|
||||
*
|
||||
* @param {string[]} address A hex address
|
||||
* @param {int} network ID
|
||||
*
|
||||
*/
|
||||
async removeAccount (address, network) {
|
||||
|
@ -939,6 +942,23 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates implementation ABI for proxy account type.
|
||||
*
|
||||
* @param {string[]} address A hex address
|
||||
* @param {int} network ID
|
||||
*
|
||||
*/
|
||||
async updateABI (address, network, newABI) {
|
||||
// Sets new ABI for implementation contract
|
||||
try {
|
||||
await this.keyringController.updateABI(address, network, newABI)
|
||||
} catch (e) {
|
||||
log.error(e)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Imports an account with the specified import strategy.
|
||||
|
@ -951,7 +971,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||
*/
|
||||
async importAccountWithStrategy (strategy, args) {
|
||||
let keyring
|
||||
if (strategy === 'Contract') {
|
||||
if (strategy === importTypes.CONTRACT.DEFAULT || strategy === importTypes.CONTRACT.PROXY) {
|
||||
args.contractType = strategy
|
||||
keyring = await this.keyringController.addNewKeyring('Simple Address', args)
|
||||
} else {
|
||||
const privateKey = await accountImporter.importAccount(strategy, args)
|
||||
|
|
|
@ -4,7 +4,9 @@ import { connect } from 'react-redux'
|
|||
import actions from '../../../../ui/app/actions'
|
||||
import Web3 from 'web3'
|
||||
import log from 'loglevel'
|
||||
import copyToClipboard from 'copy-to-clipboard'
|
||||
import CopyButton from '../../components/copyButton'
|
||||
import ErrorComponent from '../../components/error'
|
||||
import { getFullABI } from './helpers'
|
||||
|
||||
import { POA_CODE,
|
||||
DAI_CODE,
|
||||
|
@ -31,6 +33,7 @@ class ContractImportView extends Component {
|
|||
static propTypes = {
|
||||
error: PropTypes.string,
|
||||
network: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
displayWarning: PropTypes.func,
|
||||
importNewAccount: PropTypes.func,
|
||||
hideWarning: PropTypes.func,
|
||||
|
@ -49,9 +52,9 @@ class ContractImportView extends Component {
|
|||
abiOnChange (abi) {
|
||||
this.props.hideWarning()
|
||||
try {
|
||||
if (abi && JSON.parse(abi)) {
|
||||
if (abi) {
|
||||
this.setState({
|
||||
abi,
|
||||
abi: JSON.stringify(abi),
|
||||
abiInputDisabled: true,
|
||||
importDisabled: false,
|
||||
})
|
||||
|
@ -62,6 +65,12 @@ class ContractImportView extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
if (this.props.type !== prevProps.type) {
|
||||
this.clearInputs()
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { error } = this.props
|
||||
|
||||
|
@ -72,6 +81,7 @@ class ContractImportView extends Component {
|
|||
alignItems: 'center',
|
||||
padding: '5px 0px 0px 0px',
|
||||
}}>
|
||||
<ErrorComponent error={error} />
|
||||
<span>Paste address of contract here</span>
|
||||
<input
|
||||
className="large-input"
|
||||
|
@ -84,10 +94,12 @@ class ContractImportView extends Component {
|
|||
}}
|
||||
/>
|
||||
<span style={{ marginTop: '20px' }}>Paste ABI of contract here
|
||||
<i
|
||||
className="clipboard cursor-pointer"
|
||||
style={{ marginLeft: '10px' }}
|
||||
onClick={(e) => { copyToClipboard(this.state.abi) }}
|
||||
<CopyButton
|
||||
value={this.state.abi}
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
}}
|
||||
tooltipPosition="right"
|
||||
/>
|
||||
</span>
|
||||
<textarea
|
||||
|
@ -114,26 +126,17 @@ class ContractImportView extends Component {
|
|||
|
||||
autodetectContractAbi = () => {
|
||||
const { contractAddr, web3 } = this.state
|
||||
const { type, network } = this.props
|
||||
if (!contractAddr || !web3.isAddress(contractAddr)) {
|
||||
this.clearAbi()
|
||||
return
|
||||
}
|
||||
|
||||
const networkName = this.getBlockscoutApiNetworkSuffix()
|
||||
const bloscoutApiLink = `https://blockscout.com/poa/${networkName}/api`
|
||||
const bloscoutApiContractPath = '?module=contract'
|
||||
const blockscoutApiGetAbiPath = `&action=getabi&address=${this.state.contractAddr}`
|
||||
const apiLink = `${bloscoutApiLink}${bloscoutApiContractPath}${blockscoutApiGetAbiPath}`
|
||||
fetch(apiLink)
|
||||
.then(response => {
|
||||
return response.json()
|
||||
})
|
||||
.then(responseJson => {
|
||||
this.abiOnChange(responseJson && responseJson.result)
|
||||
})
|
||||
.catch((e) => {
|
||||
getFullABI(web3.eth, contractAddr, network, type)
|
||||
.then(finalABI => this.abiOnChange(finalABI))
|
||||
.catch(e => {
|
||||
this.clearAbi()
|
||||
log.debug(e)
|
||||
this.props.displayWarning(e.message)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -186,7 +189,7 @@ class ContractImportView extends Component {
|
|||
return this.props.displayWarning('Invalid contract ABI')
|
||||
}
|
||||
|
||||
this.props.importNewAccount('Contract', { addr: contractAddr, network: this.props.network, abi })
|
||||
this.props.importNewAccount(this.props.type, { addr: contractAddr, network: this.props.network, abi })
|
||||
// JS runtime requires caught rejections but failures are handled by Redux
|
||||
.catch()
|
||||
}
|
||||
|
@ -213,6 +216,15 @@ class ContractImportView extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
clearInputs () {
|
||||
this.setState({
|
||||
contractAddr: '',
|
||||
abi: '',
|
||||
abiInputDisabled: false,
|
||||
importDisabled: true,
|
||||
})
|
||||
}
|
||||
|
||||
clearAbi () {
|
||||
this.setState({
|
||||
abi: '',
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
const importTypes = {
|
||||
PRIVATE_KEY: 'Private Key',
|
||||
JSON_FILE: 'JSON File',
|
||||
CONTRACT: {
|
||||
DEFAULT: 'Contract',
|
||||
PROXY: 'Proxy',
|
||||
},
|
||||
}
|
||||
|
||||
const labels = {
|
||||
CONTRACT: 'CONTRACT',
|
||||
PROXY: 'PROXY',
|
||||
HARDWARE: 'HARDWARE',
|
||||
IMPORTED: 'IMPORTED',
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
importTypes,
|
||||
labels,
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
import log from 'loglevel'
|
||||
import { importTypes } from './enums'
|
||||
|
||||
const nestedJsonObjToArray = (jsonObj) => {
|
||||
return jsonObjToArray(jsonObj)
|
||||
}
|
||||
|
||||
const jsonObjToArray = (jsonObj) => {
|
||||
return Object.keys(jsonObj).reduce((arr, key) => {
|
||||
if (jsonObj[key].constructor === Object || jsonObj[key].constructor === Array) {
|
||||
arr = arr.concat(jsonObjToArray(jsonObj[key]))
|
||||
} else if (jsonObj[key].constructor === String) {
|
||||
arr.push(jsonObj[key])
|
||||
}
|
||||
return arr
|
||||
}, [])
|
||||
}
|
||||
|
||||
const getBlockscoutApiNetworkSuffix = (network) => {
|
||||
switch (Number(network)) {
|
||||
case 1:
|
||||
return 'mainnet'
|
||||
case 99:
|
||||
return 'core'
|
||||
case 77:
|
||||
return 'sokol'
|
||||
case 100:
|
||||
return 'dai'
|
||||
case 42:
|
||||
return 'kovan'
|
||||
case 3:
|
||||
return 'ropsten'
|
||||
case 4:
|
||||
return 'rinkeby'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const fetchABI = (addr, network) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const networkName = getBlockscoutApiNetworkSuffix(network)
|
||||
const bloscoutApiLink = `https://blockscout.com/poa/${networkName}/api`
|
||||
const bloscoutApiContractPath = '?module=contract'
|
||||
const blockscoutApiGetAbiPath = `&action=getabi&address=${addr}`
|
||||
const apiLink = `${bloscoutApiLink}${bloscoutApiContractPath}${blockscoutApiGetAbiPath}`
|
||||
fetch(apiLink)
|
||||
.then(response => {
|
||||
return response.json()
|
||||
})
|
||||
.then(responseJson => {
|
||||
resolve(responseJson && responseJson.result)
|
||||
})
|
||||
.catch((e) => {
|
||||
log.debug(e)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getFullABI = (eth, contractAddr, network, type) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetchABI(contractAddr, network)
|
||||
.then((targetABI) => {
|
||||
targetABI = targetABI && JSON.parse(targetABI)
|
||||
let finalABI = targetABI
|
||||
if (type === importTypes.CONTRACT.PROXY) {
|
||||
if (!eth.contract(targetABI).at(contractAddr).implementation) {
|
||||
const e = {
|
||||
message: 'This is not a valid Delegate Proxy contract',
|
||||
}
|
||||
reject(e)
|
||||
}
|
||||
try {
|
||||
eth.contract(targetABI).at(contractAddr).implementation.call((err, implAddr) => {
|
||||
fetchABI(implAddr, network)
|
||||
.then((implABI) => {
|
||||
implABI = implABI && JSON.parse(implABI)
|
||||
finalABI = implABI ? targetABI.concat(implABI) : targetABI
|
||||
resolve(finalABI)
|
||||
})
|
||||
.catch(e => reject(e))
|
||||
})
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
} else {
|
||||
resolve(finalABI)
|
||||
}
|
||||
})
|
||||
.catch(e => { reject(e) })
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
nestedJsonObjToArray,
|
||||
getFullABI,
|
||||
}
|
|
@ -1,96 +1,76 @@
|
|||
const inherits = require('util').inherits
|
||||
const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const connect = require('react-redux').connect
|
||||
const actions = require('../../../../ui/app/actions')
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import PropTypes from 'prop-types'
|
||||
import actions from '../../../../ui/app/actions'
|
||||
import Select from 'react-select'
|
||||
import { importTypes } from './enums'
|
||||
import { nestedJsonObjToArray } from './helpers'
|
||||
|
||||
// Subviews
|
||||
const JsonImportView = require('./json.js')
|
||||
const PrivateKeyImportView = require('./private-key.js')
|
||||
const ContractImportView = require('./contract.js')
|
||||
import JsonImportView from './json.js'
|
||||
import PrivateKeyImportView from './private-key.js'
|
||||
import ContractImportView from './contract.js'
|
||||
|
||||
const menuItems = [
|
||||
'Private Key',
|
||||
'JSON File',
|
||||
'Contract',
|
||||
]
|
||||
const menuItems = nestedJsonObjToArray(importTypes)
|
||||
|
||||
module.exports = connect(mapStateToProps)(AccountImportSubview)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {
|
||||
menuItems,
|
||||
class AccountImportSubview extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
description: '',
|
||||
type: importTypes.PRIVATE_KEY,
|
||||
}
|
||||
}
|
||||
|
||||
inherits(AccountImportSubview, Component)
|
||||
function AccountImportSubview () {
|
||||
Component.call(this)
|
||||
static propTypes = {
|
||||
menuItems: PropTypes.array,
|
||||
warning: PropTypes.node,
|
||||
goHome: PropTypes.func,
|
||||
displayWarning: PropTypes.func,
|
||||
showImportPage: PropTypes.func,
|
||||
}
|
||||
|
||||
AccountImportSubview.prototype.render = function () {
|
||||
render () {
|
||||
const props = this.props
|
||||
const state = this.state || {}
|
||||
const { menuItems } = props
|
||||
const { type } = state
|
||||
|
||||
return (
|
||||
h('div', {
|
||||
style: {
|
||||
<div style={{
|
||||
width: '100%',
|
||||
},
|
||||
}, [
|
||||
h('.section-title', { style: {
|
||||
}}>
|
||||
<div className="section-title" style={{
|
||||
height: '1px',
|
||||
width: '100%',
|
||||
}}),
|
||||
h('div', {
|
||||
style: {
|
||||
}} />
|
||||
<div style={{
|
||||
width: '100%',
|
||||
paddingLeft: '30px',
|
||||
paddingRight: '30px',
|
||||
},
|
||||
}, [
|
||||
h('.flex-row.flex-center', [
|
||||
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
|
||||
onClick: (event) => {
|
||||
props.dispatch(actions.goHome())
|
||||
},
|
||||
style: {
|
||||
padding: '0 30px',
|
||||
}}>
|
||||
<div className="flex-row flex-center">
|
||||
<div
|
||||
className="i fa fa-arrow-left fa-lg cursor-pointer"
|
||||
onClick={(event) => { props.goHome() }}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '30px',
|
||||
},
|
||||
}),
|
||||
h('h2.page-subtitle', {
|
||||
style: {
|
||||
}}
|
||||
/>
|
||||
<h2 className="page-subtitle" style={{
|
||||
fontFamily: 'Nunito SemiBold',
|
||||
},
|
||||
}, 'Import Accounts'),
|
||||
]),
|
||||
h('.error', {
|
||||
style: {
|
||||
}}
|
||||
>Import Accounts</h2>
|
||||
</div>
|
||||
<div
|
||||
className="error"
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
alignItems: 'center',
|
||||
},
|
||||
}, [
|
||||
h('span', 'Imported accounts will not be associated with your originally created Nifty Wallet account seedphrase.'),
|
||||
]),
|
||||
h('div', {
|
||||
style: {
|
||||
padding: '10px 0',
|
||||
},
|
||||
}, [
|
||||
|
||||
h('h3', { style: { padding: '3px' } }, 'Select Type'),
|
||||
|
||||
h('style', `
|
||||
.has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label {
|
||||
color: rgb(174,174,174);
|
||||
}
|
||||
`),
|
||||
|
||||
h(Select, {
|
||||
}}>
|
||||
<span>Imported accounts will not be associated with your originally created Nifty Wallet account seedphrase.</span>
|
||||
</div>
|
||||
<div style={{ padding: '10px 0' }}>
|
||||
<h3 style={{ padding: '3px' }}>Select Type</h3>
|
||||
<Select {...{
|
||||
name: 'import-type-select',
|
||||
clearable: false,
|
||||
value: type || menuItems[0],
|
||||
|
@ -100,38 +80,75 @@ AccountImportSubview.prototype.render = function () {
|
|||
label: type,
|
||||
}
|
||||
}),
|
||||
onChange: (opt) => {
|
||||
props.dispatch(actions.showImportPage())
|
||||
this.setState({ type: opt.value })
|
||||
},
|
||||
}),
|
||||
]),
|
||||
|
||||
this.renderImportView(),
|
||||
]),
|
||||
])
|
||||
onChange: (opt) => { this.onChange(opt) },
|
||||
}}/>
|
||||
<p className="hw-connect__header__msg" dangerouslySetInnerHTML={{__html: this.state.description}} />
|
||||
</div>
|
||||
{this.renderImportView()}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
AccountImportSubview.prototype.componentWillUnmount = function () {
|
||||
this.props.dispatch(actions.displayWarning(''))
|
||||
onChange (opt) {
|
||||
const props = this.props
|
||||
props.showImportPage()
|
||||
const type = opt.value
|
||||
let description
|
||||
switch (type) {
|
||||
case importTypes.PRIVATE_KEY:
|
||||
case importTypes.JSON_FILE:
|
||||
description = ''
|
||||
break
|
||||
case importTypes.CONTRACT.DEFAULT:
|
||||
description = `Contract type will automatically retrieve its ABI, if it was verified in <a href='https://blockscout.com' target='_blank'>Blockscout</a>`
|
||||
break
|
||||
case importTypes.CONTRACT.PROXY:
|
||||
description = `Proxy contract type will automatically contain ABI of implementation, if proxy and implementation were both verified in <a href='https://blockscout.com' target='_blank'>Blockscout</a>`
|
||||
break
|
||||
default:
|
||||
description = ''
|
||||
break
|
||||
}
|
||||
this.setState({ type, description })
|
||||
}
|
||||
|
||||
AccountImportSubview.prototype.renderImportView = function () {
|
||||
const props = this.props
|
||||
componentWillUnmount () {
|
||||
this.props.displayWarning('')
|
||||
}
|
||||
renderImportView () {
|
||||
const { menuItems } = this.props
|
||||
const state = this.state || {}
|
||||
const { type } = state
|
||||
const { menuItems } = props
|
||||
const current = type || menuItems[0]
|
||||
|
||||
switch (current) {
|
||||
case 'Private Key':
|
||||
return h(PrivateKeyImportView)
|
||||
case 'JSON File':
|
||||
return h(JsonImportView)
|
||||
case 'Contract':
|
||||
return h(ContractImportView)
|
||||
case importTypes.PRIVATE_KEY:
|
||||
return <PrivateKeyImportView/>
|
||||
case importTypes.JSON_FILE:
|
||||
return <JsonImportView/>
|
||||
case importTypes.CONTRACT.DEFAULT:
|
||||
return <ContractImportView type={importTypes.CONTRACT.DEFAULT}/>
|
||||
case importTypes.CONTRACT.PROXY:
|
||||
return <ContractImportView type={importTypes.CONTRACT.PROXY}/>
|
||||
default:
|
||||
return h(JsonImportView)
|
||||
return <JsonImportView/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
menuItems,
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
goHome: () => dispatch(actions.goHome()),
|
||||
displayWarning: warning => dispatch(actions.displayWarning(warning)),
|
||||
showImportPage: options => dispatch(actions.showImportPage()),
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountImportSubview)
|
||||
|
|
|
@ -1,23 +1,47 @@
|
|||
const Component = require('react').Component
|
||||
const PropTypes = require('prop-types')
|
||||
const h = require('react-hyperscript')
|
||||
const actions = require('../../../ui/app/actions')
|
||||
const connect = require('react-redux').connect
|
||||
const Dropdown = require('./dropdown').Dropdown
|
||||
const DropdownMenuItem = require('./dropdown').DropdownMenuItem
|
||||
const Identicon = require('./identicon')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
const copyToClipboard = require('copy-to-clipboard')
|
||||
const ethNetProps = require('eth-net-props')
|
||||
const { getCurrentKeyring, ifLooseAcc, ifContractAcc } = require('../util')
|
||||
const { getHdPaths } = require('./connect-hardware/util')
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import actions from '../../../ui/app/actions'
|
||||
import { connect } from 'react-redux'
|
||||
import { Dropdown, DropdownMenuItem } from './dropdown'
|
||||
import Identicon from './identicon'
|
||||
import ethUtil from 'ethereumjs-util'
|
||||
import copyToClipboard from 'copy-to-clipboard'
|
||||
import ethNetProps from 'eth-net-props'
|
||||
import { getCurrentKeyring, ifLooseAcc, ifContractAcc, ifHardwareAcc } from '../util'
|
||||
import { getHdPaths, isLedger } from './connect-hardware/util'
|
||||
import { LEDGER } from './connect-hardware/enum'
|
||||
import { importTypes, labels } from '../accounts/import/enums'
|
||||
import { getFullABI } from '../accounts/import/helpers'
|
||||
import log from 'loglevel'
|
||||
import Web3 from 'web3'
|
||||
|
||||
class AccountsDropdownMenuItemWrapper extends DropdownMenuItem {
|
||||
render () {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
style={{
|
||||
padding: '8px 0px',
|
||||
}}
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.props.onClick()}
|
||||
>
|
||||
<span className="acc-dd-menu-item-text">{this.props.label}</span>
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class AccountDropdowns extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
const web3 = new Web3(global.ethereumProvider)
|
||||
this.state = {
|
||||
accountSelectorActive: false,
|
||||
optionsMenuActive: false,
|
||||
web3,
|
||||
labels: {},
|
||||
isProxy: false,
|
||||
contractProps: null,
|
||||
}
|
||||
this.accountSelectorToggleClassName = 'accounts-selector'
|
||||
this.optionsMenuToggleClassName = 'account-dropdown'
|
||||
|
@ -25,16 +49,9 @@ class AccountDropdowns extends Component {
|
|||
|
||||
renderAccounts () {
|
||||
const { identities, selected, keyrings, network } = this.props
|
||||
const accountOrder = keyrings.reduce((list, keyring) => {
|
||||
if (ifContractAcc(keyring) && keyring.network === network) {
|
||||
list = list.concat(keyring.accounts)
|
||||
} else if (!ifContractAcc(keyring)) {
|
||||
list = list.concat(keyring.accounts)
|
||||
}
|
||||
return list
|
||||
}, [])
|
||||
const accountOrder = this.getAccounts()
|
||||
|
||||
return accountOrder.map((address, index) => {
|
||||
const accountsViews = accountOrder.map((address, index) => {
|
||||
const identity = identities[address]
|
||||
if (!identity) {
|
||||
return null
|
||||
|
@ -54,24 +71,72 @@ class AccountDropdowns extends Component {
|
|||
return this.accountsDropdownItemView(index, isSelected, keyring, identity)
|
||||
}
|
||||
})
|
||||
return accountsViews
|
||||
}
|
||||
|
||||
accountsDropdownItemView (index, isSelected, keyring, identity) {
|
||||
return h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
closeMenu: () => {},
|
||||
onClick: () => {
|
||||
this.props.actions.showAccountDetail(identity.address)
|
||||
if (this.ifHardwareAcc(keyring)) {
|
||||
const ledger = 'ledger'
|
||||
if (keyring.type.toLowerCase().includes(ledger)) {
|
||||
const { labels } = this.state
|
||||
const { address, name } = identity
|
||||
const leftBorder = isSelected ? <div className="accs-dd-menu-item-selected" /> : null
|
||||
const accountIcon = (
|
||||
<Identicon
|
||||
overflow="none"
|
||||
address={identity.address}
|
||||
diameter={24}
|
||||
style={{ marginLeft: '10px' }}
|
||||
/>
|
||||
)
|
||||
const accountName = (
|
||||
<span
|
||||
className="accs-dd-menu-item-account-name"
|
||||
style={{ color: isSelected ? 'white' : '' }}
|
||||
>{name || ''}
|
||||
</span>
|
||||
)
|
||||
const accountLabel = labels[address] ? <div className="keyring-label">{labels[address]}</div> : null
|
||||
const removeIcon = ifLooseAcc(keyring) ? (
|
||||
<div
|
||||
className="remove"
|
||||
onClick={(event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
this.props.actions.showDeleteImportedAccount(identity)
|
||||
this.setState({
|
||||
accountSelectorActive: false,
|
||||
optionsMenuActive: false,
|
||||
})
|
||||
}}
|
||||
/>) : null
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={`account_${index}`}
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.accountOnClick(keyring, address)}
|
||||
style={{
|
||||
marginTop: index === 0 ? '5px' : '',
|
||||
fontSize: '16px',
|
||||
padding: '8px 0px',
|
||||
}}
|
||||
>
|
||||
{leftBorder}
|
||||
{accountIcon}
|
||||
{accountName}
|
||||
{accountLabel}
|
||||
{removeIcon}
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
}
|
||||
|
||||
accountOnClick (keyring, address) {
|
||||
this.props.actions.showAccountDetail(address)
|
||||
if (ifHardwareAcc(keyring)) {
|
||||
if (isLedger(keyring.type)) {
|
||||
const hdPaths = getHdPaths()
|
||||
return new Promise((resolve, reject) => {
|
||||
this.props.actions.connectHardwareAndUnlockAddress(ledger, hdPaths[1].value, identity.address)
|
||||
this.props.actions.connectHardwareAndUnlockAddress(LEDGER, hdPaths[1].value, address)
|
||||
.then(_ => resolve())
|
||||
.catch(e => {
|
||||
this.props.actions.connectHardwareAndUnlockAddress(ledger, hdPaths[0].value, identity.address)
|
||||
this.props.actions.connectHardwareAndUnlockAddress(LEDGER, hdPaths[0].value, address)
|
||||
.then(_ => resolve())
|
||||
.catch(e => reject(e))
|
||||
})
|
||||
|
@ -82,316 +147,279 @@ class AccountDropdowns extends Component {
|
|||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
style: {
|
||||
marginTop: index === 0 ? '5px' : '',
|
||||
fontSize: '16px',
|
||||
padding: '8px 0px',
|
||||
},
|
||||
},
|
||||
[
|
||||
isSelected ? h('div', {
|
||||
style: {
|
||||
width: '4px',
|
||||
height: '26px',
|
||||
background: '#60db97',
|
||||
position: 'absolute',
|
||||
left: '-25px',
|
||||
},
|
||||
}) : null,
|
||||
h(
|
||||
Identicon,
|
||||
{
|
||||
overflow: 'none',
|
||||
address: identity.address,
|
||||
diameter: 24,
|
||||
style: {
|
||||
marginLeft: '10px',
|
||||
},
|
||||
},
|
||||
),
|
||||
h('span', {
|
||||
style: {
|
||||
marginLeft: '10px',
|
||||
fontSize: '16px',
|
||||
maxWidth: '95px',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
color: isSelected ? 'white' : '',
|
||||
},
|
||||
}, identity.name || ''),
|
||||
this.indicateIfLoose(keyring),
|
||||
ifLooseAcc(keyring) ? h('.remove', {
|
||||
onClick: (event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
this.props.actions.showDeleteImportedAccount(identity)
|
||||
this.setState({
|
||||
accountSelectorActive: false,
|
||||
optionsMenuActive: false,
|
||||
}
|
||||
|
||||
ifProxyAcc (address, setProxy) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.props.actions.getContract(address)
|
||||
.then(contractProps => {
|
||||
if (setProxy) {
|
||||
this.setState({contractProps})
|
||||
}
|
||||
resolve(contractProps && contractProps.contractType === importTypes.CONTRACT.PROXY)
|
||||
})
|
||||
.catch(e => reject(e))
|
||||
})
|
||||
},
|
||||
}) : null,
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
ifHardwareAcc (keyring) {
|
||||
if (keyring && keyring.type.search('Hardware') !== -1) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
indicateIfLoose (keyring) {
|
||||
setLabel (keyring, address) {
|
||||
if (ifLooseAcc(keyring)) {
|
||||
let label
|
||||
if (ifContractAcc(keyring)) {
|
||||
label = 'CONTRACT'
|
||||
} else if (this.ifHardwareAcc(keyring)) {
|
||||
label = 'HARDWARE'
|
||||
const setProxy = false
|
||||
this.ifProxyAcc(address, setProxy)
|
||||
.then(isProxy => {
|
||||
label = isProxy ? labels.PROXY : labels.CONTRACT
|
||||
this.setLabelToState(label, address)
|
||||
})
|
||||
} else if (ifHardwareAcc(keyring)) {
|
||||
label = labels.HARDWARE
|
||||
this.setLabelToState(label, address)
|
||||
} else {
|
||||
label = 'IMPORTED'
|
||||
label = labels.IMPORTED
|
||||
this.setLabelToState(label, address)
|
||||
}
|
||||
}
|
||||
return h('.keyring-label', label)
|
||||
}
|
||||
|
||||
return null
|
||||
setLabelToState (label, address) {
|
||||
const labelsArr = this.state.labels
|
||||
labelsArr[address] = label
|
||||
this.setState({labelsArr})
|
||||
}
|
||||
|
||||
renderAccountSelector () {
|
||||
const { actions } = this.props
|
||||
const { accountSelectorActive } = this.state
|
||||
let menuItems = []
|
||||
menuItems = Object.assign(menuItems, this.renderAccounts())
|
||||
const bottomMenuItems = [
|
||||
<AccountsDropdownMenuItemWrapper key="AccountsDropdownMenuItemAdd" onClick={() => actions.addNewAccount()} label="Create Account" />,
|
||||
<AccountsDropdownMenuItemWrapper key="AccountsDropdownMenuItemImport" onClick={() => actions.showImportPage()} label="Import Account" />,
|
||||
<AccountsDropdownMenuItemWrapper key="AccountsDropdownMenuItemConnectHD" onClick={() => actions.showConnectHWWalletPage()} label="Connect hardware wallet" />,
|
||||
]
|
||||
menuItems = menuItems.concat(bottomMenuItems)
|
||||
|
||||
return h(
|
||||
Dropdown,
|
||||
{
|
||||
useCssTransition: true, // Hardcoded because account selector is temporarily in app-header
|
||||
style: {
|
||||
return (
|
||||
<Dropdown
|
||||
useCssTransition={true} // Hardcoded because account selector is temporarily in app-header
|
||||
style={{
|
||||
position: 'absolute',
|
||||
marginLeft: '-213px',
|
||||
top: '38px',
|
||||
minWidth: '180px',
|
||||
maxHeight: accountSelectorActive ? '300px' : '0px',
|
||||
width: '265px',
|
||||
},
|
||||
innerStyle: {
|
||||
}}
|
||||
innerStyle={{
|
||||
padding: '8px 25px',
|
||||
},
|
||||
isOpen: accountSelectorActive,
|
||||
onClickOutside: (event) => {
|
||||
}}
|
||||
isOpen={accountSelectorActive}
|
||||
onClickOutside={(event) => {
|
||||
const { classList } = event.target
|
||||
const isNotToggleElement = !classList.contains(this.accountSelectorToggleClassName)
|
||||
if (accountSelectorActive && isNotToggleElement) {
|
||||
this.setState({ accountSelectorActive: false })
|
||||
}
|
||||
},
|
||||
},
|
||||
[
|
||||
...this.renderAccounts(),
|
||||
h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
style: {
|
||||
padding: '8px 0px',
|
||||
},
|
||||
closeMenu: () => {},
|
||||
onClick: () => actions.addNewAccount(),
|
||||
},
|
||||
[
|
||||
h('span', { style: { fontSize: '16px', color: '#60db97' } }, 'Create Account'),
|
||||
],
|
||||
),
|
||||
h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
style: {
|
||||
padding: '8px 0px',
|
||||
},
|
||||
closeMenu: () => {},
|
||||
onClick: () => actions.showImportPage(),
|
||||
},
|
||||
[
|
||||
h('span', {
|
||||
style: {
|
||||
fontSize: '16px',
|
||||
marginBottom: '5px',
|
||||
color: '#60db97',
|
||||
},
|
||||
}, 'Import Account'),
|
||||
]
|
||||
),
|
||||
h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
style: {
|
||||
padding: '8px 0px',
|
||||
},
|
||||
closeMenu: () => {},
|
||||
onClick: () => actions.showConnectHWWalletPage(),
|
||||
},
|
||||
[
|
||||
h('span', {
|
||||
style: {
|
||||
fontSize: '16px',
|
||||
marginBottom: '5px',
|
||||
color: '#60db97',
|
||||
},
|
||||
}, 'Connect hardware wallet'),
|
||||
]
|
||||
),
|
||||
]
|
||||
}}
|
||||
>
|
||||
{menuItems}
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
|
||||
renderAccountOptions () {
|
||||
const { actions, selected, network, keyrings, identities } = this.props
|
||||
const { optionsMenuActive } = this.state
|
||||
const { optionsMenuActive, isProxy } = this.state
|
||||
|
||||
const keyring = getCurrentKeyring(selected, network, keyrings, identities)
|
||||
|
||||
return h(
|
||||
Dropdown,
|
||||
{
|
||||
style: {
|
||||
return (
|
||||
<Dropdown
|
||||
style={{
|
||||
position: 'relative',
|
||||
marginLeft: '-234px',
|
||||
minWidth: '180px',
|
||||
// marginTop: '30px',
|
||||
top: '30px',
|
||||
width: '280px',
|
||||
},
|
||||
isOpen: optionsMenuActive,
|
||||
onClickOutside: (event) => {
|
||||
}}
|
||||
isOpen={optionsMenuActive}
|
||||
onClickOutside={(event) => {
|
||||
const { classList } = event.target
|
||||
const isNotToggleElement = !classList.contains(this.optionsMenuToggleClassName)
|
||||
if (optionsMenuActive && isNotToggleElement) {
|
||||
this.setState({ optionsMenuActive: false })
|
||||
}
|
||||
},
|
||||
},
|
||||
[
|
||||
h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
closeMenu: () => {},
|
||||
onClick: () => {
|
||||
}}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.viewOnBlockExplorer()}
|
||||
>View on block explorer</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.showQRCode()}
|
||||
>Show QR Code</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.copyAddress()}
|
||||
>Copy address to clipboard</DropdownMenuItem>
|
||||
{ifContractAcc(keyring) ? <DropdownMenuItem
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.copyABI()}
|
||||
>Copy ABI to clipboard</DropdownMenuItem> : null}
|
||||
{isProxy ? <DropdownMenuItem
|
||||
closeMenu={() => {}}
|
||||
onClick={() => this.updateABI()}
|
||||
>Update implementation ABI</DropdownMenuItem> : null}
|
||||
{(!ifHardwareAcc(keyring) && !(ifContractAcc(keyring))) ? <DropdownMenuItem
|
||||
closeMenu={() => {}}
|
||||
onClick={() => actions.requestAccountExport()}
|
||||
>Export Private Key</DropdownMenuItem> : null}
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
|
||||
viewOnBlockExplorer = () => {
|
||||
const { selected, network } = this.props
|
||||
const url = ethNetProps.explorerLinks.getExplorerAccountLinkFor(selected, network)
|
||||
global.platform.openWindow({ url })
|
||||
},
|
||||
},
|
||||
`View on block explorer`,
|
||||
),
|
||||
h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
closeMenu: () => {},
|
||||
onClick: () => {
|
||||
const { selected, identities } = this.props
|
||||
var identity = identities[selected]
|
||||
}
|
||||
|
||||
showQRCode = () => {
|
||||
const { selected, identities, actions } = this.props
|
||||
const identity = identities[selected]
|
||||
actions.showQrView(selected, identity ? identity.name : '')
|
||||
},
|
||||
},
|
||||
'Show QR Code',
|
||||
),
|
||||
h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
closeMenu: () => {},
|
||||
onClick: () => {
|
||||
}
|
||||
|
||||
copyAddress = () => {
|
||||
const { selected } = this.props
|
||||
const checkSumAddress = selected && ethUtil.toChecksumAddress(selected)
|
||||
copyToClipboard(checkSumAddress)
|
||||
},
|
||||
},
|
||||
'Copy address to clipboard',
|
||||
),
|
||||
ifContractAcc(keyring) ? h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
closeMenu: () => {},
|
||||
onClick: async () => {
|
||||
const { selected } = this.props
|
||||
const contractProps = await this.props.actions.getContract(selected)
|
||||
}
|
||||
|
||||
copyABI = async () => {
|
||||
const { contractProps } = this.state
|
||||
const abi = contractProps && contractProps.abi
|
||||
copyToClipboard(JSON.stringify(abi))
|
||||
},
|
||||
},
|
||||
'Copy ABI to clipboard',
|
||||
) : null,
|
||||
(!this.ifHardwareAcc(keyring) && !(ifContractAcc(keyring))) ? h(
|
||||
DropdownMenuItem,
|
||||
{
|
||||
closeMenu: () => {},
|
||||
onClick: () => {
|
||||
actions.requestAccountExport()
|
||||
},
|
||||
},
|
||||
'Export Private Key',
|
||||
) : null,
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
updateABI = async () => {
|
||||
const { actions, selected, network } = this.props
|
||||
const { web3 } = this.state
|
||||
actions.showLoadingIndication()
|
||||
getFullABI(web3.eth, selected, network, importTypes.CONTRACT.PROXY)
|
||||
.then(finalABI => {
|
||||
actions.updateABI(selected, network, finalABI)
|
||||
.then()
|
||||
.catch(e => {
|
||||
log.debug(e)
|
||||
})
|
||||
.finally(() => actions.hideLoadingIndication())
|
||||
})
|
||||
.catch(e => {
|
||||
log.debug(e)
|
||||
actions.hideLoadingIndication()
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
const { style, enableAccountsSelector, enableAccountOptions } = this.props
|
||||
const { optionsMenuActive, accountSelectorActive } = this.state
|
||||
|
||||
return h(
|
||||
'span',
|
||||
{
|
||||
style: style,
|
||||
},
|
||||
[
|
||||
enableAccountsSelector && h(
|
||||
'div.accounts-selector',
|
||||
{
|
||||
style: {
|
||||
background: 'url(images/switch_acc.svg) white center center no-repeat',
|
||||
height: '25px',
|
||||
width: '25px',
|
||||
marginRight: '3px',
|
||||
},
|
||||
onClick: (event) => {
|
||||
const accountSelector = enableAccountsSelector && (
|
||||
<div
|
||||
className="accounts-selector accounts-selector-additional-style"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
this.setState({
|
||||
accountSelectorActive: !accountSelectorActive,
|
||||
optionsMenuActive: false,
|
||||
})
|
||||
},
|
||||
},
|
||||
this.renderAccountSelector(),
|
||||
),
|
||||
enableAccountOptions && h(
|
||||
'div.address-dropdown.account-dropdown',
|
||||
{
|
||||
onClick: (event) => {
|
||||
}}
|
||||
>
|
||||
{this.renderAccountSelector()}
|
||||
</div>
|
||||
)
|
||||
const accountOptions = enableAccountOptions && (
|
||||
<div
|
||||
className="address-dropdown account-dropdown"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
this.setState({
|
||||
accountSelectorActive: false,
|
||||
optionsMenuActive: !optionsMenuActive,
|
||||
})
|
||||
},
|
||||
},
|
||||
this.renderAccountOptions()
|
||||
),
|
||||
]
|
||||
}}
|
||||
>
|
||||
{this.renderAccountOptions()}
|
||||
</div>
|
||||
)
|
||||
return (
|
||||
<span style={style}>
|
||||
{accountSelector}
|
||||
{accountOptions}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
getAccounts () {
|
||||
const { keyrings, network } = this.props
|
||||
const accountOrder = keyrings.reduce((list, keyring) => {
|
||||
if (ifContractAcc(keyring) && keyring.network === network) {
|
||||
list = list.concat(keyring.accounts)
|
||||
} else if (!ifContractAcc(keyring)) {
|
||||
list = list.concat(keyring.accounts)
|
||||
}
|
||||
return list
|
||||
}, [])
|
||||
return accountOrder
|
||||
}
|
||||
|
||||
checkIfProxy () {
|
||||
const { selected } = this.props
|
||||
const setProxy = true
|
||||
this.ifProxyAcc(selected, setProxy)
|
||||
.then(isProxy => {
|
||||
this.setState({isProxy})
|
||||
})
|
||||
}
|
||||
|
||||
setAllLabels () {
|
||||
const { identities, keyrings, network } = this.props
|
||||
const accountOrder = this.getAccounts()
|
||||
|
||||
accountOrder.forEach((address) => {
|
||||
const keyring = getCurrentKeyring(address, network, keyrings, identities)
|
||||
this.setLabel(keyring, address)
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.setAllLabels()
|
||||
this.checkIfProxy()
|
||||
}
|
||||
|
||||
// switch to the first account in the list on network switch, if unlocked account was contract before change
|
||||
componentDidUpdate (prevProps) {
|
||||
const { selected, keyrings } = this.props
|
||||
if (prevProps.selected !== selected) {
|
||||
this.checkIfProxy()
|
||||
}
|
||||
if (prevProps.keyrings.length !== keyrings.length) {
|
||||
this.setAllLabels()
|
||||
}
|
||||
if (!isNaN(this.props.network)) {
|
||||
const { selected, network, keyrings, identities } = this.props
|
||||
const { network } = this.props
|
||||
if (network !== prevProps.network) {
|
||||
const { keyrings, identities } = this.props
|
||||
const keyring = getCurrentKeyring(selected, this.props.network, keyrings, identities)
|
||||
const firstKeyring = keyrings && keyrings[0]
|
||||
const firstKeyRingAcc = firstKeyring && firstKeyring.accounts && firstKeyring.accounts[0]
|
||||
if (!keyring || (ifContractAcc(keyring) && firstKeyRingAcc)) {
|
||||
return this.props.actions.showAccountDetail(firstKeyRingAcc)
|
||||
}
|
||||
this.setAllLabels()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,6 +444,8 @@ AccountDropdowns.propTypes = {
|
|||
const mapDispatchToProps = (dispatch) => {
|
||||
return {
|
||||
actions: {
|
||||
showLoadingIndication: () => dispatch(actions.showLoadingIndication()),
|
||||
hideLoadingIndication: () => dispatch(actions.hideLoadingIndication()),
|
||||
showConfigPage: () => dispatch(actions.showConfigPage()),
|
||||
requestAccountExport: () => dispatch(actions.requestExportAccount()),
|
||||
showAccountDetail: (address) => dispatch(actions.showAccountDetail(address)),
|
||||
|
@ -434,6 +464,7 @@ const mapDispatchToProps = (dispatch) => {
|
|||
},
|
||||
displayToast: (msg) => dispatch(actions.displayToast(msg)),
|
||||
hideToast: () => dispatch(actions.hideToast()),
|
||||
updateABI: (address, network, abi) => dispatch(actions.updateABI(address, network, abi)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,7 +453,11 @@ class AddTokenScreen extends Component {
|
|||
const { symbol = '', decimals = '' } = await this.tokenInfoGetter(address)
|
||||
|
||||
const autoFilled = Boolean(symbol && decimals)
|
||||
this.setState({ autoFilled })
|
||||
this.setState({
|
||||
autoFilled,
|
||||
warning: '',
|
||||
customAddressError: null,
|
||||
})
|
||||
this.handleCustomSymbolChange(symbol || '')
|
||||
this.handleCustomDecimalsChange(decimals || '')
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { LEDGER } from './enum'
|
||||
|
||||
function isLedger (device) {
|
||||
return device && device.toLowerCase().includes('ledger')
|
||||
return device && device.toLowerCase().includes(LEDGER)
|
||||
}
|
||||
|
||||
function isTrezor (device) {
|
||||
|
|
|
@ -26,15 +26,18 @@ CopyButton.prototype.render = function () {
|
|||
|
||||
const message = copied ? 'Copied' : props.title || ' Copy '
|
||||
const defaultCopyStyles = ['clipboard', 'cursor-pointer']
|
||||
|
||||
return h('.copy-button', {
|
||||
style: {
|
||||
const originalStyle = {
|
||||
display: display || 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
}
|
||||
const style = Object.assign(originalStyle, this.props.style)
|
||||
|
||||
return h('.copy-button', {
|
||||
style,
|
||||
}, [
|
||||
h(Tooltip, {
|
||||
title: message,
|
||||
position: this.props.tooltipPosition,
|
||||
}, [
|
||||
h('i', {
|
||||
style: {
|
||||
|
|
|
@ -94,7 +94,7 @@ class DropdownMenuItem extends Component {
|
|||
}
|
||||
|
||||
DropdownMenuItem.propTypes = {
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
closeMenu: PropTypes.func,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
children: PropTypes.node,
|
||||
style: PropTypes.object,
|
||||
|
|
|
@ -11,6 +11,7 @@ import actions from '../../../../ui/app/actions'
|
|||
import abiEncoder from 'web3-eth-abi'
|
||||
import Web3 from 'web3'
|
||||
import copyToClipboard from 'copy-to-clipboard'
|
||||
import CopyButton from '../copyButton'
|
||||
|
||||
class SendTransactionField extends Component {
|
||||
constructor (props) {
|
||||
|
@ -221,10 +222,12 @@ class SendTransactionScreen extends PersistentForm {
|
|||
style={{ marginTop: '10px' }}
|
||||
>
|
||||
{params.name || `${paramName} ${ind + 1}`}
|
||||
{!isInput ? <i
|
||||
className="clipboard cursor-pointer"
|
||||
style={{ marginLeft: '10px' }}
|
||||
onClick={(e) => { copyToClipboard(defaultValue) }}
|
||||
{!isInput ? <CopyButton
|
||||
value={defaultValue}
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
marginLeft: '5px',
|
||||
}}
|
||||
/> : null}
|
||||
</h3>
|
||||
)
|
||||
|
|
|
@ -134,15 +134,18 @@ TokenList.prototype.renderTokenStatusBar = function () {
|
|||
const tokensFromCurrentNetwork = tokens.filter(token => (parseInt(token.network) === parseInt(network) || !token.network))
|
||||
|
||||
let msg
|
||||
let noTokens = false
|
||||
if (tokensFromCurrentNetwork.length === 1) {
|
||||
msg = `You own 1 token`
|
||||
} else if (tokensFromCurrentNetwork.length > 1) {
|
||||
msg = `You own ${tokensFromCurrentNetwork.length} tokens`
|
||||
} else {
|
||||
msg = `No tokens found`
|
||||
noTokens = true
|
||||
}
|
||||
|
||||
return h('div', {
|
||||
return h('div', [
|
||||
h('div', {
|
||||
style: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
|
@ -166,6 +169,12 @@ TokenList.prototype.renderTokenStatusBar = function () {
|
|||
}, [
|
||||
'Add Token',
|
||||
]),
|
||||
]),
|
||||
noTokens ? h('div', {
|
||||
style: {
|
||||
height: '70px',
|
||||
},
|
||||
}) : null,
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ TransactionList.prototype.render = function () {
|
|||
}, [
|
||||
h('p', {
|
||||
style: {
|
||||
marginTop: '50px',
|
||||
margin: '50px 0',
|
||||
},
|
||||
}, 'No transaction history.'),
|
||||
]),
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
.accs-dd-menu-item-selected {
|
||||
width: 4px;
|
||||
height: 26px;
|
||||
background: #60db97;
|
||||
position: absolute;
|
||||
left: -25px;
|
||||
}
|
||||
.accs-dd-menu-item-account-name {
|
||||
margin-left: 10px;
|
||||
font-size: 16px;
|
||||
max-width: 95px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.acc-dd-menu-item-text {
|
||||
font-size: 16px;
|
||||
margin-bottom: 5px;
|
||||
color: #60db97;
|
||||
}
|
||||
.accounts-selector-additional-style {
|
||||
background: url(images/switch_acc.svg) white center center no-repeat;
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
margin-right: 3px;
|
||||
}
|
|
@ -44,6 +44,7 @@ module.exports = {
|
|||
getCurrentKeyring,
|
||||
ifLooseAcc,
|
||||
ifContractAcc,
|
||||
ifHardwareAcc,
|
||||
}
|
||||
|
||||
function valuesFor (obj) {
|
||||
|
@ -326,6 +327,7 @@ function ifLooseAcc (keyring) {
|
|||
} catch (e) { return }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checks, if keyring is contract
|
||||
*
|
||||
|
@ -340,3 +342,17 @@ function ifContractAcc (keyring) {
|
|||
return isContract
|
||||
} catch (e) { return }
|
||||
}
|
||||
|
||||
/**
|
||||
* checks, if keyring is of hardware type
|
||||
*
|
||||
* @param {object} keyring
|
||||
*
|
||||
* returns {boolean} true, if keyring is of hardware type and false, if it is not
|
||||
**/
|
||||
function ifHardwareAcc (keyring) {
|
||||
if (keyring && keyring.type.search('Hardware') !== -1) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ var cssFiles = {
|
|||
'first-time.css': fs.readFileSync(path.join(__dirname, '../mascara/src/app/first-time/index.css'), 'utf8'),
|
||||
'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'),
|
||||
'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'),
|
||||
'dropdowns.css': fs.readFileSync(path.join(__dirname, '/app/css/dropdowns.css'), 'utf8'),
|
||||
}
|
||||
|
||||
function bundleCss () {
|
||||
|
|
|
@ -10444,7 +10444,7 @@
|
|||
}
|
||||
},
|
||||
"eth-keychain-controller": {
|
||||
"version": "github:vbaranov/KeyringController#52961c8fac58177c9b39ec7754de3ecda90e8a08",
|
||||
"version": "github:vbaranov/KeyringController#b4527590d38a9421962343f7ea56518df775456d",
|
||||
"from": "github:vbaranov/KeyringController#simple-address",
|
||||
"requires": {
|
||||
"bip39": "^2.4.0",
|
||||
|
@ -10461,7 +10461,7 @@
|
|||
"dependencies": {
|
||||
"babelify": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
|
||||
"integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
|
||||
"requires": {
|
||||
"babel-core": "^6.0.14",
|
||||
|
@ -10473,22 +10473,12 @@
|
|||
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
|
||||
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
|
||||
"requires": {
|
||||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
|
||||
"ethereumjs-util": "^5.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereumjs-abi": {
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
|
||||
"requires": {
|
||||
"bn.js": "^4.10.0",
|
||||
"ethereumjs-util": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ethereumjs-abi": {
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
|
||||
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
|
||||
"requires": {
|
||||
"bn.js": "^4.10.0",
|
||||
|
@ -16158,7 +16148,7 @@
|
|||
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
|
||||
"ethereumjs-util": "^5.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -16180,7 +16170,7 @@
|
|||
"dev": true
|
||||
},
|
||||
"ethereumjs-abi": {
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
|
||||
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
|
||||
"requires": {
|
||||
"bn.js": "^4.10.0",
|
||||
|
@ -19601,7 +19591,7 @@
|
|||
"integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
|
||||
"ethereumjs-util": "^5.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -19617,7 +19607,7 @@
|
|||
}
|
||||
},
|
||||
"ethereumjs-abi": {
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
|
||||
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215",
|
||||
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
|
||||
"requires": {
|
||||
"bn.js": "^4.10.0",
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
"test:e2e:chrome:beta": "SELENIUM_BROWSER=chrome test/e2e/beta/run-all.sh",
|
||||
"test:e2e:firefox": "shell-parallel -s 'npm run ganache:start' -x 'sleep 3 && npm run test:e2e:run:firefox'",
|
||||
"test:e2e:firefox:beta": "SELENIUM_BROWSER=firefox test/e2e/beta/run-all.sh",
|
||||
"test:e2e:run:chrome": "SELENIUM_BROWSER=chrome mocha test/e2e/metamask.spec --bail --recursive",
|
||||
"test:e2e:run:firefox": "SELENIUM_BROWSER=firefox mocha test/e2e/metamask.spec --bail --recursive",
|
||||
"test:e2e:run:chrome": "SELENIUM_BROWSER=chrome mocha test/e2e/nw.spec --bail --recursive",
|
||||
"test:e2e:run:firefox": "SELENIUM_BROWSER=firefox mocha test/e2e/nw.spec --bail --recursive",
|
||||
"test:screens": "shell-parallel -s 'npm run ganache:start' -x 'sleep 3 && npm run test:screens:run'",
|
||||
"test:screens:run": "node test/screens/new-ui.js",
|
||||
"test:coverage": "nyc --reporter=text --reporter=html npm run test:unit && npm run test:coveralls-upload",
|
||||
|
|
|
@ -252,7 +252,8 @@ module.exports = {
|
|||
error: By.css('span.error'),
|
||||
selectArrow: By.className('Select-arrow-zone'),
|
||||
selectType: By.name('import-type-select'),
|
||||
itemContract: By.id('react-select-3--option-2'),
|
||||
itemContract: By.id('react-select-4--option-2'),
|
||||
itemProxyContract: By.id('react-select-3--option-3'),
|
||||
contractAddress: By.id('address-box'),
|
||||
contractABI: By.id('abi-box'),
|
||||
title: By.css('#app-content > div > div.app-primary.from-right > div > div:nth-child(2) > div.flex-row.flex-center > h2'),
|
||||
|
@ -312,13 +313,14 @@ module.exports = {
|
|||
menu: By.id('wallet-view__tab-tokens'),
|
||||
token: By.className('token-cell'),
|
||||
balance: By.css('#token-cell_0 > h3'),
|
||||
amount: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > span'),
|
||||
amount: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > div:nth-child(1) > span'),
|
||||
textNoTokens: 'No tokens found',
|
||||
textYouOwn1token: 'You own 1 token',
|
||||
buttonAdd: By.css('div.full-flex-height:nth-child(2) > div:nth-child(1) > button:nth-child(2)'),
|
||||
buttonAdd: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > div:nth-child(1) > button'),
|
||||
buttonAdd2: By.css('#app-content > div > div.app-primary.from-right > div > section > div.full-flex-height > div > div:nth-child(1) > button'),
|
||||
buttonAddText: 'Add Token',
|
||||
counter: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > span'),
|
||||
counterFF: By.css('div.full-flex-height:nth-child(2) > div:nth-child(1) > span:nth-child(1)'),
|
||||
counter: By.css('#app-content > div > div.app-primary.from-left > div > section > div.full-flex-height > div > div:nth-child(1) > span'),
|
||||
counterFF: By.css('div.full-flex-height:nth-child(2) > div:nth-child(1) > div:nth-child(1) > span:nth-child(1)'),
|
||||
},
|
||||
},
|
||||
buyEther: {
|
||||
|
|
|
@ -239,7 +239,8 @@ class Functions {
|
|||
try {
|
||||
const tab = await this.waitUntilShowUp(screens.main.tokens.menu)
|
||||
await this.click(tab)
|
||||
const button = await this.waitUntilShowUp(screens.main.tokens.buttonAdd, 300)
|
||||
await this.delay(1000)
|
||||
const button = await this.waitUntilShowUp(screens.main.tokens.buttonAdd2, 300)
|
||||
await this.click(button)
|
||||
let count = 20
|
||||
do {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,144 @@
|
|||
const path = require('path')
|
||||
const Func = require('./func').Functions
|
||||
const account1 = '0x2E428ABd9313D256d64D1f69fe3929C3BE18fD1f'
|
||||
const account2 = '0xd7b7AFeCa35e32594e29504771aC847E2a803742'
|
||||
const testsFolder = './test-cases'
|
||||
const setup = require(`${testsFolder}/setup.spec`)
|
||||
const login = require(`${testsFolder}/login.spec`)
|
||||
const { accountCreation, getCreatedAccounts } = require(`${testsFolder}/account-creation.spec`)
|
||||
const connectHDWallet = require(`${testsFolder}/connect-hd-wallet.spec`)
|
||||
const importAccount = require(`${testsFolder}/import-account.spec`)
|
||||
const importContractAccount = require(`${testsFolder}/import-contract-account.spec`)
|
||||
const deleteImportedAccount = require(`${testsFolder}/delete-imported-account.spec`)
|
||||
const signData = require(`${testsFolder}/sign-data.spec`)
|
||||
const exportPrivateKey = require(`${testsFolder}/export-private-key.spec`)
|
||||
const importGanacheSeedPhrase = require(`${testsFolder}/import-ganache-seed-phrase.spec`)
|
||||
const RSKNetworkTests = require(`${testsFolder}/RSK-network-tests.js`)
|
||||
const checkEmittedEvents = require(`${testsFolder}/check-emitted-events.spec`)
|
||||
const addCustomToken = require(`${testsFolder}/add-token-custom.spec`)
|
||||
const changePassword = require(`${testsFolder}/change-password.spec`)
|
||||
const addTokeFromSearch = require(`${testsFolder}/add-token-search.spec`)
|
||||
const customRPC = require(`${testsFolder}/custom-rpc.spec`)
|
||||
|
||||
describe('Metamask popup page', async function () {
|
||||
|
||||
this.timeout(15 * 60 * 1000)
|
||||
const f = new Func()
|
||||
let driver, extensionId
|
||||
const password = '123456789'
|
||||
const newPassword = {
|
||||
correct: 'abcDEF123!@#',
|
||||
short: '123',
|
||||
incorrect: '1234567890',
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
if (process.env.SELENIUM_BROWSER === 'chrome') {
|
||||
const extPath = path.resolve('dist/chrome')
|
||||
driver = await Func.buildChromeWebDriver(extPath)
|
||||
f.driver = driver
|
||||
extensionId = await f.getExtensionIdChrome()
|
||||
f.extensionId = extensionId
|
||||
await driver.get(`chrome-extension://${extensionId}/popup.html`)
|
||||
|
||||
} else if (process.env.SELENIUM_BROWSER === 'firefox') {
|
||||
const extPath = path.resolve('dist/firefox')
|
||||
driver = await Func.buildFirefoxWebdriver()
|
||||
f.driver = driver
|
||||
await f.installWebExt(extPath)
|
||||
await f.delay(700)
|
||||
extensionId = await f.getExtensionIdFirefox()
|
||||
f.extensionId = extensionId
|
||||
await driver.get(`moz-extension://${extensionId}/popup.html`)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
// logs command not supported in firefox
|
||||
// https://github.com/SeleniumHQ/selenium/issues/2910
|
||||
if (process.env.SELENIUM_BROWSER === 'chrome') {
|
||||
// check for console errors
|
||||
const errors = await f.checkBrowserForConsoleErrors(driver)
|
||||
if (errors.length) {
|
||||
const errorReports = errors.map(err => err.message)
|
||||
const errorMessage = `Errors found in browser console:\n${errorReports.join('\n')}`
|
||||
console.log(errorMessage)
|
||||
}
|
||||
}
|
||||
// gather extra data if test failed
|
||||
if (this.currentTest.state === 'failed') {
|
||||
await f.verboseReportOnFailure(this.currentTest)
|
||||
}
|
||||
})
|
||||
|
||||
after(async function () {
|
||||
await driver.quit()
|
||||
})
|
||||
|
||||
describe('Setup', async () => {
|
||||
await setup(f)
|
||||
})
|
||||
|
||||
describe('Log In', async () => {
|
||||
await login(f, password)
|
||||
})
|
||||
|
||||
describe('Account Creation', async () => {
|
||||
await accountCreation(f, password)
|
||||
})
|
||||
|
||||
describe('Connect Hardware Wallet', async () => {
|
||||
await connectHDWallet(f)
|
||||
})
|
||||
|
||||
describe('Import Account', async () => {
|
||||
await importAccount(f)
|
||||
})
|
||||
|
||||
describe('Import Contract account', async () => {
|
||||
await importContractAccount(f, account1, getCreatedAccounts)
|
||||
})
|
||||
|
||||
describe('Delete Imported Account', async () => {
|
||||
await deleteImportedAccount(f)
|
||||
})
|
||||
|
||||
describe('Sign Data', async () => {
|
||||
await signData(f)
|
||||
})
|
||||
|
||||
describe('Export private key', async () => {
|
||||
await exportPrivateKey(f, password)
|
||||
})
|
||||
|
||||
describe('Import Ganache seed phrase', async () => {
|
||||
await importGanacheSeedPhrase(f, account2, password)
|
||||
})
|
||||
|
||||
describe('RSK network tests', async () => {
|
||||
await RSKNetworkTests(f, account1)
|
||||
})
|
||||
|
||||
describe('Check the filter of emitted events', async () => {
|
||||
await checkEmittedEvents(f, account1, account2)
|
||||
})
|
||||
|
||||
describe('Add Token: Custom', async () => {
|
||||
await addCustomToken(f, account1, account2)
|
||||
})
|
||||
|
||||
describe('Change password', async () => {
|
||||
await changePassword(f, password, newPassword)
|
||||
})
|
||||
|
||||
describe('Add Token:Search', async () => {
|
||||
await addTokeFromSearch(f)
|
||||
})
|
||||
|
||||
describe('Custom Rpc', async () => {
|
||||
await customRPC(f)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
const assert = require('assert')
|
||||
const { screens, elements, NETWORKS } = require('../elements')
|
||||
|
||||
const RSKNetworkTests = async (f, account1) => {
|
||||
it('connects to RSK mainnet', async function () {
|
||||
await f.setProvider(NETWORKS.RSK)
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('connects to RSK testnet', async function () {
|
||||
await f.setProvider(NETWORKS.RSK_TESTNET)
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('checks zero exchange rate for RSK testnet', async function () {
|
||||
const balanceField = await f.waitUntilShowUp(screens.main.balance)
|
||||
const balanceUSDField = await f.waitUntilShowUp(screens.main.balanceUSD)
|
||||
await f.delay(2000)
|
||||
const balance = await balanceField.getText()
|
||||
const balanceUSD = await balanceUSDField.getText()
|
||||
console.log('Balance = ' + parseFloat(balance))
|
||||
console.log('balanceUSD = ' + parseFloat(balanceUSD))
|
||||
assert.equal(parseFloat(balance) > 0.0001, true, 'Balance of account ' + account1 + ' is TOO LOW in RSK testnet !!! Please refill it!!!!')
|
||||
assert.equal(parseFloat(balanceUSD), 0, 'USD balance of account is not zero')
|
||||
})
|
||||
|
||||
it('opens RSK faucet', async function () {
|
||||
await f.waitUntilShowUp(screens.main.buttons.buyRSK)
|
||||
const buttons = await f.driver.findElements(screens.main.buttons.buyRSK)
|
||||
assert.equal(buttons.length, 1, 'main screen isn\'t displayed')
|
||||
const buyButton = buttons[0]
|
||||
const buyButtonText = await buyButton.getText()
|
||||
assert.equal(buyButtonText, 'Buy', 'button has incorrect name')
|
||||
await buyButton.click()
|
||||
await f.delay(2000)
|
||||
const title = await f.waitUntilShowUp(screens.buyEther.title)
|
||||
assert.equal(await title.getText(), 'Buy RBTC', "screen 'Buy RBTC' has incorrect title text")
|
||||
await f.waitUntilShowUp(screens.buyEther.faucetLinkRSK)
|
||||
const faucetButtons = await f.driver.findElements(screens.buyEther.faucetLinkRSK)
|
||||
assert.equal(faucetButtons.length, 1, 'there is no faucet button on the screen')
|
||||
const faucetLinkButton = faucetButtons[0]
|
||||
assert.equal(await faucetLinkButton.getText(), 'RSK Testnet Test Faucet', "screen 'Buy RSK' has incorrect name for faucet link")
|
||||
await faucetLinkButton.click()
|
||||
await f.delay(3000)
|
||||
const [tab0, tab1] = await f.driver.getAllWindowHandles()
|
||||
await f.driver.switchTo().window(tab1)
|
||||
const faucetLink = await f.driver.getCurrentUrl()
|
||||
assert.equal(faucetLink, 'https://faucet.testnet.rsk.co/', 'Incorrect faucet link for RSK network')
|
||||
await f.driver.close()
|
||||
await f.driver.switchTo().window(tab0)
|
||||
const arrow = await f.waitUntilShowUp(elements.buttonArrow)
|
||||
await arrow.click()
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('opens send transaction screen', async function () {
|
||||
const sendButton = await f.waitUntilShowUp(screens.main.buttons.sendRSK)
|
||||
assert.equal(await sendButton.getText(), screens.main.buttons.sendText)
|
||||
await f.click(sendButton)
|
||||
})
|
||||
|
||||
it('adds recipient address and amount', async function () {
|
||||
const sendTranscationScreen = await f.waitUntilShowUp(screens.sendTransaction.title)
|
||||
assert.equal(await sendTranscationScreen.getText(), screens.sendTransaction.titleText, 'Transaction screen has incorrect titlr')
|
||||
const inputAddress = await f.waitUntilShowUp(screens.sendTransaction.field.address)
|
||||
const inputAmmount = await f.waitUntilShowUp(screens.sendTransaction.field.amount)
|
||||
await inputAddress.sendKeys(account1)
|
||||
await f.clearField(inputAmmount)
|
||||
await inputAmmount.sendKeys('0.000001')
|
||||
const button = await f.waitUntilShowUp(screens.sendTransaction.buttonNext)
|
||||
assert.equal(await button.getText(), 'Next', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('confirms transaction', async function () {
|
||||
const inputGasLimit = await f.waitUntilShowUp(screens.confirmTransaction.fields.gasLimit)
|
||||
await f.clearField(inputGasLimit)
|
||||
await inputGasLimit.sendKeys('31500')
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.submit)
|
||||
assert.equal(await button.getAttribute('value'), 'Submit', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('finds the transaction in the transactions list', async function () {
|
||||
const transactionAmount = await f.waitUntilShowUp(screens.main.transactionList)
|
||||
assert.equal(await transactionAmount.getText(), '<0.001')
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = RSKNetworkTests
|
|
@ -0,0 +1,150 @@
|
|||
const assert = require('assert')
|
||||
const { menus, screens, NETWORKS } = require('../elements')
|
||||
const clipboardy = require('clipboardy')
|
||||
const createdAccounts = []
|
||||
|
||||
const accountCreation = async (f, password) => {
|
||||
const newAccountName = 'new name'
|
||||
|
||||
it('sets provider type to localhost', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('copy icon is displayed and clickable', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.main.iconCopy)
|
||||
await field.click()
|
||||
assert.notEqual(field, false, 'copy icon doesn\'t present')
|
||||
})
|
||||
|
||||
it("Account's address is displayed and has length 20 symbols", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.main.address)
|
||||
createdAccounts.push((await field.getText()).toUpperCase())
|
||||
console.log(createdAccounts[0])
|
||||
assert.notEqual(createdAccounts[0].length, 20, "address isn't displayed")
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.length, 42, "address account wasn't copied to clipboard")
|
||||
})
|
||||
|
||||
it('open \'Account name\' change dialog', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.dot.menu)
|
||||
await menu.click()
|
||||
const field = await f.waitUntilShowUp(screens.main.edit)
|
||||
await field.click()
|
||||
const accountName = await f.waitUntilShowUp(screens.main.fieldAccountName)
|
||||
assert.notEqual(accountName, false, '\'Account name\' change dialog isn\'t opened')
|
||||
assert.equal(await accountName.getAttribute('value'), 'Account 1', 'incorrect account name')
|
||||
})
|
||||
|
||||
it('fill out new account\'s name', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.main.fieldAccountName)
|
||||
await field.clear()
|
||||
await field.sendKeys(newAccountName)
|
||||
})
|
||||
|
||||
it('dialog \'Account name\' is disappeared if click button \'Save\'', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.main.buttons.save)
|
||||
assert.equal(await button.getText(), 'Save', 'button has incorrect name')
|
||||
assert.notEqual(button, true, 'button \'Save\' does not present')
|
||||
await f.click(button)
|
||||
const accountName = await f.waitUntilShowUp(screens.main.fieldAccountName, 10)
|
||||
assert.equal(accountName, false, '\'Account name\' change dialog isn\'t opened')
|
||||
})
|
||||
|
||||
it('account has new name', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const account1 = await f.waitUntilShowUp(menus.account.account1)
|
||||
assert.equal(await account1.getText(), newAccountName, 'account\'s name didn\'t changed')
|
||||
await accountMenu.click()
|
||||
})
|
||||
|
||||
it('adds a second account', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.createAccount)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it("Account's address is displayed and has length 20 symbols", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.main.address)
|
||||
createdAccounts.push((await field.getText()).toUpperCase())
|
||||
console.log(createdAccounts[1])
|
||||
assert.notEqual(createdAccounts[1].length, 20, "address isn't displayed")
|
||||
})
|
||||
|
||||
it('logs out of the vault', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.sandwich.menu)
|
||||
await menu.click()
|
||||
await f.delay(500)
|
||||
const button = await f.waitUntilShowUp(menus.sandwich.logOut)
|
||||
assert.equal(await button.getText(), 'Log Out', 'button has incorrect name')
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('accepts account password after lock', async () => {
|
||||
const box = await f.waitUntilShowUp(screens.lock.fieldPassword)
|
||||
await box.sendKeys(password)
|
||||
const button = await f.waitUntilShowUp(screens.lock.buttonLogin)
|
||||
assert.equal(await button.getText(), 'Log In', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('shows QR code option', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.dot.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.dot.showQRcode)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it('checks QR code address is the same as account details address', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.QRcode.address)
|
||||
const text = await field.getText()
|
||||
assert.equal(text.toUpperCase(), createdAccounts[1], 'QR address doesn\'t match')
|
||||
})
|
||||
|
||||
it('copy icon is displayed and clickable', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.QRcode.iconCopy)
|
||||
await field.click()
|
||||
assert.notEqual(field, false, 'copy icon doesn\'t present')
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.length, 42, "address account wasn't copied to clipboard")
|
||||
})
|
||||
|
||||
it('close QR code screen by clicking button arrow', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.QRcode.buttonArrow)
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('user is able to open \'Info\' screen', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.sandwich.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.sandwich.info)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it('screen \'Info\' has correct title', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.info.title)
|
||||
assert.equal(await title.getText(), screens.info.titleText, 'title is incorrect')
|
||||
})
|
||||
|
||||
it('close \'Info\' screen by clicking button arrow', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.info.buttonArrow)
|
||||
await button.click()
|
||||
})
|
||||
}
|
||||
|
||||
const getCreatedAccounts = () => {
|
||||
return createdAccounts
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
accountCreation,
|
||||
getCreatedAccounts,
|
||||
}
|
|
@ -0,0 +1,524 @@
|
|||
const assert = require('assert')
|
||||
const { screens, menus, NETWORKS } = require('../elements')
|
||||
const token = { supply: 101, name: 'Test', decimals: 0, ticker: 'ABC' }
|
||||
let tokenAddress
|
||||
|
||||
const addCustomToken = async (f, account1, account2) => {
|
||||
describe('Add token to LOCALHOST', function () {
|
||||
|
||||
it('Create custom token in LOCALHOST', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
tokenAddress = await f.createToken(account1, token, true)
|
||||
console.log('Token contract address: ' + tokenAddress)
|
||||
assert.equal(tokenAddress.length, 42, 'failed to create token')
|
||||
})
|
||||
|
||||
it('navigates to the add token screen', async () => {
|
||||
await f.waitUntilShowUp(screens.main.identicon)
|
||||
const tab = await f.waitUntilShowUp(screens.main.tokens.menu)
|
||||
await tab.click()
|
||||
const addTokenButton = await f.waitUntilShowUp(screens.main.tokens.buttonAdd2)
|
||||
assert.equal(await addTokenButton.getText(), screens.main.tokens.buttonAddText)
|
||||
await f.click(addTokenButton)
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('checks add token screen has correct title', async () => {
|
||||
const addTokenScreen = await f.waitUntilShowUp(screens.addToken.title)
|
||||
assert.equal(await addTokenScreen.getText(), screens.addToken.titleText)
|
||||
})
|
||||
|
||||
it('adds token parameters', async () => {
|
||||
const tab = await f.waitUntilShowUp(screens.addToken.tab.custom, 30)
|
||||
if (!await f.waitUntilShowUp(screens.addToken.custom.fields.contractAddress)) await tab.click()
|
||||
})
|
||||
|
||||
it('address input is displayed and has correct placeholder', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.custom.fields.contractAddress)
|
||||
assert.equal(await field.getAttribute('placeholder'), 'Token Contract Address', 'incorrect placeholder')
|
||||
})
|
||||
|
||||
it('fill out address input', async () => {
|
||||
const tokenContractAddress = await f.waitUntilShowUp(screens.addToken.custom.fields.contractAddress)
|
||||
await tokenContractAddress.sendKeys(tokenAddress)
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('field \'Symbol\' enabled and has correct value', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.custom.fields.tokenSymbol)
|
||||
assert.equal(await field.isEnabled(), true, 'field disabled')
|
||||
assert.equal(await field.getAttribute('placeholder'), 'Like "ETH"', 'incorrect placeholder')
|
||||
assert.equal(await field.getAttribute('value'), token.ticker, 'incorrect value')
|
||||
})
|
||||
|
||||
it('field \'Decimals\' enabled and has correct value', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.custom.fields.decimals)
|
||||
assert.equal(await field.isEnabled(), false, 'field disabled')
|
||||
assert.equal(await field.getAttribute('value'), token.decimals, 'incorrect value')
|
||||
})
|
||||
|
||||
it('checks the token balance', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.custom.buttons.add)
|
||||
await f.click(button)
|
||||
await f.delay(2000)
|
||||
const tokenBalance = await f.waitUntilShowUp(screens.main.tokens.balance)
|
||||
assert.equal(await tokenBalance.getText(), token.supply + ' ' + token.ticker, 'balance is incorrect or not displayed')
|
||||
})
|
||||
|
||||
it('click to token opens the etherscan', async () => {
|
||||
const link = await f.waitUntilShowUp(screens.main.tokens.token)
|
||||
await link.click()
|
||||
await f.delay(2000)
|
||||
const allHandles = await f.driver.getAllWindowHandles()
|
||||
console.log('allHandles.length ' + allHandles.length)
|
||||
assert.equal(allHandles.length, 2, 'etherscan wasn\'t opened')
|
||||
await f.switchToLastPage()
|
||||
await f.delay(2000)
|
||||
const title = await f.waitUntilCurrentUrl()
|
||||
console.log(title)
|
||||
assert.equal(title.includes('https://etherscan.io/token/'), true, 'etherscan wasn\'t opened')
|
||||
await f.switchToFirstPage()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Token menu', function () {
|
||||
|
||||
it('token menu is displayed and clickable ', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
})
|
||||
|
||||
it('link \'View on blockexplorer...\' leads to correct page ', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.token.view)
|
||||
assert.notEqual(menu, false, 'item isn\'t displayed')
|
||||
assert.equal(await menu.getText(), menus.token.viewText, 'incorrect name')
|
||||
await menu.click()
|
||||
await f.delay(2000)
|
||||
const allHandles = await f.driver.getAllWindowHandles()
|
||||
console.log('allHandles.length ' + allHandles.length)
|
||||
assert.equal(allHandles.length, 3, 'etherscan wasn\'t opened')
|
||||
await f.switchToLastPage()
|
||||
const title = await f.waitUntilCurrentUrl()
|
||||
|
||||
console.log(title)
|
||||
assert.equal(title.includes('https://etherscan.io/token/'), true, 'etherscan wasn\'t opened')
|
||||
await f.switchToFirstPage()
|
||||
})
|
||||
|
||||
it('item \'Copy\' is displayed and clickable ', async () => {
|
||||
let menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.token.copy)
|
||||
assert.notEqual(item, false, 'item isn\'t displayed')
|
||||
assert.equal(await item.getText(), menus.token.copyText, 'incorrect name')
|
||||
await item.click()
|
||||
menu = await f.waitUntilShowUp(menus.token.menu, 10)
|
||||
assert.notEqual(menu, false, 'menu wasn\'t closed')
|
||||
})
|
||||
|
||||
it('item \'Remove\' is displayed', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.token.remove)
|
||||
assert.notEqual(item, false, 'item isn\'t displayed')
|
||||
assert.equal(await item.getText(), menus.token.removeText, 'incorrect name')
|
||||
})
|
||||
|
||||
it('item \'Send \' is displayed', async () => {
|
||||
const item = await f.waitUntilShowUp(menus.token.send)
|
||||
assert.notEqual(item, false, 'item isn\'t displayed')
|
||||
assert.equal(await item.getText(), menus.token.sendText, 'incorrect name')
|
||||
await f.waitUntilShowUp(menus.token.menu)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check support of token per network basis ', async () => {
|
||||
const inexistentToken = '0xB8c77482e45F1F44dE1745F52C74426C631bDD51'
|
||||
describe('Token should be displayed only for network, where it was added ', async () => {
|
||||
|
||||
it('token should not be displayed in POA network', async () => {
|
||||
await f.setProvider(NETWORKS.POA)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in SOKOL testnet', async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in MAINNET', async () => {
|
||||
await f.setProvider(NETWORKS.MAINNET)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in ROPSTEN testnet', async () => {
|
||||
await f.setProvider(NETWORKS.ROPSTEN)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in KOVAN testnet', async () => {
|
||||
await f.setProvider(NETWORKS.KOVAN)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in RINKEBY testnet', async () => {
|
||||
await f.setProvider(NETWORKS.RINKEBY)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in RSK network', async () => {
|
||||
await f.setProvider(NETWORKS.RSK)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in RSK testnet', async () => {
|
||||
await f.setProvider(NETWORKS.RSK_TESTNET)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
})
|
||||
|
||||
describe.skip('Custom tokens validation ', async () => {
|
||||
|
||||
it('can not add inexistent token to POA network', async () => {
|
||||
await f.setProvider(NETWORKS.POA)
|
||||
console.log(tokenAddress)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in POA network')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to SOKOL testnet', async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
assert(await f.isDisabledAddInexistentToken(inexistentToken), true, 'can add inexistent token in SOKOL testnet')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to ROPSTEN testnet', async () => {
|
||||
await f.setProvider(NETWORKS.ROPSTEN)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in ROPSTEN testnet')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to KOVAN testnet', async () => {
|
||||
await f.setProvider(NETWORKS.KOVAN)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in KOVAN testnet')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to RINKEBY testnet', async () => {
|
||||
await f.setProvider(NETWORKS.RINKEBY)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in RINKEBY testnet')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to MAINNET', async () => {
|
||||
await f.setProvider(NETWORKS.MAINNET)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in MAINNET')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to RSK mainnet', async () => {
|
||||
await f.setProvider(NETWORKS.RSK)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in RSK mainnet')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to RSK testnet', async () => {
|
||||
await f.setProvider(NETWORKS.RSK_TESTNET)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress), true, 'can add inexistent token in RSK testnet')
|
||||
})
|
||||
|
||||
it('can not add inexistent token to LOCALHOST network', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
assert(await f.isDisabledAddInexistentToken(tokenAddress.slice(0, tokenAddress.length - 2) + '0'), true, 'can add inexistent token in LOCALHOST network')
|
||||
})
|
||||
|
||||
it('token still should be displayed in LOCALHOST network', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
await f.waitUntilDisappear(screens.main.tokens.amount)
|
||||
assert.notEqual(await f.waitUntilShowUp(screens.main.tokens.amount), false, 'App is frozen')
|
||||
const tokens = await f.driver.findElements(screens.main.tokens.amount)
|
||||
assert.equal(tokens.length, 1, '\'Tokens\' section doesn\'t contain field with amount of tokens')
|
||||
assert.equal(await tokens[0].getText(), screens.main.tokens.textYouOwn1token, 'Token isn\'t displayed')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Transfer tokens', function () {
|
||||
|
||||
const invalidAddress = '0xkqjefwblknnecwe'
|
||||
const invalidAmount = 'eeeee'
|
||||
const largeAmount = '123'
|
||||
const preciseAmount = '0.123456789123456789123'
|
||||
const negativeAmount = '-1'
|
||||
|
||||
it('switch to account 1 ', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.account1)
|
||||
await item.click()
|
||||
await f.delay(2000)
|
||||
const accountName = await f.waitUntilShowUp(screens.main.accountName)
|
||||
assert.equal(await accountName.getText(), 'Account 1', 'account name incorrect')
|
||||
})
|
||||
|
||||
it('open screen \'Transfer tokens\' ', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.token.send)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it('field \'Amount\' is displayed and has correct placeholder ', async () => {
|
||||
const item = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
assert.equal(await item.getAttribute('placeholder'), screens.sendTokens.field.amountPlaceholder, 'placeholder is incorrect')
|
||||
})
|
||||
|
||||
it('field \'Address\' is displayed and has correct placeholder ', async () => {
|
||||
const item = await f.waitUntilShowUp(screens.sendTokens.field.address)
|
||||
assert.equal(await item.getAttribute('placeholder'), screens.sendTokens.field.addressPlaceholder, 'placeholder is incorrect')
|
||||
})
|
||||
|
||||
it('token\'s balance is correct ', async () => {
|
||||
const item = await f.waitUntilShowUp(screens.sendTokens.balance)
|
||||
assert.equal(await item.getText(), token.supply, 'token\'s balance is incorrect')
|
||||
})
|
||||
|
||||
it('token\'s symbol is correct ', async () => {
|
||||
const item = await f.waitUntilShowUp(screens.sendTokens.symbol)
|
||||
assert.equal(await item.getText(), token.ticker, 'token\'s symbol is incorrect')
|
||||
})
|
||||
|
||||
it('error message if invalid token\'s amount', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
assert.equal(await button.getText(), 'Next', 'button \'Next\' has incorrect name')
|
||||
await f.click(button)
|
||||
const error = await f.waitUntilShowUp(screens.sendTokens.error)
|
||||
assert.equal(await error.getText(), screens.sendTokens.errorText.invalidAmount, ' error message is incorrect')
|
||||
})
|
||||
|
||||
it('error message if invalid address', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
await amount.sendKeys('1')
|
||||
const address = await f.waitUntilShowUp(screens.sendTokens.field.address)
|
||||
await address.sendKeys(invalidAddress)
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
await f.click(button)
|
||||
await f.click(button)
|
||||
await f.delay(2000)
|
||||
const error = await f.waitUntilShowUp(screens.sendTokens.error)
|
||||
assert.equal(await error.getText(), screens.sendTokens.errorText.address, ' error message is incorrect')
|
||||
})
|
||||
|
||||
it('error message if amount is large', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
await amount.sendKeys(largeAmount)
|
||||
const address = await f.waitUntilShowUp(screens.sendTokens.field.address)
|
||||
await f.clearField(address)
|
||||
await address.sendKeys(account2)
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
await f.click(button)
|
||||
await f.click(button)
|
||||
await f.delay(2000)
|
||||
const error = await f.waitUntilShowUp(screens.sendTokens.error)
|
||||
assert.equal(await error.getText(), screens.sendTokens.errorText.largeAmount, ' error message is incorrect')
|
||||
})
|
||||
|
||||
it('error message if amount is invalid', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
await f.clearField(amount)
|
||||
await amount.sendKeys(invalidAmount)
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
await f.click(button)
|
||||
await f.click(button)
|
||||
await f.delay(2000)
|
||||
const error = await f.waitUntilShowUp(screens.sendTokens.error)
|
||||
assert.equal(await error.getText(), screens.sendTokens.errorText.invalidAmount, ' error message is incorrect')
|
||||
})
|
||||
|
||||
it.skip('error message if amount is too precise', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
await f.clearField(amount)
|
||||
await amount.sendKeys(preciseAmount)
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
await f.click(button)
|
||||
await f.click(button)
|
||||
await f.delay(2000)
|
||||
const error = await f.waitUntilShowUp(screens.sendTokens.error)
|
||||
assert.equal(await error.getText(), screens.sendTokens.errorText.tooPrecise, ' error message is incorrect')
|
||||
})
|
||||
|
||||
it('error message if amount is negative', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
await f.clearField(amount)
|
||||
await amount.sendKeys(negativeAmount)
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
await f.click(button)
|
||||
await f.click(button)
|
||||
await f.delay(2000)
|
||||
const error = await f.waitUntilShowUp(screens.sendTokens.error)
|
||||
assert.equal(await error.getText(), screens.sendTokens.errorText.negativeAmount, ' error message is incorrect')
|
||||
})
|
||||
|
||||
it('\'Confirm transaction\' screen is opened if address and amount are correct', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.sendTokens.field.amount)
|
||||
await f.clearField(amount)
|
||||
await amount.sendKeys('5')
|
||||
const button = await f.waitUntilShowUp(screens.sendTokens.button.next)
|
||||
await f.click(button)
|
||||
|
||||
const buttonSubmit = await f.waitUntilShowUp(screens.confirmTransaction.button.submit)
|
||||
assert.notEqual(buttonSubmit, false, 'incorrect screen was opened')
|
||||
})
|
||||
|
||||
it('\'Confirm transaction\' screen: token\'s amount is correct', async () => {
|
||||
const amount = await f.waitUntilShowUp(screens.confirmTransaction.amount)
|
||||
assert.equal(await amount.getText(), '5.000', ' amount is incorrect')
|
||||
})
|
||||
|
||||
it('\'Confirm transaction\' screen: token\'s symbol is correct', async () => {
|
||||
const symbol = await f.waitUntilShowUp(screens.confirmTransaction.symbol)
|
||||
assert.equal(await symbol.getText(), token.ticker, ' symbol is incorrect')
|
||||
})
|
||||
|
||||
it('submit transaction', async () => {
|
||||
await f.driver.navigate().refresh()
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.submit)
|
||||
await f.click(button)
|
||||
const list = await f.waitUntilShowUp(screens.main.transactionList)
|
||||
assert.notEqual(list, false, ' main screen isn\'t opened')
|
||||
})
|
||||
|
||||
it('correct amount substracted from sender\'s tokens balance', async () => {
|
||||
const tab = await f.waitUntilShowUp(screens.main.tokens.menu)
|
||||
await tab.click()
|
||||
await f.driver.navigate().refresh()
|
||||
await f.delay(5000)
|
||||
await f.driver.navigate().refresh()
|
||||
await f.delay(5000)
|
||||
await f.driver.navigate().refresh()
|
||||
await f.delay(5000)
|
||||
const balance = await f.waitUntilShowUp(screens.main.tokens.balance)
|
||||
assert.equal(await balance.getText(), (token.supply - 5) + ' ' + token.ticker, 'balance is incorrect')
|
||||
})
|
||||
|
||||
it('switch to account 2 ', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.account2)
|
||||
await item.click()
|
||||
await f.delay(2000)
|
||||
const accountName = await f.waitUntilShowUp(screens.main.accountName)
|
||||
assert.equal(await accountName.getText(), 'Account 2', 'account name incorrect')
|
||||
})
|
||||
|
||||
it('added token isn\'t displayed for another account in the same network', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.createAccount)
|
||||
await item.click()
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
await f.delay(2000)
|
||||
})
|
||||
|
||||
it('add token to another account in the same network', async () => {
|
||||
const addTokenButton = await f.waitUntilShowUp(screens.main.tokens.buttonAdd)
|
||||
assert.equal(await addTokenButton.getText(), screens.main.tokens.buttonAddText)
|
||||
await f.click(addTokenButton)
|
||||
|
||||
const tokenContractAddress = await f.waitUntilShowUp(screens.addToken.custom.fields.contractAddress)
|
||||
await tokenContractAddress.sendKeys(tokenAddress)
|
||||
|
||||
const buttonAdd = await f.waitUntilShowUp(screens.addToken.custom.buttons.add)
|
||||
await f.click(buttonAdd)
|
||||
})
|
||||
|
||||
it('tokens were transfered, balance is updated', async () => {
|
||||
const balance = await f.waitUntilShowUp(screens.main.tokens.balance)
|
||||
assert.equal(await balance.getText(), '5 ' + token.ticker, 'balance is incorrect')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Remove token, provider is localhost', function () {
|
||||
|
||||
it('switch to account 1 ', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.account1)
|
||||
await item.click()
|
||||
await f.delay(2000)
|
||||
const accountName = await f.waitUntilShowUp(screens.main.accountName)
|
||||
assert.equal(await accountName.getText(), 'Account 1', 'account name incorrect')
|
||||
})
|
||||
|
||||
it('remove option opens \'Remove token\' screen ', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
const menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
const remove = await f.waitUntilShowUp(menus.token.remove)
|
||||
await remove.click()
|
||||
})
|
||||
|
||||
it('screen \'Remove token\' has correct title', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.removeToken.title)
|
||||
assert.equal(await title.getText(), screens.removeToken.titleText, 'title is incorrect')
|
||||
})
|
||||
|
||||
it('screen \'Remove token\' has correct label', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.removeToken.label)
|
||||
assert.equal((await title.getText()).includes(screens.removeToken.labelText + token.ticker), true, 'label is incorrect')
|
||||
})
|
||||
|
||||
it('button "No" bring back to "Main" screen', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.removeToken.title)
|
||||
assert.equal(await title.getText(), screens.removeToken.titleText, 'title is incorrect')
|
||||
const button = await f.waitUntilShowUp(screens.removeToken.buttons.no)
|
||||
assert.notEqual(button, false, 'button \'No\' isn\'t displayed ')
|
||||
assert.equal(await button.getText(), 'No', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const token = await f.waitUntilShowUp(screens.main.tokens.balance)
|
||||
assert.notEqual(await token.getText(), '', 'token is disapeared after return from remove token screen ')
|
||||
})
|
||||
|
||||
it('button "Yes" delete token', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
const remove = await f.waitUntilShowUp(menus.token.remove)
|
||||
await remove.click()
|
||||
|
||||
const title = await f.waitUntilShowUp(screens.removeToken.title)
|
||||
assert.equal(await title.getText(), screens.removeToken.titleText, 'title is incorrect')
|
||||
|
||||
const button = await f.waitUntilShowUp(screens.removeToken.buttons.yes)
|
||||
assert.notEqual(button, false, 'button \'Yes\' isn\'t displayed ')
|
||||
assert.equal(await button.getText(), 'Yes', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('check if token was removed from SOKOL network', async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('check if token was removed from KOVAN network', async () => {
|
||||
await f.setProvider(NETWORKS.KOVAN)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('check if token was removed from ROPSTEN network', async () => {
|
||||
await f.setProvider(NETWORKS.ROPSTEN)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('check if token was removed from MAINNET network', async () => {
|
||||
await f.setProvider(NETWORKS.MAINNET)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('check if token was removed from POA network', async () => {
|
||||
await f.setProvider(NETWORKS.POA)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('check if token was removed from RINKEBY network', async () => {
|
||||
await f.setProvider(NETWORKS.RINKEBY)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = addCustomToken
|
|
@ -0,0 +1,301 @@
|
|||
const assert = require('assert')
|
||||
const { screens, menus, elements, NETWORKS } = require('../elements')
|
||||
|
||||
const addTokeFromSearch = async (f) => {
|
||||
const request = {
|
||||
valid: 'cry',
|
||||
invalid: 'zzz',
|
||||
notExistingAddress: '0xE18035BF8712672935FDB4e5e431b1a0183d2DFC',
|
||||
}
|
||||
const Qtum = {
|
||||
name: 'Qtum (QTUM)',
|
||||
address: '0x9a642d6b3368ddc662CA244bAdf32cDA716005BC',
|
||||
}
|
||||
|
||||
describe('add Mainnet\'s tokens', function () {
|
||||
|
||||
it(' field \'Search\' is displayed', async () => {
|
||||
await f.setProvider(NETWORKS.MAINNET)
|
||||
await f.delay(2000)
|
||||
const tab = await f.waitUntilShowUp(screens.main.tokens.menu)
|
||||
await tab.click()
|
||||
const button = await f.waitUntilShowUp(screens.main.tokens.buttonAdd2, 300)
|
||||
await f.click(button)
|
||||
const field = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
assert.notEqual(field, false, 'field \'Search\' isn\'t displayed')
|
||||
})
|
||||
|
||||
it('button \'Next\' is disabled if no tokens found', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
assert.equal(await button.isEnabled(), false, 'button is enabled')
|
||||
assert.equal(await button.getText(), 'Next', 'button has incorrect name')
|
||||
})
|
||||
|
||||
it('button \'Cancel\' is enabled and lead to main screen ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.cancel)
|
||||
assert.equal(await button.isEnabled(), true, 'button isn\'t enabled')
|
||||
assert.equal(await button.getText(), 'Cancel', 'button has incorrect name')
|
||||
})
|
||||
|
||||
it('Search by name: searching result list is empty if request invalid', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
await field.sendKeys(request.invalid)
|
||||
const list = await f.waitUntilShowUp(screens.addToken.search.token.unselected, 20)
|
||||
assert.equal(list, false, 'unexpected tokens are displayed')
|
||||
})
|
||||
|
||||
it('Search by name: searching result list isn\'t empty ', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
await f.clearField(field)
|
||||
await field.sendKeys(request.valid)
|
||||
await f.waitUntilShowUp(screens.addToken.search.token.unselected)
|
||||
const list = await f.driver.findElements(screens.addToken.search.token.unselected)
|
||||
assert.notEqual(list, 0, 'tokens aren\'t displayed')
|
||||
})
|
||||
|
||||
it('Token\'s info contains name, symbol and picture ', async () => {
|
||||
const tokens = await f.driver.findElements(screens.addToken.search.token.unselected)
|
||||
const names = await f.driver.findElements(screens.addToken.search.token.name)
|
||||
const icons = await f.driver.findElements(screens.addToken.search.token.icon)
|
||||
assert.equal(tokens.length, names.length, 'some names are missed')
|
||||
assert.equal(tokens.length, icons.length, 'some icons are missed')
|
||||
})
|
||||
|
||||
it('button \'Next\' is disabled if no one token is selected', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
assert.equal(await button.isEnabled(), false, 'button is enabled')
|
||||
})
|
||||
|
||||
it('user can select one token', async () => {
|
||||
const token = await f.waitUntilShowUp(screens.addToken.search.token.unselected)
|
||||
await token.click()
|
||||
})
|
||||
|
||||
it('button \'Next\' is enabled if token is selected', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
assert.equal(await button.isEnabled(), true, 'button is disabled')
|
||||
})
|
||||
|
||||
it('user can unselected token', async () => {
|
||||
const token = await f.waitUntilShowUp(screens.addToken.search.token.selected)
|
||||
await token.click()
|
||||
})
|
||||
|
||||
it('button \'Next\' is disabled after token was unselected', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
assert.equal(await button.isEnabled(), false, 'button is enabled')
|
||||
})
|
||||
|
||||
it('user can select two tokens', async () => {
|
||||
await f.waitUntilShowUp(screens.addToken.search.token.unselected)
|
||||
const tokensUnselected = await f.driver.findElements(screens.addToken.search.token.unselected)
|
||||
await tokensUnselected[0].click()
|
||||
await tokensUnselected[2].click()
|
||||
const tokensSelected = await f.driver.findElements(screens.addToken.search.token.selected)
|
||||
assert.equal(tokensSelected.length, 2, 'user can\'t select 2 tokens')
|
||||
})
|
||||
|
||||
it('click button \'Next\' opens confirm screen ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
await f.click(button)
|
||||
const buttonAdd = await f.waitUntilShowUp(screens.addToken.search.confirm.button.add)
|
||||
assert.notEqual(buttonAdd, false, 'failed to open screen confirmation')
|
||||
})
|
||||
|
||||
it('confirm screen: two selected tokens are displayed and have correct parameters', async () => {
|
||||
const tokens = await f.driver.findElements(screens.addToken.search.confirm.token.item)
|
||||
assert.equal(tokens.length, 2, 'incorrect number of tokens are presented')
|
||||
|
||||
const names = await f.driver.findElements(screens.addToken.search.confirm.token.name)
|
||||
const name0 = await names[0].getText()
|
||||
const name1 = await names[1].getText()
|
||||
assert.equal(name0.length > 10, true, 'empty token name')
|
||||
assert.equal(name1.length > 10, true, 'empty token name')
|
||||
await f.delay(2000)
|
||||
const balances = await f.driver.findElements(screens.addToken.search.confirm.token.balance)
|
||||
const balance0 = await balances[1].getText()
|
||||
const balance1 = await balances[2].getText()
|
||||
assert.equal(balance0, '0', 'balance isn\'t 0')
|
||||
assert.equal(balance1, '0', 'balance isn\'t 0')
|
||||
})
|
||||
|
||||
it('button \'Back\' is enabled and leads to previous screen ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.confirm.button.back)
|
||||
assert.equal(await button.isEnabled(), true, 'button isn\'t enabled')
|
||||
await f.click(button)
|
||||
const fieldSearch = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
assert.notEqual(fieldSearch, false, 'add token screen didn\'t opened')
|
||||
})
|
||||
|
||||
it('button \'Next\' is enabled if confirmation list isn\'t empty', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
assert.equal(await button.isEnabled(), true, 'button is disabled')
|
||||
})
|
||||
|
||||
it('previous selected tokens remain selected after new search', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
await f.clearField(field)
|
||||
await field.sendKeys(request.valid)
|
||||
await f.waitUntilShowUp(screens.addToken.search.token.selected)
|
||||
const listSelected = await f.driver.findElements(screens.addToken.search.token.selected)
|
||||
assert.equal(listSelected.length, 2, 'tokens are unselected')
|
||||
})
|
||||
|
||||
it('user can unselect token', async () => {
|
||||
const tokensUnselected = await f.driver.findElements(screens.addToken.search.token.unselected)
|
||||
assert.notEqual(tokensUnselected.length, 0, 'all tokens are selected')
|
||||
|
||||
let tokensSelected = await f.driver.findElements(screens.addToken.search.token.selected)
|
||||
await tokensSelected[0].click()
|
||||
const old = tokensSelected.length
|
||||
|
||||
tokensSelected = await f.driver.findElements(screens.addToken.search.token.selected)
|
||||
assert.equal(tokensSelected.length, old - 1, 'can\'t unselect token')
|
||||
})
|
||||
|
||||
it('confirm screen: unselected token aren\'t displayed', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
await f.click(button)
|
||||
await f.waitUntilShowUp(screens.addToken.search.confirm.token.item)
|
||||
const tokens = await f.driver.findElements(screens.addToken.search.confirm.token.item)
|
||||
assert.equal(tokens.length, 1, 'incorrect number of tokens are presented')
|
||||
const back = await f.waitUntilShowUp(screens.addToken.search.confirm.button.back)
|
||||
await f.click(back)
|
||||
})
|
||||
|
||||
it('Search by contract address: searching result list is empty if address invalid ', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
await field.sendKeys(request.notExistingAddress)
|
||||
const list = await f.waitUntilShowUp(screens.addToken.search.token.unselected, 20)
|
||||
assert.equal(list, false, 'unexpected tokens are displayed')
|
||||
})
|
||||
|
||||
it('Search by valid contract address: searching result list contains one token ', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.addToken.search.fieldSearch)
|
||||
await f.clearField(field)
|
||||
await f.clearField(field)
|
||||
await field.sendKeys(Qtum.address)
|
||||
const token = await f.waitUntilShowUp(screens.addToken.search.token.unselected)
|
||||
const list = await f.driver.findElements(screens.addToken.search.token.unselected)
|
||||
assert.notEqual(list, 0, 'tokens aren\'t displayed')
|
||||
await token.click()
|
||||
})
|
||||
|
||||
it('Token\'s info contains correct name ', async () => {
|
||||
const name = await f.waitUntilShowUp(screens.addToken.search.token.name)
|
||||
assert.equal(await name.getText(), Qtum.name, 'incorrect token\'s name')
|
||||
})
|
||||
|
||||
it('one more token added to confirmation list', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.button.next)
|
||||
await f.click(button)
|
||||
await f.waitUntilShowUp(screens.addToken.search.confirm.token.item)
|
||||
const list = await f.driver.findElements(screens.addToken.search.confirm.token.item)
|
||||
assert.equal(list.length, 2, 'token wasn\'t added')
|
||||
})
|
||||
|
||||
it('button \'Add tokens\' is enabled and clickable', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.addToken.search.confirm.button.add)
|
||||
assert.equal(await button.isEnabled(), true, 'button isn\'t enabled')
|
||||
await f.click(button)
|
||||
const identicon = await f.waitUntilShowUp(screens.main.identicon)
|
||||
assert.notEqual(identicon, false, 'main screen didn\'t opened')
|
||||
})
|
||||
|
||||
it('all selected tokens are displayed on main screen', async () => {
|
||||
await f.waitUntilShowUp(screens.main.tokens.token)
|
||||
const tokens = await f.driver.findElements(screens.main.tokens.token)
|
||||
assert.equal(tokens.length, 2, 'tokens weren\'t added')
|
||||
})
|
||||
|
||||
it('correct value of counter of owned tokens', async () => {
|
||||
const counter = await f.waitUntilShowUp(screens.main.tokens.counter)
|
||||
assert.equal(await counter.getText(), 'You own 2 tokens', 'incorrect value of counter')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Token should be displayed only for network, where it was added ', async () => {
|
||||
|
||||
it('token should not be displayed in POA network', async () => {
|
||||
await f.setProvider(NETWORKS.POA)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in DAI network', async () => {
|
||||
await f.setProvider(NETWORKS.DAI)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in SOKOL testnet', async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in LOCALHOST network', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in ROPSTEN testnet', async () => {
|
||||
await f.setProvider(NETWORKS.ROPSTEN)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in KOVAN testnet', async () => {
|
||||
await f.setProvider(NETWORKS.KOVAN)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in RINKEBY testnet', async () => {
|
||||
await f.setProvider(NETWORKS.RINKEBY)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in RSK mainnet', async () => {
|
||||
await f.setProvider(NETWORKS.RSK)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
|
||||
it('token should not be displayed in RSK testnet', async () => {
|
||||
await f.setProvider(NETWORKS.RSK_TESTNET)
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
})
|
||||
describe('remove Mainnet\'s tokens', function () {
|
||||
|
||||
it('remove tokens', async () => {
|
||||
|
||||
let menu
|
||||
let button
|
||||
let counter
|
||||
let buttonYes
|
||||
|
||||
await f.setProvider(NETWORKS.MAINNET)
|
||||
await f.waitUntilShowUp(elements.loader, 25)
|
||||
await f.waitUntilDisappear(elements.loader, 50)
|
||||
menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
button = await f.waitUntilShowUp(menus.token.remove)
|
||||
await button.click()
|
||||
buttonYes = await f.waitUntilShowUp(screens.removeToken.buttons.yes)
|
||||
await buttonYes.click()
|
||||
counter = await f.waitUntilShowUp(screens.main.tokens.counter)
|
||||
assert.equal(await counter.getText(), 'You own 1 token', 'incorrect value of counter')
|
||||
const tokensNumber = await f.driver.findElements(screens.main.tokens.token)
|
||||
assert.equal(tokensNumber.length, 1, 'incorrect amount of token\'s is displayed')
|
||||
|
||||
menu = await f.waitUntilShowUp(menus.token.menu)
|
||||
await menu.click()
|
||||
button = await f.waitUntilShowUp(menus.token.remove)
|
||||
await button.click()
|
||||
buttonYes = await f.waitUntilShowUp(screens.removeToken.buttons.yes)
|
||||
await buttonYes.click()
|
||||
counter = await f.waitUntilShowUp(screens.main.tokens.counter)
|
||||
assert.equal(await counter.getText(), 'No tokens found', 'incorrect value of counter')
|
||||
|
||||
assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = addTokeFromSearch
|
|
@ -0,0 +1,174 @@
|
|||
const assert = require('assert')
|
||||
const { screens, menus, NETWORKS } = require('../elements')
|
||||
|
||||
const changePassword = async (f, password, newPassword) => {
|
||||
let fieldNewPassword
|
||||
let fieldConfirmNewPassword
|
||||
let fieldOldPassword
|
||||
let buttonYes
|
||||
|
||||
describe('Check screen "Settings" -> "Change password" ', async () => {
|
||||
|
||||
it('checks if current network name (localhost) is correct', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
const menu = await f.waitUntilShowUp(menus.sandwich.menu, 300)
|
||||
await menu.click()
|
||||
const settings = await f.waitUntilShowUp(menus.sandwich.settings)
|
||||
await settings.click()
|
||||
const field = await f.waitUntilShowUp(screens.settings.currentNetwork)
|
||||
assert.equal(await field.getText(), 'http://localhost:8545', 'current network is incorrect')
|
||||
})
|
||||
|
||||
it('error should not be displayed', async () => {
|
||||
const error = await f.waitUntilShowUp(screens.settings.error, 10)
|
||||
assert.equal(error, false, 'improper error is displayed')
|
||||
})
|
||||
|
||||
it('checks if "Change password" button is present and enabled', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.sandwich.menu, 300)
|
||||
await menu.click()
|
||||
const settings = await f.waitUntilShowUp(menus.sandwich.settings)
|
||||
await settings.click()
|
||||
await f.waitUntilShowUp(screens.settings.fieldNewRPC)
|
||||
const buttons = await f.driver.findElements(screens.settings.buttons.changePassword)
|
||||
await f.scrollTo(buttons[0])
|
||||
assert.equal(buttons.length, 1, 'Button "Change password" is not present')
|
||||
assert.equal(await buttons[0].getText(), 'Change password', 'button has incorrect name')
|
||||
assert.equal(await buttons[0].isEnabled(), true, 'Button "Change password" is disabled')
|
||||
await f.click(buttons[0])
|
||||
})
|
||||
|
||||
it('screen has correct title', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.changePassword.title)
|
||||
assert.equal(await title.getText(), screens.changePassword.titleText, '"Change password" screen contains incorrect title')
|
||||
})
|
||||
|
||||
it('screen contains correct label', async () => {
|
||||
await f.waitUntilShowUp(screens.changePassword.label)
|
||||
const labels = await f.driver.findElements(screens.changePassword.label)
|
||||
assert.equal(labels.length, 1, 'screen "Change password" doesn\'t contain label')
|
||||
assert.equal(await labels[0].getText(), screens.changePassword.labelText, 'label contains incorrect title')
|
||||
})
|
||||
|
||||
it('clicking the button "No" bring back to "Setting" screen ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.changePassword.buttonNo)
|
||||
assert.equal(await button.getText(), 'No', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const title = await f.waitUntilShowUp(screens.settings.title)
|
||||
assert.equal(await title.getText(), screens.settings.titleText, 'button "No" doesnt open settings screen')
|
||||
const buttonChangePass = await f.driver.findElement(screens.settings.buttons.changePassword)
|
||||
await f.scrollTo(buttonChangePass)
|
||||
await f.click(buttonChangePass)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Validation of errors ', async () => {
|
||||
|
||||
before(async () => {
|
||||
fieldOldPassword = await f.waitUntilShowUp(screens.changePassword.fieldOldPassword)
|
||||
await fieldOldPassword.sendKeys(password)
|
||||
fieldNewPassword = await f.waitUntilShowUp(screens.changePassword.fieldNewPassword)
|
||||
fieldConfirmNewPassword = await f.waitUntilShowUp(screens.changePassword.fieldConfirmNewPassword)
|
||||
buttonYes = await f.waitUntilShowUp(screens.changePassword.buttonYes)
|
||||
})
|
||||
|
||||
it('error if new password shorter than 8 digits', async () => {
|
||||
await fieldNewPassword.sendKeys(newPassword.short)
|
||||
await fieldConfirmNewPassword.sendKeys(newPassword.short)
|
||||
assert.equal(await buttonYes.getText(), 'Yes', 'button has incorrect name')
|
||||
await f.click(buttonYes)
|
||||
await f.delay(2000)
|
||||
const errors = await f.driver.findElements(screens.changePassword.error)
|
||||
assert.equal(errors.length > 0, true, 'error isn\'t displayed')
|
||||
assert.equal(await errors[0].getText(), screens.changePassword.errorText.notLong, 'Error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('error if new password doesn\'t match confirmation', async () => {
|
||||
await f.clearField(fieldNewPassword)
|
||||
await f.clearField(fieldConfirmNewPassword)
|
||||
await fieldNewPassword.sendKeys(newPassword.correct)
|
||||
await fieldConfirmNewPassword.sendKeys(newPassword.incorrect)
|
||||
await f.click(buttonYes)
|
||||
await f.delay(2000)
|
||||
const errors = await f.driver.findElements(screens.changePassword.error)
|
||||
assert.equal(errors.length > 0, true, 'error isn\'t displayed')
|
||||
assert.equal(await errors[0].getText(), screens.changePassword.errorText.dontMatch, 'Error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('error if new password match old password', async () => {
|
||||
await f.clearField(fieldNewPassword)
|
||||
await f.clearField(fieldConfirmNewPassword)
|
||||
await fieldNewPassword.sendKeys(password)
|
||||
await fieldConfirmNewPassword.sendKeys(password)
|
||||
await f.click(buttonYes)
|
||||
await f.delay(2000)
|
||||
const errors = await f.driver.findElements(screens.changePassword.error)
|
||||
assert.equal(errors.length > 0, true, 'error isn\'t displayed')
|
||||
assert.equal(await errors[0].getText(), screens.changePassword.errorText.differ, 'Error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('error if old password incorrect', async () => {
|
||||
await f.clearField(fieldOldPassword)
|
||||
await fieldOldPassword.sendKeys(newPassword.incorrect)
|
||||
await f.click(buttonYes)
|
||||
await f.click(buttonYes)
|
||||
await f.delay(2000)
|
||||
const errors = await f.driver.findElements(screens.changePassword.error)
|
||||
assert.equal(errors.length > 0, true, 'error isn\'t displayed')
|
||||
assert.equal(await errors[0].getText(), screens.changePassword.errorText.incorrectPassword, 'Error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('no errors if old, new, confirm new passwords are correct; user can change password', async () => {
|
||||
await f.clearField(fieldNewPassword)
|
||||
await f.clearField(fieldOldPassword)
|
||||
await f.clearField(fieldConfirmNewPassword)
|
||||
|
||||
await fieldOldPassword.sendKeys(password)
|
||||
await fieldNewPassword.sendKeys(newPassword.correct)
|
||||
await fieldConfirmNewPassword.sendKeys(newPassword.correct)
|
||||
await f.click(buttonYes)
|
||||
await f.waitUntilShowUp(screens.settings.buttons.changePassword, 25)
|
||||
const buttons = await f.driver.findElements(screens.settings.buttons.changePassword)
|
||||
assert.equal(buttons.length, 1, 'Button "Change password" is not present')
|
||||
assert.equal(await buttons[0].isEnabled(), true, 'Button "Change password" is disabled')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check if new password is accepted', async () => {
|
||||
|
||||
it('user can log out', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.sandwich.menu)
|
||||
await menu.click()
|
||||
const itemLogOut = await f.waitUntilShowUp(menus.sandwich.logOut)
|
||||
await itemLogOut.click()
|
||||
const field = await f.waitUntilShowUp(screens.lock.fieldPassword)
|
||||
assert.notEqual(field, false, 'password box isn\'t present after logout')
|
||||
})
|
||||
|
||||
it('can\'t login with old password', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.lock.fieldPassword)
|
||||
await field.sendKeys(password)
|
||||
const button = await f.waitUntilShowUp(screens.lock.buttonLogin)
|
||||
await f.click(button)
|
||||
const error = await f.waitUntilShowUp(screens.lock.error)
|
||||
assert.notEqual(error, false, 'error isn\'t displayed if password incorrect')
|
||||
assert.equal(await error.getText(), screens.lock.errorText, 'error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('accepts new password after lock', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.lock.fieldPassword)
|
||||
await f.clearField(field)
|
||||
await field.sendKeys(newPassword.correct)
|
||||
const button = await f.waitUntilShowUp(screens.lock.buttonLogin)
|
||||
await f.click(button)
|
||||
|
||||
await f.waitUntilShowUp(screens.main.buttons.buy)
|
||||
const buttons = await f.driver.findElements(screens.main.buttons.buy)
|
||||
assert.equal(buttons.length, 1, 'main screen isn\'t displayed')
|
||||
assert.equal(await buttons[0].getText(), 'Buy', 'button has incorrect name')
|
||||
password = newPassword.correct
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = changePassword
|
|
@ -0,0 +1,68 @@
|
|||
const assert = require('assert')
|
||||
const { screens, menus, NETWORKS } = require('../elements')
|
||||
const eventsEmitter = 'https://vbaranov.github.io/event-listener-dapp/'
|
||||
|
||||
const checkEmittedEvents = async (f, account1, account2) => {
|
||||
it('emit event', async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
let account
|
||||
if (process.env.SELENIUM_BROWSER === 'chrome') {
|
||||
account = account1
|
||||
} else if (process.env.SELENIUM_BROWSER === 'firefox') {
|
||||
account = account2
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.account2)
|
||||
await item.click()
|
||||
}
|
||||
|
||||
const balanceField = await f.waitUntilShowUp(screens.main.balance)
|
||||
await f.delay(2000)
|
||||
const balance = await balanceField.getText()
|
||||
console.log('Account = ' + account)
|
||||
console.log('Balance = ' + balance)
|
||||
assert.equal(parseFloat(balance) > 0.001, true, 'Balance of account ' + account + ' TOO LOW !!! Please refill with Sokol eth!!!!')
|
||||
await f.driver.get(eventsEmitter)
|
||||
const button = await f.waitUntilShowUp(screens.eventsEmitter.button)
|
||||
await button.click()
|
||||
await f.delay(1000)
|
||||
})
|
||||
|
||||
it('confirms transaction in MetaMask popup', async () => {
|
||||
const windowHandles = await f.driver.getAllWindowHandles()
|
||||
await f.driver.switchTo().window(windowHandles[windowHandles.length - 1])
|
||||
await f.delay(5000)
|
||||
const gasPrice = await f.waitUntilShowUp(screens.confirmTransaction.fields.gasPrice)
|
||||
await gasPrice.sendKeys('10')
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.submit)
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('check number of events', async () => {
|
||||
const windowHandles = await f.driver.getAllWindowHandles()
|
||||
await f.driver.switchTo().window(windowHandles[0])
|
||||
await f.delay(5000)
|
||||
const event = await f.waitUntilShowUp(screens.eventsEmitter.event, 600)
|
||||
const events = await f.driver.findElements(screens.eventsEmitter.event)
|
||||
console.log('number of events = ' + events.length)
|
||||
if (!event) console.log("event wasn't created or transaction failed".toUpperCase())
|
||||
else {
|
||||
const events = await f.driver.findElements(screens.eventsEmitter.event)
|
||||
assert.equal(events.length, 1, 'More than 1 event was fired: ' + events.length + ' events')
|
||||
}
|
||||
})
|
||||
|
||||
it('open app', async () => {
|
||||
if (process.env.SELENIUM_BROWSER === 'chrome') {
|
||||
await f.driver.get(`chrome-extension://${f.extensionId}/popup.html`)
|
||||
} else if (process.env.SELENIUM_BROWSER === 'firefox') {
|
||||
await f.driver.get(`moz-extension://${f.extensionId}/popup.html`)
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.account1)
|
||||
await item.click()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = checkEmittedEvents
|
|
@ -0,0 +1,101 @@
|
|||
const assert = require('assert')
|
||||
const { menus, screens } = require('../elements')
|
||||
|
||||
const connectHDWallet = async (f) => {
|
||||
it("Account menu contais item 'Connect HD wallet'", async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.account.item)
|
||||
const items = await f.driver.findElements(menus.account.item)
|
||||
await f.delay(500)
|
||||
assert.equal(await items[4].getText(), 'Connect hardware wallet', "item's text incorrect")
|
||||
await items[4].click()
|
||||
})
|
||||
|
||||
|
||||
it("Opens screen 'Connect HD wallet',title is correct", async () => {
|
||||
const title = await f.waitUntilShowUp(screens.hdWallet.title)
|
||||
assert.equal(await title.getText(), 'Connect to hardware wallet', "item's text incorrect")
|
||||
})
|
||||
|
||||
if (process.env.SELENIUM_BROWSER === 'chrome') {
|
||||
it("Button 'Connect' disabled by default", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.hdWallet.buttonConnect.disabled)
|
||||
assert.notEqual(button, false, "button isn't displayed")
|
||||
assert.equal(await button.getText(), 'CONNECT', 'button has incorrect text')
|
||||
})
|
||||
|
||||
it('Ledger image is displayed', async () => {
|
||||
const image = await f.waitUntilShowUp(screens.hdWallet.image)
|
||||
assert.notEqual(image, false, "ledger's image isn't displayed")
|
||||
const src = await image.getAttribute('src')
|
||||
assert.equal(src.includes('images/ledger-logo.svg'), true, 'Ledger has incorrect image')
|
||||
})
|
||||
|
||||
it('Trezor image is displayed', async () => {
|
||||
const images = await f.driver.findElements(screens.hdWallet.image)
|
||||
assert.notEqual(images[1], false, "trezor's image isn't displayed")
|
||||
const src = await images[1].getAttribute('src')
|
||||
assert.equal(src.includes('images/trezor-logo.svg'), true, 'Trezor has incorrect image')
|
||||
})
|
||||
|
||||
it("Button 'Connect' enabled if Trezor selected", async () => {
|
||||
const images = await f.driver.findElements(screens.hdWallet.image)
|
||||
await images[1].click()
|
||||
const button = await f.waitUntilShowUp(screens.hdWallet.buttonConnect.enabled)
|
||||
assert.equal(await button.isEnabled(), true, 'button is disabled')
|
||||
})
|
||||
|
||||
it("Button 'Connect' enabled if Ledger selected", async () => {
|
||||
const images = await f.driver.findElements(screens.hdWallet.image)
|
||||
await images[0].click()
|
||||
const button = await f.waitUntilShowUp(screens.hdWallet.buttonConnect.enabled)
|
||||
assert.equal(await button.isEnabled(), true, 'button is disabled')
|
||||
})
|
||||
|
||||
it('Only one device can be selected', async () => {
|
||||
const selected = await f.driver.findElements(screens.hdWallet.imageSelected)
|
||||
assert.equal(await selected.length, 1, 'more than one device is selected')
|
||||
})
|
||||
|
||||
it('Error message if connect Ledger', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.hdWallet.buttonConnect.enabled)
|
||||
await button.click()
|
||||
const error = await f.waitUntilShowUp(screens.hdWallet.error)
|
||||
const shouldBe = "TransportError: U2F browser support is needed for Ledger. Please use Chrome, Opera or Firefox with a U2F extension. Also make sure you're on an HTTPS connection"
|
||||
assert.equal(await error.getText(), shouldBe, 'error has incorrect text')
|
||||
})
|
||||
|
||||
it('Popup opens if connect Trezor', async () => {
|
||||
const images = await f.driver.findElements(screens.hdWallet.image)
|
||||
await images[1].click()
|
||||
const button = await f.waitUntilShowUp(screens.hdWallet.buttonConnect.enabled)
|
||||
await button.click()
|
||||
await f.delay(2000)
|
||||
const allHandles = await f.driver.getAllWindowHandles()
|
||||
assert.equal(allHandles.length, 2, "popup isn't opened")
|
||||
f.driver.switchTo().window(allHandles[1])
|
||||
await f.delay(2000)
|
||||
f.driver.close()
|
||||
f.driver.switchTo().window(allHandles[0])
|
||||
await f.delay(2000)
|
||||
assert.equal(allHandles.length, 2, "popup isn't opened")
|
||||
await f.switchToFirstPage()
|
||||
await f.driver.navigate().refresh()
|
||||
})
|
||||
}
|
||||
it('Button arrow leads to main screen', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.account.item)
|
||||
const items = await f.driver.findElements(menus.account.item)
|
||||
await f.delay(500)
|
||||
await items[4].click()
|
||||
const arrow = await f.waitUntilShowUp(screens.hdWallet.buttonArrow)
|
||||
await arrow.click()
|
||||
const ident = await f.waitUntilShowUp(screens.main.identicon, 20)
|
||||
assert.notEqual(ident, false, "main screen isn't opened")
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = connectHDWallet
|
|
@ -0,0 +1,150 @@
|
|||
const assert = require('assert')
|
||||
const { screens, menus, NETWORKS } = require('../elements')
|
||||
|
||||
const customRPC = async (f) => {
|
||||
const invalidStringUrl = 'http://lwkdfowi**&#v er'
|
||||
const urlWithoutHttp = 'infura.com'
|
||||
const invalidEndpoint = 'http://abrakadabrawdjkwjeciwkasuhlvflwe.com'
|
||||
const correctRpcUrl = 'https://poa.infura.io/test'
|
||||
|
||||
it('switches to settings screen through menu \'Network -> Custom RPC\'', async function () {
|
||||
await f.setProvider(NETWORKS.CUSTOM)
|
||||
const settings = await f.waitUntilShowUp(screens.settings.title)
|
||||
assert.equal(await settings.getText(), screens.settings.titleText, 'inappropriate screen is opened')
|
||||
})
|
||||
|
||||
it('error message if new Rpc url is invalid', async function () {
|
||||
const field = await f.waitUntilShowUp(screens.settings.fieldNewRPC)
|
||||
await field.sendKeys(invalidStringUrl)
|
||||
const button = await f.waitUntilShowUp(screens.settings.buttonSave)
|
||||
assert.equal(await button.getText(), 'Save', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
await f.delay(1000)
|
||||
assert.equal(await f.waitUntilShowUp(screens.settings.buttons.delete, 5), false, 'invalid Rpc was added')
|
||||
const errors = await f.driver.findElements(screens.settings.error)
|
||||
assert.equal(errors.length, 1, 'error isn\'t displayed if Rpc url incorrect')
|
||||
assert.equal(await errors[0].getText(), screens.settings.errors.invalidRpcUrl, 'error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('error message if new Rpc url has no HTTP/HTTPS prefix', async function () {
|
||||
const fieldRpc = await f.driver.findElement(screens.settings.fieldNewRPC)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await fieldRpc.sendKeys(urlWithoutHttp)
|
||||
const button = await f.waitUntilShowUp(screens.settings.buttonSave)
|
||||
await f.click(button)
|
||||
await f.delay(1000)
|
||||
assert.equal(await f.waitUntilShowUp(screens.settings.buttons.delete, 5), false, 'invalid Rpc was added')
|
||||
const errors = await f.driver.findElements(screens.settings.error)
|
||||
assert.equal(errors.length, 1, 'error isn\'t displayed if Rpc url incorrect')
|
||||
assert.equal(await errors[0].getText(), screens.settings.errors.invalidHTTP, 'error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('error message if Rpc doesn\'t exist', async function () {
|
||||
const fieldRpc = await f.driver.findElement(screens.settings.fieldNewRPC)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await fieldRpc.sendKeys(invalidEndpoint)
|
||||
const button = await f.waitUntilShowUp(screens.settings.buttonSave)
|
||||
await f.click(button)
|
||||
await f.delay(1000)
|
||||
assert.equal(await f.waitUntilShowUp(screens.settings.buttons.delete, 5), false, 'invalid Rpc was added')
|
||||
await f.waitUntilShowUp(screens.settings.error)
|
||||
const errors = await f.driver.findElements(screens.settings.error)
|
||||
assert.equal(errors.length, 1, 'error isn\'t displayed if Rpc url incorrect')
|
||||
assert.equal(await errors[0].getText(), screens.settings.errors.invalidRpcEndpoint, 'error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('user can add valid custom rpc', async function () {
|
||||
const fieldRpc = await f.driver.findElement(screens.settings.fieldNewRPC)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await fieldRpc.sendKeys(correctRpcUrl + 0)
|
||||
await f.driver.findElement(screens.settings.buttonSave).click()
|
||||
await f.delay(20000)
|
||||
const customUrlElement = await f.waitUntilShowUp(screens.settings.currentNetwork)
|
||||
assert.equal(await customUrlElement.getText(), correctRpcUrl + 0, 'Added Url doesn\'t match')
|
||||
})
|
||||
|
||||
it('new added Rpc displayed in network dropdown menu', async function () {
|
||||
let menu = await f.waitUntilShowUp(screens.main.network)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.networks.addedCustomRpc)
|
||||
assert.equal(await item.getText(), correctRpcUrl + 0, 'Added custom Url isn\'t displayed ')
|
||||
menu = await f.waitUntilShowUp(screens.main.network)
|
||||
await menu.click()
|
||||
})
|
||||
|
||||
it('user can add four more valid custom rpc', async function () {
|
||||
const fieldRpc = await f.waitUntilShowUp(screens.settings.fieldNewRPC)
|
||||
const customUrlElement = await f.waitUntilShowUp(screens.settings.currentNetwork)
|
||||
for (let i = 1; i < 5; i++) {
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await f.clearField(fieldRpc)
|
||||
await fieldRpc.sendKeys(correctRpcUrl + i)
|
||||
await f.driver.findElement(screens.settings.buttonSave).click()
|
||||
await f.delay(5000)
|
||||
assert.equal(await customUrlElement.getText(), correctRpcUrl + i, '#' + i + ': Current RPC field contains incorrect URL')
|
||||
}
|
||||
})
|
||||
|
||||
it('new added Rpc displayed in network dropdown menu', async function () {
|
||||
let menu = await f.waitUntilShowUp(screens.main.network)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.networks.addedCustomRpc)
|
||||
const items = await f.driver.findElements(menus.networks.addedCustomRpc)
|
||||
assert.equal(items.length, 5, 'Incorrect number of added RPC')
|
||||
|
||||
menu = await f.waitUntilShowUp(screens.main.network)
|
||||
await menu.click()
|
||||
})
|
||||
|
||||
it('click button \'Delete\' opens screen \'Delete Custom RPC\'', async function () {
|
||||
await f.delay(1000)
|
||||
const button = await f.waitUntilShowUp(screens.settings.buttons.delete, 10)
|
||||
assert.equal(await button.getText(), 'Delete', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const title = await f.waitUntilShowUp(screens.settings.title)
|
||||
assert.equal(await title.getText(), screens.deleteCustomRPC.titleText, 'inappropriate screen is opened')
|
||||
})
|
||||
|
||||
it('click button \'No\' opens screen \'Settings\'', async function () {
|
||||
const button = await f.waitUntilShowUp(screens.deleteCustomRPC.buttons.no)
|
||||
assert.equal(await button.getText(), 'No', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const title = await f.waitUntilShowUp(screens.settings.title)
|
||||
assert.equal(await title.getText(), screens.settings.titleText, 'inappropriate screen is opened')
|
||||
})
|
||||
|
||||
it('user able to delete custom rpc', async function () {
|
||||
const buttonDelete = await f.waitUntilShowUp(screens.settings.buttons.delete, 25)
|
||||
await f.click(buttonDelete)
|
||||
const yesButton = await f.waitUntilShowUp(screens.deleteCustomRPC.buttons.yes)
|
||||
assert.equal(await yesButton.getText(), 'Yes')
|
||||
await f.click(yesButton)
|
||||
const title = await f.waitUntilShowUp(screens.settings.title)
|
||||
assert.equal(await title.getText(), screens.settings.titleText, 'inappropriate screen is opened')
|
||||
})
|
||||
|
||||
it('deleted custom rpc isn\'t displayed in \'Settings\' screen', async function () {
|
||||
const currentNetwork = await f.waitUntilShowUp(screens.settings.currentNetwork)
|
||||
assert.equal(await currentNetwork.getText(), 'POA Network', 'custom Rpc is displayed after deletion')
|
||||
})
|
||||
|
||||
it('deleted custom rpc isn\'t displayed in network dropdown menu', async function () {
|
||||
await f.delay(2000)
|
||||
let menu = await f.waitUntilShowUp(screens.main.network)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.networks.addedCustomRpc, 20)
|
||||
const items = await f.driver.findElements(menus.networks.addedCustomRpc)
|
||||
assert.equal(items.length, 4, 'deleted custom rpc is displayed in network dropdown menu')
|
||||
menu = await f.waitUntilShowUp(screens.main.network)
|
||||
await menu.click()
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = customRPC
|
|
@ -0,0 +1,57 @@
|
|||
const assert = require('assert')
|
||||
const { menus, screens } = require('../elements')
|
||||
const { account } = menus
|
||||
const { deleteImportedAccount: deleteImportedAccountScr, settings } = screens
|
||||
|
||||
const deleteImportedAccount = async (f) => {
|
||||
it('Open delete imported account screen', async function () {
|
||||
const menu = await f.waitUntilShowUp(account.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(account.delete)
|
||||
await item.click()
|
||||
const deleteImportedAccountTitle = await f.waitUntilShowUp(deleteImportedAccountScr.title)
|
||||
assert.equal(await deleteImportedAccountTitle.getText(), deleteImportedAccountScr.titleText)
|
||||
})
|
||||
|
||||
it("Can't remove imported account with 'No' button", async function () {
|
||||
const button = await f.waitUntilShowUp(deleteImportedAccountScr.buttons.no)
|
||||
assert.equal(await button.getText(), 'No', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const settingsTitle = await f.waitUntilShowUp(settings.title)
|
||||
assert.equal(await settingsTitle.getText(), 'Settings')
|
||||
// check, that imported account still exists
|
||||
const menu = await f.waitUntilShowUp(account.menu)
|
||||
await menu.click()
|
||||
await f.delay(2000)
|
||||
const label = await f.waitUntilShowUp(account.label)
|
||||
assert.equal(await label.getText(), 'IMPORTED')
|
||||
})
|
||||
|
||||
it('Open delete imported account screen again', async function () {
|
||||
const menu = await f.waitUntilShowUp(account.menu)
|
||||
await menu.click()
|
||||
await f.delay(2000)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(account.delete)
|
||||
const buttons = await f.driver.findElements(account.delete)
|
||||
assert.notEqual(buttons[0], false, "icon 'remove' isn't displayed")
|
||||
await buttons[0].click()
|
||||
})
|
||||
|
||||
it("Remove imported account with 'Yes' button", async function () {
|
||||
const button = await f.waitUntilShowUp(deleteImportedAccountScr.buttons.yes)
|
||||
assert.equal(await button.getText(), 'Yes', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const settingsTitle = await f.waitUntilShowUp(settings.title)
|
||||
assert.equal(await settingsTitle.getText(), 'Settings', "screen 'Settings' has incorrect title")
|
||||
// check, that imported account is removed
|
||||
const menu = await f.waitUntilShowUp(account.menu)
|
||||
await menu.click()
|
||||
await f.delay(3000)
|
||||
const label = await f.waitUntilShowUp(account.label, 25)
|
||||
assert.equal(label, false, "account isn't deleted")
|
||||
await menu.click()
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = deleteImportedAccount
|
|
@ -0,0 +1,84 @@
|
|||
const assert = require('assert')
|
||||
const clipboardy = require('clipboardy')
|
||||
const { screens, menus } = require('../elements')
|
||||
|
||||
const exportPrivateKey = async (f, password) => {
|
||||
it('open dialog', async () => {
|
||||
await f.driver.navigate().refresh()
|
||||
const menu = await f.waitUntilShowUp(menus.dot.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.dot.exportPR)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it('warning is displayed', async () => {
|
||||
await f.waitUntilShowUp(screens.exportPR.error)
|
||||
const error = await f.driver.findElements(screens.exportPR.error)
|
||||
assert.equal(error.length, 1, 'warning isn\'t present')
|
||||
assert.equal(await error[0].getText(), screens.exportPR.warningText, 'warning\'s text incorrect')
|
||||
})
|
||||
|
||||
it('button \'Cancel\' leads back to main screen', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.exportPR.button.cancel)
|
||||
assert.equal(await button.getText(), 'Cancel', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const field = await f.waitUntilShowUp(screens.exportPR.fieldPassword, 20)
|
||||
assert.equal(field, false, 'field \'password\' is displayed after closing')
|
||||
})
|
||||
|
||||
it('error message if password incorrect', async () => {
|
||||
await f.driver.navigate().refresh()
|
||||
const menu = await f.waitUntilShowUp(menus.dot.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.dot.exportPR)
|
||||
await item.click()
|
||||
const field = await f.waitUntilShowUp(screens.exportPR.fieldPassword)
|
||||
await field.sendKeys('abrakadabr')
|
||||
const button = await f.waitUntilShowUp(screens.exportPR.button.submit)
|
||||
assert.equal(await button.getText(), 'Submit', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
await f.delay(500)
|
||||
const error = await f.driver.findElements(screens.exportPR.error)
|
||||
assert.equal(error.length, 2, 'warning isn\'t present')
|
||||
assert.equal(await error[1].getText(), screens.exportPR.errorText, 'error\'s text incorrect')
|
||||
})
|
||||
|
||||
it('private key is shown if password correct', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.exportPR.fieldPassword)
|
||||
await f.clearField(field)
|
||||
await field.sendKeys(password)
|
||||
const button = await f.waitUntilShowUp(screens.exportPR.button.submit)
|
||||
await f.click(button)
|
||||
const key = await f.waitUntilShowUp(screens.yourPR.key)
|
||||
const pr = await key.getText()
|
||||
assert.equal(pr.length, 32 * 2, 'private key isn\'t displayed')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
await f.waitUntilShowUp(screens.yourPR.copy)
|
||||
const icons = await f.driver.findElements(screens.yourPR.copy)
|
||||
assert.notEqual(icons[1], false, 'icon copy isn\'t displayed')
|
||||
await icons[1].click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.length, 64, "private key wasn't copied to clipboard")
|
||||
})
|
||||
|
||||
it('file loaded if click button \'Save\' ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.yourPR.button.save)
|
||||
assert.equal(await button.getText(), 'Save as File', 'button has incorrect name')
|
||||
assert.notEqual(button, false, 'button \'Save\' isn\'t displayed')
|
||||
})
|
||||
|
||||
it('button \'Done\' leads back to main screen', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.yourPR.button.done)
|
||||
await f.click(button)
|
||||
const field = await f.waitUntilShowUp(screens.yourPR.key, 20)
|
||||
assert.equal(field, false, 'screen \'Your PR\' is displayed after closing')
|
||||
await f.driver.navigate().refresh()
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = exportPrivateKey
|
|
@ -0,0 +1,69 @@
|
|||
const assert = require('assert')
|
||||
const { menus, screens, elements, NETWORKS } = require('../elements')
|
||||
const { account } = menus
|
||||
const { main: {
|
||||
tokens: tokensEl,
|
||||
balance: balanceEl,
|
||||
},
|
||||
importAccounts,
|
||||
} = screens
|
||||
const addr = '0xf4702CbA917260b2D6731Aea6385215073e8551b'
|
||||
const addrPrivKey = '76bd0ced0a47055bb5d060e1ae4a8cb3ece658d668823e250dae6e79d3ab4435'
|
||||
|
||||
const importAccount = async (f) => {
|
||||
it('Open import account menu', async () => {
|
||||
await f.setProvider(NETWORKS.POA)
|
||||
await f.delay(2000)
|
||||
const menu = await f.waitUntilShowUp(account.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(account.import)
|
||||
await item.click()
|
||||
const importAccountTitle = await f.waitUntilShowUp(importAccounts.title)
|
||||
assert.equal(await importAccountTitle.getText(), importAccounts.textTitle)
|
||||
})
|
||||
|
||||
it('Imports account', async () => {
|
||||
const privateKeyBox = await f.waitUntilShowUp(importAccounts.fieldPrivateKey)
|
||||
await privateKeyBox.sendKeys(addrPrivKey)
|
||||
const button = await f.waitUntilShowUp(importAccounts.buttonImport)
|
||||
assert.equal(await button.getText(), 'Import', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const menu = await f.waitUntilShowUp(account.menu)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(account.label)
|
||||
const labels = await f.driver.findElements(account.label)
|
||||
const label = labels[0]
|
||||
assert.equal(await label.getText(), 'IMPORTED')
|
||||
await menu.click()
|
||||
})
|
||||
|
||||
it('Auto-detect tokens for POA core network ', async () => {
|
||||
// await setProvider(NETWORKS.POA)
|
||||
const tab = await f.waitUntilShowUp(tokensEl.menu)
|
||||
await tab.click()
|
||||
const balance = await f.waitUntilShowUp(tokensEl.balance)
|
||||
console.log(await balance.getText())
|
||||
assert.equal(await balance.getText(), '1 DOPR', 'token isnt\' auto-detected')
|
||||
})
|
||||
|
||||
it.skip('Auto-detect tokens for MAIN core network ', async () => {
|
||||
await f.setProvider(NETWORKS.MAINNET)
|
||||
await f.waitUntilShowUp(elements.loader, 25)
|
||||
await f.waitUntilDisappear(elements.loader, 25)
|
||||
const balance = await f.waitUntilShowUp(tokensEl.balance)
|
||||
console.log(await balance.getText())
|
||||
assert.equal(await balance.getText(), '0.001 WETH', 'token isnt\' auto-detected')
|
||||
})
|
||||
|
||||
it('Check Sokol balance', async () => {
|
||||
await f.setProvider(NETWORKS.POA)
|
||||
await f.delay(2000)
|
||||
const balanceField = await f.waitUntilShowUp(balanceEl)
|
||||
const balance = await balanceField.getText()
|
||||
console.log(`Account = ${addr}`)
|
||||
console.log('Balance = ' + balance)
|
||||
assert.equal(parseFloat(balance) > 0.001, true, `Balance of account ${addr} TOO LOW !!! Please refill with Sokol eth!!!!`)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = importAccount
|
|
@ -0,0 +1,862 @@
|
|||
const assert = require('assert')
|
||||
const clipboardy = require('clipboardy')
|
||||
const { menus, screens, elements, NETWORKS } = require('../elements')
|
||||
let abiClipboard
|
||||
|
||||
const importContractAccount = async (f, account1, getCreatedAccounts) => {
|
||||
describe('Proxy contract', async () => {
|
||||
const proxyContract = '0x0518ac3db78eb326f42dbcfb4b2978e8059989a5'
|
||||
const proxyABI = [{'constant': true, 'inputs': [], 'name': 'proxyOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'version', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}], 'name': 'upgradeTo', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'implementation', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'upgradeabilityOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}, {'name': 'data', 'type': 'bytes'}], 'name': 'upgradeToAndCall', 'outputs': [], 'payable': true, 'stateMutability': 'payable', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'newOwner', 'type': 'address'}], 'name': 'transferProxyOwnership', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'inputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'payable': true, 'stateMutability': 'payable', 'type': 'fallback'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'previousOwner', 'type': 'address'}, {'indexed': false, 'name': 'newOwner', 'type': 'address'}], 'name': 'ProxyOwnershipTransferred', 'type': 'event'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'version', 'type': 'string'}, {'indexed': true, 'name': 'implementation', 'type': 'address'}], 'name': 'Upgraded', 'type': 'event'}] // eslint-disable-line no-unused-vars
|
||||
const joinedABI = [{'constant': true, 'inputs': [], 'name': 'proxyOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'version', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}], 'name': 'upgradeTo', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'implementation', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'upgradeabilityOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}, {'name': 'data', 'type': 'bytes'}], 'name': 'upgradeToAndCall', 'outputs': [], 'payable': true, 'stateMutability': 'payable', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'newOwner', 'type': 'address'}], 'name': 'transferProxyOwnership', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'inputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'payable': true, 'stateMutability': 'payable', 'type': 'fallback'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'previousOwner', 'type': 'address'}, {'indexed': false, 'name': 'newOwner', 'type': 'address'}], 'name': 'ProxyOwnershipTransferred', 'type': 'event'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'version', 'type': 'string'}, {'indexed': true, 'name': 'implementation', 'type': 'address'}], 'name': 'Upgraded', 'type': 'event'}, {'constant': true, 'inputs': [], 'name': 'desc', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'methodFromImplementation', 'outputs': [{'name': 'yep', 'type': 'bool'}], 'payable': false, 'stateMutability': 'pure', 'type': 'function'}]
|
||||
|
||||
describe('imports ABI of proxy and implementation together', async () => {
|
||||
it('opens import account menu', async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
const menu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.import2)
|
||||
await item.click()
|
||||
const importAccountTitle = await f.waitUntilShowUp(screens.importAccounts.title)
|
||||
assert.equal(await importAccountTitle.getText(), screens.importAccounts.textTitle)
|
||||
})
|
||||
|
||||
it("Select type 'Proxy'", async () => {
|
||||
await f.delay(1000)
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.selectArrow)
|
||||
await field.click()
|
||||
const item = await f.waitUntilShowUp(screens.importAccounts.itemProxyContract)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it("Fill 'Address' with valid proxy contract , SOKOL", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractAddress)
|
||||
await f.clearField(field, 100)
|
||||
await field.sendKeys(proxyContract)
|
||||
})
|
||||
|
||||
it('ABI of Proxy + Implementation is fetched and matches the pattern', async () => {
|
||||
await f.delay(5000)
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractABI)
|
||||
abiClipboard = await field.getText()
|
||||
console.log(abiClipboard)
|
||||
assert.deepEqual(JSON.parse(abiClipboard), joinedABI, "ABI isn't fetched")
|
||||
})
|
||||
|
||||
it("Click button 'Import', main screen opens", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport)
|
||||
await f.click(button)
|
||||
const ident = await f.waitUntilShowUp(screens.main.identicon, 20)
|
||||
assert.notEqual(ident, false, "main screen isn't opened")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Check 3dots menu for 'Proxy' account", () => {
|
||||
|
||||
it('open 3dots menu', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.dot.menu)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.dot.item)
|
||||
const items = await f.driver.findElements(menus.dot.item)
|
||||
assert.equal(items.length, 5, '3dot menu has incorrect number of items')
|
||||
})
|
||||
|
||||
it('Check text of items', async () => {
|
||||
const items = await f.driver.findElements(menus.dot.item)
|
||||
assert.equal(await items[0].getText(), 'View on block explorer', '1st item has incorrect text')
|
||||
assert.equal(await items[1].getText(), 'Show QR Code', '2nd item has incorrect text')
|
||||
assert.equal(await items[2].getText(), 'Copy address to clipboard', '3d item has incorrect text')
|
||||
assert.equal(await items[3].getText(), 'Copy ABI to clipboard', '4th item has incorrect text')
|
||||
assert.equal(await items[4].getText(), 'Update implementation ABI', '5th item has incorrect text')
|
||||
})
|
||||
|
||||
it("Click 'Update implementation ABI'", async () => {
|
||||
const items = await f.driver.findElements(menus.dot.item)
|
||||
await items[4].click()
|
||||
const menu = await f.waitUntilShowUp(menus.dot.item, 20)
|
||||
assert.equal(menu, false, "3dot menu wasn't closed")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Remove imported 'Proxy' account", async () => {
|
||||
it("Label 'PROXY' present", async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await menu.click()
|
||||
await f.delay(2000)
|
||||
await f.waitUntilShowUp(menus.account.label)
|
||||
const labels = await f.driver.findElements(menus.account.label)
|
||||
const label = labels[1]
|
||||
assert.equal(await label.getText(), 'PROXY', 'label incorrect')
|
||||
})
|
||||
it('Delete imported account', async () => {
|
||||
await f.waitUntilShowUp(menus.account.delete)
|
||||
const items = await f.driver.findElements(menus.account.delete)
|
||||
await items[1].click()
|
||||
const button = await f.waitUntilShowUp(screens.deleteImportedAccount.buttons.yes)
|
||||
await button.click()
|
||||
const buttonArrow = await f.waitUntilShowUp(screens.settings.buttons.arrow)
|
||||
await buttonArrow.click()
|
||||
const identicon = await f.waitUntilShowUp(screens.main.identicon)
|
||||
assert.notEqual(identicon, false, 'main screen didn\'t opened')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Simple contract', async () => {
|
||||
const contractSokol = '0x215b2ab35749e5a9f3efe890de602fb9844e842f'
|
||||
console.log('Contract ' + contractSokol + ' , Sokol')
|
||||
const wrongAddress = '0xB87b6077D59B01Ab9fa8cd5A1A21D02a4d60D35'
|
||||
const notContractAddress = '0x56B2e3C3cFf7f3921Dc2e0F8B8e20d1eEc29216b'
|
||||
describe('Import Contract', async () => {
|
||||
|
||||
it('opens import account menu', async () => {
|
||||
await f.setProvider(NETWORKS.ROPSTEN)
|
||||
const menu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await menu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.import2)
|
||||
await item.click()
|
||||
const importAccountTitle = await f.waitUntilShowUp(screens.importAccounts.title)
|
||||
assert.equal(await importAccountTitle.getText(), screens.importAccounts.textTitle)
|
||||
})
|
||||
|
||||
it("Warning's text is correct", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.warning)
|
||||
assert.equal(await field.getText(), 'Imported accounts will not be associated with your originally created Nifty Wallet account seedphrase.', "incorrect warning's text")
|
||||
})
|
||||
|
||||
it("Select type 'Contract'", async () => {
|
||||
await f.delay(1000)
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.selectArrow)
|
||||
await field.click()
|
||||
await f.delay(2000)
|
||||
const item = await f.waitUntilShowUp(screens.importAccounts.itemContract)
|
||||
await item.click()
|
||||
})
|
||||
|
||||
it("Field 'Address' is displayed", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractAddress)
|
||||
assert.notEqual(field, false, "field 'Address' isn't displayed")
|
||||
await field.sendKeys(wrongAddress)
|
||||
})
|
||||
|
||||
it("Button 'Import' is displayed", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport)
|
||||
assert.notEqual(button, false, "button 'Import' isn't displayed")
|
||||
assert.equal(await button.getText(), 'Import', 'wrong name of button')
|
||||
})
|
||||
|
||||
it("Button 'Import' is disabled if incorrect address", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport)
|
||||
assert.equal(await button.isEnabled(), false, 'button enabled')
|
||||
})
|
||||
|
||||
it("Field 'ABI' is displayed", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractABI)
|
||||
assert.notEqual(field, false, "field 'ABI' isn't displayed")
|
||||
})
|
||||
|
||||
it("Field 'ABI' is empty if contract isn't verified in current network", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractABI)
|
||||
assert.equal(await field.getText(), '', "field 'ABI' isn't displayed")
|
||||
})
|
||||
|
||||
it("Fill 'Address' with not contract address , SOKOL", async () => {
|
||||
await f.setProvider(NETWORKS.SOKOL)
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractAddress)
|
||||
await f.clearField(field, 100)
|
||||
await field.sendKeys(notContractAddress)
|
||||
})
|
||||
|
||||
it("Button 'Import' is disabled if not contract address", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport)
|
||||
assert.equal(await button.isEnabled(), false, 'button enabled')
|
||||
})
|
||||
|
||||
it("Fill 'Address' with valid contract , SOKOL", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractAddress)
|
||||
await f.clearField(field, 100)
|
||||
await field.sendKeys(contractSokol)
|
||||
})
|
||||
|
||||
it("Button 'Import' is enabled if contract address is correct", async () => {
|
||||
await f.delay(5000)
|
||||
const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport)
|
||||
assert.equal(await button.isEnabled(), true, 'button enabled')
|
||||
})
|
||||
|
||||
it('ABI is fetched ', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.contractABI)
|
||||
abiClipboard = await field.getText()
|
||||
assert.equal(abiClipboard.length, 4457, "ABI isn't fetched")
|
||||
})
|
||||
|
||||
it('icon copy is displayed for ABI ', async () => {
|
||||
const field = await f.waitUntilShowUp(screens.importAccounts.iconCopy)
|
||||
assert.notEqual(field, false, "icon copy isn't displayed")
|
||||
await field.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text, abiClipboard, "address account wasn't copied to clipboard")
|
||||
})
|
||||
|
||||
it("Click button 'Import', main screen opens", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport)
|
||||
await f.click(button)
|
||||
const ident = await f.waitUntilShowUp(screens.main.identicon, 20)
|
||||
assert.notEqual(ident, false, "main screen isn't opened")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Check 3dots menu for 'Contract' account", () => {
|
||||
|
||||
it('open 3dots menu', async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.dot.menu)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.dot.item)
|
||||
const items = await f.driver.findElements(menus.dot.item)
|
||||
assert.equal(items.length, 4, '3dot menu has incorrect number of items')
|
||||
})
|
||||
|
||||
it('Check text of items', async () => {
|
||||
const items = await f.driver.findElements(menus.dot.item)
|
||||
assert.equal(await items[0].getText(), 'View on block explorer', '1st item has incorrect text')
|
||||
assert.equal(await items[1].getText(), 'Show QR Code', '2nd item has incorrect text')
|
||||
assert.equal(await items[2].getText(), 'Copy address to clipboard', '3d item has incorrect text')
|
||||
assert.equal(await items[3].getText(), 'Copy ABI to clipboard', '4th item has incorrect text')
|
||||
})
|
||||
|
||||
it("Click 'Copy ABI'", async () => {
|
||||
const items = await f.driver.findElements(menus.dot.item)
|
||||
await items[3].click()
|
||||
const menu = await f.waitUntilShowUp(menus.dot.item, 20)
|
||||
assert.equal(menu, false, "3dot menu wasn't closed")
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text, abiClipboard, "ABI wasn't copied to clipboard")
|
||||
})
|
||||
})
|
||||
|
||||
describe('Execute Method screen', () => {
|
||||
const notContractAddress = '0x56B2e3C3cFf7f3921Dc2e0F8B8e20d1eEc29216b'
|
||||
describe("Check UI and button's functionality", () => {
|
||||
|
||||
it("Click button 'Execute method'", async () => {
|
||||
await f.driver.navigate().refresh()
|
||||
await f.delay(2000)
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonExecuteMethod)
|
||||
assert.notEqual(button, false, "button doesn't displayed")
|
||||
assert.equal(await button.getText(), 'Execute methods', 'button has incorrect name')
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('title is displayed and correct', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.executeMethod.title)
|
||||
assert.notEqual(title, false, 'title isn\'t displayed')
|
||||
assert.equal(await title.getText(), screens.executeMethod.titleText, 'incorrect text')
|
||||
})
|
||||
|
||||
it('Click arrow button leads to main screen', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonArrow)
|
||||
await f.click(button)
|
||||
const identicon = await f.waitUntilShowUp(screens.main.identicon, 40)
|
||||
assert.notEqual(identicon, false, "main screen isn't opened")
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check output for data type : ADDRESS', () => {
|
||||
|
||||
const address = '0x56B2e3C3cFf7f3921Dc2e0F8B8e20d1eEc29216b'
|
||||
|
||||
it("Click button 'Execute method'", async () => {
|
||||
await f.driver.navigate().refresh()
|
||||
await f.delay(2000)
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonExecuteMethod)
|
||||
assert.notEqual(button, false, "button doesn't displayed")
|
||||
assert.equal(await button.getText(), 'Execute methods', 'button has incorrect name')
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it("Select method 'returnAddress'", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[3].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it("Button 'Call data' is displayed and disabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), false, "Button 'Call data' is enabled")
|
||||
})
|
||||
|
||||
it("Fill out input field 'Address'", async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[0], false, "field parameter#1 isn't displayed")
|
||||
await fields[0].sendKeys(address)
|
||||
})
|
||||
|
||||
it("Button 'Call data' is displayed and enabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[1], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[1])
|
||||
assert.equal(text.toLowerCase(), address.toLowerCase(), 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
const icon = await f.waitUntilShowUp(screens.executeMethod.copy)
|
||||
assert.notEqual(icon, false, 'icon copy isn\'t displayed')
|
||||
await icon.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.toLowerCase(), address.toLowerCase(), "output wasn't copied to clipboard")
|
||||
})
|
||||
|
||||
it("2nd call doesn't throw the error", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
await button.click()
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(field, false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(field)
|
||||
assert.equal(text.toLowerCase(), address.toLowerCase(), 'incorrect value was returned')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check output for data type : STRING', () => {
|
||||
const stringValue = 'POA network'
|
||||
|
||||
it("Select method 'returnString'", async () => {
|
||||
await f.delay(3000)
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[14].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it('Fill out input parameter field ', async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[0], false, "field parameter#1 isn't displayed")
|
||||
await fields[0].sendKeys(stringValue)
|
||||
})
|
||||
|
||||
it("Click button 'Call data' ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[1], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[1])
|
||||
assert.equal(text, stringValue, 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
const icon = await f.waitUntilShowUp(screens.executeMethod.copy)
|
||||
assert.notEqual(icon, false, 'icon copy isn\'t displayed')
|
||||
await icon.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.toLowerCase(), stringValue.toLowerCase(), "output wasn't copied to clipboard")
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check output for data type : BOOLEAN', () => {
|
||||
|
||||
it("Select method 'returnBoolean'", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[5].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it('Select value TRUE from dropdown menu', async () => {
|
||||
const arrows = await f.driver.findElements(screens.executeMethod.selectArrow)
|
||||
await arrows[1].click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
assert.equal(await list[1].getText(), 'true', 'TRUE menu item: incorrect text')
|
||||
assert.equal(list.length, 2, "drop down menu isn't displayed")
|
||||
await list[1].click()
|
||||
})
|
||||
|
||||
it("Click button 'Call data' ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value: TRUE', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[0], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[0])
|
||||
assert.equal(text, 'true', 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('Select value FALSE from dropdown menu', async () => {
|
||||
const arrows = await f.driver.findElements(screens.executeMethod.selectArrow)
|
||||
await arrows[1].click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
assert.equal(await list[0].getText(), 'false', 'FALSE menu item: incorrect text')
|
||||
assert.equal(list.length, 2, "drop down menu isn't displayed")
|
||||
await list[0].click()
|
||||
})
|
||||
|
||||
it("Click button 'Call data' ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value, FALSE', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[0], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[0])
|
||||
assert.equal(text, 'false', 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
const icon = await f.waitUntilShowUp(screens.executeMethod.copy)
|
||||
assert.notEqual(icon, false, 'icon copy isn\'t displayed')
|
||||
await icon.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.toLowerCase(), 'false', "output wasn't copied to clipboard")
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('Check output for data type : BYTES', () => {
|
||||
|
||||
const bytesValue = '0x010203'
|
||||
|
||||
it("Select method 'returnBytes1'", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[7].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it('Fill out input parameter field ', async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[0], false, "field parameter#1 isn't displayed")
|
||||
await fields[0].sendKeys(bytesValue)
|
||||
})
|
||||
|
||||
it("Click button 'Call data' ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[1], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[1])
|
||||
assert.equal(text, bytesValue, 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
const icon = await f.waitUntilShowUp(screens.executeMethod.copy)
|
||||
assert.notEqual(icon, false, 'icon copy isn\'t displayed')
|
||||
await icon.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.toLowerCase(), bytesValue.toLowerCase(), "output wasn't copied to clipboard")
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check output for data type : UINT256', () => {
|
||||
|
||||
const uint256Value = '1122334455667788991122334455667788'
|
||||
|
||||
it("Select method 'returnUint256'", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[17].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it('Fill out input parameter field ', async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[0], false, "field parameter#1 isn't displayed")
|
||||
await fields[0].sendKeys(uint256Value)
|
||||
})
|
||||
|
||||
it("Click button 'Call data' ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[1], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[1])
|
||||
assert.equal(text, uint256Value, 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
const icon = await f.waitUntilShowUp(screens.executeMethod.copy)
|
||||
assert.notEqual(icon, false, 'icon copy isn\'t displayed')
|
||||
await icon.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.toLowerCase(), uint256Value.toLowerCase(), "output wasn't copied to clipboard")
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check output for data type : INT256', () => {
|
||||
|
||||
const int256Value = '-1122334455667788991122334455667788'
|
||||
|
||||
it("Select method 'returnInt256'", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[10].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it('Fill out input parameter field ', async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[0], false, "field parameter#1 isn't displayed")
|
||||
await fields[0].sendKeys(int256Value)
|
||||
})
|
||||
|
||||
it("Click button 'Call data' ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCall)
|
||||
assert.notEqual(button, false, "button 'Call data' isn't displayed")
|
||||
assert.equal(await button.isEnabled(), true, "Button 'Call data' is disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it('method returns correct value', async () => {
|
||||
await f.delay(3000)
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldOutput)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldOutput)
|
||||
assert.notEqual(fields[1], false, "field 'Output' isn't displayed")
|
||||
const text = await f.waitUntilHasValue(fields[1])
|
||||
assert.equal(text, int256Value, 'incorrect value was returned')
|
||||
})
|
||||
|
||||
it('icon copy cliboard is displayed and clickable', async () => {
|
||||
const icon = await f.waitUntilShowUp(screens.executeMethod.copy)
|
||||
assert.notEqual(icon, false, 'icon copy isn\'t displayed')
|
||||
await icon.click()
|
||||
})
|
||||
|
||||
it('Check clipboard buffer', async () => {
|
||||
const text = clipboardy.readSync()
|
||||
assert.equal(text.toLowerCase(), int256Value.toLowerCase(), "output wasn't copied to clipboard")
|
||||
})
|
||||
})
|
||||
|
||||
describe('Check executed method', () => {
|
||||
|
||||
it("Select method 'transfer'", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.selectArrow)
|
||||
await field.click()
|
||||
await f.waitUntilShowUp(screens.executeMethod.items)
|
||||
const list = await f.driver.findElements(screens.executeMethod.items)
|
||||
await list[21].click()
|
||||
assert.equal(list.length, 22, "drop down menu isn't displayed")
|
||||
})
|
||||
|
||||
it("Button 'Copy ABI encoded' is displayed", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCopyABI)
|
||||
assert.notEqual(button, false, "button 'Copy ABI encoded' isn't displayed")
|
||||
})
|
||||
|
||||
it("Button 'Copy ABI encoded' is disabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCopyABI)
|
||||
assert.equal(await button.isEnabled(), false, "button 'Copy ABI encoded' enabled")
|
||||
})
|
||||
|
||||
it("Button 'Next' is disabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonNext)
|
||||
assert.equal(await button.isEnabled(), false, "button 'Next' enabled")
|
||||
})
|
||||
|
||||
it("Fill out parameter '_value' with valid data", async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[1], false, "field address isn't displayed")
|
||||
await fields[1].sendKeys('1')
|
||||
})
|
||||
|
||||
it("Button 'Copy ABI encoded' is disabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCopyABI)
|
||||
assert.equal(await button.isEnabled(), false, "button 'Copy ABI encoded' enabled")
|
||||
})
|
||||
|
||||
it("Button 'Next' is disabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonNext)
|
||||
assert.equal(await button.isEnabled(), false, "button 'Next' enabled")
|
||||
})
|
||||
it("Fill out parameter '_to' with wrong data", async () => {
|
||||
await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
const fields = await f.driver.findElements(screens.executeMethod.fieldParameter)
|
||||
assert.notEqual(fields[0], false, "field address isn't displayed")
|
||||
await fields[0].sendKeys(wrongAddress)
|
||||
})
|
||||
|
||||
it("Error message if click 'Copy ABI encoded' with wrong address", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCopyABI)
|
||||
await button.click()
|
||||
const error = await f.waitUntilShowUp(elements.error)
|
||||
assert.notEqual(error, false, 'no error message')
|
||||
})
|
||||
|
||||
it('Close error message', async () => {
|
||||
const button = await f.waitUntilShowUp(elements.errorClose)
|
||||
await button.click()
|
||||
const title = await f.waitUntilShowUp(screens.executeMethod.title)
|
||||
assert.notEqual(title, false, "error message isn't closed")
|
||||
})
|
||||
|
||||
it.skip("Error message if click 'Next' with wrong address", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonNext)
|
||||
await button.click()
|
||||
const error = await f.waitUntilShowUp(elements.error)
|
||||
assert.notEqual(error, false, 'no error message')
|
||||
})
|
||||
|
||||
it.skip('Close error message', async () => {
|
||||
const button = await f.waitUntilShowUp(elements.errorClose)
|
||||
await button.click()
|
||||
const title = await f.waitUntilShowUp(screens.executeMethod.title)
|
||||
assert.notEqual(title, false, "error message isn't closed")
|
||||
})
|
||||
|
||||
it("Fill out parameter '_to' with valid data", async () => {
|
||||
const field = await f.waitUntilShowUp(screens.executeMethod.fieldParameter)
|
||||
await f.clearField(field, 100)
|
||||
await field.sendKeys(notContractAddress)
|
||||
assert.notEqual(field, false, "field address isn't displayed")
|
||||
})
|
||||
|
||||
it("Button 'Next' is enabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonNext)
|
||||
assert.equal(await button.isEnabled(), true, "button 'Next' disabled")
|
||||
})
|
||||
|
||||
it("Button 'Copy ABI encoded' is enabled", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonCopyABI)
|
||||
assert.equal(await button.isEnabled(), true, "button 'Copy ABI encoded' disabled")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it("Click button 'Next'", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonNext)
|
||||
assert.notEqual(button, false, "button 'Next' isn't displayed")
|
||||
await button.click()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Choose Contract Executor', () => {
|
||||
|
||||
it('Title is displayed and correct', async () => {
|
||||
await f.delay(5000)
|
||||
const title = await f.waitUntilShowUp(screens.chooseContractExecutor.title)
|
||||
assert.notEqual(title, false, 'title isn\'t displayed')
|
||||
assert.equal(await title.getText(), screens.chooseContractExecutor.titleText, 'incorrect text')
|
||||
})
|
||||
|
||||
it('Two accounts displayed', async () => {
|
||||
const accs = await f.waitUntilShowUp(screens.chooseContractExecutor.account)
|
||||
assert.notEqual(accs, false, 'accounts aren\'t displayed')
|
||||
const accounts = await f.driver.findElements(screens.chooseContractExecutor.account)
|
||||
assert.equal(accounts.length, 4, "number of accounts isn't 2")
|
||||
})
|
||||
|
||||
it("Click arrow button leads to 'Execute Method' screen ", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.chooseContractExecutor.buttonArrow)
|
||||
assert.notEqual(button, false, 'button isn\'t displayed')
|
||||
await button.click()
|
||||
await f.delay(2000)
|
||||
|
||||
const title = await f.waitUntilShowUp(screens.executeMethod.title)
|
||||
assert.notEqual(title, false, 'title isn\'t displayed')
|
||||
assert.equal(await title.getText(), screens.executeMethod.titleText, "'Execute Method' screen isn't opened")
|
||||
})
|
||||
|
||||
it("Return back to 'Choose Contract Executor' screen", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.executeMethod.buttonNext)
|
||||
assert.notEqual(button, false, "button 'Next' isn't displayed")
|
||||
await button.click()
|
||||
})
|
||||
|
||||
it("Button 'Next' is disabled by default", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.chooseContractExecutor.buttonNext)
|
||||
assert.notEqual(button, false, 'button isn\'t displayed')
|
||||
assert.equal(await button.isEnabled(), false, 'button enabled by default')
|
||||
})
|
||||
|
||||
it('User is able to select account', async () => {
|
||||
await f.waitUntilShowUp(screens.chooseContractExecutor.account)
|
||||
const accounts = await f.driver.findElements(screens.chooseContractExecutor.account)
|
||||
const account = accounts[1]
|
||||
await account.click()
|
||||
const selected = await f.driver.findElements(screens.chooseContractExecutor.selectedAccount)
|
||||
assert.equal(selected.length, 1, "account isn't selected")
|
||||
})
|
||||
|
||||
it('User is able to select only one account', async () => {
|
||||
const account = (await f.driver.findElements(screens.chooseContractExecutor.account))[2]
|
||||
await account.click()
|
||||
const selected = await f.driver.findElements(screens.chooseContractExecutor.selectedAccount)
|
||||
assert.equal(selected.length, 1, 'more than one accounts are selected')
|
||||
})
|
||||
|
||||
it("Click button 'Next' open 'Confirm transaction' screen", async () => {
|
||||
const button = await f.waitUntilShowUp(screens.chooseContractExecutor.buttonNext)
|
||||
await button.click()
|
||||
await f.delay(3000)
|
||||
const reject = await f.waitUntilShowUp(screens.confirmTransaction.button.reject)
|
||||
assert.notEqual(reject, false, "button reject isn't displayed")
|
||||
})
|
||||
|
||||
it("Button 'Buy POA' is displayed", async function () {
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.buyEther)
|
||||
assert.equal(await button.getText(), 'Buy POA', 'button has incorrect name')
|
||||
assert.equal(await button.isEnabled(), true, 'button is disabled')
|
||||
})
|
||||
|
||||
it("Open screen 'Buy'", async function () {
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.buyEther)
|
||||
await button.click()
|
||||
const title = await f.waitUntilShowUp(screens.buyEther.title)
|
||||
assert.equal(await title.getText(), 'Buy POA', "screen 'Buy POA' has incorrect title text")
|
||||
const arrow = await f.waitUntilShowUp(elements.buttonArrow)
|
||||
await arrow.click()
|
||||
})
|
||||
|
||||
it("Click button 'Reject' open contract's account screen", async () => {
|
||||
const reject = await f.waitUntilShowUp(screens.confirmTransaction.button.reject)
|
||||
assert.equal(await reject.getText(), 'Reject', 'button has incorrect name')
|
||||
await reject.click()
|
||||
const buttonExecute = await f.waitUntilShowUp(screens.executeMethod.buttonExecuteMethod)
|
||||
assert.notEqual(buttonExecute, false, "contract's account hasn't opened")
|
||||
})
|
||||
|
||||
it("Button arrow leads to executor's account screen", async () => {
|
||||
assert.equal(await f.executeTransferMethod(0, account1), true, "can't execute the method 'transfer'")
|
||||
await f.delay(2000)
|
||||
const arrow = await f.waitUntilShowUp(elements.buttonArrow)
|
||||
await arrow.click()
|
||||
await f.delay(2000)
|
||||
const address = await f.waitUntilShowUp(screens.main.address)
|
||||
assert.equal((await address.getText()).toUpperCase(), getCreatedAccounts()[0], "executors account isn't opened")
|
||||
})
|
||||
|
||||
it('Switch to contract account ', async () => {
|
||||
const accountMenu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await accountMenu.click()
|
||||
const item = await f.waitUntilShowUp(menus.account.account4)
|
||||
await item.click()
|
||||
await f.delay(2000)
|
||||
const address = await f.waitUntilShowUp(screens.main.address)
|
||||
assert.equal((await address.getText()).toUpperCase(), contractSokol.toUpperCase(), "contract's account isn't opened")
|
||||
})
|
||||
|
||||
it("Confirm transaction: button 'Reject All' leads to contract's account screen", async () => {
|
||||
assert.equal(await f.executeTransferMethod(0, account1), true, "can't execute the method 'transfer'")
|
||||
const rejectAll = await f.waitUntilShowUp(screens.confirmTransaction.button.rejectAll)
|
||||
assert.equal(await rejectAll.getText(), 'Reject All', 'button has incorrect name')
|
||||
await rejectAll.click()
|
||||
await f.delay(2000)
|
||||
const address = await f.waitUntilShowUp(screens.main.address)
|
||||
assert.equal((await address.getText()).toUpperCase(), contractSokol.toUpperCase(), "contract account isn't opened")
|
||||
})
|
||||
|
||||
it("Confirm transaction: button 'Submit' leads to contract's account screen", async () => {
|
||||
assert.equal(await f.executeTransferMethod(2, account1), true, "can't execute the method 'transfer'")
|
||||
await f.delay(2000)
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.submit)
|
||||
assert.equal(await button.getAttribute('value'), 'Submit', 'button has incorrect name')
|
||||
await button.click()
|
||||
await f.delay(2000)
|
||||
const address = await f.waitUntilShowUp(screens.main.address)
|
||||
assert.equal((await address.getText()).toUpperCase(), contractSokol.toUpperCase(), "contract account isn't opened")
|
||||
})
|
||||
|
||||
it("Label 'CONTRACT' present", async () => {
|
||||
const menu = await f.waitUntilShowUp(menus.account.menu)
|
||||
await menu.click()
|
||||
await f.waitUntilShowUp(menus.account.label)
|
||||
const label = (await f.driver.findElements(menus.account.label))[1]
|
||||
assert.equal(await label.getText(), 'CONTRACT', 'label incorrect')
|
||||
})
|
||||
it('Delete imported account', async () => {
|
||||
await f.waitUntilShowUp(menus.account.delete)
|
||||
const items = await f.driver.findElements(menus.account.delete)
|
||||
await items[1].click()
|
||||
const button = await f.waitUntilShowUp(screens.deleteImportedAccount.buttons.yes)
|
||||
await button.click()
|
||||
const buttonArrow = await f.waitUntilShowUp(screens.settings.buttons.arrow)
|
||||
await buttonArrow.click()
|
||||
const identicon = await f.waitUntilShowUp(screens.main.identicon)
|
||||
assert.notEqual(identicon, false, 'main screen didn\'t opened')
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = importContractAccount
|
|
@ -0,0 +1,68 @@
|
|||
const assert = require('assert')
|
||||
const { screens, menus, NETWORKS } = require('../elements')
|
||||
const testSeedPhrase = 'horn among position unable audit puzzle cannon apology gun autumn plug parrot'
|
||||
|
||||
const importGanacheSeedPhrase = async (f, account2, password) => {
|
||||
it('logs out', async () => {
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
const menu = await f.waitUntilShowUp(menus.sandwich.menu)
|
||||
await menu.click()
|
||||
const logOut = await f.waitUntilShowUp(menus.sandwich.logOut)
|
||||
assert.equal(await logOut.getText(), menus.sandwich.textLogOut)
|
||||
await logOut.click()
|
||||
})
|
||||
|
||||
it('restores from seed phrase', async () => {
|
||||
const restoreSeedLink = await f.waitUntilShowUp(screens.lock.linkRestore)
|
||||
assert.equal(await restoreSeedLink.getText(), screens.lock.linkRestoreText)
|
||||
await restoreSeedLink.click()
|
||||
})
|
||||
|
||||
it('adds seed phrase', async () => {
|
||||
const seedTextArea = await f.waitUntilShowUp(screens.restoreVault.textArea)
|
||||
await seedTextArea.sendKeys(testSeedPhrase)
|
||||
|
||||
let field = await f.driver.findElement(screens.restoreVault.fieldPassword)
|
||||
await field.sendKeys(password)
|
||||
field = await f.driver.findElement(screens.restoreVault.fieldPasswordConfirm)
|
||||
await field.sendKeys(password)
|
||||
field = await f.waitUntilShowUp(screens.restoreVault.buttos.ok)
|
||||
await f.click(field)
|
||||
})
|
||||
|
||||
it('balance renders', async () => {
|
||||
const balance = await f.waitUntilShowUp(screens.main.balance)
|
||||
assert.equal(await balance.getText(), '100.000', "balance isn't correct")
|
||||
})
|
||||
|
||||
it('sends transaction', async () => {
|
||||
const sendButton = await f.waitUntilShowUp(screens.main.buttons.send)
|
||||
assert.equal(await sendButton.getText(), screens.main.buttons.sendText)
|
||||
await f.click(sendButton)
|
||||
})
|
||||
|
||||
it('adds recipient address and amount', async () => {
|
||||
const sendTranscationScreen = await f.waitUntilShowUp(screens.sendTransaction.title)
|
||||
assert.equal(await sendTranscationScreen.getText(), screens.sendTransaction.titleText, 'Transaction screen has incorrect titlr')
|
||||
const inputAddress = await f.waitUntilShowUp(screens.sendTransaction.field.address)
|
||||
const inputAmmount = await f.waitUntilShowUp(screens.sendTransaction.field.amount)
|
||||
await inputAddress.sendKeys(account2)
|
||||
await inputAmmount.sendKeys('10')
|
||||
const button = await f.waitUntilShowUp(screens.sendTransaction.buttonNext)
|
||||
assert.equal(await button.getText(), 'Next', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('confirms transaction', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.confirmTransaction.button.submit)
|
||||
assert.equal(await button.getAttribute('value'), 'Submit', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('finds the transaction in the transactions list', async () => {
|
||||
const transactionAmount = await f.waitUntilShowUp(screens.main.transactionList)
|
||||
assert.equal(await transactionAmount.getText(), '10.0')
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = importGanacheSeedPhrase
|
|
@ -0,0 +1,58 @@
|
|||
const assert = require('assert')
|
||||
const { screens } = require('../elements')
|
||||
|
||||
const login = async (f, password) => {
|
||||
it('title is \'Nifty Wallet\'', async () => {
|
||||
const title = await f.driver.getTitle()
|
||||
assert.equal(title, 'Nifty Wallet', 'title is incorrect')
|
||||
})
|
||||
|
||||
it('screen \'Terms of Use\' has not empty agreement', async () => {
|
||||
await f.delay(5000)
|
||||
const terms = await f.waitUntilShowUp(screens.TOU.agreement, 900)
|
||||
const text = await terms.getText()
|
||||
assert.equal(text.length > 400, true, 'agreement is too short')
|
||||
})
|
||||
|
||||
it('screen \'Terms of Use\' has correct title', async () => {
|
||||
const terms = await f.waitUntilShowUp(screens.TOU.title)
|
||||
assert.equal(await terms.getText(), screens.TOU.titleText, 'title is incorrect')
|
||||
})
|
||||
|
||||
it('checks if the TOU contains link \'Terms of service\'', async () => {
|
||||
const element = await f.waitUntilShowUp(screens.TOU.linkTerms)
|
||||
await f.scrollTo(screens.TOU.linkTerms)
|
||||
assert.notEqual(element, null, ' link \'Terms of service\' isn\'t present')
|
||||
assert.equal(await element.getText(), screens.TOU.linkTermsText, 'incorrect name of link \'Terms of service\'')
|
||||
})
|
||||
|
||||
it('checks if the button \'Accept\' is present and enabled', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.TOU.button)
|
||||
assert.notEqual(button, false, 'button isn\'t present')
|
||||
assert.equal(await button.isEnabled(), true, 'button isn\'t enabled')
|
||||
assert.equal(await button.getText(), 'Accept', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('accepts password with length of eight', async () => {
|
||||
const passwordBox = await f.waitUntilShowUp(screens.create.fieldPassword)
|
||||
const passwordBoxConfirm = await f.waitUntilShowUp(screens.create.fieldPasswordConfirm)
|
||||
const button = await f.waitUntilShowUp(screens.create.button)
|
||||
assert.equal(await button.getText(), 'Create', 'button has incorrect name')
|
||||
await passwordBox.sendKeys(password)
|
||||
await passwordBoxConfirm.sendKeys(password)
|
||||
await f.click(button)
|
||||
})
|
||||
|
||||
it('shows vault was created and seed phrase', async () => {
|
||||
await f.delay(300)
|
||||
const element = await f.waitUntilShowUp(screens.seedPhrase.fieldPhrase)
|
||||
const seedPhrase = await element.getText()
|
||||
assert.equal(seedPhrase.split(' ').length, 12)
|
||||
const continueAfterSeedPhrase = await f.waitUntilShowUp(screens.seedPhrase.buttonIveCopied)
|
||||
assert.equal(await continueAfterSeedPhrase.getText(), screens.seedPhrase.textButtonIveCopied)
|
||||
await f.click(continueAfterSeedPhrase)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = login
|
|
@ -0,0 +1,9 @@
|
|||
const setup = async (f) => {
|
||||
it('switches to extensions list', async () => {
|
||||
await f.delay(300)
|
||||
await f.switchToFirstPage()
|
||||
await f.delay(5000)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = setup
|
|
@ -0,0 +1,67 @@
|
|||
const assert = require('assert')
|
||||
const webdriver = require('selenium-webdriver')
|
||||
const { By } = webdriver
|
||||
const { screens, NETWORKS } = require('../elements')
|
||||
|
||||
const signData = async (f) => {
|
||||
it('Simulate sign request ', async () => {
|
||||
await f.delay(5000)
|
||||
await f.setProvider(NETWORKS.LOCALHOST)
|
||||
await f.driver.get('https://danfinlay.github.io/js-eth-personal-sign-examples/')
|
||||
const button = await f.waitUntilShowUp(By.id('ethSignButton'))
|
||||
assert.notEqual(button, false, "resource isn't responding")
|
||||
await button.click()
|
||||
await f.delay(5000)
|
||||
})
|
||||
|
||||
it('navigates back to MetaMask popup in the tab', async () => {
|
||||
if (process.env.SELENIUM_BROWSER === 'chrome') {
|
||||
await f.driver.get(`chrome-extension://${f.extensionId}/popup.html`)
|
||||
} else if (process.env.SELENIUM_BROWSER === 'firefox') {
|
||||
await f.driver.get(`moz-extension://${f.extensionId}/popup.html`)
|
||||
}
|
||||
await f.delay(700)
|
||||
})
|
||||
|
||||
it('error message is displayed and contains text', async () => {
|
||||
const error = await f.waitUntilShowUp(screens.signMessage.error)
|
||||
assert.notEqual(error, false, 'error message isn\'t displayed')
|
||||
const text = await error.getText()
|
||||
assert.equal(text.length > 183, true, 'error message hasn\'t text')
|
||||
})
|
||||
|
||||
it('account name is displayed and correct', async () => {
|
||||
const name = await f.waitUntilShowUp(screens.signMessage.accountName)
|
||||
assert.notEqual(name, false, 'account name isn\'t displayed')
|
||||
assert.equal(await name.getText(), 'new name', 'account name is incorrect')
|
||||
})
|
||||
|
||||
it('title is displayed and correct', async () => {
|
||||
const title = await f.waitUntilShowUp(screens.signMessage.title)
|
||||
assert.notEqual(title, false, 'title isn\'t displayed')
|
||||
assert.equal(await title.getText(), 'Sign message', 'title is incorrect')
|
||||
})
|
||||
|
||||
it('message is displayed and correct', async () => {
|
||||
const message = await f.waitUntilShowUp(screens.signMessage.message)
|
||||
assert.notEqual(message, false, 'message isn\'t displayed')
|
||||
assert.equal((await message.getText()).length > 32, true, 'message is incorrect')
|
||||
})
|
||||
|
||||
it('button \'Cancel\' is enabled and lead to main screen ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.signMessage.buttons.cancel)
|
||||
assert.equal(await button.isEnabled(), true, 'button isn\'t enabled')
|
||||
assert.equal(await button.getText(), 'Cancel', 'button has incorrect name')
|
||||
})
|
||||
|
||||
it('button \'Sign\' is enabled and lead to main screen ', async () => {
|
||||
const button = await f.waitUntilShowUp(screens.signMessage.buttons.sign)
|
||||
assert.equal(await button.isEnabled(), true, 'button isn\'t enabled')
|
||||
assert.equal(await button.getText(), 'Sign', 'button has incorrect name')
|
||||
await f.click(button)
|
||||
const identicon = await f.waitUntilShowUp(screens.main.identicon)
|
||||
assert.notEqual(identicon, false, 'main screen didn\'t opened')
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = signData
|
|
@ -0,0 +1,54 @@
|
|||
const assert = require('assert')
|
||||
const {
|
||||
nestedJsonObjToArray,
|
||||
} = require('../../../../../../old-ui/app/accounts/import/helpers')
|
||||
|
||||
describe('#nestedJsonObjToArray', () => {
|
||||
const JsonPattern1 = {
|
||||
key1: 'val1',
|
||||
key2: 'val2',
|
||||
}
|
||||
const JsonPattern2 = {
|
||||
key1: 'val1',
|
||||
key2: {
|
||||
key3_1: 'val2',
|
||||
key3_2: 'val3',
|
||||
},
|
||||
}
|
||||
const JsonPattern3 = {
|
||||
key1: 'val1',
|
||||
key2: ['val2', 'val3'],
|
||||
key3: {
|
||||
key3_1: 'val4',
|
||||
key3_2: 'val5',
|
||||
},
|
||||
}
|
||||
const JsonPattern4 = {
|
||||
key1: 'val1',
|
||||
key2: {
|
||||
key3_1: 'val2',
|
||||
key3_2: {
|
||||
key3_2_1: 'val3',
|
||||
key3_2_3: 'val4',
|
||||
},
|
||||
},
|
||||
}
|
||||
const JsonPattern5 = {
|
||||
key1: 'val1',
|
||||
key2: {
|
||||
key3_1: 'val2',
|
||||
key3_2: {
|
||||
key3_2_1: 'val3',
|
||||
key3_2_3: ['val4', 'val5', {key3_2_3_1: 'val6'}],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
it('converts nested json objects to arrays correctly', () => {
|
||||
assert.deepEqual(['val1', 'val2'], nestedJsonObjToArray(JsonPattern1))
|
||||
assert.deepEqual(['val1', 'val2', 'val3'], nestedJsonObjToArray(JsonPattern2))
|
||||
assert.deepEqual(['val1', 'val2', 'val3', 'val4', 'val5'], nestedJsonObjToArray(JsonPattern3))
|
||||
assert.deepEqual(['val1', 'val2', 'val3', 'val4'], nestedJsonObjToArray(JsonPattern4))
|
||||
assert.deepEqual(['val1', 'val2', 'val3', 'val4', 'val5', 'val6'], nestedJsonObjToArray(JsonPattern5))
|
||||
})
|
||||
})
|
|
@ -106,6 +106,7 @@ var actions = {
|
|||
changePassword,
|
||||
getContract,
|
||||
removeAccount,
|
||||
updateABI,
|
||||
showNewVaultSeed: showNewVaultSeed,
|
||||
showInfoPage: showInfoPage,
|
||||
CLOSE_WELCOME_SCREEN: 'CLOSE_WELCOME_SCREEN',
|
||||
|
@ -665,6 +666,26 @@ function removeAccount (address, network) {
|
|||
}
|
||||
}
|
||||
|
||||
function updateABI (address, network, newABI) {
|
||||
return dispatch => {
|
||||
dispatch(actions.showLoadingIndication())
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
background.updateABI(address, network, newABI, (err, account) => {
|
||||
dispatch(actions.hideLoadingIndication())
|
||||
if (err) {
|
||||
dispatch(actions.displayWarning(err.message))
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
log.info('Implementation ABI for proxy updated: ' + account)
|
||||
dispatch(actions.showAccountsPage())
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function addNewKeyring (type, opts) {
|
||||
return (dispatch) => {
|
||||
dispatch(actions.showLoadingIndication())
|
||||
|
|
Loading…
Reference in New Issue