Merge pull request #2589 from ethereum/vmSandbox

Script Execution - Async/Await support
pull/5370/head
yann300 5 years ago committed by GitHub
commit 02915fbadf
  1. 3
      src/app.js
  2. 2
      src/app/components/hidden-panel.js
  3. 45
      src/app/panels/terminal.js
  4. 2
      src/remixAppManager.js
  5. 57
      test-browser/tests/terminal.js

@ -332,6 +332,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
engine.register([
menuicons,
landingPage,
hiddenPanel,
sidePanel,
pluginManagerComponent,
filePanel,
@ -384,7 +385,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
await appManager.activatePlugin(['contentImport', 'theme', 'editor', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'offsetToLineColumnConverter'])
await appManager.activatePlugin(['mainPanel', 'menuicons'])
await appManager.activatePlugin(['home', 'sidePanel', 'pluginManager', 'fileExplorers', 'settings', 'contextualListener', 'terminal'])
await appManager.activatePlugin(['home', 'sidePanel', 'hiddenPanel', 'pluginManager', 'fileExplorers', 'settings', 'contextualListener', 'scriptRunner', 'terminal'])
// Set workspace after initial activation
if (Array.isArray(workspace)) await appManager.activatePlugin(workspace)

@ -14,7 +14,7 @@ const profile = {
displayName: 'Hidden Panel',
description: '',
version: packageJson.version,
methods: []
methods: ['addView', 'removeView']
}
export class HiddenPanel extends AbstractPanel {

@ -81,7 +81,7 @@ class Terminal extends Plugin {
scopedCommands.log(`> ${script}`)
self._shell(script, scopedCommands, function (error, output) {
if (error) scopedCommands.error(error)
else scopedCommands.log(output)
else if (output) scopedCommands.log(output)
})
}, { activate: true })
function basicFilter (value, query) { try { return value.indexOf(query) !== -1 } catch (e) { return false } }
@ -98,6 +98,26 @@ class Terminal extends Plugin {
if (opts.shell) self._shell = opts.shell // ???
register(self)
}
onActivation () {
this.on('scriptRunner', 'log', (msg) => {
this.commands['log'].apply(this.commands, msg.data)
})
this.on('scriptRunner', 'info', (msg) => {
this.commands['info'].apply(this.commands, msg.data)
})
this.on('scriptRunner', 'warn', (msg) => {
this.commands['warn'].apply(this.commands, msg.data)
})
this.on('scriptRunner', 'error', (msg) => {
this.commands['error'].apply(this.commands, msg.data)
})
}
onDeactivation () {
this.off('scriptRunner', 'log')
this.off('scriptRunner', 'info')
this.off('scriptRunner', 'warn')
this.off('scriptRunner', 'error')
}
logHtml (html) {
var command = this.commands['html']
if (typeof command === 'function') command(html)
@ -124,6 +144,7 @@ class Terminal extends Plugin {
${self._view.input}
</div>
`
self._view.icon = yo`
<i onmouseenter=${hover} onmouseleave=${hover} onmousedown=${minimize}
class="btn btn-secondary btn-sm align-items-center ${css.toggleTerminal} fas fa-angle-double-down" data-id="terminalToggleIcon"></i>`
@ -659,17 +680,27 @@ class Terminal extends Plugin {
}
return self.commands[name]
}
_shell (script, scopedCommands, done) { // default shell
async _shell (script, scopedCommands, done) { // default shell
if (script.indexOf('remix:') === 0) {
return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.')
}
var self = this
var context = domTerminalFeatures(self, scopedCommands, self.blockchain)
if (script.indexOf('remix.') === 0) {
// we keep the old feature. This will basically only be called when the command is querying the "remix" object.
// for all the other case, we use the Code Executor plugin
var context = domTerminalFeatures(self, scopedCommands, self.blockchain)
try {
var cmds = vm.createContext(Object.assign(self._jsSandboxContext, context, self._jsSandboxRegistered))
var result = vm.runInContext(script, cmds)
self._jsSandboxContext = Object.assign(cmds, context)
return done(null, result)
} catch (error) {
return done(error.message)
}
}
try {
var cmds = vm.createContext(Object.assign(self._jsSandboxContext, context, self._jsSandboxRegistered))
var result = vm.runInContext(script, cmds)
self._jsSandboxContext = Object.assign(cmds, context)
done(null, result)
await this.call('scriptRunner', 'execute', script)
done()
} catch (error) {
done(error.message)
}

@ -4,7 +4,7 @@ import { EventEmitter } from 'events'
import QueryParams from './lib/query-params'
const requiredModules = [ // services + layout views + system views
'manager', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'fileManager', 'contentImport',
'manager', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'fileManager', 'contentImport', 'scriptRunner',
'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', 'fileExplorers',
'terminal', 'settings', 'pluginManager']

@ -10,7 +10,7 @@ module.exports = {
'Should execution a simple console command': function (browser) {
browser
.waitForElementVisible('*[data-id="terminalCli"]', 10000)
.executeScript('1+1')
.executeScript('console.log(1 + 1)')
.journalLastChild('2')
},
@ -52,8 +52,63 @@ module.exports = {
.executeScript('remix.debugHelp()')
.journalChildIncludes('Here are some examples of scripts that can be run (using remix.exeCurrent() or directly from the console)')
.journalChildIncludes('Please see https://www.npmjs.com/package/remix-debug for more informations')
},
'Async/Await Script': function (browser) {
browser
.addFile('asyncAwait.js', { content: asyncAwait })
.switchFile('browser/asyncAwait.js')
.executeScript(`remix.execute('browser/asyncAwait.js')`)
.journalLastChild('Waiting Promise')
.pause(5500)
.journalLastChild('result - Promise Resolved')
},
'Call Remix File Manager from a script': function (browser) {
browser
.addFile('asyncAwaitWithFileManagerAccess.js', { content: asyncAwaitWithFileManagerAccess })
.switchFile('browser/asyncAwaitWithFileManagerAccess.js')
.executeScript(`remix.execute('browser/asyncAwaitWithFileManagerAccess.js')`)
.journalLastChildIncludes('contract Ballot {')
.end()
},
tearDown: sauce
}
const asyncAwait = `
var p = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Promise Resolved")
}, 5000)
})
}
var run = async () => {
console.log('Waiting Promise')
var result = await p()
console.log('result - ', result)
}
run()
`
const asyncAwaitWithFileManagerAccess = `
var p = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Promise Resolved")
}, 0)
})
}
var run = async () => {
console.log('Waiting Promise')
var result = await p()
let text = await remix.call('fileManager', 'getFile', 'browser/3_Ballot.sol')
console.log('result - ', text)
}
run()
`

Loading…
Cancel
Save