diff --git a/.circleci/config.yml b/.circleci/config.yml
index 17d63cc969..2f87db9f05 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -46,13 +46,14 @@ jobs:
- checkout
- restore_cache:
keys:
- - dep-bundle-3-{{ checksum "package.json" }}
+ - dep-bundle-4-{{ checksum "package.json" }}
- run: npm install
- save_cache:
- key: dep-bundle-3-{{ checksum "package.json" }}
+ key: dep-bundle-4-{{ checksum "package.json" }}
paths:
- ~/repo/node_modules
- - run: cd src/app/debugger/remix-debugger && ./ci/browser_tests.sh
+ - run: npm run build_debugger
+ - run: ./ci/browser_tests_debugger.sh
workflows:
version: 2
diff --git a/src/app/debugger/remix-debugger/ci/browser_tests.sh b/ci/browser_tests_debugger.sh
similarity index 92%
rename from src/app/debugger/remix-debugger/ci/browser_tests.sh
rename to ci/browser_tests_debugger.sh
index fb1fa5a9bd..5d80223ca2 100755
--- a/src/app/debugger/remix-debugger/ci/browser_tests.sh
+++ b/ci/browser_tests_debugger.sh
@@ -19,7 +19,6 @@ SAUCECONNECT_JOBIDENTIFIER="remix_tests_${BUILD_ID}"
SAUCECONNECT_READYFILE="sc.ready"
TEST_EXITCODE=0
-npm install && npm run build
npm run serve &
wget $SAUCECONNECT_URL
@@ -29,7 +28,7 @@ while [ ! -f $SAUCECONNECT_READYFILE ]; do
sleep .5
done
-npm run nightwatch_remote_parallel || TEST_EXITCODE=1
+npm run nightwatch_remote_debugger_parallel || TEST_EXITCODE=1
node ci/sauceDisconnect.js $SAUCECONNECT_USERNAME $SAUCECONNECT_ACCESSKEY $SAUCECONNECT_JOBIDENTIFIER
diff --git a/src/app/debugger/remix-debugger/nightwatch.js b/nightwatch_debugger.js
similarity index 95%
rename from src/app/debugger/remix-debugger/nightwatch.js
rename to nightwatch_debugger.js
index b81c8176b5..ad88f23acb 100644
--- a/src/app/debugger/remix-debugger/nightwatch.js
+++ b/nightwatch_debugger.js
@@ -2,8 +2,8 @@
var buildId = process.env.CIRCLE_BUILD_NUM || process.env.TRAVIS_JOB_NUMBER
module.exports = {
- 'src_folders': ['./test-browser/test'],
- 'output_folder': './test-browser/test/reports',
+ 'src_folders': ['./test-browser-debugger/test'],
+ 'output_folder': './test-browser-debugger/test/reports',
'custom_commands_path': '',
'custom_assertions_path': '',
'globals_path': '',
diff --git a/package.json b/package.json
index d201648fcf..12a7fc62ce 100644
--- a/package.json
+++ b/package.json
@@ -142,6 +142,7 @@
"linkremixsolidity": "cd node_modules && rm -rf remix-solidity && ln -s ../remix/remix-solidity remix-solidity && cd ..",
"linkremixdebugger": "cd node_modules && rm -rf remix-debugger && ln -s ../remix/remix-debugger remix-debugger && cd ..",
"build": "browserify src/index.js -o build/app.js",
+ "build_debugger": "browserify src/app/debugger/remix-debugger/index.js -o src/app/debugger/remix-debugger/build/app.js",
"browsertest": "sleep 5 && npm run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='assets/css/font-awesome.min.css' assets/css/",
"downloadsolc": "rimraf soljson.js && cd node_modules/solc && wget --no-check-certificate https://solc-bin.ethereum.org/soljson.js && cd ../../",
@@ -154,13 +155,15 @@
"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",
+ "nightwatch_remote_safari": "nightwatch --config nightwatch.js --env safari",
+ "nightwatch_remote_debugger_parallel": "nightwatch --config nightwatch_debugger.js --env local",
"onchange": "onchange build/app.js -- npm-run-all lint",
"prepublish": "mkdirp build; npm-run-all -ls downloadsolc_root build",
"remixd": "node ./node_modules/remixd/src/main.js -s ./contracts",
"selenium": "execr --silent selenium-standalone start",
"selenium-install": "selenium-standalone install",
"serve": "execr --silent http-server .",
+ "serve_debugger": "execr --silent http-server src/app/debugger/remix-debugger",
"sourcemap": "exorcist --root ../ build/app.js.map > build/app.js",
"start": "npm-run-all -lpr serve watch onchange remixd",
"test": "npm run csslint; standard && node test/index.js",
diff --git a/src/app/debugger/remix-debugger/README.md b/src/app/debugger/remix-debugger/README.md
deleted file mode 100644
index 99745fc323..0000000000
--- a/src/app/debugger/remix-debugger/README.md
+++ /dev/null
@@ -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.
-
-## 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`
diff --git a/src/app/debugger/remix-debugger/ci/deploy_from_travis.sh b/src/app/debugger/remix-debugger/ci/deploy_from_travis.sh
deleted file mode 100755
index e80aba8e47..0000000000
--- a/src/app/debugger/remix-debugger/ci/deploy_from_travis.sh
+++ /dev/null
@@ -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
diff --git a/src/app/debugger/remix-debugger/ci/deploy_key.enc b/src/app/debugger/remix-debugger/ci/deploy_key.enc
deleted file mode 100644
index 99ddf96eee..0000000000
Binary files a/src/app/debugger/remix-debugger/ci/deploy_key.enc and /dev/null differ
diff --git a/src/app/debugger/remix-debugger/ci/sauceDisconnect.js b/src/app/debugger/remix-debugger/ci/sauceDisconnect.js
deleted file mode 100644
index b29328db5c..0000000000
--- a/src/app/debugger/remix-debugger/ci/sauceDisconnect.js
+++ /dev/null
@@ -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()
diff --git a/src/app/debugger/remix-debugger/findClient.js b/src/app/debugger/remix-debugger/findClient.js
deleted file mode 100644
index 8ceb9bce00..0000000000
--- a/src/app/debugger/remix-debugger/findClient.js
+++ /dev/null
@@ -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)
-}
diff --git a/src/app/debugger/remix-debugger/package.json b/src/app/debugger/remix-debugger/package.json
deleted file mode 100644
index 00fbfc8bcb..0000000000
--- a/src/app/debugger/remix-debugger/package.json
+++ /dev/null
@@ -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"
- ]
- }
- ]
- ]
- }
-}
diff --git a/src/app/debugger/remix-debugger/runNode.sh b/src/app/debugger/remix-debugger/runNode.sh
deleted file mode 100755
index 79575a46f2..0000000000
--- a/src/app/debugger/remix-debugger/runNode.sh
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/src/app/debugger/remix-debugger/test-browser/resources/insertTestWeb3.js b/src/app/debugger/remix-debugger/test-browser-debugger/resources/insertTestWeb3.js
similarity index 94%
rename from src/app/debugger/remix-debugger/test-browser/resources/insertTestWeb3.js
rename to src/app/debugger/remix-debugger/test-browser-debugger/resources/insertTestWeb3.js
index 833c7198e1..0d0b2614b7 100644
--- a/src/app/debugger/remix-debugger/test-browser/resources/insertTestWeb3.js
+++ b/src/app/debugger/remix-debugger/test-browser-debugger/resources/insertTestWeb3.js
@@ -70,7 +70,8 @@ function waitForRemix (data) {
}, 500)
}
-loadJSON('/test-browser/resources/testWeb3.json', function (result) {
+console.log('injecting test web3...')
+loadJSON('/test-browser-debugger/resources/testWeb3.json', function (result) {
var data = JSON.parse(result)
waitForRemix(data)
})
diff --git a/src/app/debugger/remix-debugger/test-browser/resources/testWeb3.json b/src/app/debugger/remix-debugger/test-browser-debugger/resources/testWeb3.json
similarity index 100%
rename from src/app/debugger/remix-debugger/test-browser/resources/testWeb3.json
rename to src/app/debugger/remix-debugger/test-browser-debugger/resources/testWeb3.json
diff --git a/src/app/debugger/remix-debugger/test-browser/test/init.js b/src/app/debugger/remix-debugger/test-browser-debugger/test/init.js
similarity index 100%
rename from src/app/debugger/remix-debugger/test-browser/test/init.js
rename to src/app/debugger/remix-debugger/test-browser-debugger/test/init.js
diff --git a/src/app/debugger/remix-debugger/test-browser/test/sauce.js b/src/app/debugger/remix-debugger/test-browser-debugger/test/sauce.js
similarity index 100%
rename from src/app/debugger/remix-debugger/test-browser/test/sauce.js
rename to src/app/debugger/remix-debugger/test-browser-debugger/test/sauce.js
diff --git a/src/app/debugger/remix-debugger/test-browser/test/vmdebugger.js b/src/app/debugger/remix-debugger/test-browser-debugger/test/vmdebugger.js
similarity index 100%
rename from src/app/debugger/remix-debugger/test-browser/test/vmdebugger.js
rename to src/app/debugger/remix-debugger/test-browser-debugger/test/vmdebugger.js
diff --git a/test-browser-debugger/test/init.js b/test-browser-debugger/test/init.js
new file mode 100644
index 0000000000..9d54e25785
--- /dev/null
+++ b/test-browser-debugger/test/init.js
@@ -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
+}
diff --git a/test-browser-debugger/test/sauce.js b/test-browser-debugger/test/sauce.js
new file mode 100644
index 0000000000..4a41fe5930
--- /dev/null
+++ b/test-browser-debugger/test/sauce.js
@@ -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()
+ }
+}
diff --git a/test-browser-debugger/test/vmdebugger.js b/test-browser-debugger/test/vmdebugger.js
new file mode 100644
index 0000000000..f84555a0f3
--- /dev/null
+++ b/test-browser-debugger/test/vmdebugger.js
@@ -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 ', '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
+}