diff --git a/src/app/components/plugin-manager-component.js b/src/app/components/plugin-manager-component.js index 1fb8011b83..d2431a56bc 100644 --- a/src/app/components/plugin-manager-component.js +++ b/src/app/components/plugin-manager-component.js @@ -105,12 +105,12 @@ class PluginManagerComponent { ` return yo` -
+

${mod.profile.name}

${mod.profile.description} ${ctrBtns}
- ` + ` } reRender () { diff --git a/src/app/components/swap-panel-api.js b/src/app/components/swap-panel-api.js index f603dfedc3..9b2f8cc3bf 100644 --- a/src/app/components/swap-panel-api.js +++ b/src/app/components/swap-panel-api.js @@ -8,17 +8,17 @@ class SwapPanelApi { verticalIconsComponent.event.on('showContent', (moduleName) => { if (!swapPanelComponent.contents[moduleName]) return if (this.currentContent === moduleName) { - this.event.emit('toggle') + this.event.emit('toggle', moduleName) return } + this.showContent(moduleName) this.event.emit('showing', moduleName) - this.component.showContent(moduleName) - this.currentContent = moduleName }) } showContent (moduleName) { this.component.showContent(moduleName) + this.currentContent = moduleName } /* diff --git a/src/app/components/swap-panel-component.js b/src/app/components/swap-panel-component.js index c6db7d221f..4f13c118ed 100644 --- a/src/app/components/swap-panel-component.js +++ b/src/app/components/swap-panel-component.js @@ -15,6 +15,7 @@ class SwapPanelComponent { showContent (moduleName) { // hiding the current view and display the `moduleName` + if (moduleName === this.currentNode) return if (this.contents[moduleName]) { this.contents[moduleName].style.display = 'block' if (this.currentNode) { diff --git a/src/app/contract/contractParser.js b/src/app/contract/contractParser.js index 3d3afa6733..de9abb5c34 100644 --- a/src/app/contract/contractParser.js +++ b/src/app/contract/contractParser.js @@ -1,5 +1,6 @@ 'use strict' +var solcTranslate = require('solc/translate') var remixLib = require('remix-lib') var txHelper = remixLib.execution.txHelper @@ -42,7 +43,7 @@ var getDetails = function (contractName, contract, source) { } if (source && contract.assembly !== null) { - detail['Assembly'] = formatAssemblyText(contract.evm.legacyAssembly, '', source.content) + detail['Assembly'] = solcTranslate.prettyPrintLegacyAssemblyJSON(contract.evm.legacyAssembly, source.content) } return detail @@ -58,36 +59,6 @@ var retrieveMetadataHash = function (bytecode) { } } -var formatAssemblyText = function (asm, prefix, source) { - if (typeof asm === typeof '' || asm === null || asm === undefined) { - return prefix + asm + '\n' - } - var text = prefix + '.code\n' - asm['.code'].forEach(function (item, _i) { - var v = item.value === undefined ? '' : item.value - var src = '' - if (item.begin !== undefined && item.end !== undefined) { - src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g') - } - if (src.length > 30) { - src = src.slice(0, 30) + '...' - } - if (item.name !== 'tag') { - text += ' ' - } - text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n' - }) - text += prefix + '.data\n' - let asmData = (asm['.data'] || []) - for (let i in asmData) { - let item = asmData[i] - - text += ' ' + prefix + '' + i + ':\n' - text += formatAssemblyText(item, prefix + ' ', source) - } - return text -} - var gethDeploy = function (contractName, jsonInterface, bytecode) { var code = '' var funABI = txHelper.getConstructorInterface(jsonInterface) diff --git a/src/app/staticanalysis/staticAnalysisView.js b/src/app/staticanalysis/staticAnalysisView.js index 5ab26748e9..3f0718ef0c 100644 --- a/src/app/staticanalysis/staticAnalysisView.js +++ b/src/app/staticanalysis/staticAnalysisView.js @@ -46,7 +46,7 @@ staticAnalysisView.prototype.render = function () { ${this.modulesView}
- + -
` - self._view.config.plugins = yo`
` - self._view.config.plugin = yo` -
-
Plugin
-
-
Load plugin from JSON description:
- ${self._view.pluginInput} - - ${self._view.config.plugins} -
-
` self._view.el = yo`
${self._view.config.general} - ${self._view.config.plugin} ${self._view.gistToken} ${self._view.config.themes}
` - function loadPlugins (plugins, opt) { - for (var k in plugins) { - (function (plugin) { - if (!self._view.plugins[plugin.title]) self._view.plugins[plugin.title] = {} - self._view.plugins[plugin.title].json = plugin - self._view.plugins[plugin.title].el = yo`
-
{ onLoadPlugin(plugin.title) }}>${plugin.title}
- ${opt.removable ? yo` { onRemovePlugin(plugin.title) }}>` : yo``} -
` - self._view.config.plugins.appendChild(self._view.plugins[plugin.title].el) - })(plugins[k]) - } - } - - function getSavedPlugin () { - var savedPlugin = self._deps.config.get('settings/plugins-list') - return savedPlugin ? JSON.parse(savedPlugin) : {} - } - function setSavedPlugin (savedPlugins) { - self._deps.config.set('settings/plugins-list', JSON.stringify(savedPlugins)) - } - loadPlugins(defaultPlugins, {removable: false}) - loadPlugins(getSavedPlugin(), {removable: true}) - - function onLoadPlugin (name) { - self.event.trigger('plugin-loadRequest', [self._view.plugins[name].json]) - } - function onRemovePlugin (name) { - var savedPlugin = getSavedPlugin() - delete savedPlugin[name] - setSavedPlugin(savedPlugin) - if (self._view.plugins[name]) { - self._view.plugins[name].el.parentNode.removeChild(self._view.plugins[name].el) - delete self._view.plugins[name] - } - } - function onloadPluginJson (event) { - try { - var json = JSON.parse(self._view.pluginInput.value) - } catch (e) { - return tooltip('cannot parse the plugin definition to JSON') - } - var savedPlugin = getSavedPlugin() - if (self._view.plugins[json.title]) return tooltip('Plugin already loaded') - savedPlugin[json.title] = json - setSavedPlugin(savedPlugin) - loadPlugins([json], {removable: true}) - } - function onchangeGenerateContractMetadata (event) { self._deps.config.set('settings/generate-contract-metadata', !self._deps.config.get('settings/generate-contract-metadata')) } diff --git a/src/app/tabs/styles/test-tab-styles.js b/src/app/tabs/styles/test-tab-styles.js index cc79dc8f18..7a3c663a79 100644 --- a/src/app/tabs/styles/test-tab-styles.js +++ b/src/app/tabs/styles/test-tab-styles.js @@ -45,6 +45,8 @@ var css = csjs` .buttons { ${styles.rightPanel.testTab.box_listTests}; margin: 2%; + display: flex; + align-items: center; } .runButton { ${styles.rightPanel.testTab.button_runTests}; @@ -58,6 +60,9 @@ var css = csjs` font-weight: bold; margin-bottom: 1em; } + .label { + display: flex; + align-items: center; + } ` - module.exports = css diff --git a/src/app/tabs/test-tab.js b/src/app/tabs/test-tab.js index c4bd9b3d1c..ea39a4531a 100644 --- a/src/app/tabs/test-tab.js +++ b/src/app/tabs/test-tab.js @@ -109,8 +109,8 @@ module.exports = class TestTab { } self._deps.filePanel.event.register('newTestFileCreated', file => { - var testList = document.querySelector("[class^='testList']") - var test = yo`` + var testList = self.view.querySelector("[class^='testList']") + var test = yo`` testList.appendChild(test) self.data.allTests.push(file) self.data.selectedTests.push(file) @@ -142,13 +142,32 @@ module.exports = class TestTab { function listTests () { var tests = self.data.allTests - return tests.map(test => yo``) + return tests.map(test => yo``) } - function toggleCheckbox (e, test) { - var selectedTests = self.data.selectedTests - selectedTests = e.target.checked ? [...selectedTests, test] : selectedTests.filter(el => el !== test) + function toggleCheckbox (eChecked, test) { + if (!self.data.selectedTests) { + self.data.selectedTests = self._view.el.querySelectorAll('.singleTest:checked') + } + let selectedTests = self.data.selectedTests + selectedTests = eChecked ? [...selectedTests, test] : selectedTests.filter(el => el !== test) self.data.selectedTests = selectedTests + let checkAll = self._view.el.querySelector('[id="checkAllTests"]') + if (eChecked) { + checkAll.checked = true + } else if (!selectedTests.length) { + checkAll.checked = false + } + } + + function checkAll (event) { + let checkBoxes = self._view.el.querySelectorAll('.singleTest') + const checkboxesLabels = self._view.el.querySelectorAll('.singleTestLabel') + // checks/unchecks all + for (let i = 0; i < checkBoxes.length; i++) { + checkBoxes[i].checked = event.target.checked + toggleCheckbox(event.target.checked, checkboxesLabels[i].innerText) + } } var runTests = function () { @@ -186,12 +205,20 @@ module.exports = class TestTab {
For more details, see How to test smart contracts guide in our documentation. -
Generate test file
+
Generate test file
${self.testList} -
-
Run Tests
+
+
Run Tests
+
${testsOutput} ${testsSummary} diff --git a/src/framingService.js b/src/framingService.js index bb15139d32..fa50132742 100644 --- a/src/framingService.js +++ b/src/framingService.js @@ -1,15 +1,11 @@ export default { start: (appStore, swapPanelApi, verticalIconApi, mainPanelApi, resizeFeature) => { - swapPanelApi.event.on('toggle', () => { + swapPanelApi.event.on('toggle', (moduleName) => { resizeFeature.panel1.clientWidth !== 0 ? resizeFeature.minimize() : resizeFeature.maximise() if (moduleName === 'file explorers') { mainPanelApi.showContent('code editor') } }) - mainPanelApi.event.on('toggle', () => { - verticalIconApi.select('code editor') - resizeFeature.maximise() - }) swapPanelApi.event.on('showing', (moduleName) => { if (moduleName === 'file explorers') { mainPanelApi.showContent('code editor') @@ -19,10 +15,14 @@ export default { // warn the content that it is being displayed. TODO should probably be done in each view if (current && current.api.__showing) current.api.__showing() }) - mainPanelApi.event.on('showing', (moduleName) => {}) + mainPanelApi.event.on('toggle', () => { + verticalIconApi.select('code editor') + resizeFeature.maximise() + }) + // mainPanelApi.event.on('showing', (moduleName) => {}) verticalIconApi.select('file explorers') - resizeFeature.minimize() verticalIconApi.select('homepage') + resizeFeature.minimize() } } diff --git a/test-browser/helpers/contracts.js b/test-browser/helpers/contracts.js index 36c99b4778..fef021a582 100644 --- a/test-browser/helpers/contracts.js +++ b/test-browser/helpers/contracts.js @@ -23,11 +23,17 @@ module.exports = { testEditorValue, renameFile, removeFile, - getAddressAtPosition + getAddressAtPosition, + clickLaunchIcon +} + +function clickLaunchIcon (icon) { + this.click('#icon-panel div[title="' + icon + '"]') + return this } function getCompiledContracts (browser, compiled, callback) { - browser.execute(function () { + browser.clickLaunchIcon('solidity').execute(function () { var contracts = document.querySelectorAll('#compileTabView select option') if (!contracts) { return null @@ -44,14 +50,14 @@ function getCompiledContracts (browser, compiled, callback) { } function selectContract (browser, contractName, callback) { - browser.click('.runView') + browser.clickLaunchIcon('settings').clickLaunchIcon('run transactions') .setValue('#runTabView select[class^="contractNames"]', contractName).perform(() => { callback() }) } function createContract (browser, inputParams, callback) { - browser.click('.runView') + browser.clickLaunchIcon('settings').clickLaunchIcon('run transactions') .setValue('div[class^="contractActionsContainerSingle"] input', inputParams, function () { browser.click('#runTabView button[class^="instanceButton"]').pause(500).perform(function () { callback() }) }) @@ -79,7 +85,7 @@ function verifyContract (browser, compiledContractNames, callback) { function testContracts (browser, fileName, contractCode, compiledContractNames, callback) { browser - .click('.compileView') + .clickLaunchIcon('solidity') .clearValue('#input textarea') .perform((client, done) => { addFile(browser, fileName, contractCode, done) @@ -211,7 +217,7 @@ function setEditorValue (value, callback) { } function addInstance (browser, address, isValidFormat, isValidChecksum, callback) { - browser.clearValue('.ataddressinput').setValue('.ataddressinput', address, function () { + browser.clickLaunchIcon('run transactions').clearValue('.ataddressinput').setValue('.ataddressinput', address, function () { browser.click('div[class^="atAddress"]') .execute(function () { var ret = document.querySelector('div[class^="modalBody"] div').innerHTML @@ -259,7 +265,7 @@ function modalFooterOKClick () { } function addFile (browser, name, content, done) { - browser.click('.newFile') + browser.clickLaunchIcon('run transactions').clickLaunchIcon('file explorers').click('.newFile') .perform((client, done) => { browser.execute(function (fileName) { if (fileName !== 'Untitled.sol') { @@ -366,7 +372,7 @@ function useFilter (browser, filter, test, done) { } function switchFile (browser, name, done) { - browser + browser.clickLaunchIcon('settings').clickLaunchIcon('file explorers') .click('li[key="' + name + '"]') .pause(2000) .perform(() => { diff --git a/test-browser/helpers/init.js b/test-browser/helpers/init.js index a5cd421de6..e4dc8d0784 100644 --- a/test-browser/helpers/init.js +++ b/test-browser/helpers/init.js @@ -1,12 +1,31 @@ +var helpers = require('./contracts') + module.exports = function (browser, callback) { + browser.clickLaunchIcon = helpers.clickLaunchIcon browser .url('http://127.0.0.1:8080/#version=builtin') .injectScript('test-browser/helpers/applytestmode.js', function () { browser.resizeWindow(2560, 1440, () => { - browser.click('#autoCompile') + initModules(browser, () => { + browser.clickLaunchIcon('solidity').click('#autoCompile') .perform(function () { callback() }) + }) }) }) } + +function initModules (browser, callback) { + browser.click('#icon-panel div[title="plugin manager"]') + .execute(function () { + document.querySelector('div[title="plugin manager"]').scrollTop = document.querySelector('div[title="plugin manager"]').scrollHeight + }, [], function () { + browser.click('#pluginManager div[title="solidity"] button') + .click('#pluginManager div[title="run transactions"] button') + .click('#pluginManager div[title="solidity static analysis"] button') + .click('#pluginManager div[title="debugger"] button') + .click('#icon-panel div[title="file explorers"]') + .perform(() => { callback() }) + }) +} diff --git a/test-browser/tests/ballot.js b/test-browser/tests/ballot.js index d5b5d06c7b..2861632bc0 100644 --- a/test-browser/tests/ballot.js +++ b/test-browser/tests/ballot.js @@ -26,14 +26,15 @@ function runTests (browser, testData) { browser.clickFunction = contractHelper.clickFunction browser.modalFooterOKClick = contractHelper.modalFooterOKClick browser.setEditorValue = contractHelper.setEditorValue + browser.clickLaunchIcon = contractHelper.clickLaunchIcon browser - .waitForElementVisible('.newFile', 10000) - .click('.compileView') + .waitForElementVisible('#icon-panel', 10000) + .clickLaunchIcon('solidity') .perform((client, done) => { contractHelper.testContracts(browser, 'Untitled.sol', sources[0]['browser/Untitled.sol'], ['Ballot'], function () { done() }) - }).click('.runView') + }).clickLaunchIcon('run transactions') .setValue('input[placeholder="uint8 _numProposals"]', '1') .click('#runTabView button[class^="instanceButton"]') .waitForElementPresent('.instance:nth-of-type(2)') @@ -44,6 +45,7 @@ function runTests (browser, testData) { .pause(500) .click('span#tx0x0571a2439ea58bd349dd130afb8aff62a33af14c06de0dbc3928519bdf13ce2e div[class^="debug"]') .pause(2000) + .clickLaunchIcon('debugger') .click('#jumppreviousbreakpoint') .pause(2000) .perform(function (client, done) { @@ -63,7 +65,7 @@ function runTests (browser, testData) { done() }) }) - .click('.runView') + .clickLaunchIcon('run transactions') .click('div[class^="udappClose"]') .perform((client, done) => { console.log('ballot.abi') @@ -77,6 +79,7 @@ function runTests (browser, testData) { done() }) }) + .clickLaunchIcon('file explorers') .perform((client, done) => { console.log('addInstance 0x692a70D2e424a56D2C6C27aA97D1a86395877b3A') contractHelper.addInstance(browser, '0x692a70D2e424a56D2C6C27aA97D1a86395877b3A', true, true, () => { diff --git a/test-browser/tests/compiling.js b/test-browser/tests/compiling.js index af09962aa8..fc82913722 100644 --- a/test-browser/tests/compiling.js +++ b/test-browser/tests/compiling.js @@ -24,9 +24,10 @@ function runTests (browser) { browser.setEditorValue = contractHelper.setEditorValue browser.modalFooterOKClick = contractHelper.modalFooterOKClick browser.getEditorValue = contractHelper.getEditorValue + browser.clickLaunchIcon = contractHelper.clickLaunchIcon browser - .waitForElementVisible('.newFile', 10000) - .click('.compileView') + .waitForElementVisible('#icon-panel', 10000) + .clickLaunchIcon('solidity') .perform(() => { // the first fn is used to pass browser to the other ones. async.waterfall([function (callback) { callback(null, browser) }, testSimpleContract, testReturnValues, testInputValues, testRecorder.test], function () { @@ -37,7 +38,7 @@ function runTests (browser) { function testSimpleContract (browser, callback) { contractHelper.testContracts(browser, 'Untitled.sol', sources[0]['browser/Untitled.sol'], ['TestContract'], function () { - browser.click('.runView') + browser.clickLaunchIcon('run transactions') .click('#runTabView button[class^="instanceButton"]') .waitForElementPresent('.instance:nth-of-type(2)') .click('.instance:nth-of-type(2)') @@ -68,7 +69,7 @@ function testSimpleContract (browser, callback) { function testReturnValues (browser, callback) { contractHelper.testContracts(browser, 'returnValues.sol', sources[1]['browser/returnValues.sol'], ['testReturnValues'], function () { - browser.click('.runView') + browser.clickLaunchIcon('run transactions') .click('#runTabView button[class^="instanceButton"]') .waitForElementPresent('.instance:nth-of-type(2)') .click('.instance:nth-of-type(2)') @@ -106,7 +107,7 @@ function testReturnValues (browser, callback) { function testInputValues (browser, callback) { contractHelper.testContracts(browser, 'inputValues.sol', sources[2]['browser/inputValues.sol'], ['test'], function () { - browser.click('.runView') + browser.clickLaunchIcon('run transactions') .click('#runTabView button[class^="instanceButton"]') .waitForElementPresent('.instance:nth-of-type(2)') .click('.instance:nth-of-type(2)') diff --git a/test-browser/tests/sharedFolderExplorer.js b/test-browser/tests/sharedFolderExplorer.js index e4e8efbdb1..d40923f2d0 100644 --- a/test-browser/tests/sharedFolderExplorer.js +++ b/test-browser/tests/sharedFolderExplorer.js @@ -52,6 +52,7 @@ function runTests (browser, testData) { browser.modalFooterOKClick = contractHelper.modalFooterOKClick browser.getEditorValue = contractHelper.getEditorValue browser.testEditorValue = contractHelper.testEditorValue + browser.clickLaunchIcon = contractHelper.clickLaunchIcon var browserName = browser.options.desiredCapabilities.browserName if (browserName === 'safari' || browserName === 'internet explorer') { console.log('do not run remixd test for ' + browserName + ': sauce labs doesn\'t seems to handle websocket') @@ -64,7 +65,8 @@ function runTests (browser, testData) { return } browser - .waitForElementVisible('.newFile', 10000) + .waitForElementVisible('#icon-panel', 10000) + .clickLaunchIcon('file explorers') .click('.websocketconn') .waitForElementVisible('#modal-footer-ok', 10000) .click('#modal-footer-ok') @@ -125,7 +127,7 @@ function runTests (browser, testData) { testImportFromRemixd(browser, () => { done() }) }) .perform(function () { - browser.click('[data-path="localhost"]') // collapse and expand + browser.clickLaunchIcon('file explorers').click('[data-path="localhost"]') // collapse and expand .waitForElementNotVisible('[data-path="localhost/folder1"]') .click('[data-path="localhost"]') .waitForElementVisible('[data-path="localhost/folder1"]') diff --git a/test-browser/tests/simpleContract.js b/test-browser/tests/simpleContract.js index d2f18c427f..6165039b1f 100644 --- a/test-browser/tests/simpleContract.js +++ b/test-browser/tests/simpleContract.js @@ -20,10 +20,12 @@ module.exports = { function runTests (browser) { browser.setEditorValue = contractHelper.setEditorValue browser.getEditorValue = contractHelper.getEditorValue + browser.clickLaunchIcon = contractHelper.clickLaunchIcon browser - .waitForElementVisible('.newFile', 10000) - .click('.compileView') - .click('#filepanel label[data-path="browser"]') + .waitForElementVisible('#icon-panel', 10000) + .clickLaunchIcon('solidity') + .clickLaunchIcon('file explorers') + .click('#swap-panel label[data-path="browser"]') .perform(() => { // the first fn is used to pass browser to the other ones. async.waterfall([function (callback) { callback(null, browser) }, @@ -63,7 +65,7 @@ function testSuccessImport (browser, callback) { function testFailedImport (browser, callback) { console.log('testFailedImport') contractHelper.addFile(browser, 'Untitled3.sol', sources[2]['browser/Untitled3.sol'], () => { - browser.assert.containsText('#compileTabView .error pre', 'Unable to import "browser/Untitled11.sol": File not found') + browser.clickLaunchIcon('solidity').assert.containsText('#compileTabView .error pre', 'Unable to import "browser/Untitled11.sol": File not found') .perform(function () { callback(null, browser) }) @@ -94,8 +96,8 @@ function testAutoDeployLib (browser, callback) { function testManualDeployLib (browser, callback) { console.log('testManualDeployLib') - browser.click('i[class^="clearinstance"]').pause(5000).click('.settingsView').click('#generatecontractmetadata').perform(() => { - browser.click('.compileView').click('#compile').perform(() => { // that should generate the JSON artefact + browser.click('i[class^="clearinstance"]').pause(5000).clickLaunchIcon('settings').click('#generatecontractmetadata').perform(() => { + browser.clickLaunchIcon('solidity').click('#compile').perform(() => { // that should generate the JSON artefact contractHelper.verifyContract(browser, ['test'], () => { contractHelper.selectContract(browser, 'lib', () => { // deploy lib contractHelper.createContract(browser, '', () => { diff --git a/test-browser/tests/staticanalysis.js b/test-browser/tests/staticanalysis.js index 182e3eccdd..accb26ffcc 100644 --- a/test-browser/tests/staticanalysis.js +++ b/test-browser/tests/staticanalysis.js @@ -34,12 +34,13 @@ module.exports = { function runTests (browser) { browser.setEditorValue = contractHelper.setEditorValue + browser.clickLaunchIcon = contractHelper.clickLaunchIcon browser - .waitForElementVisible('.newFile', 10000) - .click('.compileView') + .waitForElementVisible('#icon-panel', 10000) + .clickLaunchIcon('solidity') contractHelper.testContracts(browser, 'Untitled.sol', sources[0]['browser/Untitled.sol'], ['TooMuchGas', 'test1', 'test2'], function () { browser - .click('.staticanalysisView') + .clickLaunchIcon('solidity static analysis') .click('#staticanalysisView button') .waitForElementPresent('#staticanalysisresult .staticAnalysisWarning', 2000, true, function () { dom.listSelectorContains(['browser/Untitled.sol:2:33:Use of tx.origin', diff --git a/test-browser/tests/units/testRecorder.js b/test-browser/tests/units/testRecorder.js index 41742bd9cc..745daa98c2 100644 --- a/test-browser/tests/units/testRecorder.js +++ b/test-browser/tests/units/testRecorder.js @@ -7,9 +7,10 @@ module.exports = { return sources }, test: function (browser, callback) { + browser.clickLaunchIcon = contractHelper.clickLaunchIcon contractHelper.addFile(browser, 'scenario.json', {content: records}, () => { browser - .click('.runView') + .clickLaunchIcon('run transactions') .click('div[class^="cardContainer"] i[class^="arrow"]') .click('#runTabView .runtransaction') .waitForElementPresent('.instance:nth-of-type(2)')