pull/5370/head
yann300 5 years ago committed by Liana Husikyan
parent 676056ab06
commit 48971f792f
  1. 2
      src/app/tabs/runTab/settings.js
  2. 75
      src/app/ui/sendTxCallbacks.js
  3. 7
      src/app/ui/universal-dapp-ui.js
  4. 2
      test-browser/commands/clickInstance.js
  5. 4
      test-browser/commands/journalLastChild.js
  6. 27
      test-browser/commands/sendLowLevelTx.js
  7. 175
      test-browser/tests/specialFunctions.js

@ -115,7 +115,7 @@ class SettingsUI {
<div class="${css.crow}">
<div class="${css.col1_1}">Value</div>
<div class="${css.gasValueContainer}">
<input type="text" class="form-control ${css.gasNval} ${css.col2}" id="deployAndRunTransferValue" value="0" title="Enter the value and choose the unit">
<input type="text" class="form-control ${css.gasNval} ${css.col2}" id="value" value="0" title="Enter the value and choose the unit">
<select name="unit" class="form-control p-1 ${css.gasNvalUnit} ${css.col2_2}" id="unit">
<option data-unit="wei">wei</option>
<option data-unit="gwei">gwei</option>

@ -1,11 +1,51 @@
const yo = require('yo-yo')
const remixLib = require('remix-lib')
const confirmDialog = require('./confirmDialog')
const modalCustom = require('./modal-dialog-custom')
const modalDialog = require('./modaldialog')
const typeConversion = remixLib.execution.typeConversion
const Web3 = require('web3')
UniversalDAppUI.prototype.confirmationCb = function (executionContext, udapp, network, tx, gasEstimation, continueTxExecution, cancelCb) {
module.exports = {
getCallBacksWithContext: (udapp, executionContext) => {
let callbacks = {}
callbacks.confirmationCb = confirmationCb
callbacks.continueCb = continueCb
callbacks.promptCb = promptCb
callbacks.udapp = udapp
callbacks.executionContext = executionContext
return callbacks
}
}
const continueCb = (error, continueTxExecution, cancelCb) => {
if (error) {
const msg = typeof error !== 'string' ? error.message : error
modalDialog(
'Gas estimation failed',
yo`
<div>Gas estimation errored with the following message (see below).
The transaction execution will likely fail. Do you want to force sending? <br>${msg}</div>
`,
{
label: 'Send Transaction',
fn: () => continueTxExecution()
},
{
label: 'Cancel Transaction',
fn: () => cancelCb()
}
)
} else {
continueTxExecution()
}
}
const promptCb = (okCb, cancelCb) => {
modalCustom.promptPassphrase('Passphrase requested', 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
}
const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
let self = this
if (network.name !== 'Main') {
return continueTxExecution(null)
@ -67,36 +107,3 @@ UniversalDAppUI.prototype.confirmationCb = function (executionContext, udapp, ne
}
)
}
module.exports = confirmationCb
const continueCb = (error, continueTxExecution, cancelCb) => {
if (error) {
const msg = typeof error !== 'string' ? error.message : error
modalDialog(
'Gas estimation failed',
yo`
<div>Gas estimation errored with the following message (see below).
The transaction execution will likely fail. Do you want to force sending? <br>${msg}</div>
`,
{
label: 'Send Transaction',
fn: () => continueTxExecution()
},
{
label: 'Cancel Transaction',
fn: () => cancelCb()
}
)
} else {
continueTxExecution()
}
}
module.exports = continueCb
const promptCb = (okCb, cancelCb) => {
modalCustom.promptPassphrase('Passphrase requested', 'Personal mode is enabled. Please provide passphrase of account', '', okCb, cancelCb)
}
module.exports = promptCb

@ -13,6 +13,7 @@ var remixLib = require('remix-lib')
var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat
var TreeView = require('./TreeView')
var txCallBacks = require('./sendTxCallbacks')
function UniversalDAppUI (udapp, logCallback, executionContext) {
this.udapp = udapp
@ -195,7 +196,6 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address
return instance
}
// TODO this is used by renderInstance when a new instance is displayed.
// this returns a DOM element.
UniversalDAppUI.prototype.getCallButton = function (args) {
@ -233,6 +233,7 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i
}
}
// contractsDetails is used to resolve libraries
const callbacksInContext = txCallBacks.getCallBacksWithContext(self, self.executionContext)
txFormat.buildData(args.contractName, args.contractABI, {}, false, args.funABI, args.funABI.type !== 'fallback' ? value : '', (error, data) => {
if (!error) {
if (!lookupOnly) {
@ -241,7 +242,7 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i
self.logCallback(`${logMsg}`)
}
if (args.funABI.type === 'fallback') data.dataHex = value
self.udapp.callFunction(args.address, data, args.funABI, this.confirmationCb, continueCb, promptCb, (error, txResult) => {
self.udapp.callFunction(args.address, data, args.funABI, callbacksInContext.confirmationCb, callbacksInContext.continueCb, callbacksInContext.promptCb, (error, txResult) => {
if (!error) {
var isVM = self.executionContext.isVM()
if (isVM) {
@ -266,7 +267,7 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i
self.logCallback(msg)
}, (data, runTxCallback) => {
// called for libraries deployment
self.udapp.runTx(data, this.confirmationCb, runTxCallback)
self.udapp.runTx(data, callbacksInContext.confirmationCb, runTxCallback)
})
}

@ -4,7 +4,7 @@ class ClickInstance extends EventEmitter {
command (index) {
index = index + 2
let selector = '.instance:nth-of-type(' + index + ') > div > button'
this.api.waitForElementPresent(selector).click(selector).perform(() => { this.emit('complete') })
this.api.waitForElementPresent(selector).scrollAndClick(selector).perform(() => { this.emit('complete') })
return this
}
}

@ -3,8 +3,8 @@ const EventEmitter = require('events')
class JournalLastChild extends EventEmitter {
command (val) {
this.api
.waitForElementVisible('#journal div:last-child span.text-info', 10000)
.assert.containsText('#journal div:last-child span.text-info', val).perform(() => {
.waitForElementVisible('#journal > div:last-child', 10000)
.assert.containsText('#journal > div:last-child', val).perform(() => {
this.emit('complete')
})
return this

@ -1,20 +1,17 @@
const EventEmitter = require('events')
class sendLowLevelTx extends EventEmitter {
command (browser, address, value, callData, callback) {
this.api.perform((client, done) => {
browser.execute(function (value) {
browser.waitForElementVisible('deployAndRunLLTxSendTransaction', 1000)
.getElementById('deployAndRunLLTxCalldata').value = callData
.waitForElementVisible('deployAndRunTransferValue')
.getElementById('deployAndRunTransferValue').value = value
.click('deployAndRunLLTxSendTransaction', callback)
.done()
if (callback) {
callback.call(this.api)
}
this.emit('complete')
})
})
command (address, value, callData) {
console.log('low level transact to ', address, value, callData)
this.api.waitForElementVisible(`#instance${address} #deployAndRunLLTxSendTransaction`, 1000)
.clearValue(`#instance${address} #deployAndRunLLTxCalldata`)
.setValue(`#instance${address} #deployAndRunLLTxCalldata`, callData)
.waitForElementVisible('#value')
.clearValue('#value')
.setValue('#value', value)
.scrollAndClick(`#instance${address} #deployAndRunLLTxSendTransaction`)
.perform(() => {
this.emit('complete')
})
return this
}
}

@ -2,6 +2,15 @@
var init = require('../helpers/init')
var sauce = require('./sauce')
/**
* both are declared, sending data
* both are declared - receive called, sending wei
* both are declared - fallback should fail cause not payable, sending data and wei
* receive is declared, failing, fallback is not declared, sending data
* receive is not declared, fallback is payable, sending wei
* receive is not declared, fallback is payable, sending data and wei
* both are not declared, sending data and wei, should fail
*/
module.exports = {
before: function (browser, done) {
init(browser, done)
@ -9,22 +18,139 @@ module.exports = {
'@sources': function () {
return sources
},
'Use special functions receive/fullback': function (browser) {
'Use special functions receive/fallback - both are declared, sending data': function (browser) {
browser.waitForElementVisible('#icon-panel', 10000)
.testContracts('receiveAndFallback.sol', sources[0]['browser/receiveAndFallback.sol'], ['CheckSpecials'])
.testContracts('receiveAndFallback.sol', sources[0]['browser/receiveAndFallback.sol'], ['CheckSpecials']) // compile
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.createContract('') // deploy
.clickInstance(0)
.perform((done) => { /*
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '0', '0xaa')
.pause(1000)
.journalLastChildIncludes('to:CheckSpecials.(fallback)')
.journalLastChildIncludes('value:0 wei')
.journalLastChildIncludes('data:0xaa')
.perform(done)
})
})
},
'Use special functions receive/follback - both are declared - receive called, sending wei': function (browser) {
// don't need to redeploy it, same contract
browser.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '1', '')
.pause(1000)
.journalLastChildIncludes('to:CheckSpecials.(receive)')
.journalLastChildIncludes('value:1 wei')
.journalLastChildIncludes('data:0x')
.perform(done)
})
})
},
'Use special functions receive/follback - both are declared - fallback should fail cause not payable, sending data and wei': function (browser) {
// don't need to redeploy it, same contract
browser.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '10', '0xaa')
.pause(1000)
.journalLastChildIncludes('to CheckSpecials.(fallback) errored:')
.journalLastChildIncludes('The called function should be payable if you send value')
.perform(done)
})
})
},
'Use special functions receive/follback - receive is declared, failing, fallback is not declared, sending data': function (browser) {
browser.waitForElementVisible('#icon-panel', 10000)
.testContracts('receiveOnly.sol', sources[1]['browser/receiveOnly.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.clickInstance(1)
.perform((done) => {
browser.getAddressAtPosition(1, (address) => {
browser.sendLowLevelTx(address, '0', '0xaa')
.journalLastChild('dd')
.waitForElementVisible('label[id="deployAndRunLLTxError"]')
.assert.containsText('label[id="deployAndRunLLTxError"]', '')
.pause(1000)
.waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`)
.assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `'fallback' function is not defined`)
.perform(done)
})
})
},
'Use special functions receive/fallback - receive is not declared, fallback is payable, sending wei': function (browser) {
browser.waitForElementVisible('#icon-panel', 10000)
.testContracts('fallbackOnlyPayable.sol', sources[2]['browser/fallbackOnlyPayable.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.clickInstance(2)
.perform((done) => {
browser.getAddressAtPosition(2, (address) => {
browser.sendLowLevelTx(address, '1', '')
.pause(1000)
.journalLastChildIncludes('to:CheckSpecials.(fallback)')
.journalLastChildIncludes('value:1 wei')
.journalLastChildIncludes('data:0x')
.perform(done)
})
*/ })
})
},
'Use special functions receive/follback - receive is not declared, fallback is payable, sending data and wei': function (browser) {
// don't need to redeploy it, same contract
browser.perform((done) => {
browser.getAddressAtPosition(2, (address) => {
browser.sendLowLevelTx(address, '1', '0xaa')
.pause(1000)
.journalLastChildIncludes('to:CheckSpecials.(fallback)')
.journalLastChildIncludes('value:1 wei')
.journalLastChildIncludes('data:0xaa')
.perform(done)
})
})
},
'Use special functions receive/fallback - receive is not declared, fallback should fail cause not payable, sending wei': function (browser) {
browser.waitForElementVisible('#icon-panel', 10000)
.testContracts('fallbackOnlyNotPayable.sol', sources[3]['browser/fallbackOnlyNotPayable.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.clickInstance(3)
.perform((done) => {
browser.getAddressAtPosition(3, (address) => {
browser.sendLowLevelTx(address, '1', '')
.pause(1000)
.waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`)
.assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `should have either 'receive' or payable 'fallback'`)
.perform(done)
})
})
},
'Use special functions receive/fallback - receive and fallback are declared, sending data and wei': function (browser) {
browser.waitForElementVisible('#icon-panel', 10000)
.testContracts('receiveAndFallbackBothPayable.sol', sources[4]['browser/receiveAndFallbackBothPayable.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.pause(10000)
.selectContract('CheckSpecials')
.pause(10000)
.waitForElementVisible('#value')
.clearValue('#value')
.setValue('#value', 0)
.createContract('')
.pause(10000)
.clickInstance(4)
.pause(10000)
.perform((done) => {
browser.getAddressAtPosition(4, (address) => {
browser.sendLowLevelTx(address, '1', '0xaa')
.pause(100000)
.journalLastChildIncludes('to:CheckSpecials.(fallback)')
.journalLastChildIncludes('value:1 wei')
.journalLastChildIncludes('data:0xaa')
.perform(done)
})
})
.end()
},
tearDown: sauce
}
@ -38,18 +164,41 @@ var sources = [
fallback() external {}
}
`
},
}
},
{
'browser/receiveOnly.sol': {
content: `
contract CheckSpecials {
receive() payable external{}
receive() payable external {}
}
`
},
'browser/fallbackOnly.sol': {
}
},
{
'browser/fallbackOnlyPayable.sol': {
content: `
contract CheckSpecials {
fallback() payable external {}
}
`
}
},
{
'browser/fallbackOnlyNotPayable.sol': {
content: `
contract CheckSpecials {
fallback() external {}
}
`
}
},
{
'browser/receiveAndFallbackBothPayable.sol': {
content: `
contract CheckSpecials {
fallback() payable external{}
receive() payable external {}
fallback() payable external {}
}
`
}

Loading…
Cancel
Save