commit
f436b3289d
@ -1,73 +0,0 @@ |
|||||||
# `remix-debugger` |
|
||||||
|
|
||||||
The Remix Debugger is a webapp to debug the Ethereum VM and transactions. |
|
||||||
|
|
||||||
+ [Installation](#installation) |
|
||||||
+ [Development](#development) |
|
||||||
+ [First steps](#firststeps) |
|
||||||
+ [Tests](#tests) |
|
||||||
|
|
||||||
## Installation |
|
||||||
|
|
||||||
Make sure Node is [installed on your setup](https://docs.npmjs.com/getting-started/installing-node), and that a [local `geth`/`eth` node is running](../README.md#how-to-use). |
|
||||||
|
|
||||||
```bash |
|
||||||
git clone https://github.com/ethereum/remix |
|
||||||
cd remix/remix-debugger |
|
||||||
npm install |
|
||||||
``` |
|
||||||
|
|
||||||
This will build the debugger. Start it by opening `index.html` in your browser. |
|
||||||
|
|
||||||
## Development |
|
||||||
|
|
||||||
Run `npm run start_dev` to start a local webserver, accessible at `http://127.0.0.1:8080`. Your browser will reload when files are updated. |
|
||||||
|
|
||||||
## <a name="firststeps"></a>First steps |
|
||||||
|
|
||||||
Once Remix is connected to a node, you will be able to debug transactions. |
|
||||||
|
|
||||||
You can do that: |
|
||||||
- using a block number and a transaction index. |
|
||||||
- using a transaction hash. |
|
||||||
|
|
||||||
After loading the transaction succeeded, the hash, from and to field will show up. The VM trace is then loaded. |
|
||||||
|
|
||||||
The debugger itself contains several controls that allow stepping over the trace and seing the current state of a selected step: |
|
||||||
|
|
||||||
#### Slider and Stepping action |
|
||||||
|
|
||||||
The slider allows to move quickly from a state to another. |
|
||||||
|
|
||||||
Stepping actions are: |
|
||||||
- Step Into Back |
|
||||||
- Step Over Back |
|
||||||
- Step Over Forward |
|
||||||
- Step Into Forward |
|
||||||
- Jump Next Call: this will select the next state that refers to a context changes - CALL, CALLCODE, DELEGATECALL, CREATE. |
|
||||||
|
|
||||||
#### State Viewer |
|
||||||
|
|
||||||
The upper right panel contains basic informations about the current step: |
|
||||||
- VMTraceStep: the index in the trace of the current step. |
|
||||||
- Step |
|
||||||
- Add memory |
|
||||||
- Gas: gas used by this step |
|
||||||
- Remaining gas: gas left |
|
||||||
- Loaded address: the current code loaded, refers to the executing code. |
|
||||||
|
|
||||||
The other 6 panels describe the current selected state: |
|
||||||
- Instructions list: list of all the instruction that defines the current executing code. |
|
||||||
- Stack |
|
||||||
- Storage Changes |
|
||||||
- Memory |
|
||||||
- Call Data$ |
|
||||||
- Call Stack |
|
||||||
|
|
||||||
## Tests |
|
||||||
|
|
||||||
* To run unit tests, run `npm test`. |
|
||||||
|
|
||||||
* For local headless browser tests: |
|
||||||
* To install `selenium`: `npm run selenium-install` |
|
||||||
* Every time you want to run local browser tests, run: `npm run test-browser` |
|
@ -1,35 +0,0 @@ |
|||||||
#!/bin/bash |
|
||||||
|
|
||||||
set -e |
|
||||||
|
|
||||||
SHA=`git rev-parse --verify HEAD` |
|
||||||
|
|
||||||
git config user.name "Travis CI" |
|
||||||
git config user.email "builds@ethereum.org" |
|
||||||
git checkout --orphan gh-pages |
|
||||||
git rm --cached -r . |
|
||||||
echo "# Automatic build" > README.md |
|
||||||
echo "Built website from {$SHA}. See https://github.com/ethereum/remix/ for details." >> README.md |
|
||||||
# -f is needed because "build" is part of .gitignore |
|
||||||
|
|
||||||
# copying file to the root folder |
|
||||||
cp remix-debugger/index.html index.html |
|
||||||
mkdir build |
|
||||||
cp remix-debugger/build/app.js build/app.js |
|
||||||
mkdir assets |
|
||||||
cp -R remix-debugger/assets/. assets/ |
|
||||||
|
|
||||||
git add -f README.md index.html build/app.js assets |
|
||||||
git commit -m "Built website from {$SHA}." |
|
||||||
|
|
||||||
ENCRYPTION_LABEL=fade88419824 |
|
||||||
ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key" |
|
||||||
ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv" |
|
||||||
ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR} |
|
||||||
ENCRYPTED_IV=${!ENCRYPTED_IV_VAR} |
|
||||||
openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in ci/deploy_key.enc -out deploy_key -d |
|
||||||
chmod 600 deploy_key |
|
||||||
eval `ssh-agent -s` |
|
||||||
ssh-add deploy_key |
|
||||||
|
|
||||||
git push -f git@github.com:ethereum/remix.git gh-pages |
|
Binary file not shown.
@ -1,72 +0,0 @@ |
|||||||
const https = require('https') |
|
||||||
|
|
||||||
var userName = process.argv[2] |
|
||||||
var accessKey = process.argv[3] |
|
||||||
var tunnelName = process.argv[4] |
|
||||||
|
|
||||||
function removeTunnel () { |
|
||||||
const requestPath = `/rest/v1/${userName}/tunnels` |
|
||||||
console.log(requestPath) |
|
||||||
callSauce(requestPath, 'GET', function (error, result) { |
|
||||||
if (error) { |
|
||||||
console.log(error) |
|
||||||
} else { |
|
||||||
var data = JSON.parse(result) |
|
||||||
for (var k in data) { |
|
||||||
retrieveTunnel(data[k], function (error, result) { |
|
||||||
if (error) { |
|
||||||
console.log(error) |
|
||||||
} else if (result.identtifier === tunnelName) { |
|
||||||
deleteTunnel(result.id, function () { |
|
||||||
console.log('tunnel deleted ' + data[k] + ' ' + tunnelName) |
|
||||||
}) |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
function retrieveTunnel (tunnelid, callback) { |
|
||||||
const requestPath = `/rest/v1/${userName}/tunnels/${tunnelid}` |
|
||||||
callSauce(requestPath, 'GET', function (error, result) { |
|
||||||
if (error) { |
|
||||||
callback(error) |
|
||||||
} else { |
|
||||||
callback(null, {'identtifier': JSON.parse(result).tunnel_identifier, 'id': tunnelid}) |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
function deleteTunnel (tunnelid, callback) { |
|
||||||
const requestPath = `/rest/v1/${userName}/tunnels/${tunnelid}` |
|
||||||
callSauce(requestPath, 'DELETE', callback) |
|
||||||
} |
|
||||||
|
|
||||||
function callSauce (requestPath, type, callback) { |
|
||||||
function responseCallback (res) { |
|
||||||
res.setEncoding('utf8') |
|
||||||
console.log('Response: ', res.statusCode, JSON.stringify(res.headers)) |
|
||||||
res.on('data', function onData (chunk) { |
|
||||||
console.log('BODY: ' + chunk) |
|
||||||
callback(null, chunk) |
|
||||||
}) |
|
||||||
res.on('end', function onEnd () {}) |
|
||||||
} |
|
||||||
|
|
||||||
var req = https.request({ |
|
||||||
hostname: 'saucelabs.com', |
|
||||||
path: requestPath, |
|
||||||
method: type, |
|
||||||
auth: userName + ':' + accessKey |
|
||||||
}, responseCallback) |
|
||||||
|
|
||||||
req.on('error', function onError (e) { |
|
||||||
console.log('problem with request: ' + e.message) |
|
||||||
callback(e.message) |
|
||||||
}) |
|
||||||
req.write('') |
|
||||||
req.end() |
|
||||||
} |
|
||||||
|
|
||||||
removeTunnel() |
|
@ -1,43 +0,0 @@ |
|||||||
var which = require('which') |
|
||||||
|
|
||||||
var geth = null |
|
||||||
var eth = null |
|
||||||
|
|
||||||
try { |
|
||||||
geth = which.sync('geth') |
|
||||||
} catch (e) { |
|
||||||
} |
|
||||||
|
|
||||||
try { |
|
||||||
eth = which.sync('eth') |
|
||||||
} catch (e) { |
|
||||||
} |
|
||||||
if (process.argv.length > 2) { |
|
||||||
if (geth && process.argv[2] === 'geth') { |
|
||||||
runGeth() |
|
||||||
} else if (eth && process.argv[2] === 'eth') { |
|
||||||
runEth() |
|
||||||
} |
|
||||||
} else if (geth && eth) { |
|
||||||
console.log('both eth and geth has been found in your system') |
|
||||||
console.log('restart the command with the desired client:') |
|
||||||
console.log('npm run start_eth') |
|
||||||
console.log('or') |
|
||||||
console.log('npm run start_geth') |
|
||||||
} else if (geth) { |
|
||||||
runGeth() |
|
||||||
} else if (eth) { |
|
||||||
runEth() |
|
||||||
} else { |
|
||||||
console.log('neither eth or geth has been found in your system') |
|
||||||
} |
|
||||||
|
|
||||||
function runEth () { |
|
||||||
console.log('starting eth...') |
|
||||||
process.exit(20) |
|
||||||
} |
|
||||||
|
|
||||||
function runGeth () { |
|
||||||
console.log('starting geth...') |
|
||||||
process.exit(21) |
|
||||||
} |
|
@ -1,150 +0,0 @@ |
|||||||
{ |
|
||||||
"name": "remix-debugger", |
|
||||||
"version": "0.1.2", |
|
||||||
"description": "Ethereum IDE and tools for the web", |
|
||||||
"contributors": [ |
|
||||||
{ |
|
||||||
"name": "Yann Levreau", |
|
||||||
"email": "yann@ethdev.com" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "Liana Husikyan", |
|
||||||
"email": "liana@ethdev.com" |
|
||||||
} |
|
||||||
], |
|
||||||
"main": "./index.js", |
|
||||||
"devDependencies": { |
|
||||||
"babel-eslint": "^7.1.1", |
|
||||||
"babel-plugin-transform-object-assign": "^6.22.0", |
|
||||||
"babel-plugin-yo-yoify": "^0.3.3", |
|
||||||
"babel-polyfill": "^6.22.0", |
|
||||||
"babel-preset-env": "^1.6.1", |
|
||||||
"babel-preset-es2015": "^6.24.0", |
|
||||||
"babel-preset-stage-0": "^6.24.1", |
|
||||||
"babelify": "^7.3.0", |
|
||||||
"browserify": "^13.0.1", |
|
||||||
"browserify-livereload": "^1.0.10", |
|
||||||
"clipboard-copy": "^1.2.0", |
|
||||||
"csjs-inject": "^1.0.1", |
|
||||||
"ethereum-common": "0.0.18", |
|
||||||
"ethereumjs-block": "^1.2.2", |
|
||||||
"ethereumjs-tx": "^1.1.1", |
|
||||||
"ethereumjs-util": "^4.5.0", |
|
||||||
"ethereumjs-vm": "2.3.1", |
|
||||||
"fast-async": "^6.1.2", |
|
||||||
"http-server": "^0.9.0", |
|
||||||
"nightwatch": "^0.9.5", |
|
||||||
"notify-error": "^1.2.0", |
|
||||||
"npm-run-all": "^4.1.2", |
|
||||||
"onchange": "^3.3.0", |
|
||||||
"remix-core": "latest", |
|
||||||
"remix-lib": "latest", |
|
||||||
"remix-solidity": "latest", |
|
||||||
"selenium-standalone": "^6.0.1", |
|
||||||
"solc": "^0.4.13", |
|
||||||
"standard": "^7.0.1", |
|
||||||
"standard-reporter": "^1.0.5", |
|
||||||
"tape": "^4.6.0", |
|
||||||
"watchify": "^3.9.0", |
|
||||||
"web3": "^0.15.3", |
|
||||||
"yo-yo": "^1.2.1", |
|
||||||
"yo-yoify": "^3.1.0" |
|
||||||
}, |
|
||||||
"scripts": { |
|
||||||
"build": "mkdirp build; browserify index.js > build/app.js", |
|
||||||
"lint": "standard | notify-error", |
|
||||||
"nightwatch_local": "nightwatch --config nightwatch.js --env local", |
|
||||||
"nightwatch_remote_chrome": "nightwatch --config nightwatch.js --env chrome", |
|
||||||
"nightwatch_remote_firefox": "nightwatch --config nightwatch.js --env default", |
|
||||||
"nightwatch_remote_ie": "nightwatch --config nightwatch.js --env ie", |
|
||||||
"nightwatch_remote_parallel": "nightwatch --config nightwatch.js --env safari,chrome,default", |
|
||||||
"nightwatch_remote_safari": "nightwatch --config nightwatch.js --env safari", |
|
||||||
"onchange": "onchange build/app.js -- npm run lint", |
|
||||||
"selenium": "selenium-standalone start", |
|
||||||
"selenium-install": "selenium-standalone install", |
|
||||||
"serve": "http-server .", |
|
||||||
"start": "./runNode.sh", |
|
||||||
"start_dev": "npm-run-all -lpr serve watch onchange", |
|
||||||
"start_eth": "npm run warning_message; eth -j --rpccorsdomain '*'", |
|
||||||
"start_geth": "npm run warning_message; geth --rpc --rpcapi 'web3,eth,debug' --rpcport 8545 --rpccorsdomain '*'", |
|
||||||
"test": "standard && tape ./test/tests.js && ./ci/browser_tests.sh", |
|
||||||
"test-browser": "npm-run-all -lpr selenium serve waittest", |
|
||||||
"waittest": "sleep 5 && npm run nightwatch_local", |
|
||||||
"warning_message": "echo 'DO NOT DO THIS IF eth/geth STORES PRIVATE KEYS!! External system might be able to access your node through the RPC server.\n\n';", |
|
||||||
"watch": "mkdirp build; watchify index.js -p [ browserify-livereload --host 127.0.0.1 --port 1337 ] -dv -o build/app.js" |
|
||||||
}, |
|
||||||
"repository": { |
|
||||||
"type": "git", |
|
||||||
"url": "git+https://github.com/ethereum/remix.git" |
|
||||||
}, |
|
||||||
"author": "cpp-ethereum team", |
|
||||||
"license": "MIT", |
|
||||||
"bugs": { |
|
||||||
"url": "https://github.com/ethereum/remix/issues" |
|
||||||
}, |
|
||||||
"homepage": "https://github.com/ethereum/remix#readme", |
|
||||||
"standard": { |
|
||||||
"ignore": [ |
|
||||||
"node_modules/*", |
|
||||||
"build/*", |
|
||||||
"test/resources/*" |
|
||||||
] |
|
||||||
}, |
|
||||||
"babel": { |
|
||||||
"plugins": [ |
|
||||||
"transform-es2015-template-literals", |
|
||||||
"transform-es2015-literals", |
|
||||||
"transform-es2015-function-name", |
|
||||||
"transform-es2015-arrow-functions", |
|
||||||
"transform-es2015-block-scoped-functions", |
|
||||||
"transform-es2015-classes", |
|
||||||
"transform-es2015-object-super", |
|
||||||
"transform-es2015-shorthand-properties", |
|
||||||
"transform-es2015-duplicate-keys", |
|
||||||
"transform-es2015-computed-properties", |
|
||||||
"transform-es2015-for-of", |
|
||||||
"transform-es2015-sticky-regex", |
|
||||||
"transform-es2015-unicode-regex", |
|
||||||
"check-es2015-constants", |
|
||||||
"transform-es2015-spread", |
|
||||||
"transform-es2015-parameters", |
|
||||||
"transform-es2015-destructuring", |
|
||||||
"transform-es2015-block-scoping", |
|
||||||
"transform-object-assign" |
|
||||||
] |
|
||||||
}, |
|
||||||
"browserify": { |
|
||||||
"transform": [ |
|
||||||
[ |
|
||||||
"babelify", |
|
||||||
{ |
|
||||||
"sourceMapsAbsolute": false, |
|
||||||
"sourceMaps": true, |
|
||||||
"plugins": [ |
|
||||||
[ |
|
||||||
"fast-async", |
|
||||||
{ |
|
||||||
"runtimePattern": null, |
|
||||||
"compiler": { |
|
||||||
"es7": true, |
|
||||||
"noRuntime": true, |
|
||||||
"promises": true, |
|
||||||
"wrapAwait": true |
|
||||||
} |
|
||||||
} |
|
||||||
], |
|
||||||
[ |
|
||||||
"yo-yoify" |
|
||||||
], |
|
||||||
[ |
|
||||||
"transform-object-assign" |
|
||||||
] |
|
||||||
], |
|
||||||
"presets": [ |
|
||||||
"es2015" |
|
||||||
] |
|
||||||
} |
|
||||||
] |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
@ -1,14 +0,0 @@ |
|||||||
#!/usr/bin/env bash |
|
||||||
|
|
||||||
node findClient.js $1 |
|
||||||
RUNCLIENT=$? |
|
||||||
if [ $RUNCLIENT -eq '20' ] |
|
||||||
then |
|
||||||
npm run start_eth |
|
||||||
fi |
|
||||||
|
|
||||||
if [ $RUNCLIENT -eq '21' ] |
|
||||||
then |
|
||||||
echo $? |
|
||||||
npm run start_geth |
|
||||||
fi |
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,31 @@ |
|||||||
|
// var remixLib = require('remix-lib')
|
||||||
|
var styleGuideLight = require('./style-guide') |
||||||
|
var styleGuideDark = require('./styleGuideDark') |
||||||
|
var Storage = require('remix-lib').Storage |
||||||
|
module.exports = { |
||||||
|
|
||||||
|
chooser: function () { |
||||||
|
var themeStorage = new Storage('style:') |
||||||
|
if (themeStorage.exists('theme')) { |
||||||
|
if (themeStorage.get('theme') === 'dark') { |
||||||
|
return styleGuideDark() |
||||||
|
} else { |
||||||
|
return styleGuideLight() |
||||||
|
} |
||||||
|
} else { |
||||||
|
return styleGuideLight() |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
switchTheme: function (theme) { |
||||||
|
var themeStorage = new Storage('style:') |
||||||
|
themeStorage.set('theme', theme) |
||||||
|
if (theme === 'dark') { |
||||||
|
return styleGuideDark() |
||||||
|
} else if (theme === 'light') { |
||||||
|
return styleGuideLight() |
||||||
|
} else { |
||||||
|
return styleGuideLight() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,173 @@ |
|||||||
|
module.exports = function (browser, callback) { |
||||||
|
extendBrowser(browser) |
||||||
|
browser |
||||||
|
.url('http://127.0.0.1:8080') |
||||||
|
.injectScript('test-browser-debugger/resources/insertTestWeb3.js', function () { |
||||||
|
// wait for the script to load test web3...
|
||||||
|
console.log('waiting for script ..') |
||||||
|
setTimeout(function () { |
||||||
|
callback() |
||||||
|
}, 5000) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function extendBrowser (browser) { |
||||||
|
browser.multipleClick = function (id, time) { |
||||||
|
for (var k = 0; k < time; k++) { |
||||||
|
browser.click(id) |
||||||
|
} |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertCurrentSelectedItem = function (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.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 |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertStack = function (value) { |
||||||
|
return assertPanel('#stackpanel', browser, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertStorageChanges = function (value) { |
||||||
|
return assertPanel('#storagepanel', browser, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertMemory = function (value) { |
||||||
|
return assertPanel('#memorypanel', browser, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertCallData = function (value) { |
||||||
|
return assertPanel('#calldatapanel', browser, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertCallStack = function (value) { |
||||||
|
return assertPanel('#callstackpanel', browser, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertStackValue = function (index, value) { |
||||||
|
return assertPanelValue('#stackpanel', browser, index, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertStorageChangesValue = function (index, value) { |
||||||
|
return assertPanelValue('#storagepanel', browser, index, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertMemoryValue = function (index, value) { |
||||||
|
return assertPanelValue('#memorypanel', browser, index, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.assertCallStackValue = function (index, value) { |
||||||
|
return assertPanelValue('#callstackpanel', browser, index, value) |
||||||
|
} |
||||||
|
|
||||||
|
browser.debugerKeyCode = { |
||||||
|
'Enter': 13, |
||||||
|
'Up': 38, |
||||||
|
'Down': 40, |
||||||
|
'Right': '39', |
||||||
|
'Left': 37, |
||||||
|
'Esc': 27, |
||||||
|
'SpaceBar': 32, |
||||||
|
'Ctrl': 17, |
||||||
|
'Alt': 18, |
||||||
|
'Shift': 16 |
||||||
|
} |
||||||
|
|
||||||
|
/* browser.sendKeys is not working for safari */ |
||||||
|
/* still not working properly |
||||||
|
browser.fireEvent = function (el, key, times, callback) { |
||||||
|
var data = { |
||||||
|
'id': el.substring(1), |
||||||
|
'key': key, |
||||||
|
'times': times |
||||||
|
} |
||||||
|
browser.execute(function (data) { |
||||||
|
data = JSON.parse(data) |
||||||
|
var el = document.getElementById(data.id) |
||||||
|
var eventObj |
||||||
|
console.log(el) |
||||||
|
console.log(data) |
||||||
|
var k = 0 |
||||||
|
if (document.createEventObject) { |
||||||
|
eventObj = document.createEventObject() |
||||||
|
eventObj.keyCode = data.key |
||||||
|
while (k < data.times) { |
||||||
|
console.log('firing brfore createEventObject') |
||||||
|
el.fireEvent('onkeypress', eventObj) |
||||||
|
console.log('firing') |
||||||
|
k++ |
||||||
|
} |
||||||
|
} else if (typeof (KeyboardEvent) === 'function') { |
||||||
|
eventObj = new KeyboardEvent('keyup') |
||||||
|
eventObj.key = data.key |
||||||
|
eventObj.which = data.key |
||||||
|
while (k < data.times) { |
||||||
|
console.log('firing brfore createEvent') |
||||||
|
el.dispatchEvent(eventObj) |
||||||
|
console.log('firing') |
||||||
|
k++ |
||||||
|
} |
||||||
|
} |
||||||
|
}, [JSON.stringify(data)], function () { |
||||||
|
callback() |
||||||
|
}) |
||||||
|
} |
||||||
|
*/ |
||||||
|
} |
||||||
|
|
||||||
|
function assertPanel (id, browser, value) { |
||||||
|
var selector = '.dropdownpanel div.dropdowncontent ul' |
||||||
|
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) |
||||||
|
} |
||||||
|
} |
||||||
|
return ret |
||||||
|
}, [id, selector], function (returnValues) { |
||||||
|
value.map(function (item, index) { |
||||||
|
if (returnValues.value.length) { |
||||||
|
var testValue = returnValues.value[index].replace(/\r\n/g, '').replace(/\t/g, '').replace(/\s/g, '') |
||||||
|
browser.assert.equal(testValue, value[index]) |
||||||
|
} else { |
||||||
|
browser.assert.equal(item, '') |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
function assertPanelValue (id, browser, index, value) { |
||||||
|
var selector = id + ' .dropdownpanel .dropdowncontent ul' |
||||||
|
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 |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
const https = require('https') |
||||||
|
|
||||||
|
module.exports = function sauce (callback) { |
||||||
|
const currentTest = this.client.currentTest |
||||||
|
const username = this.client.options.username |
||||||
|
const sessionId = this.client.capabilities['webdriver.remote.sessionid'] |
||||||
|
const accessKey = this.client.options.accessKey |
||||||
|
|
||||||
|
if (!this.client.launch_url.match(/saucelabs/)) { |
||||||
|
console.log('Not saucelabs ...') |
||||||
|
return callback() |
||||||
|
} |
||||||
|
|
||||||
|
if (!username || !accessKey || !sessionId) { |
||||||
|
console.log(this.client) |
||||||
|
console.log('No username, accessKey or sessionId') |
||||||
|
return callback() |
||||||
|
} |
||||||
|
|
||||||
|
const passed = currentTest.results.passed === currentTest.results.tests |
||||||
|
|
||||||
|
const data = JSON.stringify({passed}) |
||||||
|
|
||||||
|
const requestPath = `/rest/v1/${username}/jobs/${sessionId}` |
||||||
|
|
||||||
|
function responseCallback (res) { |
||||||
|
res.setEncoding('utf8') |
||||||
|
console.log('Response: ', res.statusCode, JSON.stringify(res.headers)) |
||||||
|
res.on('data', function onData (chunk) { |
||||||
|
console.log('BODY: ' + chunk) |
||||||
|
}) |
||||||
|
res.on('end', function onEnd () { |
||||||
|
console.info('Finished updating saucelabs') |
||||||
|
callback() |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
console.log('Updating saucelabs', requestPath) |
||||||
|
|
||||||
|
const req = https.request({ |
||||||
|
hostname: 'saucelabs.com', |
||||||
|
path: requestPath, |
||||||
|
method: 'PUT', |
||||||
|
auth: `${username}:${accessKey}`, |
||||||
|
headers: { |
||||||
|
'Content-Type': 'application/json', |
||||||
|
'Content-Length': data.length |
||||||
|
} |
||||||
|
}, responseCallback) |
||||||
|
|
||||||
|
req.on('error', function onError (e) { |
||||||
|
console.log('problem with request: ' + e.message) |
||||||
|
}) |
||||||
|
req.write(data) |
||||||
|
req.end() |
||||||
|
} catch (error) { |
||||||
|
console.log('Error', error) |
||||||
|
callback() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,192 @@ |
|||||||
|
'use strict' |
||||||
|
var init = require('./init') |
||||||
|
var sauce = require('./sauce') |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
beforeEach: function (browser, done) { |
||||||
|
try { |
||||||
|
init(browser, function () { |
||||||
|
done() |
||||||
|
}) |
||||||
|
} catch (e) { |
||||||
|
var mes = 'error ' + e.message |
||||||
|
console.log(mes) |
||||||
|
done(mes) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
'vmdebugger': function (browser) { |
||||||
|
loadTraceNotFound(browser) |
||||||
|
.click('#unload') |
||||||
|
loadTrace(browser) |
||||||
|
.click('#unload') |
||||||
|
panels(browser) |
||||||
|
.click('#unload') |
||||||
|
slider(browser) |
||||||
|
.click('#unload') |
||||||
|
stepping(browser) |
||||||
|
.click('#unload') |
||||||
|
stepdetail(browser) |
||||||
|
.end() |
||||||
|
}, |
||||||
|
|
||||||
|
tearDown: sauce |
||||||
|
} |
||||||
|
|
||||||
|
function loadTraceNotFound (browser) { |
||||||
|
browser |
||||||
|
.clearValue('#txinput') |
||||||
|
.setValue('#txinput', '0x20ef65b8b186ca942zcccd634f37074dde49b541c27994fc7596740ef44cfd51') |
||||||
|
.click('#load') |
||||||
|
.click('#txinfo .title') |
||||||
|
.execute(function () { |
||||||
|
return document.querySelector('#txinfo .dropdownpanel .dropdownrawcontent').innerHTML |
||||||
|
}, [], function (result) { |
||||||
|
console.log(result.value) |
||||||
|
if (result.value.indexOf('not found') === -1) { |
||||||
|
browser.assert.fail(' txinput panel does not contain <not found> ', 'info about error', '') |
||||||
|
} |
||||||
|
}) |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
function loadTrace (browser) { |
||||||
|
browser |
||||||
|
.clearValue('#txinput') |
||||||
|
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51') |
||||||
|
.click('#load') |
||||||
|
.click('#txinfo .title') |
||||||
|
.execute(function () { |
||||||
|
return document.querySelector('#txinfo .dropdownpanel .dropdownrawcontent').innerHTML |
||||||
|
}, [], function (result) { |
||||||
|
if (result.value.indexOf('0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51') === -1) { |
||||||
|
browser.assert.fail(' txinput panel does not contain 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51 ', 'info about error', '') |
||||||
|
} |
||||||
|
}) |
||||||
|
.click('#unload') |
||||||
|
.waitForElementNotVisible('#vmdebugger', 1000) |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
function panels (browser) { |
||||||
|
browser |
||||||
|
.clearValue('#txinput') |
||||||
|
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51') |
||||||
|
.click('#load') |
||||||
|
.multipleClick('#intoforward', 63) |
||||||
|
.assertStack(['0:0x', '1:0x60', '2:0x65', '3:0x38', '4:0x55', '5:0x60fe47b1']) |
||||||
|
.assertStorageChanges(['0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563:Objectkey:0x00value:0x38']) |
||||||
|
.assertCallData(['0:0x60fe47b10000000000000000000000000000000000000000000000000000000000000038']) |
||||||
|
.assertCallStack(['0:0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5']) |
||||||
|
.assertStackValue(1, '1:0x60') |
||||||
|
.assertMemoryValue(6, '0x60:60606040526040516020806045833981????R??Q????E?9?') |
||||||
|
.assertMemoryValue(7, '0x70:01604052808051906020019091905050???R??Q???????PP') |
||||||
|
.assertMemoryValue(8, '0x80:5b806001016000600050819055505b50?????????P??UP?P') |
||||||
|
.click('#intoforward') // CREATE
|
||||||
|
.assertStack(['']) |
||||||
|
.assertStorageChanges([]) |
||||||
|
.assertMemory(['']) |
||||||
|
.assertCallData(['0:0x0000000000000000000000000000000000000000000000000000000000000000000000000000006060606040526040516020806045833981016040528080519060200190919050505b806001016000600050819055']) |
||||||
|
.assertCallStack(['0:0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5', '1:(ContractCreation-Step63)']) |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
function slider (browser) { |
||||||
|
browser |
||||||
|
.clearValue('#txinput') |
||||||
|
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51') |
||||||
|
.click('#load') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
/* |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.RIGHT_ARROW) |
||||||
|
.sendKeys('#slider', browser.Keys.LEFT_ARROW) |
||||||
|
*/ |
||||||
|
.assertCurrentSelectedItem('041 PUSH4 60fe47b1') |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
function stepping (browser) { |
||||||
|
browser |
||||||
|
.clearValue('#txinput') |
||||||
|
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51') |
||||||
|
.click('#load') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.assertCurrentSelectedItem('004 MSTORE') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoback') |
||||||
|
.click('#intoback') |
||||||
|
.assertCurrentSelectedItem('002 PUSH1 40') |
||||||
|
.multipleClick('#intoforward', 62) |
||||||
|
.assertCurrentSelectedItem('181 CREATE') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#overforward') |
||||||
|
.assertCurrentSelectedItem('007 MLOAD') |
||||||
|
.click('#intoback') |
||||||
|
.click('#intoback') |
||||||
|
.click('#intoback') |
||||||
|
.click('#intoback') |
||||||
|
.click('#intoback') |
||||||
|
.click('#overforward') |
||||||
|
.assertCurrentSelectedItem('182 PUSH1 01') |
||||||
|
.click('#overforward') |
||||||
|
.assertCurrentSelectedItem('184 PUSH1 00') |
||||||
|
.click('#intoback') |
||||||
|
.click('#intoback') |
||||||
|
.click('#overback') |
||||||
|
.assertCurrentSelectedItem('181 CREATE') |
||||||
|
return browser |
||||||
|
} |
||||||
|
|
||||||
|
function stepdetail (browser) { |
||||||
|
browser |
||||||
|
.clearValue('#txinput') |
||||||
|
.setValue('#txinput', '0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51') |
||||||
|
.click('#load') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#intoforward') |
||||||
|
/* |
||||||
|
.fireEvent('#slider', browser.debugerKeyCode.Right, 4, function () { |
||||||
|
browser.assertSticker('6', '6', '', '3', '84476', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') |
||||||
|
.click('#nextcall') |
||||||
|
.assertSticker('63', '63', '', '32000', '79283', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') |
||||||
|
.click('#intoforward') |
||||||
|
.click('#overforward') |
||||||
|
.assertSticker('108', '44', '', '0', '27145', '(Contract Creation - Step 63)') |
||||||
|
.click('#intoforward') |
||||||
|
.assertSticker('109', '64', '', '3', '25145', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') |
||||||
|
.end() |
||||||
|
}) |
||||||
|
*/ |
||||||
|
.assertStepDetail('6', '6', '', '3', '84476', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') |
||||||
|
.multipleClick('#intoforward', 57) |
||||||
|
.assertStepDetail('63', '63', '', '32000', '79283', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') |
||||||
|
.click('#overforward') |
||||||
|
.click('#intoback') |
||||||
|
.assertStepDetail('108', '44', '', '0', '27145', '(ContractCreation-Step63)') |
||||||
|
.click('#intoforward') |
||||||
|
.assertStepDetail('109', '64', '', '3', '25145', '0x0d3a18d64dfe4f927832ab58d6451cecc4e517c5') |
||||||
|
return browser |
||||||
|
} |
Loading…
Reference in new issue