Fixed signMessage, recorder test

yann300-patch-36
David Disu 3 years ago committed by yann300
parent 969b2e7489
commit e31c3c210c
  1. 13
      apps/remix-ide-e2e/src/commands/signMessage.ts
  2. 3
      apps/remix-ide-e2e/src/commands/verifyCallReturnValue.ts
  3. 33
      apps/remix-ide-e2e/src/tests/recorder.test.ts
  4. 14
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  5. 7
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  6. 4
      libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
  7. 26
      libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
  8. 8
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  9. 14
      libs/remix-ui/run-tab/src/lib/types/index.ts

@ -20,9 +20,12 @@ function signMsg (browser: NightwatchBrowser, msg: string, cb: (hash: { value: s
browser browser
.waitForElementPresent('i[id="remixRunSignMsg"]') .waitForElementPresent('i[id="remixRunSignMsg"]')
.click('i[id="remixRunSignMsg"]') .click('i[id="remixRunSignMsg"]')
.waitForElementVisible('textarea[id="prompt_text"]') .waitForElementVisible('*[data-id="signMessageTextarea"]', 120000)
.setValue('textarea[id="prompt_text"]', msg, () => { .click('*[data-id="signMessageTextarea"]')
browser.modalFooterOKClick().perform( .setValue('*[data-id="signMessageTextarea"]', msg)
.waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
.click('[data-id="udappNotify-modal-footer-ok-react"]')
.perform(
(client, done) => { (client, done) => {
browser.waitForElementVisible('span[id="remixRunSignMsgHash"]').getText('span[id="remixRunSignMsgHash"]', (v) => { hash = v; done() }) browser.waitForElementVisible('span[id="remixRunSignMsgHash"]').getText('span[id="remixRunSignMsgHash"]', (v) => { hash = v; done() })
} }
@ -32,13 +35,13 @@ function signMsg (browser: NightwatchBrowser, msg: string, cb: (hash: { value: s
browser.waitForElementVisible('span[id="remixRunSignMsgSignature"]').getText('span[id="remixRunSignMsgSignature"]', (v) => { signature = v; done() }) browser.waitForElementVisible('span[id="remixRunSignMsgSignature"]').getText('span[id="remixRunSignMsgSignature"]', (v) => { signature = v; done() })
} }
) )
.modalFooterOKClick() .waitForElementPresent('[data-id="udappNotify-modal-footer-ok-react"]')
.click('[data-id="udappNotify-modal-footer-ok-react"]')
.perform( .perform(
() => { () => {
cb(hash, signature) cb(hash, signature)
} }
) )
})
} }
module.exports = SelectContract module.exports = SelectContract

@ -15,7 +15,7 @@ class VerifyCallReturnValue extends EventEmitter {
function verifyCallReturnValue (browser: NightwatchBrowser, address: string, checks: string[], done: VoidFunction) { function verifyCallReturnValue (browser: NightwatchBrowser, address: string, checks: string[], done: VoidFunction) {
browser.execute(function (address: string) { browser.execute(function (address: string) {
const nodes = document.querySelectorAll('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]') as NodeListOf<HTMLElement> const nodes = document.querySelectorAll('#instance' + address + ' [data-id="udapp_value"]') as NodeListOf<HTMLElement>
const ret = [] const ret = []
for (let k = 0; k < nodes.length; k++) { for (let k = 0; k < nodes.length; k++) {
const text = nodes[k].innerText ? nodes[k].innerText : nodes[k].textContent const text = nodes[k].innerText ? nodes[k].innerText : nodes[k].textContent
@ -23,7 +23,6 @@ function verifyCallReturnValue (browser: NightwatchBrowser, address: string, che
} }
return ret return ret
}, [address], function (result) { }, [address], function (result) {
console.log('verifyCallReturnValue', result)
for (const k in checks) { for (const k in checks) {
browser.assert.equal(result.value[k].trim(), checks[k].trim()) browser.assert.equal(result.value[k].trim(), checks[k].trim())
} }

@ -17,16 +17,14 @@ module.exports = {
.pause(5000) .pause(5000)
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite .selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite
.click('div[class^="cardContainer"] i[class^="arrow"]') .click('[data-id="udapp_arrow"]')
.click('#runTabView .runtransaction') .click('[data-id="runtransaction"]')
.waitForElementPresent('.instance:nth-of-type(2)') .clickInstance(0)
.click('.instance:nth-of-type(2) > div > button') .clickInstance(1)
.waitForElementPresent('.instance:nth-of-type(3)')
.click('.instance:nth-of-type(3) > div > button')
.clickFunction('getInt - call') .clickFunction('getInt - call')
.clickFunction('getAddress - call') .clickFunction('getAddress - call')
.clickFunction('getFromLib - call') .clickFunction('getFromLib - call')
.waitForElementPresent('div[class^="contractActionsContainer"] div[class^="value"] ul') .waitForElementPresent('[data-id="udapp_value"]')
.getAddressAtPosition(1, (address) => { .getAddressAtPosition(1, (address) => {
console.log('Test Recorder ' + address) console.log('Test Recorder ' + address)
addressRef = address addressRef = address
@ -39,11 +37,15 @@ module.exports = {
.testContracts('testRecorder.sol', sources[0]['testRecorder.sol'], ['testRecorder']) .testContracts('testRecorder.sol', sources[0]['testRecorder.sol'], ['testRecorder'])
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.createContract('12') .createContract('12')
.waitForElementPresent('.instance:nth-of-type(2)') .clickInstance(0)
.click('.instance:nth-of-type(2) > div > button')
.clickFunction('set - transact (not payable)', { types: 'uint256 _p', values: '34' }) .clickFunction('set - transact (not payable)', { types: 'uint256 _p', values: '34' })
.click('i.savetransaction') .click('i.savetransaction')
.modalFooterOKClick() .waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]')
.execute(function () {
const modalOk = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
modalOk.click()
})
.getEditorValue(function (result) { .getEditorValue(function (result) {
const parsed = JSON.parse(result) const parsed = JSON.parse(result)
browser.assert.equal(JSON.stringify(parsed.transactions[0].record.parameters), JSON.stringify(scenario.transactions[0].record.parameters)) browser.assert.equal(JSON.stringify(parsed.transactions[0].record.parameters), JSON.stringify(scenario.transactions[0].record.parameters))
@ -73,11 +75,16 @@ module.exports = {
.pause(1000) .pause(1000)
.createContract('') .createContract('')
.click('i.savetransaction') .click('i.savetransaction')
.modalFooterOKClick() .waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]')
.execute(function () {
const modalOk = document.querySelector('[data-id="udappNotify-modal-footer-ok-react"]') as any
modalOk.click()
})
.click('*[data-id="deployAndRunClearInstances"]') // clear udapp .click('*[data-id="deployAndRunClearInstances"]') // clear udapp
.click('*[data-id="terminalClearConsole"]') // clear terminal .click('*[data-id="terminalClearConsole"]') // clear terminal
.click('#runTabView .runtransaction') .click('[data-id="runtransaction"]')
.clickInstance(1) .clickInstance(2)
.pause(1000) .pause(1000)
.clickFunction('set2 - transact (not payable)', { types: 'uint256 _po', values: '10' }) .clickFunction('set2 - transact (not payable)', { types: 'uint256 _po', values: '10' })
.testFunction('last', .testFunction('last',

@ -550,7 +550,8 @@ export const updateTxFeeContent = (content: string) => {
dispatch(setTxFeeContent(content)) dispatch(setTxFeeContent(content))
} }
const addInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any, decodedResponse?: any }) => { const addInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record<number, any> }) => {
instance.decodedResponse = {}
dispatch(addNewInstance(instance)) dispatch(addNewInstance(instance))
} }
@ -590,7 +591,7 @@ export const getContext = () => {
} }
export const runTransactions = ( export const runTransactions = (
index: number, instanceIndex: number,
lookupOnly: boolean, lookupOnly: boolean,
funcABI: FuncABI, funcABI: FuncABI,
inputsValues: string, inputsValues: string,
@ -601,7 +602,8 @@ export const runTransactions = (
logBuilder: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element,
mainnetPrompt: MainnetPrompt, mainnetPrompt: MainnetPrompt,
gasEstimationPrompt: (msg: string) => JSX.Element, gasEstimationPrompt: (msg: string) => JSX.Element,
passphrasePrompt: (msg: string) => JSX.Element) => { passphrasePrompt: (msg: string) => JSX.Element,
funcIndex?: number) => {
let callinfo = '' let callinfo = ''
if (lookupOnly) callinfo = 'call' if (lookupOnly) callinfo = 'call'
else if (funcABI.type === 'fallback' || funcABI.type === 'receive') callinfo = 'lowLevelInteracions' else if (funcABI.type === 'fallback' || funcABI.type === 'receive') callinfo = 'lowLevelInteracions'
@ -625,9 +627,9 @@ export const runTransactions = (
return terminalLogger(log) return terminalLogger(log)
}, },
(returnValue) => { (returnValue) => {
const decodedResponse = txFormat.decodeResponse(returnValue, funcABI) const response = txFormat.decodeResponse(returnValue, funcABI)
dispatch(setDecodedResponse(index, decodedResponse)) dispatch(setDecodedResponse(instanceIndex, response, funcIndex))
}, },
(network, tx, gasEstimation, continueTxExecution, cancelCb) => { (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
confirmationHandler(mainnetPrompt, network, tx, gasEstimation, continueTxExecution, cancelCb) confirmationHandler(mainnetPrompt, network, tx, gasEstimation, continueTxExecution, cancelCb)
@ -651,9 +653,7 @@ const saveScenario = (promptCb, cb) => {
if (!fileProvider) return if (!fileProvider) return
const newFile = path + '/' + plugin.REACT_API.recorder.pathToScenario const newFile = path + '/' + plugin.REACT_API.recorder.pathToScenario
try { try {
console.log('newFile: ', newFile)
const newPath = await createNonClashingNameAsync(newFile, plugin.fileManager) const newPath = await createNonClashingNameAsync(newFile, plugin.fileManager)
console.log('newPath: ', newPath)
// eslint-disable-next-line standard/no-callback-literal // eslint-disable-next-line standard/no-callback-literal
if (!fileProvider.set(newPath, txJSON)) return cb('Failed to create file ' + newFile) if (!fileProvider.set(newPath, txJSON)) return cb('Failed to create file ' + newFile)
plugin.fileManager.open(newFile) plugin.fileManager.open(newFile)

@ -240,12 +240,13 @@ export const clearAllInstances = () => {
} }
} }
export const setDecodedResponse = (index: number, decodedResponse) => { export const setDecodedResponse = (instanceIndex: number, response, funcIndex?: number) => {
return { return {
type: 'SET_DECODED_RESPONSE', type: 'SET_DECODED_RESPONSE',
payload: { payload: {
index, instanceIndex,
decodedResponse funcIndex,
response
} }
} }
} }

@ -16,7 +16,7 @@ export function RecorderUI (props: RecorderProps) {
</div> </div>
</div> </div>
<div> <div>
<div><i className="udapp_arrow fas fa-angle-down"></i></div> <div><i className="udapp_arrow fas fa-angle-down" data-id="udapp_arrow"></i></div>
</div> </div>
</div> </div>
) )
@ -43,7 +43,7 @@ export function RecorderUI (props: RecorderProps) {
<i className="fas fa-save savetransaction udapp_recorder udapp_icon" <i className="fas fa-save savetransaction udapp_recorder udapp_icon"
onClick={triggerRecordButton} title="Save Transactions" aria-hidden="true"> onClick={triggerRecordButton} title="Save Transactions" aria-hidden="true">
</i> </i>
<i className="fas fa-play runtransaction udapp_runTxs udapp_icon" title="Run Transactions" aria-hidden="true" onClick={handleClickRunButton}></i> <i className="fas fa-play runtransaction udapp_runTxs udapp_icon" title="Run Transactions" data-id="runtransaction" aria-hidden="true" onClick={handleClickRunButton}></i>
</div> </div>
</div> </div>
</TreeViewItem> </TreeViewItem>

@ -104,7 +104,7 @@ export function UniversalDappUI (props: UdappProps) {
props.removeInstance(props.index) props.removeInstance(props.index)
} }
const runTransaction = (lookupOnly, funcABI: FuncABI, valArr, inputsValues) => { const runTransaction = (lookupOnly, funcABI: FuncABI, valArr, inputsValues, funcIndex?: number) => {
const functionName = funcABI.type === 'function' ? funcABI.name : `(${funcABI.type})` const functionName = funcABI.type === 'function' ? funcABI.name : `(${funcABI.type})`
const logMsg = `${lookupOnly ? 'call' : 'transact'} to ${props.instance.name}.${functionName}` const logMsg = `${lookupOnly ? 'call' : 'transact'} to ${props.instance.name}.${functionName}`
@ -121,7 +121,8 @@ export function UniversalDappUI (props: UdappProps) {
props.logBuilder, props.logBuilder,
props.mainnetPrompt, props.mainnetPrompt,
props.gasEstimationPrompt, props.gasEstimationPrompt,
props.passphrasePrompt) props.passphrasePrompt,
funcIndex)
} }
const extractDataDefault = (item, parent?) => { const extractDataDefault = (item, parent?) => {
@ -235,27 +236,34 @@ export function UniversalDappUI (props: UdappProps) {
const lookupOnly = funcABI.stateMutability === 'view' || funcABI.stateMutability === 'pure' || isConstant const lookupOnly = funcABI.stateMutability === 'view' || funcABI.stateMutability === 'pure' || isConstant
const inputs = props.getFuncABIInputs(funcABI) const inputs = props.getFuncABIInputs(funcABI)
return <ContractGUI return <>
<ContractGUI
funcABI={funcABI} funcABI={funcABI}
clickCallBack={(valArray: { name: string, type: string }[], inputsValues: string) => { clickCallBack={(valArray: { name: string, type: string }[], inputsValues: string) => {
runTransaction(lookupOnly, funcABI, valArray, inputsValues) runTransaction(lookupOnly, funcABI, valArray, inputsValues, index)
}} }}
inputs={inputs} inputs={inputs}
evmBC={evmBC} evmBC={evmBC}
lookupOnly={lookupOnly} lookupOnly={lookupOnly}
key={index} key={index}
/> />
}) <div className="udapp_value" data-id="udapp_value">
}
<div className="udapp_value">
<TreeView id="treeView"> <TreeView id="treeView">
{ {
Object.keys(props.instance.decodedResponse || {}).map((innerkey) => { Object.keys(props.instance.decodedResponse || {}).map((key) => {
return renderData(props.instance.decodedResponse[innerkey], props.instance.decodedResponse, innerkey, innerkey) const funcIndex = index.toString()
const response = props.instance.decodedResponse[key]
return key === funcIndex ? Object.keys(response || {}).map((innerkey) => {
return renderData(props.instance.decodedResponse[key][innerkey], response, innerkey, innerkey)
}) : null
}) })
} }
</TreeView> </TreeView>
</div> </div>
</>
})
}
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className="d-flex flex-row justify-content-between mt-2"> <div className="d-flex flex-row justify-content-between mt-2">

@ -69,7 +69,7 @@ export interface RunTabState {
contractData?: ContractData, contractData?: ContractData,
address: string, address: string,
name: string, name: string,
decodedResponse?: any, decodedResponse?: Record<number, any>,
abi?: any abi?: any
}[], }[],
error: string error: string
@ -553,7 +553,7 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
case 'ADD_INSTANCE': { case 'ADD_INSTANCE': {
const payload: { contractData: ContractData, address: string, name: string, abi?: any, decodedResponse?: any } = action.payload const payload: { contractData: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record<number, any> } = action.payload
return { return {
...state, ...state,
@ -587,14 +587,14 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
case 'SET_DECODED_RESPONSE': { case 'SET_DECODED_RESPONSE': {
const payload: any = action.payload const payload: { instanceIndex: number, funcIndex: number, response: any } = action.payload
return { return {
...state, ...state,
instances: { instances: {
...state.instances, ...state.instances,
instanceList: state.instances.instanceList.map((instance, index) => { instanceList: state.instances.instanceList.map((instance, index) => {
if (payload.index === index) instance.decodedResponse = payload.decodedResponse if (payload.instanceIndex === index) instance.decodedResponse[payload.funcIndex] = payload.response
return instance return instance
}) })
} }

@ -204,7 +204,7 @@ export interface InstanceContainerProps {
contractData?: ContractData, contractData?: ContractData,
address: string, address: string,
name: string, name: string,
decodedResponse?: any, decodedResponse?: Record<number, any>,
abi?: any abi?: any
}[], }[],
error: string error: string
@ -213,7 +213,7 @@ export interface InstanceContainerProps {
removeInstance: (index: number) => void, removeInstance: (index: number) => void,
getContext: () => 'memory' | 'blockchain', getContext: () => 'memory' | 'blockchain',
runTransactions: ( runTransactions: (
index: number, instanceIndex: number,
lookupOnly: boolean, lookupOnly: boolean,
funcABI: FuncABI, funcABI: FuncABI,
inputsValues: string, inputsValues: string,
@ -224,7 +224,8 @@ export interface InstanceContainerProps {
logBuilder: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element,
mainnetPrompt: MainnetPrompt, mainnetPrompt: MainnetPrompt,
gasEstimationPrompt: (msg: string) => JSX.Element, gasEstimationPrompt: (msg: string) => JSX.Element,
passphrasePrompt: (msg: string) => JSX.Element) => void, passphrasePrompt: (msg: string) => JSX.Element,
funcIndex?: number) => void,
gasEstimationPrompt: (msg: string) => JSX.Element, gasEstimationPrompt: (msg: string) => JSX.Element,
logBuilder: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element,
passphrasePrompt: (message: string) => JSX.Element, passphrasePrompt: (message: string) => JSX.Element,
@ -277,7 +278,7 @@ export interface UdappProps {
contractData?: ContractData, contractData?: ContractData,
address: string, address: string,
name: string, name: string,
decodedResponse?: any, decodedResponse?: Record<number, any>,
abi?: any abi?: any
}, },
context: 'memory' | 'blockchain', context: 'memory' | 'blockchain',
@ -288,7 +289,7 @@ export interface UdappProps {
passphrasePrompt: (message: string) => JSX.Element, passphrasePrompt: (message: string) => JSX.Element,
mainnetPrompt: (tx: Tx, network: Network, amount: string, gasEstimation: string, gasFees: (maxFee: string, cb: (txFeeText: string, priceStatus: boolean) => void) => void, determineGasPrice: (cb: (txFeeText: string, gasPriceValue: string, gasPriceStatus: boolean) => void) => void) => JSX.Element, mainnetPrompt: (tx: Tx, network: Network, amount: string, gasEstimation: string, gasFees: (maxFee: string, cb: (txFeeText: string, priceStatus: boolean) => void) => void, determineGasPrice: (cb: (txFeeText: string, gasPriceValue: string, gasPriceStatus: boolean) => void) => void) => JSX.Element,
runTransactions: ( runTransactions: (
index: number, instanceIndex: number,
lookupOnly: boolean, lookupOnly: boolean,
funcABI: FuncABI, funcABI: FuncABI,
inputsValues: string, inputsValues: string,
@ -299,7 +300,8 @@ export interface UdappProps {
logBuilder: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element,
mainnetPrompt: MainnetPrompt, mainnetPrompt: MainnetPrompt,
gasEstimationPrompt: (msg: string) => JSX.Element, gasEstimationPrompt: (msg: string) => JSX.Element,
passphrasePrompt: (msg: string) => JSX.Element) => void, passphrasePrompt: (msg: string) => JSX.Element,
funcIndex?: number) => void,
sendValue: string, sendValue: string,
getFuncABIInputs: (funcABI: FuncABI) => string getFuncABIInputs: (funcABI: FuncABI) => string
} }

Loading…
Cancel
Save