Merge pull request #120 from yann300/uiPanels

redesigning the layout
pull/7/head
chriseth 8 years ago committed by GitHub
commit 99e9baaed6
  1. 28
      ci/browser_tests.sh
  2. 8
      index.html
  3. 5
      nightwatch.js
  4. 10
      src/code/opcodes.js
  5. 4
      src/helpers/traceHelper.js
  6. 25
      src/helpers/ui.js
  7. 2
      src/trace/traceAnalyser.js
  8. 6
      src/trace/traceManager.js
  9. 55
      src/ui/ASMCode.js
  10. 12
      src/ui/ButtonNavigator.js
  11. 17
      src/ui/CalldataPanel.js
  12. 17
      src/ui/CallstackPanel.js
  13. 71
      src/ui/CodeListView.js
  14. 85
      src/ui/DropdownPanel.js
  15. 10
      src/ui/Ethdebugger.js
  16. 22
      src/ui/FullStoragesChanges.js
  17. 9
      src/ui/MemoryPanel.js
  18. 19
      src/ui/StackPanel.js
  19. 100
      src/ui/StepDetail.js
  20. 4
      src/ui/StepManager.js
  21. 150
      src/ui/Sticker.js
  22. 17
      src/ui/StoragePanel.js
  23. 77
      src/ui/TxBrowser.js
  24. 72
      src/ui/VmDebugger.js
  25. 42
      src/ui/styles/basicStyles.js
  26. 28
      src/ui/styles/dropdownPanel.js
  27. 12
      src/ui/styles/sliderStyles.js
  28. 136
      test-browser/init.js
  29. 74
      test-browser/vmdebugger.js
  30. 77
      test/resources/insertTestWeb3.js

@ -1,6 +1,5 @@
#!/usr/bin/env bash
SAUCECONNECT_URL="https://saucelabs.com/downloads/sc-4.3.16-linux.tar.gz"
SAUCECONNECT_USERNAME="yanneth"
SAUCECONNECT_ACCESSKEY="1f5a4560-b02b-41aa-b52b-f033aad30870"
@ -18,10 +17,29 @@ while [ ! -f $SAUCECONNECT_READYFILE ]; do
sleep .5
done
npm run nightwatch_remote_firefox || TEST_EXITCODE=1
npm run nightwatch_remote_chrome || TEST_EXITCODE=1
npm run nightwatch_remote_safari || TEST_EXITCODE=1
npm run nightwatch_remote_ie || TEST_EXITCODE=1
npm run nightwatch_remote_firefox
if [ $? -eq 1 ]
then
TEST_EXITCODE=1
fi
npm run nightwatch_remote_chrome
if [ $? -eq 1 ]
then
TEST_EXITCODE=1
fi
npm run nightwatch_remote_safari
if [ $? -eq 1 ]
then
TEST_EXITCODE=1
fi
npm run nightwatch_remote_ie
if [ $? -eq 1 ]
then
TEST_EXITCODE=1
fi
node ci/sauceDisconnect.js $SAUCECONNECT_USERNAME $SAUCECONNECT_ACCESSKEY $SAUCECONNECT_JOBIDENTIFIER

@ -6,10 +6,10 @@
<script type="text/javascript">
function loadDebugger() {
var container = document.getElementById('app')
container.vmdebugger = new window.remix.ui.Debugger()
container.vmdebugger.addProvider('INTERNAL')
container.vmdebugger.switchProvider('INTERNAL')
container.appendChild(container.vmdebugger.render())
container.debugger = new window.remix.ui.Debugger()
container.debugger.addProvider('INTERNAL')
container.debugger.switchProvider('INTERNAL')
container.appendChild(container.debugger.render())
}
</script>
<div id="app"></div>

@ -62,7 +62,8 @@ module.exports = {
'desiredCapabilities': {
'browserName': 'safari',
'javascriptEnabled': true,
'platform': 'MAC',
'platform': 'OS X 10.11',
'version': '9.0',
'acceptSslCerts': true,
'build': 'build-' + TRAVIS_JOB_NUMBER,
'tunnel-identifier': 'remix_tests_' + TRAVIS_JOB_NUMBER
@ -74,6 +75,8 @@ module.exports = {
'browserName': 'internet explorer',
'javascriptEnabled': true,
'acceptSslCerts': true,
'platform': 'WIN8.1',
'version': '11',
'build': 'build-' + TRAVIS_JOB_NUMBER,
'tunnel-identifier': 'remix_tests_' + TRAVIS_JOB_NUMBER
}

@ -136,11 +136,11 @@ var codes = {
0x9e: ['SWAP', 3, 0, 0, false],
0x9f: ['SWAP', 3, 0, 0, false],
0xa0: ['LOG', 375, 2, 0, false],
0xa1: ['LOG', 375, 3, 0, false],
0xa2: ['LOG', 375, 4, 0, false],
0xa3: ['LOG', 375, 5, 0, false],
0xa4: ['LOG', 375, 6, 0, false],
0xa0: ['LOG0', 375, 2, 0, false],
0xa1: ['LOG1', 375, 3, 0, false],
0xa2: ['LOG2', 375, 4, 0, false],
0xa3: ['LOG3', 375, 5, 0, false],
0xa4: ['LOG4', 375, 6, 0, false],
// '0xf0' range - closures
0xf0: ['CREATE', 32000, 3, 1, true],

@ -25,6 +25,10 @@ module.exports = {
return step.op === 'RETURN'
},
isStopInstruction: function (step) {
return step.op === 'STOP'
},
isSSTOREInstruction: function (step) {
return step.op === 'SSTORE'
},

@ -1,7 +1,7 @@
'use strict'
module.exports = {
formatMemory: function (mem, width) {
var ret = ''
var ret = {}
if (!mem) {
return ret
}
@ -13,7 +13,7 @@ module.exports = {
for (var k = 0; k < mem.length; k += (width * 2)) {
var memory = mem.substr(k, width * 2)
var content = this.tryConvertAsciiFormat(memory)
ret += '0x' + (k / 2).toString(16) + '\t\t' + content.raw + '\t' + content.ascii + '\n'
ret['0x' + (k / 2).toString(16)] = content.raw + '\t' + content.ascii
}
return ret
},
@ -33,12 +33,27 @@ module.exports = {
return ret
},
/**
* format @args css1, css2, css3 to css inline style
*
* @param {Object} css1 - css inline declaration
* @param {Object} css2 - css inline declaration
* @param {Object} css3 - css inline declaration
* @param {Object} ...
* @return {String} css inline style
* if the key start with * the value is direcly appended to the inline style (which should be already inline style formatted)
* used if multiple occurences of the same key is needed
*/
formatCss: function (css1, css2) {
var ret = ''
for (var arg in arguments) {
for (var k in arguments[arg]) {
if (arguments[arg][k] && ret.indexOf(k) === -1) {
ret += k + ':' + arguments[arg][k] + ';'
if (k.indexOf('*') === 0) {
ret += arguments[arg][k]
} else {
ret += k + ':' + arguments[arg][k] + ';'
}
}
}
}
@ -51,5 +66,9 @@ module.exports = {
}
hex = hex.replace(/^0+/, '')
return '0x' + hex
},
runInBrowser: function () {
return typeof window !== 'undefined'
}
}

@ -118,7 +118,7 @@ TraceAnalyser.prototype.buildDepth = function (index, step, tx, callStack, conte
this.traceCache.pushSteps(index, context.currentCallIndex)
context.lastCallIndex = context.currentCallIndex
context.currentCallIndex = 0
} else if (traceHelper.isReturnInstruction(step)) {
} else if (traceHelper.isReturnInstruction(step) || traceHelper.isStopInstruction(step)) {
if (index + 1 < this.trace.length) {
callStack.pop()
this.traceCache.pushCallChanges(step, index + 1)

@ -222,7 +222,11 @@ TraceManager.prototype.getReturnValue = function (stepIndex, callback) {
if (check) {
return callback(check, null)
}
callback(null, this.traceCache.returnValues[stepIndex])
if (!this.traceCache.returnValues[stepIndex]) {
callback('current step is not a return step')
} else {
callback(null, this.traceCache.returnValues[stepIndex])
}
}
TraceManager.prototype.getCurrentStep = function (stepIndex, callback) {

@ -1,55 +0,0 @@
'use strict'
var style = require('./styles/basicStyles')
var yo = require('yo-yo')
var ui = require('../helpers/ui')
function ASMCode (_parent, _codeManager) {
this.parent = _parent
this.codeManager = _codeManager
this.code
this.address
this.codeView
this.init()
}
ASMCode.prototype.render = function () {
var view = (
yo`<select size='10' id='asmitems' ref='itemsList' style=${ui.formatCss(style.instructionsList)}>
${this.codeView}
</select>`
)
if (!this.view) {
this.view = view
}
return view
}
ASMCode.prototype.init = function () {
this.codeManager.register('changed', this, this.changed)
}
ASMCode.prototype.indexChanged = function (index) {
document.getElementById('asmitems').value = index
}
ASMCode.prototype.changed = function (code, address, index) {
if (this.address !== address) {
this.code = code
this.address = address
this.renderAssemblyItems()
yo.update(this.view, this.render())
}
this.indexChanged(index)
}
ASMCode.prototype.renderAssemblyItems = function () {
if (this.code) {
this.codeView = this.code.map(function (item, i) {
return yo`<option key=${i} value=${i}>${item}</option>`
})
return this.codeView
}
}
module.exports = ASMCode

@ -1,6 +1,8 @@
'use strict'
var util = require('../helpers/global')
var EventManager = require('../lib/eventManager')
var style = require('./styles/basicStyles')
var ui = require('../helpers/ui')
var yo = require('yo-yo')
function ButtonNavigator (_traceManager) {
@ -21,19 +23,19 @@ module.exports = ButtonNavigator
ButtonNavigator.prototype.render = function () {
var self = this
var view = yo`<div>
<button id='overback' onclick=${function () { self.trigger('stepOverBack') }} disabled=${this.overBackDisabled} >
<button id='overback' style=${ui.formatCss(style.button)} onclick=${function () { self.trigger('stepOverBack') }} disabled=${this.overBackDisabled} >
Step Over Back
</button>
<button id='intoback' onclick=${function () { self.trigger('stepIntoBack') }} disabled=${this.intoBackDisabled} >
<button id='intoback' style=${ui.formatCss(style.button)} onclick=${function () { self.trigger('stepIntoBack') }} disabled=${this.intoBackDisabled} >
Step Into Back
</button>
<button id='intoforward' onclick=${function () { self.trigger('stepIntoForward') }} disabled=${this.intoForwardDisabled} >
<button id='intoforward' style=${ui.formatCss(style.button)} onclick=${function () { self.trigger('stepIntoForward') }} disabled=${this.intoForwardDisabled} >
Step Into Forward
</button>
<button id='overforward' onclick=${function () { self.trigger('stepOverForward') }} disabled=${this.overForwardDisabled} >
<button id='overforward' style=${ui.formatCss(style.button)} onclick=${function () { self.trigger('stepOverForward') }} disabled=${this.overForwardDisabled} >
Step Over Forward
</button>
<button id='nextcall' onclick=${function () { self.trigger('jumpNextCall') }} disabled=${this.nextCallDisabled} >
<button id='nextcall' style=${ui.formatCss(style.button)} onclick=${function () { self.trigger('jumpNextCall') }} disabled=${this.nextCallDisabled} >
Jump Next Call
</button>
</div>`

@ -1,11 +1,11 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function CalldataPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Call Data')
this.basicPanel = new DropdownPanel('Call Data')
this.init()
}
@ -21,22 +21,13 @@ CalldataPanel.prototype.init = function () {
self.traceManager.getCallDataAt(index, function (error, calldata) {
if (error) {
self.basicPanel.data = ''
self.basicPanel.update({})
console.log(error)
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = self.format(calldata)
self.basicPanel.update(calldata)
}
self.basicPanel.update()
})
})
}
CalldataPanel.prototype.format = function (calldata) {
var ret = ''
for (var key in calldata) {
ret += calldata[key] + '\n'
}
return ret
}
module.exports = CalldataPanel

@ -1,11 +1,11 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function CallstackPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Call Stack')
this.basicPanel = new DropdownPanel('Call Stack')
this.init()
}
@ -22,21 +22,12 @@ CallstackPanel.prototype.init = function () {
self.traceManager.getCallStackAt(index, function (error, callstack) {
if (error) {
console.log(error)
self.basicPanel.data = ''
self.basicPanel.update({})
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = self.format(callstack)
self.basicPanel.update(callstack)
}
self.basicPanel.update()
})
})
}
CallstackPanel.prototype.format = function (callstack) {
var ret = ''
for (var key in callstack) {
ret += callstack[key] + '\n'
}
return ret
}
module.exports = CallstackPanel

@ -0,0 +1,71 @@
'use strict'
var style = require('./styles/basicStyles')
var yo = require('yo-yo')
var ui = require('../helpers/ui')
var DropdownPanel = require('./DropdownPanel')
function CodeListView (_parent, _codeManager) {
this.parent = _parent
this.codeManager = _codeManager
this.code
this.address
this.codeView
this.itemSelected
this.basicPanel = new DropdownPanel('Instructions', true)
this.init()
}
CodeListView.prototype.render = function () {
return yo`<div id='asmcodes' >${this.basicPanel.render({height: style.instructionsList.height})}</div>`
}
CodeListView.prototype.init = function () {
var self = this
this.codeManager.register('changed', this, this.changed)
this.parent.register('traceUnloaded', this, function () {
self.changed([], '', -1)
})
}
CodeListView.prototype.indexChanged = function (index) {
if (index >= 0) {
if (this.itemSelected) {
this.itemSelected.removeAttribute('selected')
this.itemSelected.removeAttribute('style')
if (this.itemSelected.firstChild) {
this.itemSelected.firstChild.removeAttribute('style')
}
}
this.itemSelected = this.codeView.children[index]
this.itemSelected.setAttribute('style', ui.formatCss({'background-color': '#eeeeee'}))
this.itemSelected.setAttribute('selected', 'selected')
if (this.itemSelected.firstChild) {
this.itemSelected.firstChild.setAttribute('style', ui.formatCss({'margin-left': '2px'}))
}
this.codeView.scrollTop = this.itemSelected.offsetTop - parseInt(this.codeView.offsetHeight)
}
}
CodeListView.prototype.changed = function (code, address, index) {
if (this.address !== address) {
this.code = code
this.address = address
this.codeView = this.renderAssemblyItems()
this.basicPanel.data = this.codeView
this.basicPanel.update()
}
this.indexChanged(index)
}
CodeListView.prototype.renderAssemblyItems = function () {
if (this.code) {
var codeView = this.code.map(function (item, i) {
return yo`<div key=${i} value=${i}><span>${item}</span></div>`
})
return yo`<div id='asmitems' ref='itemsList' style=${ui.formatCss(style.instructionsList)}>
${codeView}
</div>`
}
}
module.exports = CodeListView

@ -0,0 +1,85 @@
'use strict'
var yo = require('yo-yo')
var ui = require('../helpers/ui')
var styleDropdown = require('./styles/dropdownPanel')
var basicStyles = require('./styles/basicStyles')
function DropdownPanel (_name, _raw) {
this.data
this.name = _name
this.view
_raw = _raw === undefined ? false : _raw
this.raw = _raw
}
DropdownPanel.prototype.update = function (_data) {
if (!this.view) {
return
}
if (_data) {
this.data = _data
}
this.view.querySelector('.dropdownpanel div.dropdowncontent').innerHTML = ''
if (!this.raw) {
var data = JSON.stringify(this.data, null, '\t')
if (!this.data || data === '[]' || data === '{}') {
this.data = ['Empty']
}
var div = document.createElement('div')
if (Array.isArray(this.data)) {
this.data.map(function (item, i) {
div.appendChild(yo`<div>${item}</div>`)
})
} else {
for (var k in this.data) {
var content = typeof this.data[k] === 'string' ? this.data[k] : JSON.stringify(this.data[k])
div.appendChild(yo`<div><div title=${k} style=${ui.formatCss(basicStyles.truncate, {display: 'inline-block', 'width': '10%'})} >${k}</div><div title=${content} style=${ui.formatCss(basicStyles.truncate, {display: 'inline-block', 'width': '78%'})} >${content}</div></div>`)
}
}
this.view.querySelector('.dropdownpanel div.dropdowncontent').appendChild(div)
this.view.querySelector('.dropdownpanel button.btn').style.display = 'block'
this.view.querySelector('.dropdownpanel .dropdownrawcontent').innerText = data
} else {
this.view.querySelector('.dropdownpanel div.dropdowncontent').appendChild(this.data)
this.view.querySelector('.dropdownpanel button.btn').style.display = 'none'
}
}
DropdownPanel.prototype.render = function (overridestyle) {
overridestyle === undefined ? {} : overridestyle
var self = this
var view = yo`<div>
<div class='title' style=${ui.formatCss(styleDropdown.title)} onclick=${function () { self.toggle() }}>
<div style=${ui.formatCss(styleDropdown.inner, styleDropdown.titleInner)}>${this.name}</div>
</div>
<div class='dropdownpanel' style=${ui.formatCss(styleDropdown.content)} style='display:none'>
<button onclick=${function () { self.toggleRaw() }} style=${ui.formatCss(basicStyles.button, styleDropdown.copyBtn)} class="btn" type="button">
Raw
</button>
<div style=${ui.formatCss(styleDropdown.inner, overridestyle)} class='dropdowncontent'><div>Empty</div></div>
<div style=${ui.formatCss(styleDropdown.inner, overridestyle)} class='dropdownrawcontent' style='display:none'></div>
</div>
</div>`
if (!this.view) {
this.view = view
}
return view
}
DropdownPanel.prototype.toggleRaw = function () {
var raw = this.view.querySelector('.dropdownpanel .dropdownrawcontent')
var formatted = this.view.querySelector('.dropdownpanel .dropdowncontent')
raw.style.display = raw.style.display === 'none' ? 'block' : 'none'
formatted.style.display = formatted.style.display === 'none' ? 'block' : 'none'
}
DropdownPanel.prototype.toggle = function () {
var el = this.view.querySelector('.dropdownpanel')
if (el.style.display === '') {
el.style.display = 'none'
} else {
el.style.display = ''
}
}
module.exports = DropdownPanel

@ -3,7 +3,6 @@ var TxBrowser = require('./TxBrowser')
var StepManager = require('./StepManager')
var TraceManager = require('../trace/traceManager')
var VmDebugger = require('./VmDebugger')
var Sticker = require('./Sticker')
var style = require('./styles/basicStyles')
var util = require('../helpers/global')
var EventManager = require('../lib/eventManager')
@ -49,7 +48,6 @@ function Ethdebugger () {
self.stepChanged(stepIndex)
})
this.vmDebugger = new VmDebugger(this, this.traceManager, this.codeManager)
this.sticker = new Sticker(this, this.traceManager)
}
Ethdebugger.prototype.web3 = function () {
@ -83,14 +81,10 @@ Ethdebugger.prototype.debug = function (tx) {
Ethdebugger.prototype.render = function () {
var view = yo`<div style=${ui.formatCss(style.font)}>
<h1 style=${ui.formatCss(style.container)}>VM Debugger</h1>
<div style='display:inline-block'>
<div style=${ui.formatCss({'max-width': '51%'}, style.innerShift)}>
${this.txBrowser.render()}
${this.stepManager.render()}
</div>
<div style='display:inline-block'>
${this.sticker.render()}
</div>
<div style=${ui.formatCss(style.statusMessage)} >${this.statusMessage}</div>
${this.vmDebugger.render()}
</div>`
@ -121,7 +115,7 @@ Ethdebugger.prototype.startDebugging = function (blockNumber, txIndex, tx) {
this.tx = tx
var self = this
this.traceManager.resolveTrace(tx, function (error, result) {
console.log('trace loaded ' + result + ' ' + error)
console.log('trace loaded ' + result)
if (result) {
self.statusMessage = ''
yo.update(self.view, self.render())

@ -1,5 +1,5 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function FullStoragesChanges (_parent, _traceManager) {
@ -8,7 +8,7 @@ function FullStoragesChanges (_parent, _traceManager) {
this.addresses = []
this.view
this.traceLength
this.basicPanel = new BasicPanel('Full Storages Changes', '1205px', '100px')
this.basicPanel = new DropdownPanel('Full Storages Changes')
this.init()
}
@ -20,14 +20,6 @@ FullStoragesChanges.prototype.render = function () {
return view
}
FullStoragesChanges.prototype.hide = function () {
this.view.style.display = 'none'
}
FullStoragesChanges.prototype.show = function () {
this.view.style.display = 'block'
}
FullStoragesChanges.prototype.init = function () {
var self = this
this.parent.register('newTraceLoaded', this, function (length) {
@ -35,9 +27,7 @@ FullStoragesChanges.prototype.init = function () {
self.traceManager.getAddresses(function (error, addresses) {
if (!error) {
self.addresses = addresses
self.basicPanel.data = ''
yo.update(self.view, self.render())
self.hide()
self.basicPanel.update({})
}
})
@ -58,14 +48,10 @@ FullStoragesChanges.prototype.init = function () {
self.traceManager.getStorageAt(index, null, function (error, result) {
if (!error) {
storageJSON[self.addresses[k]] = result
self.basicPanel.data = JSON.stringify(storageJSON, null, '\t')
yo.update(self.view, self.render())
self.show()
self.basicPanel.update(storageJSON)
}
}, self.addresses[k])
}
} else {
self.hide()
}
})
}

@ -1,12 +1,12 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var DropdownPanel = require('./DropdownPanel')
var util = require('../helpers/ui')
var yo = require('yo-yo')
function MemoryPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Memory')
this.basicPanel = new DropdownPanel('Memory')
this.init()
}
@ -23,11 +23,10 @@ MemoryPanel.prototype.init = function () {
self.traceManager.getMemoryAt(index, function (error, memory) {
if (error) {
console.log(error)
self.basicPanel.data = ''
self.basicPanel.update({})
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = util.formatMemory(memory, 16)
self.basicPanel.update(util.formatMemory(memory, 16))
}
self.basicPanel.update()
})
})
}

@ -1,12 +1,12 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var DropdownPanel = require('./DropdownPanel')
var ui = require('../helpers/ui')
var yo = require('yo-yo')
function StackPanel (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Stack')
this.basicPanel = new DropdownPanel('Stack')
this.init()
}
@ -22,22 +22,21 @@ StackPanel.prototype.init = function () {
self.traceManager.getStackAt(index, function (error, stack) {
if (error) {
self.basicPanel.data = ''
self.basicPanel.update({})
console.log(error)
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = self.format(stack)
self.basicPanel.update(self.format(stack))
}
self.basicPanel.update()
})
})
}
StackPanel.prototype.format = function (stack) {
var ret = ''
for (var key in stack) {
var hex = ui.normalizeHex(stack[key])
ret += hex + '\n'
}
var ret = []
stack.map(function (item, i) {
var hex = ui.normalizeHex(item)
ret.push(hex)
})
return ret
}

@ -0,0 +1,100 @@
'use strict'
var yo = require('yo-yo')
var DropdownPanel = require('./DropdownPanel')
function StepDetail (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new DropdownPanel('Step detail')
this.detail = initDetail()
this.view
this.init()
}
StepDetail.prototype.render = function () {
return yo`<div id='stepdetail' >${this.basicPanel.render()}</div>`
}
StepDetail.prototype.init = function () {
var self = this
this.parent.register('traceUnloaded', this, function () {
self.detail = initDetail()
self.basicPanel.update(self.detail)
})
this.parent.register('newTraceLoaded', this, function () {
self.detail = initDetail()
self.basicPanel.update(self.detail)
})
this.parent.register('indexChanged', this, function (index) {
if (index < 0) return
self.detail['vm trace step'] = index
self.traceManager.getCurrentStep(index, function (error, step) {
if (error) {
console.log(error)
self.detail['execution step'] = '-'
} else {
self.detail['execution step'] = step
}
self.basicPanel.update(self.detail)
})
self.traceManager.getMemExpand(index, function (error, addmem) {
if (error) {
console.log(error)
self.detail['add memory'] = '-'
} else {
self.detail['add memory'] = addmem
}
self.basicPanel.update(self.detail)
})
self.traceManager.getStepCost(index, function (error, gas) {
if (error) {
console.log(error)
self.detail.gas = '-'
} else {
self.detail.gas = gas
}
self.basicPanel.update(self.detail)
})
self.traceManager.getCurrentCalledAddressAt(index, function (error, address) {
if (error) {
console.log(error)
self.detail['loaded address'] = '-'
} else {
self.detail['loaded address'] = address
}
self.basicPanel.update(self.detail)
})
self.traceManager.getRemainingGas(index, function (error, remaingas) {
if (error) {
console.log(error)
self.detail['remaining gas'] = '-'
} else {
self.detail['remaining gas'] = remaingas
}
self.basicPanel.update(self.detail)
})
})
}
module.exports = StepDetail
function initDetail () {
return {
'vm trace step': '-',
'execution step': '-',
'add memory': '',
'gas': '',
'remaining gas': '-',
'loaded address': '-'
}
}

@ -1,11 +1,9 @@
'use strict'
var ButtonNavigator = require('./ButtonNavigator')
var Slider = require('./Slider')
var style = require('./styles/basicStyles')
var util = require('../helpers/global')
var EventManager = require('../lib/eventManager')
var yo = require('yo-yo')
var ui = require('../helpers/ui')
function StepManager (_parent, _traceManager) {
util.extend(this, new EventManager())
@ -49,7 +47,7 @@ function StepManager (_parent, _traceManager) {
StepManager.prototype.render = function () {
return (
yo`<div style=${ui.formatCss(style.container)}>
yo`<div>
${this.slider.render()}
${this.buttonNavigator.render()}
</div>`

@ -1,150 +0,0 @@
'use strict'
var yo = require('yo-yo')
function Sticker (_parent, _traceManager) {
this.parent = _parent
this.traceManager = _traceManager
this.vmTraceStep = '-'
this.step = '-'
this.addmemory = '-'
this.gas = '-'
this.remainingGas = '-'
this.loadedAddress = '-'
this.hide = true
this.view
this.init()
}
Sticker.prototype.render = function () {
var view = yo`<div style=${this.hide ? 'display: none' : 'display: block'}>
<table>
<tbody>
<tr key='vmtracestep'>
<td>
VMtracestep:
</td>
<td id='vmtracestepinfo' >
${this.vmTraceStep}
</td>
</tr>
<tr key='step'>
<td>
Step:
</td>
<td id='stepinfo'>
${this.step}
</td>
</tr>
<tr key='addmemory'>
<td>
Add memory:
</td>
<td id='addmemoryinfo'>
${this.addmemory}
</td>
</tr>
<tr key='gas'>
<td>
Gas:
</td>
<td id='gasinfo'>
${this.gas}
</td>
</tr>
<tr key='remaininggas'>
<td>
Remaining gas:
</td>
<td id='remaininggasinfo'>
${this.remainingGas}
</td>
</tr>
<tr key='loadedaddress'>
<td>
Loaded address:
</td>
<td id='loadedaddressinfo'>
${this.loadedAddress}
</td>
</tr>
</tbody>
</table>
</div>`
if (!this.view) {
this.view = view
}
return view
}
Sticker.prototype.init = function () {
var self = this
this.parent.register('traceUnloaded', this, function () {
self.hide = true
yo.update(self.view, self.render())
})
this.parent.register('newTraceLoaded', this, function () {
self.hide = false
yo.update(self.view, self.render())
})
this.parent.register('indexChanged', this, function (index) {
if (index < 0) return
self.vmTraceStep = index
self.traceManager.getCurrentStep(index, function (error, step) {
if (error) {
console.log(error)
self.step = '-'
} else {
self.step = step
}
yo.update(self.view, self.render())
})
self.traceManager.getMemExpand(index, function (error, addmem) {
if (error) {
console.log(error)
self.addmemory = '-'
} else {
self.addmemory = addmem
}
yo.update(self.view, self.render())
})
self.traceManager.getStepCost(index, function (error, gas) {
if (error) {
console.log(error)
self.gas = '-'
} else {
self.gas = gas
}
yo.update(self.view, self.render())
})
self.traceManager.getCurrentCalledAddressAt(index, function (error, address) {
if (error) {
console.log(error)
self.loadedAddress = '-'
} else {
self.loadedAddress = address
}
yo.update(self.view, self.render())
})
self.traceManager.getRemainingGas(index, function (error, remaingas) {
if (error) {
console.log(error)
self.remainingGas = '-'
} else {
self.remainingGas = remaingas
}
yo.update(self.view, self.render())
})
})
}
module.exports = Sticker

@ -1,11 +1,11 @@
'use strict'
var BasicPanel = require('./BasicPanel')
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager, _address) {
this.parent = _parent
this.traceManager = _traceManager
this.basicPanel = new BasicPanel('Storage Changes')
this.basicPanel = new DropdownPanel('Storage Changes')
this.address = _address
this.init()
this.disabled = false
@ -25,21 +25,12 @@ StoragePanel.prototype.init = function () {
self.traceManager.getStorageAt(index, self.parent.tx, function (error, storage) {
if (error) {
console.log(error)
self.basicPanel.data = self.formatStorage(storage)
self.basicPanel.update({})
} else if (self.parent.currentStepIndex === index) {
self.basicPanel.data = self.formatStorage(storage)
self.basicPanel.update(storage)
}
self.basicPanel.update()
}, self.address)
})
}
StoragePanel.prototype.formatStorage = function (storage) {
var ret = ''
for (var key in storage) {
ret += key + ' ' + storage[key] + '\n'
}
return ret
}
module.exports = StoragePanel

@ -5,17 +5,17 @@ var traceHelper = require('../helpers/traceHelper')
var yo = require('yo-yo')
var ui = require('../helpers/ui')
var init = require('../helpers/init')
var DropdownPanel = require('./DropdownPanel')
function TxBrowser (_parent) {
util.extend(this, new EventManager())
this.blockNumber
this.txNumber
this.hash
this.from
this.to
this.view
this.displayConnectionSetting = true
this.basicPanel = new DropdownPanel('Transaction')
this.basicPanel.data = {}
var self = this
_parent.register('providerChanged', this, function (provider) {
self.displayConnectionSetting = provider === 'INTERNAL'
@ -33,12 +33,10 @@ function TxBrowser (_parent) {
// invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51
TxBrowser.prototype.setDefaultValues = function () {
this.from = ' - '
this.to = ' - '
this.hash = ' - '
this.blockNumber = null
this.txNumber = ''
this.connectInfo = ''
this.basicPanel.data = {}
this.basicPanel.update()
this.updateWeb3Url(util.web3.currentProvider.host)
}
@ -57,23 +55,24 @@ TxBrowser.prototype.submit = function () {
} catch (e) {
console.log(e)
}
console.log(JSON.stringify(tx))
var info = {}
if (tx) {
if (!tx.to) {
tx.to = traceHelper.contractCreationToken('0')
}
this.from = tx.from
this.to = tx.to
this.hash = tx.hash
info.from = tx.from
info.to = tx.to
info.hash = tx.hash
this.trigger('newTraceRequested', [this.blockNumber, this.txNumber, tx])
} else {
var mes = '<not found>'
this.from = mes
this.to = mes
this.hash = mes
info.from = mes
info.to = mes
info.hash = mes
console.log('cannot find ' + this.blockNumber + ' ' + this.txNumber)
}
yo.update(this.view, this.render())
this.basicPanel.data = info
this.basicPanel.update()
}
TxBrowser.prototype.updateWeb3Url = function (newhost) {
@ -110,13 +109,16 @@ TxBrowser.prototype.updateTxN = function (ev) {
TxBrowser.prototype.load = function (txHash) {
this.txNumber = txHash
yo.update(this.view, this.render())
this.submit()
}
TxBrowser.prototype.unload = function (txHash) {
this.trigger('unloadRequested')
this.init()
}
TxBrowser.prototype.init = function (ev) {
this.setDefaultValues()
yo.update(this.view, this.render())
}
TxBrowser.prototype.connectionSetting = function () {
@ -131,43 +133,16 @@ TxBrowser.prototype.connectionSetting = function () {
TxBrowser.prototype.render = function () {
var self = this
var view = yo`<div style=${ui.formatCss(style.container)}>
var view = yo`<div>
${this.connectionSetting()}
<input onkeyup=${function () { self.updateBlockN(arguments[0]) }} type='text' placeholder=${'Block number (default 1000110)' + this.blockNumber} />
<input id='txinput' onkeyup=${function () { self.updateTxN(arguments[0]) }} type='text' value=${this.txNumber} placeholder=${'Transaction Number or hash (default 2) ' + this.txNumber} />
<button id='load' onclick=${function () { self.submit() }}>
<input onkeyup=${function () { self.updateBlockN(arguments[0]) }} type='text' placeholder=${'Block number'} />
<input id='txinput' onkeyup=${function () { self.updateTxN(arguments[0]) }} type='text' placeholder=${'Transaction index or hash'} />
<button id='load' onclick=${function () { self.submit() }} style=${ui.formatCss(style.button)}>
Load
</button>
<button id='unload' onclick=${function () { self.trigger('unloadRequested') }}>Unload</button>
<div style=${ui.formatCss(style.transactionInfo)}>
<table>
<tbody>
<tr>
<td>
Hash:
</td>
<td id='txhash' >
${this.hash}
</td>
</tr>
<tr>
<td>
From:
</td>
<td id='txfrom'>
${this.from}
</td>
</tr>
<tr>
<td>
To:
</td>
<td id='txto' >
${this.to}
</td>
</tr>
</tbody>
</table>
<button id='unload' onclick=${function () { self.unload() }} style=${ui.formatCss(style.button)}>Reset</button>
<div style=${ui.formatCss(style.transactionInfo)} id='txinfo'>
${this.basicPanel.render()}
</div>
</div>`
if (!this.view) {

@ -1,39 +1,36 @@
'use strict'
var style = require('./styles/basicStyles')
var ASMCode = require('./ASMCode')
var CodeListView = require('./CodeListView')
var CalldataPanel = require('./CalldataPanel')
var MemoryPanel = require('./MemoryPanel')
var CallstackPanel = require('./CallstackPanel')
var StackPanel = require('./StackPanel')
var StoragePanel = require('./StoragePanel')
var BasicPanel = require('./BasicPanel')
var FullStoragesChangesPanel = require('./FullStoragesChanges')
var StepDetail = require('./StepDetail')
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
var ui = require('../helpers/ui')
function VmDebugger (_parent, _traceManager, _codeManager) {
this.asmCode = new ASMCode(_parent, _codeManager)
this.asmCode = new CodeListView(_parent, _codeManager)
this.stackPanel = new StackPanel(_parent, _traceManager)
this.storagePanel = new StoragePanel(_parent, _traceManager)
this.memoryPanel = new MemoryPanel(_parent, _traceManager)
this.calldataPanel = new CalldataPanel(_parent, _traceManager)
this.callstackPanel = new CallstackPanel(_parent, _traceManager)
this.stepDetail = new StepDetail(_parent, _traceManager)
/* Return values - */
this.returnValuesPanel = new BasicPanel('Return Value', '1205px', '100px')
this.returnValuesPanel = new DropdownPanel('Return Value')
this.returnValuesPanel.data = {}
_parent.register('indexChanged', this.returnValuesPanel, function (index) {
var self = this
_traceManager.getReturnValue(index, function (error, returnValue) {
if (error) {
console.log(error)
self.data = ''
self.data = [error]
} else if (_parent.currentStepIndex === index) {
self.data = returnValue
self.data = [returnValue]
}
self.update()
if (!returnValue) {
self.hide()
}
})
})
/* Return values - */
@ -52,46 +49,17 @@ function VmDebugger (_parent, _traceManager, _codeManager) {
VmDebugger.prototype.render = function () {
var view = yo`<div id='vmdebugger' style='display:none'>
<div style=${ui.formatCss(style.container)}>
<table>
<tbody>
<tr>
<td colspan='2'>
${this.returnValuesPanel.render()}
</td>
</tr>
<tr>
<td colspan='2'>
${this.fullStoragesChangesPanel.render()}
</td>
</tr>
<tr>
<td>
${this.asmCode.render()}
</td>
<td>
${this.stackPanel.render()}
</td>
</tr>
<tr>
<td>
${this.storagePanel.render()}
</td>
<td>
${this.memoryPanel.render()}
</td>
</tr>
<tr>
<td>
${this.calldataPanel.render()}
</td>
<td>
${this.callstackPanel.render()}
</td>
</tr>
</tbody>
</table>
</div>
<div>
${this.asmCode.render()}
${this.stepDetail.render()}
${this.stackPanel.render()}
${this.storagePanel.render()}
${this.memoryPanel.render()}
${this.calldataPanel.render()}
${this.callstackPanel.render()}
${this.returnValuesPanel.render()}
${this.fullStoragesChangesPanel.render()}
</div>
</div>`
if (!this.view) {
this.view = view

@ -1,8 +1,18 @@
'use strict'
module.exports = {
truncate: {
'white-space': 'nowrap',
'overflow': 'hidden',
'text-overflow': 'ellipsis',
'margin-right': '5px'
},
font: {
'font-family': 'arial,sans-serif'
},
innerShift: {
'padding': '2px',
'margin-left': '10px'
},
container: {
'margin': '10px',
'padding': '5px'
@ -14,8 +24,10 @@ module.exports = {
'font-style': 'italic'
},
instructionsList: {
'width': '600px',
'height': '330px'
'width': '52%',
'overflow-y': 'scroll',
'max-height': '500px',
'margin': '0'
},
transactionInfo: {
'margin-top': '5px'
@ -23,10 +35,10 @@ module.exports = {
panel: {
container: {
'border': '1px solid',
'width': '600px'
'width': '70%'
},
tableContainer: {
'height': '300px',
'height': '50%',
'overflow-y': 'auto'
},
table: {
@ -43,15 +55,29 @@ module.exports = {
display: {
'display': 'block'
},
sticker: {
'vertical-align': 'top',
'margin': '5px'
},
inline: {
'display': 'inline-block'
},
vmargin: {
'margin-top': '10px',
'margin-bottom': '10px'
},
button: {
'-moz-box-shadow': 'inset 0px 1px 0px 0px #ffffff',
'-webkit-box-shadow': 'inset 0px 1px 0px 0px #ffffff',
'box-shadow': 'inset 0px 1px 0px 0px #ffffff',
'*background': 'background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f9f9f9), color-stop(1, #e9e9e9));background: -moz-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);;background: -webkit-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);background: -webkit-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);background: -webkit-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);background: -webkit-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);background: -o-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);background: -ms-linear-gradient(top, #f9f9f9 5%, #e9e9e9 100%);background: linear-gradient(to bottom, #f9f9f9 5%, #e9e9e9 100%);', // eslint-disable-line
'filter': "progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e9e9e9',GradientType=0)", // eslint-disable-line
'background-color': '#f9f9f9',
'-moz-border-radius': '6px',
'-webkit-border-radius': '6px',
'border-radius': '6px',
'border': '1px solid #dcdcdc',
'display': 'inline-block',
'cursor': 'pointer',
'color': '#666666',
'font-family': 'Arial',
'text-decoration': 'none',
'text-shadow': '0px 1px 0px #ffffff'
}
}

@ -0,0 +1,28 @@
'use strict'
module.exports = {
title: {
'border': '1px solid #dadada',
'background-color': '#eeeeee',
'width': '100%',
'color': '#363f47',
'margin-top': '5px',
'cursor': 'pointer'
},
titleInner: {
'display': 'inline-block'
},
content: {
'color': '#111111',
'width': '100%',
'font-family': 'monospace'
},
inner: {
'padding': '2px',
'margin-left': '10px',
'word-break': 'break-all'
},
copyBtn: {
'float': 'right',
'margin-top': '3px'
}
}

@ -1,16 +1,6 @@
'use strict'
module.exports = {
rule: {
'width': '600px'
},
runner: {
'position': 'absolute',
'width': '16px',
'height': '16px',
'margin': '0',
'padding': '0',
'overflow': 'hidden',
'border': '1px solid #a4bed4',
'background-color': '#f1f7ff'
'width': '98%'
}
}

@ -1,87 +1,38 @@
var init = require('../test/init')
module.exports = function (browser, callback) {
extendBrowser(browser)
browser
.url('http://127.0.0.1:8080')
.waitForElementPresent('#app div', 1000)
injectScript('./test/resources/testWeb3.json', browser, function () {
callback()
})
}
function injectScript (file, browser, callback) {
init.readFile(file, function (error, result) {
if (!error) {
browser.execute(function (data) {
var vmdebugger = document.getElementById('app').vmdebugger
data = JSON.parse(data)
var uiTestweb3 = {}
uiTestweb3.eth = {}
uiTestweb3.debug = {}
uiTestweb3.eth.getCode = function (address, callback) {
if (callback) {
callback(null, data.testCodes[address])
} else {
return data.testCodes[address]
}
}
uiTestweb3.debug.traceTransaction = function (txHash, options, callback) {
callback(null, data.testTraces[txHash])
}
uiTestweb3.debug.storageAt = function (blockNumber, txIndex, address, callback) {
callback(null, {})
}
uiTestweb3.eth.getTransaction = function (txHash, callback) {
if (callback) {
callback(null, data.testTxs[txHash])
} else {
return data.testTxs[txHash]
}
}
uiTestweb3.eth.getTransactionFromBlock = function (blockNumber, txIndex, callback) {
if (callback) {
callback(null, data.testTxsByBlock[blockNumber + '-' + txIndex])
} else {
return data.testTxsByBlock[blockNumber + '-' + txIndex]
}
}
uiTestweb3.eth.getBlockNumber = function (callback) { callback(null, 'web3 modified for testing purposes :)') }
uiTestweb3.eth.providers = { 'HttpProvider': function (url) {} }
uiTestweb3.eth.setProvider = function (provider) {}
uiTestweb3.currentProvider = {host: 'web3 modified for testing purposes :)'}
vmdebugger.addProvider('TEST', uiTestweb3)
vmdebugger.switchProvider('TEST')
}, [result], function () {
.injectScript('test/resources/insertTestWeb3.js', function () {
// wait for the script to load test web3...
setTimeout(function () {
callback()
})
}
})
}, 5000)
})
}
function extendBrowser (browser) {
browser.assertCurrentSelectedItem = function (expected) {
browser.getValue('#asmitems', function (result) {
browser.expect.element('#asmitems option[value="' + result.value + '"]').text.to.equal(expected)
browser.execute(function (id) {
var node = document.querySelector('#asmcodes div div[selected="selected"] span')
return node.innerText
}, [''], function (returnValue) {
browser.assert.equal(returnValue.value, expected)
})
return browser
}
browser.retrieveInnerText = function (selector, callback) {
browser.execute(function (selector) {
var node = document.querySelector(selector)
return node ? node.innerText : ''
}, [selector], function (returnValue) {
callback(returnValue.value)
})
return browser
}
browser.assertSticker = function (vmtracestepinfo, stepinfo, addmemoryinfo, gasinfo, remaininggasinfo, loadedaddressinfo) {
browser.expect.element('#vmtracestepinfo').text.to.equal(vmtracestepinfo)
browser.expect.element('#stepinfo').text.to.equal(stepinfo)
browser.expect.element('#addmemoryinfo').text.to.equal(addmemoryinfo)
browser.expect.element('#gasinfo').text.to.equal(gasinfo)
browser.expect.element('#remaininggasinfo').text.to.equal(remaininggasinfo)
browser.expect.element('#loadedaddressinfo').text.to.equal(loadedaddressinfo)
browser.assertStepDetail = function (vmtracestepinfo, stepinfo, addmemoryinfo, gasinfo, remaininggasinfo, loadedaddressinfo) {
assertPanel('#stepdetail', browser, ['vmtracestep' + vmtracestepinfo, 'executionstep' + stepinfo, 'addmemory' + addmemoryinfo, 'gas' + gasinfo, 'remaininggas' + remaininggasinfo, 'loadedaddress' + loadedaddressinfo])
return browser
}
@ -177,29 +128,34 @@ browser.fireEvent = function (el, key, times, callback) {
}
function assertPanel (id, browser, value) {
browser.expect.element(id + ' #basicpanel').text.to.equal(value)
return browser
}
function assertPanelValue (id, browser, index, value) {
getInnerText(id + ' #basicpanel', browser, function (result) {
var values
if (result.value.indexOf('\r\n') !== -1) {
values = result.value.split('\r\n')
} else if (result.value.indexOf('\n') !== -1) {
values = result.value.split('\n')
} else if (result.value.indexOf('\r') !== -1) {
values = result.value.split('\r')
var selector = '.dropdownpanel div.dropdowncontent div'
browser.execute(function (id, selector) {
var el = document.getElementById(id.replace('#', '').replace('.', ''))
var node = el.querySelector(selector)
var ret = []
for (var k = 0; k < node.children.length; k++) {
if (node.children[k].innerText) {
ret.push(node.children[k].innerText)
}
}
browser.assert.equal(values[index], value)
return ret
}, [id, selector], function (returnValues) {
value.map(function (item, index) {
var testValue = returnValues.value[index].replace(/\r\n/g, '').replace(/\t/g, '').replace(/\s/g, '')
browser.assert.equal(testValue, value[index])
})
})
return browser
}
function getInnerText (id, browser, callback) {
browser.execute(function (data) {
return document.querySelector(data).innerText
}, [id], function (result) {
callback(result)
function assertPanelValue (id, browser, index, value) {
var selector = id + ' .dropdownpanel .dropdowncontent div'
browser.execute(function (id, index) {
var node = document.querySelector(id)
return node.children[index].innerText
}, [selector, index], function (returnValues) {
var testValue = returnValues.value.replace(/\r\n/g, '').replace(/\t/g, '').replace(/\s/g, '')
browser.assert.equal(testValue, value)
})
return browser
}

@ -5,7 +5,9 @@ var sauce = require('./sauce')
module.exports = {
beforeEach: function (browser, done) {
try {
init(browser, done)
init(browser, function () {
done()
})
} catch (e) {
var mes = 'error ' + e.message
console.log(mes)
@ -14,42 +16,42 @@ module.exports = {
},
'vmdebugger': function (browser) {
loadTrace(browser)
browser.click('#unload')
loadTraceNotFound(browser)
browser.click('#unload')
.click('#unload')
loadTrace(browser)
.click('#unload')
panels(browser)
browser.click('#unload')
.click('#unload')
slider(browser)
browser.click('#unload')
.click('#unload')
stepping(browser)
browser.click('#unload')
sticker(browser)
browser.end()
.click('#unload')
stepdetail(browser)
.end()
},
tearDown: sauce
}
function loadTrace (browser) {
function loadTraceNotFound (browser) {
browser
.clearValue('#txinput')
.setValue('#txinput', '0x20ef65b8b186ca942zcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.assert.containsText('#txhash', '<not found>')
.click('#txinfo .title')
.click('#txinfo .dropdownpanel .btn')
.expect.element('#txinfo .dropdownpanel .dropdownrawcontent').text.to.contain('<not found>')
return browser
}
function loadTraceNotFound (browser) {
function loadTrace (browser) {
browser
.clearValue('#txinput')
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.waitForElementVisible('#vmdebugger', 1000)
.expect.element('#txhash').text.to.equal('0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
browser.expect.element('#txfrom').text.to.equal('0x00101c5bfa3fc8bad02c9f5fd65b069306251915')
browser.expect.element('#txto').text.to.equal('0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
browser.expect.element('#txto').text.to.equal('0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.click('#txinfo .title')
.click('#txinfo .dropdownpanel .btn')
.expect.element('#txinfo .dropdownpanel .dropdownrawcontent').text.to.contain('0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
browser.click('#unload')
.waitForElementNotVisible('#vmdebugger', 1000)
return browser
@ -60,22 +62,21 @@ function panels (browser) {
.clearValue('#txinput')
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.waitForElementVisible('#vmdebugger', 1000)
.click('#nextcall')
.assertStack('0x\n0x60\n0x65\n0x38\n0x55\n0x60fe47b1')
.assertStorageChanges('0x00 0x38')
.assertCallData('0x60fe47b10000000000000000000000000000000000000000000000000000000000000038')
.assertCallStack('0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.assertStack(['0x', '0x60', '0x65', '0x38', '0x55', '0x60fe47b1'])
.assertStorageChanges(['0x000x38'])
.assertCallData(['0x60fe47b10000000000000000000000000000000000000000000000000000000000000038'])
.assertCallStack(['0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5'])
.assertStackValue(1, '0x60')
.assertMemoryValue(6, '0x60\t\t60606040526040516020806045833981\t????R??Q????E?9?')
.assertMemoryValue(7, '0x70\t\t01604052808051906020019091905050\t???R??Q???????PP')
.assertMemoryValue(8, '0x80\t\t5b806001016000600050819055505b50\t?????????P??UP?P')
.assertMemoryValue(6, '0x6060606040526040516020806045833981????R??Q????E?9?')
.assertMemoryValue(7, '0x7001604052808051906020019091905050???R??Q???????PP')
.assertMemoryValue(8, '0x805b806001016000600050819055505b50?????????P??UP?P')
.click('#intoforward') // CREATE
.assertStack('')
.assertStorageChanges('')
.assertMemory('')
.assertCallData('0x0000000000000000000000000000000000000000000000000000000000000000000000000000006060606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055')
.assertCallStack('0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5\n(Contract Creation - Step 63)')
.assertStack(['Empty'])
.assertStorageChanges(['Empty'])
.assertMemory(['Empty'])
.assertCallData(['0x0000000000000000000000000000000000000000000000000000000000000000000000000000006060606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055'])
.assertCallStack(['0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', '(ContractCreation-Step63)'])
return browser
}
@ -84,7 +85,6 @@ function slider (browser) {
.clearValue('#txinput')
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.waitForElementVisible('#vmdebugger', 1000)
.click('#intoforward')
.click('#intoforward')
.click('#intoforward')
@ -114,7 +114,6 @@ function stepping (browser) {
.clearValue('#txinput')
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.waitForElementVisible('#vmdebugger', 1000)
.click('#intoforward')
.click('#intoforward')
.assertCurrentSelectedItem('004 MSTORE')
@ -136,12 +135,11 @@ function stepping (browser) {
return browser
}
function sticker (browser) {
function stepdetail (browser) {
browser
.clearValue('#txinput')
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51')
.click('#load')
.waitForElementVisible('#vmdebugger', 1000)
.click('#intoforward')
.click('#intoforward')
.click('#intoforward')
@ -161,13 +159,13 @@ function sticker (browser) {
.end()
})
*/
.assertSticker('6', '6', '', '3', '84476', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.assertStepDetail('6', '6', '', '3', '84476', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.click('#nextcall')
.assertSticker('63', '63', '', '32000', '79283', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.assertStepDetail('63', '63', '', '32000', '79283', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.click('#intoforward')
.click('#overforward')
.assertSticker('108', '44', '', '0', '27145', '(Contract Creation - Step 63)')
.assertStepDetail('108', '44', '', '0', '27145', '(ContractCreation-Step63)')
.click('#intoforward')
.assertSticker('109', '64', '', '3', '25145', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
.assertStepDetail('109', '64', '', '3', '25145', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5')
return browser
}

@ -0,0 +1,77 @@
function loadJSON (url, callback) {
var xobj = new XMLHttpRequest()
xobj.overrideMimeType('application/json')
xobj.open('GET', url, true)
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == '200') {
callback(xobj.responseText)
}
}
xobj.send(null)
}
function loadTestWeb3 (data) {
var container = document.getElementById('app')
var vmdebugger = container.debugger
var uiTestweb3 = {}
uiTestweb3.eth = {}
uiTestweb3.debug = {}
uiTestweb3.eth.getCode = function (address, callback) {
if (callback) {
callback(null, data.testCodes[address])
} else {
return data.testCodes[address]
}
}
uiTestweb3.debug.traceTransaction = function (txHash, options, callback) {
callback(null, data.testTraces[txHash])
}
uiTestweb3.debug.storageAt = function (blockNumber, txIndex, address, callback) {
callback(null, {})
}
uiTestweb3.eth.getTransaction = function (txHash, callback) {
if (callback) {
callback(null, data.testTxs[txHash])
} else {
return data.testTxs[txHash]
}
}
uiTestweb3.eth.getTransactionFromBlock = function (blockNumber, txIndex, callback) {
if (callback) {
callback(null, data.testTxsByBlock[blockNumber + '-' + txIndex])
} else {
return data.testTxsByBlock[blockNumber + '-' + txIndex]
}
}
uiTestweb3.eth.getBlockNumber = function (callback) { callback(null, 'web3 modified for testing purposes :)') }
uiTestweb3.providers = { 'HttpProvider': function (url) {} }
uiTestweb3.setProvider = function (provider) {}
uiTestweb3.currentProvider = {host: 'web3 modified for testing purposes :)'}
vmdebugger.addProvider('TEST', uiTestweb3)
vmdebugger.switchProvider('TEST')
}
function waitForRemix (data) {
setTimeout(function () {
if (!document.getElementById('app').debugger) {
waitForRemix(data)
} else {
loadTestWeb3(data)
}
}, 500)
}
loadJSON('/test/resources/testWeb3.json', function (result) {
var data = JSON.parse(result)
waitForRemix(data)
})
Loading…
Cancel
Save