From fa77260c5fd8126cc1294d4543d0fde916bf925f Mon Sep 17 00:00:00 2001 From: yann300 Date: Sun, 10 Dec 2017 14:05:59 +0100 Subject: [PATCH 1/2] Recorder fix ui --- src/app/tabs/run-tab.js | 61 ++++++++++++++++++++++++----------------- src/recorder.js | 2 +- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index bb81d7d7dd..e263592333 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -177,6 +177,13 @@ var css = csjs` .networkItem { margin-right: 5px; } + .clearinstance { + font-size: 20px; + cursor: pointer; + margin-right: 10px; + } + .transactionActions { + float: right; ` module.exports = runTab @@ -184,13 +191,26 @@ module.exports = runTab var instanceContainer = yo`
` var noInstancesText = yo`
0 contract Instances
` -var pendingTxsText = yo`
` +var pendingTxsText = yo`` function runTab (container, appAPI, appEvents, opts) { var events = new EventManager() + + var clearInstanceElement = yo`` + clearInstanceElement.addEventListener('click', () => { + events.trigger('clearInstance', []) + }) + var recorderInterface = makeRecorder(events, appAPI, appEvents) var pendingTxsContainer = yo`
- ${pendingTxsText} +
+ ${pendingTxsText} + + ${clearInstanceElement} + ${recorderInterface.recordButton} + ${recorderInterface.runButton} + +
` var el = yo` @@ -216,7 +236,7 @@ function runTab (container, appAPI, appEvents, opts) { // set the final context. Cause it is possible that this is not the one we've originaly selected selectExEnv.value = executionContext.getProvider() fillAccountsList(appAPI, el) - clearInstance() + events.trigger('clearInstance', []) }) }) selectExEnv.value = executionContext.getProvider() @@ -226,12 +246,11 @@ function runTab (container, appAPI, appEvents, opts) { updatePendingTxs(container, appAPI) }, 500) - var clearInstance = function () { + events.register('clearInstance', () => { instanceContainer.innerHTML = '' // clear the instances list noInstancesText.style.display = 'block' instanceContainer.appendChild(noInstancesText) - events.trigger('clearInstance', []) - } + }) } function fillAccountsList (appAPI, container) { @@ -275,29 +294,21 @@ function makeRecorder (events, appAPI, appEvents) { }) var css2 = csjs` .container { - margin: 10px; - display: flex; - justify-content: space-evenly; - width: 100%; } .recorder { - ${styles.button} - width: 135px; + font-size: 20px; + cursor: pointer; } .runTxs { - ${styles.button} margin-left: 10px; - width: 135px; + font-size: 20px; + cursor: pointer; } ` - var recordButton = yo`` - var runButton = yo`` - var el = yo` -
- ${recordButton} - ${runButton} -
- ` + + var recordButton = yo`` + var runButton = yo`` + recordButton.onclick = () => { var txJSON = JSON.stringify(recorder.getAll(), null, 2) var path = appAPI.currentPath() @@ -335,10 +346,10 @@ function makeRecorder (events, appAPI, appEvents) { }) } } else { - modalDialogCustom.alert('Scenario File require JSON type') + modalDialogCustom.alert('A Scenario File is required. The file must be of type JSON. Use the "Save Transactions" Button to generate a new Scenario File.') } } - return el + return { recordButton, runButton } } /* ------------------------------------------------ section CONTRACT DROPDOWN and BUTTONS @@ -371,6 +382,7 @@ function contractDropdown (events, appAPI, appEvents, instanceContainer) { return null } appAPI.getSelectedContract = getSelectedContract + var el = yo`
@@ -385,7 +397,6 @@ function contractDropdown (events, appAPI, appEvents, instanceContainer) { ${atAddressButtonInput}
At Address
-
${makeRecorder(events, appAPI, appEvents)}
` diff --git a/src/recorder.js b/src/recorder.js index 0b97d0cd06..9cea98cf30 100644 --- a/src/recorder.js +++ b/src/recorder.js @@ -21,7 +21,7 @@ class Recorder { opts.events.executioncontext.register('contextChanged', () => { self.clearAll() }) - opts.events.runtab.register('clearInstances', () => { + opts.events.runtab.register('clearInstance', () => { self.clearAll() }) From ba9ca8d09169d02e4ef051b986ab3ae41c7aff4b Mon Sep 17 00:00:00 2001 From: yann300 Date: Sun, 10 Dec 2017 15:55:18 +0100 Subject: [PATCH 2/2] add recorder tests --- src/app/tabs/run-tab.js | 4 +- test-browser/helpers/contracts.js | 37 ++++++- test-browser/tests/ballot.js | 2 + test-browser/tests/compiling.js | 4 +- test-browser/tests/units/testRecorder.js | 130 ++++++++++++++++++++--- 5 files changed, 160 insertions(+), 17 deletions(-) diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index e263592333..9620830503 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -196,7 +196,7 @@ var pendingTxsText = yo`` function runTab (container, appAPI, appEvents, opts) { var events = new EventManager() - var clearInstanceElement = yo`` + var clearInstanceElement = yo`` clearInstanceElement.addEventListener('click', () => { events.trigger('clearInstance', []) }) @@ -368,7 +368,7 @@ function contractDropdown (events, appAPI, appEvents, instanceContainer) { }) var atAddressButtonInput = yo`` - var createButtonInput = yo`` + var createButtonInput = yo`` var selectContractNames = yo`` function getSelectedContract () { diff --git a/test-browser/helpers/contracts.js b/test-browser/helpers/contracts.js index b0e6328c04..3239e84bad 100644 --- a/test-browser/helpers/contracts.js +++ b/test-browser/helpers/contracts.js @@ -14,7 +14,10 @@ module.exports = { addInstance, clickFunction, verifyCallReturnValue, - setEditorValue + createContract, + modalFooterOKClick, + setEditorValue, + getEditorValue } function getCompiledContracts (browser, compiled, callback) { @@ -34,6 +37,13 @@ function getCompiledContracts (browser, compiled, callback) { }) } +function createContract (browser, inputParams, callback) { + browser.click('.runView') + .setValue('input.create', inputParams, function () { + browser.click('#runTabView div[class^="create"]').perform(function () { callback() }) + }) +} + function verifyContract (browser, compiledContractNames, callback) { getCompiledContracts(browser, compiledContractNames, (result) => { if (result.value) { @@ -96,7 +106,7 @@ function verifyCallReturnValue (browser, address, checks, done) { return ret }, [address], function (result) { for (var k in checks) { - browser.assert.equal(checks[k], result.value[k]) + browser.assert.equal(result.value[k], checks[k]) } done() }) @@ -162,6 +172,29 @@ function addInstance (browser, address, callback) { }) } +function getEditorValue (callback) { + this.perform((client, done) => { + this.execute(function (value) { + return document.getElementById('input').editor.getValue() + }, [], function (result) { + done(result.value) + callback(result.value) + }) + }) + return this +} + +function modalFooterOKClick () { + this.perform((client, done) => { + this.execute(function () { + document.querySelector('#modal-footer-ok').click() + }, [], function (result) { + done() + }) + }) + return this +} + function addFile (browser, name, content, done) { browser.click('.newFile') .perform((client, done) => { diff --git a/test-browser/tests/ballot.js b/test-browser/tests/ballot.js index 7dd4fa2e8d..ced5879e67 100644 --- a/test-browser/tests/ballot.js +++ b/test-browser/tests/ballot.js @@ -23,6 +23,8 @@ module.exports = { function runTests (browser, testData) { browser.testFunction = contractHelper.testFunction + browser.clickFunction = contractHelper.clickFunction + browser.modalFooterOKClick = contractHelper.modalFooterOKClick browser.setEditorValue = contractHelper.setEditorValue browser .waitForElementVisible('.newFile', 10000) diff --git a/test-browser/tests/compiling.js b/test-browser/tests/compiling.js index 0d13d93a5d..f66062ad99 100644 --- a/test-browser/tests/compiling.js +++ b/test-browser/tests/compiling.js @@ -22,12 +22,14 @@ function runTests (browser) { browser.testFunction = contractHelper.testFunction browser.clickFunction = contractHelper.clickFunction browser.setEditorValue = contractHelper.setEditorValue + browser.modalFooterOKClick = contractHelper.modalFooterOKClick + browser.getEditorValue = contractHelper.getEditorValue browser .waitForElementVisible('.newFile', 10000) .click('.compileView') .perform(() => { // the first fn is used to pass browser to the other ones. - async.waterfall([function (callback) { callback(null, browser) }, testSimpleContract, testReturnValues, testInputValues, testRecorder], function () { + async.waterfall([function (callback) { callback(null, browser) }, testSimpleContract, testReturnValues, testInputValues, testRecorder.test], function () { browser.end() }) }) diff --git a/test-browser/tests/units/testRecorder.js b/test-browser/tests/units/testRecorder.js index 27043ba6d2..af67bed331 100644 --- a/test-browser/tests/units/testRecorder.js +++ b/test-browser/tests/units/testRecorder.js @@ -1,21 +1,59 @@ 'use strict' var contractHelper = require('../../helpers/contracts') -module.exports = function (browser, callback) { - contractHelper.addFile(browser, 'scenario.json', {content: records}, () => { - browser - .click('.runView') - .click('#runTabView .runtransaction') - .clickFunction('getInt - call') - .clickFunction('getAddress - call') - .clickFunction('getFromLib - call') - .waitForElementPresent('div[class^="contractProperty"] div[class^="value"]') - .perform(() => { - contractHelper.verifyCallReturnValue(browser, '0x35ef07393b57464e93deb59175ff72e6499450cf', ['0: uint256: 1', '0: uint256: 3456', '0: address: 0xca35b7d915458ef540ade6068dfe2f44e8fa733c'], () => { callback() }) +module.exports = { + '@sources': function () { + return sources + }, + test: function (browser, callback) { + contractHelper.addFile(browser, 'scenario.json', {content: records}, () => { + browser + .click('.runView') + .click('#runTabView .runtransaction') + .clickFunction('getInt - call') + .clickFunction('getAddress - call') + .clickFunction('getFromLib - call') + .waitForElementPresent('div[class^="contractProperty"] div[class^="value"]') + .perform((client, done) => { + contractHelper.verifyCallReturnValue(browser, '0x35ef07393b57464e93deb59175ff72e6499450cf', ['0: uint256: 1', '0: uint256: 3456', '0: address: 0xca35b7d915458ef540ade6068dfe2f44e8fa733c'], () => { + done() + }) + }) + .click('i[class^="clearinstance"]') + .perform((client, done) => { + contractHelper.testContracts(browser, 'testRecorder.sol', sources[0]['browser/testRecorder.sol'], ['testRecorder'], function () { + contractHelper.createContract(browser, '12', function () { + browser.clickFunction('set - transact (not payable)', {types: 'uint256 _p', values: '34'}) + .click('i.savetransaction').modalFooterOKClick().getEditorValue(function (result) { + var 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.name), JSON.stringify(scenario.transactions[0].record.name)) + browser.assert.equal(JSON.stringify(parsed.transactions[0].record.type), JSON.stringify(scenario.transactions[0].record.type)) + browser.assert.equal(JSON.stringify(parsed.transactions[0].record.from), JSON.stringify(scenario.transactions[0].record.from)) + browser.assert.equal(JSON.stringify(parsed.transactions[0].record.contractName), JSON.stringify(scenario.transactions[0].record.contractName)) + + browser.assert.equal(JSON.stringify(parsed.transactions[1].record.parameters), JSON.stringify(scenario.transactions[1].record.parameters)) + browser.assert.equal(JSON.stringify(parsed.transactions[1].record.name), JSON.stringify(scenario.transactions[1].record.name)) + browser.assert.equal(JSON.stringify(parsed.transactions[1].record.type), JSON.stringify(scenario.transactions[1].record.type)) + browser.assert.equal(JSON.stringify(parsed.transactions[1].record.from), JSON.stringify(scenario.transactions[1].record.from)) + callback() + }) + }) + }) + }) }) - }) + } } +var sources = [{'browser/testRecorder.sol': {content: `pragma solidity ^0.4.0;contract testRecorder { + function testRecorder(uint p) { + + } + function set (uint _p) { + + } +}`}}] + var records = `{ "accounts": { "account{0}": "0xca35b7d915458ef540ade6068dfe2f44e8fa733c" @@ -170,3 +208,71 @@ var records = `{ ] } }` + +var scenario = { + 'accounts': { + 'account{0}': '0xca35b7d915458ef540ade6068dfe2f44e8fa733c' + }, + 'linkReferences': {}, + 'transactions': [ + { + 'timestamp': 1512912691086, + 'record': { + 'value': '0', + 'parameters': [ + 12 + ], + 'abi': '0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798', + 'contractName': 'testRecorder', + 'bytecode': '6060604052341561000f57600080fd5b6040516020806100cd833981016040528080519060200190919050505060938061003a6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506064565b005b505600a165627a7a723058204839660366b94f5f3c8c6da233a2c5fe95ad5635b5c8a2bb630a8b845d68ecdd0029', + 'linkReferences': {}, + 'name': '', + 'type': 'constructor', + 'from': 'account{0}' + } + }, + { + 'timestamp': 1512912696128, + 'record': { + 'value': '0', + 'parameters': [ + 34 + ], + 'to': 'created{1512912691086}', + 'abi': '0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798', + 'name': 'set', + 'type': 'function', + 'from': 'account{0}' + } + } + ], + 'abis': { + '0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798': [ + { + 'constant': false, + 'inputs': [ + { + 'name': '_p', + 'type': 'uint256' + } + ], + 'name': 'set', + 'outputs': [], + 'payable': false, + 'stateMutability': 'nonpayable', + 'type': 'function' + }, + { + 'inputs': [ + { + 'name': 'p', + 'type': 'uint256' + } + ], + 'payable': false, + 'stateMutability': 'nonpayable', + 'type': 'constructor' + } + ] + } +}