From cf28daf6305fed7b977ac1f4f5be354d460d29ee Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 13 Feb 2018 13:09:53 +0100 Subject: [PATCH 01/16] make exists async --- src/app/files/basicReadOnlyExplorer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/files/basicReadOnlyExplorer.js b/src/app/files/basicReadOnlyExplorer.js index de0f62a041..f5d3ab41dd 100644 --- a/src/app/files/basicReadOnlyExplorer.js +++ b/src/app/files/basicReadOnlyExplorer.js @@ -21,10 +21,10 @@ class BasicReadOnlyExplorer { this.files = {} } - exists (path) { - if (!this.files) return false + exists (path, cb) { + if (!this.files) return cb(null, false) var unprefixedPath = this.removePrefix(path) - return this.files[unprefixedPath] !== undefined + cb(null, this.files[unprefixedPath] !== undefined) } get (path, cb) { From 269e087b6402e4eedb717a5ff606e43b23f40746 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 13 Feb 2018 13:10:24 +0100 Subject: [PATCH 02/16] make browserfiles. exists async --- src/app/files/browser-files.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/files/browser-files.js b/src/app/files/browser-files.js index ce645a083c..3117ff898c 100644 --- a/src/app/files/browser-files.js +++ b/src/app/files/browser-files.js @@ -8,12 +8,12 @@ function Files (storage) { var readonly = {} this.type = 'browser' - this.exists = function (path) { + this.exists = function (path, cb) { var unprefixedpath = this.removePrefix(path) // NOTE: ignore the config file - if (path === '.remix.config') return false + if (path === '.remix.config') return cb(null, false) - return this.isReadOnly(unprefixedpath) || storage.exists(unprefixedpath) + return cb(null, this.isReadOnly(unprefixedpath) || storage.exists(unprefixedpath)) } this.init = function (cb) { From eba52103303f94df545e5eb5e02ca44c5075c954 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 13 Feb 2018 13:12:30 +0100 Subject: [PATCH 03/16] make sharedfolder.exists async --- src/app/files/shared-folder.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/app/files/shared-folder.js b/src/app/files/shared-folder.js index 00e87011f8..f57752952d 100644 --- a/src/app/files/shared-folder.js +++ b/src/app/files/shared-folder.js @@ -65,13 +65,11 @@ module.exports = class SharedFolder { // // this.remixd.exists(path, (error, isValid) => {}) - exists (path) { - // @TODO: add new remixd.exists() method - // we remove the this.files = null at the beggining - // modify the exists() (cause it is using the this.files) to use remixd - // yes for the exists I think you might need another remixd function - if (!this.files) return false - return this.files[path] !== undefined + exists (path, cb) { + var unprefixedpath = this.removePrefix(path) + this._remixd.call('sharedfolder', 'exists', {path: unprefixedpath}, (error, result) => { + cb(error, result) + }) } get (path, cb) { From 351aafad96fa7544311219b41cc7a1db21611cb1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 13 Feb 2018 14:02:39 +0100 Subject: [PATCH 04/16] add private _exist function to browser-files.js --- src/app/files/browser-files.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/app/files/browser-files.js b/src/app/files/browser-files.js index 3117ff898c..e0a25e6db8 100644 --- a/src/app/files/browser-files.js +++ b/src/app/files/browser-files.js @@ -9,11 +9,15 @@ function Files (storage) { this.type = 'browser' this.exists = function (path, cb) { + cb(null, this._exists(path)) + } + + this._exists = function (path) { var unprefixedpath = this.removePrefix(path) // NOTE: ignore the config file - if (path === '.remix.config') return cb(null, false) + if (path === '.remix.config') return false - return cb(null, this.isReadOnly(unprefixedpath) || storage.exists(unprefixedpath)) + return this.isReadOnly(unprefixedpath) || storage.exists(unprefixedpath) } this.init = function (cb) { @@ -75,7 +79,7 @@ function Files (storage) { this.remove = function (path) { var unprefixedpath = this.removePrefix(path) - if (!this.exists(unprefixedpath)) { + if (!this._exists(unprefixedpath)) { return false } @@ -133,7 +137,7 @@ function Files (storage) { } // rename .browser-solidity.json to .remix.config - if (this.exists('.browser-solidity.json')) { + if (this._exists('.browser-solidity.json')) { this.rename('.browser-solidity.json', '.remix.config') } } From 061410e4eb0aa2fd3ab8b6ca087c9dc092080e71 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 13 Feb 2018 14:03:23 +0100 Subject: [PATCH 05/16] change exists call async --- src/app.js | 53 ++++++++++++++++++++++++++-------- src/app/files/file-explorer.js | 13 ++++++--- src/app/panels/file-panel.js | 13 +++++---- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/app.js b/src/app.js index 568c189c4c..a60caab3b1 100644 --- a/src/app.js +++ b/src/app.js @@ -214,10 +214,17 @@ Please make a backup of your contracts and start using http://remix.ethereum.org // ----------------- Compiler ----------------- var compiler = new Compiler((url, cb) => { var provider = fileManager.fileProviderOf(url) - if (provider && provider.exists(url)) { - return provider.get(url, cb) - } - handleImports.import(url, + if (provider) { + provider.exists(url, (error, exist) => { + if (error) return cb(error) + if (exist) { + return provider.get(url, cb) + } else { + return cb('file not found') + } + }) + } else { + handleImports.import(url, (loadingMsg) => { $('#output').append($('
').append($('
').text(loadingMsg)))
       },
@@ -229,6 +236,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
           cb(error)
         }
       })
+    }
   })
   var offsetToLineColumnConverter = new OffsetToLineColumnConverter(compiler.event)
 
@@ -386,14 +394,26 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
   this._components.contextView = new ContextView({
     contextualListener: this._components.contextualListener,
     jumpTo: (position) => {
+      function jumpToLine (lineColumn) {
+        if (lineColumn.start && lineColumn.start.line && lineColumn.start.column) {
+          editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1)
+        }
+      }
       if (compiler.lastCompilationResult && compiler.lastCompilationResult.data) {
         var lineColumn = offsetToLineColumnConverter.offsetToLineColumn(position, position.file, compiler.lastCompilationResult)
         var filename = compiler.getSourceName(position.file)
-        if (filename !== config.get('currentFile') && (filesProviders['browser'].exists(filename) || filesProviders['localhost'].exists(filename))) {
-          fileManager.switchFile(filename)
-        }
-        if (lineColumn.start && lineColumn.start.line && lineColumn.start.column) {
-          editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1)
+        // TODO: refactor with rendererAPI.errorClick
+        if (filename !== config.get('currentFile')) {
+          var provider = fileManager.fileProviderOf(filename)
+          if (provider) {
+            provider.exists(filename, (error, exist) => {
+              if (error) return console.log(error)
+              fileManager.switchFile(filename)
+              jumpToLine(lineColumn)
+            })
+          }
+        } else {
+          jumpToLine(lineColumn)
         }
       }
     }
@@ -541,10 +561,19 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
       }
     },
     errorClick: (errFile, errLine, errCol) => {
-      if (errFile !== config.get('currentFile') && (filesProviders['browser'].exists(errFile) || filesProviders['localhost'].exists(errFile))) {
-        fileManager.switchFile(errFile)
+      if (errFile !== config.get('currentFile')) {
+        // TODO: refactor with this._components.contextView.jumpTo
+        var provider = fileManager.fileProviderOf(errFile)
+        if (provider) {
+          provider.exists(errFile, (error, exist) => {
+            if (error) return console.log(error)
+            fileManager.switchFile(errFile)
+            editor.gotoLine(errLine, errCol)
+          })
+        }
+      } else {
+        editor.gotoLine(errLine, errCol)
       }
-      editor.gotoLine(errLine, errCol)
     }
   }
   var renderer = new Renderer(rendererAPI)
diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js
index 6613ab420b..b466926891 100644
--- a/src/app/files/file-explorer.js
+++ b/src/app/files/file-explorer.js
@@ -221,11 +221,16 @@ function fileExplorer (appAPI, files) {
       } else if (helper.checkSpecialChars(label.innerText)) {
         modalDialogCustom.alert('Special characters are not allowed')
         label.innerText = textUnderEdit
-      } else if (!files.exists(newPath)) {
-        files.rename(label.dataset.path, newPath, isFolder)
       } else {
-        modalDialogCustom.alert('File already exists.')
-        label.innerText = textUnderEdit
+        files.exists(newPath, (error, exist) => {
+          if (error) return modalDialogCustom.alert('Unexpected error while renaming: ' + error)
+          if (!exist) {
+            files.rename(label.dataset.path, newPath, isFolder)
+          } else {
+            modalDialogCustom.alert('File already exists.')
+            label.innerText = textUnderEdit
+          }
+        })
       }
     }
 
diff --git a/src/app/panels/file-panel.js b/src/app/panels/file-panel.js
index 51803bf3bf..89fbcb075f 100644
--- a/src/app/panels/file-panel.js
+++ b/src/app/panels/file-panel.js
@@ -175,11 +175,14 @@ function filepanel (appAPI, filesProvider) {
       }
 
       var name = files.type + '/' + file.name
-      if (!files.exists(name)) {
-        loadFile()
-      } else {
-        modalDialogCustom.confirm(null, `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() })
-      }
+      files.exists(name, (error, exist) => {
+        if (error) console.log(error)
+        if (!exist) {
+          loadFile()
+        } else {
+          modalDialogCustom.confirm(null, `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() })
+        }
+      })
     })
   }
 

From eb48b9204d62192ef7ee66824c0dcb64b94d07db Mon Sep 17 00:00:00 2001
From: yann300 
Date: Tue, 13 Feb 2018 15:04:54 +0100
Subject: [PATCH 06/16] typo

---
 src/app.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app.js b/src/app.js
index a60caab3b1..5e1cc75836 100644
--- a/src/app.js
+++ b/src/app.js
@@ -197,7 +197,7 @@ function run () {
   var self = this
 
   if (window.location.hostname === 'yann300.github.io') {
-    modalDialogCustom.alert(`This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-ide-alpha.`)
+    modalDialogCustom.alert('This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-ide-alpha.')
   } else if (window.location.hostname === 'ethereum.github.io' &&
   window.location.pathname.indexOf('remix-ide-alpha') === 0) {
     modalDialogCustom.alert(`This instance of the Remix IDE is an UNSTABLE ALPHA branch.\n

From 130b7d3da224608857dbd1cccceb10d2411ff5f6 Mon Sep 17 00:00:00 2001
From: yann300 
Date: Tue, 13 Feb 2018 15:06:20 +0100
Subject: [PATCH 07/16] update createNonClashingName and caller

---
 src/app.js                   | 25 ++++++++++++++++---------
 src/app/panels/file-panel.js | 14 ++++++++------
 src/app/tabs/run-tab.js      | 14 ++++++++------
 src/lib/helper.js            | 24 +++++++++++++++++++-----
 4 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/src/app.js b/src/app.js
index 5e1cc75836..bde7f76d58 100644
--- a/src/app.js
+++ b/src/app.js
@@ -3,6 +3,7 @@
 var $ = require('jquery')
 var csjs = require('csjs-inject')
 var yo = require('yo-yo')
+var async = require('async')
 var remixLib = require('remix-lib')
 var EventManager = remixLib.EventManager
 
@@ -463,15 +464,21 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
   function loadFiles (filesSet, fileProvider) {
     if (!fileProvider) fileProvider = 'browser'
 
-    for (var f in filesSet) {
-      var name = helper.createNonClashingName(f, filesProviders[fileProvider])
-      if (helper.checkSpecialChars(name)) {
-        modalDialogCustom.alert('Special characters are not allowed')
-        return
-      }
-      filesProviders[fileProvider].set(name, filesSet[f].content)
-    }
-    fileManager.switchFile()
+    async.each(Object.keys(filesSet), (file, callback) => {
+      helper.createNonClashingName(file, filesProviders[fileProvider],
+      (error, name) => {
+        if (error) {
+          modalDialogCustom.alert('Unexpected error loading the file ' + error)
+        } else if (helper.checkSpecialChars(name)) {
+          modalDialogCustom.alert('Special characters are not allowed')
+        } else {
+          filesProviders[fileProvider].set(name, filesSet[file].content)
+        }
+        callback()
+      })
+    }, (error) => {
+      if (!error) fileManager.switchFile()
+    })
   }
 
   // Replace early callback with instant response
diff --git a/src/app/panels/file-panel.js b/src/app/panels/file-panel.js
index 89fbcb075f..27d39f8724 100644
--- a/src/app/panels/file-panel.js
+++ b/src/app/panels/file-panel.js
@@ -224,12 +224,14 @@ function filepanel (appAPI, filesProvider) {
 
   function createNewFile () {
     modalDialogCustom.prompt(null, 'File Name', 'Untitled.sol', (input) => {
-      var newName = filesProvider['browser'].type + '/' + helper.createNonClashingName(input, filesProvider['browser'])
-      if (!filesProvider['browser'].set(newName, '')) {
-        modalDialogCustom.alert('Failed to create file ' + newName)
-      } else {
-        appAPI.switchFile(newName)
-      }
+      filesProvider['browser'].type + '/' + helper.createNonClashingName(input, filesProvider['browser'], (error, newName) => {
+        if (error) return modalDialogCustom.alert('Failed to create file ' + newName + ' ' + error)
+        if (!filesProvider['browser'].set(newName, '')) {
+          modalDialogCustom.alert('Failed to create file ' + newName)
+        } else {
+          appAPI.switchFile(newName)
+        }
+      })
     })
   }
 
diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js
index 96147bdacc..5b0cef0291 100644
--- a/src/app/tabs/run-tab.js
+++ b/src/app/tabs/run-tab.js
@@ -161,12 +161,14 @@ function makeRecorder (events, appAPI, appEvents) {
       var fileProvider = appAPI.fileProviderOf(path)
       if (fileProvider) {
         var newFile = path + input
-        newFile = helper.createNonClashingName(newFile, fileProvider, '.json')
-        if (!fileProvider.set(newFile, txJSON)) {
-          modalDialogCustom.alert('Failed to create file ' + newFile)
-        } else {
-          appAPI.switchFile(newFile)
-        }
+        helper.createNonClashingName(newFile, fileProvider, (error, newFile) => {
+          if (error) return modalDialogCustom.alert('Failed to create file. ' + newFile + ' ' + error)
+          if (!fileProvider.set(newFile, txJSON)) {
+            modalDialogCustom.alert('Failed to create file ' + newFile)
+          } else {
+            appAPI.switchFile(newFile)
+          }
+        })
       }
     })
   }
diff --git a/src/lib/helper.js b/src/lib/helper.js
index d577643f4a..b186dc4ffb 100644
--- a/src/lib/helper.js
+++ b/src/lib/helper.js
@@ -1,3 +1,5 @@
+var async = require('async')
+
 module.exports = {
   shortenAddress: function (address, etherBalance) {
     var len = address.length
@@ -9,7 +11,7 @@ module.exports = {
     var len = data.length
     return data.slice(0, 5) + '...' + data.slice(len - 5, len)
   },
-  createNonClashingName (name, fileProvider) {
+  createNonClashingName (name, fileProvider, cb) {
     var counter = ''
     var ext = 'sol'
     var reg = /(.*)\.([^.]+)/g
@@ -18,10 +20,22 @@ module.exports = {
       name = split[1]
       ext = split[2]
     }
-    while (fileProvider.exists(name + counter + '.' + ext)) {
-      counter = (counter | 0) + 1
-    }
-    return name + counter + '.' + ext
+    var exist = true
+    async.whilst(
+      () => { return exist },
+      (callback) => {
+        fileProvider.exists(name + counter + '.' + ext, (error, currentExist) => {
+          if (error) {
+            callback(error)
+          } else {
+            exist = currentExist
+            if (exist) counter = (counter | 0) + 1
+            callback()
+          }
+        })
+      },
+      (error) => { cb(error, name + counter + '.' + ext) }
+    )
   },
   checkSpecialChars (name) {
     return name.match(/[/:*?"<>\\'|]/) != null

From 2fd58979ba80e29ea004669b859c4921b8c97c0d Mon Sep 17 00:00:00 2001
From: yann300 
Date: Tue, 13 Feb 2018 16:00:44 +0100
Subject: [PATCH 08/16] fix renaming file

---
 src/app/files/file-explorer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js
index b466926891..82ec08c670 100644
--- a/src/app/files/file-explorer.js
+++ b/src/app/files/file-explorer.js
@@ -235,7 +235,7 @@ function fileExplorer (appAPI, files) {
     }
 
     if (event.which === 13) event.preventDefault()
-    if (event.type === 'blur' || event.which === 13 && label.getAttribute('contenteditable')) {
+    if ((event.type === 'blur' || event.which === 13) && label.getAttribute('contenteditable')) {
       var isFolder = label.className.indexOf('folder') !== -1
       var save = textUnderEdit !== label.innerText
       if (save) {

From 015fdb3a3b2d951fe75c7b4a533a36fc13f61a75 Mon Sep 17 00:00:00 2001
From: yann300 
Date: Tue, 13 Feb 2018 16:01:23 +0100
Subject: [PATCH 09/16] fix contextMenu (renaming)

---
 src/app/ui/contextMenu.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/ui/contextMenu.js b/src/app/ui/contextMenu.js
index 6491725446..15ede4ce2d 100644
--- a/src/app/ui/contextMenu.js
+++ b/src/app/ui/contextMenu.js
@@ -45,7 +45,7 @@ module.exports = (event, items) => {
   event.preventDefault()
 
   function hide (event, force) {
-    if (force || (event.target !== container)) {
+    if (container && container.parentElement && (force || (event.target !== container))) {
       container.parentElement.removeChild(container)
     }
     window.removeEventListener('click', hide)

From 842f7f2d2fc7b9c5e8bcc36e4fcf315fdb6e8106 Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 11:44:47 +0100
Subject: [PATCH 10/16] fix createNewFile

---
 src/app/panels/file-panel.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/app/panels/file-panel.js b/src/app/panels/file-panel.js
index 27d39f8724..55cde39bab 100644
--- a/src/app/panels/file-panel.js
+++ b/src/app/panels/file-panel.js
@@ -224,12 +224,12 @@ function filepanel (appAPI, filesProvider) {
 
   function createNewFile () {
     modalDialogCustom.prompt(null, 'File Name', 'Untitled.sol', (input) => {
-      filesProvider['browser'].type + '/' + helper.createNonClashingName(input, filesProvider['browser'], (error, newName) => {
+      helper.createNonClashingName(input, filesProvider['browser'], (error, newName) => {
         if (error) return modalDialogCustom.alert('Failed to create file ' + newName + ' ' + error)
         if (!filesProvider['browser'].set(newName, '')) {
           modalDialogCustom.alert('Failed to create file ' + newName)
         } else {
-          appAPI.switchFile(newName)
+          appAPI.switchFile(filesProvider['browser'].type + '/' + newName)
         }
       })
     })

From b0be15c77c0801a546e36b88c49d6d749bf63608 Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 12:35:03 +0100
Subject: [PATCH 11/16] fix import

---
 contracts/src/gmbh/company.sol       |  1 +
 src/app.js                           |  2 +-
 test-browser/tests/simpleContract.js | 48 +++++++++++++++++++++++++++-
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/contracts/src/gmbh/company.sol b/contracts/src/gmbh/company.sol
index 1b9da1a0cf..9e488c000e 100644
--- a/contracts/src/gmbh/company.sol
+++ b/contracts/src/gmbh/company.sol
@@ -1,3 +1,4 @@
+import "./contract.sol";
 contract Assets {
 
     function add(uint8 _numProposals) {
diff --git a/src/app.js b/src/app.js
index bde7f76d58..8c0728a31a 100644
--- a/src/app.js
+++ b/src/app.js
@@ -221,7 +221,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
         if (exist) {
           return provider.get(url, cb)
         } else {
-          return cb('file not found')
+          return cb('Unable to import "' + url + '": File not found')
         }
       })
     } else {
diff --git a/test-browser/tests/simpleContract.js b/test-browser/tests/simpleContract.js
index ef08304112..aa7aae59ed 100644
--- a/test-browser/tests/simpleContract.js
+++ b/test-browser/tests/simpleContract.js
@@ -28,7 +28,8 @@ function runTests (browser) {
       async.waterfall([function (callback) { callback(null, browser) },
         testSimpleContract,
         testSuccessImport,
-        testFailedImport /* testGitHubImport */
+        testFailedImport, /* testGitHubImport */
+        testImportFromRemixd
       ],
       function () {
         browser.end()
@@ -36,6 +37,26 @@ function runTests (browser) {
     })
 }
 
+function testImportFromRemixd (browser, callback) {
+  browser.click('.websocketconn')
+    .waitForElementVisible('#modal-footer-ok', 10000)
+    .click('#modal-footer-ok')
+    .waitForElementVisible('[data-path="localhost"]', 100000)
+    .click('[data-path="localhost"]')
+    .waitForElementVisible('[data-path="localhost/src"]', 100000)
+    .click('[data-path="localhost/src"]')
+    .waitForElementVisible('[data-path="localhost/src/gmbh"]', 100000)
+    .click('[data-path="localhost/src/gmbh"]')
+    .waitForElementVisible('[data-path="localhost/src/gmbh/company.sol"]', 100000)
+    .click('[data-path="localhost/src/gmbh/company.sol"]')
+    .perform(() => {
+      contractHelper.verifyContract(browser, ['Assets', 'gmbh'], function () {
+        browser.click('.websocketconn')
+        callback(null, browser)
+      })
+    })
+}
+
 function testSimpleContract (browser, callback) {
   console.log('testSimpleContract')
   contractHelper.testContracts(browser, 'Untitled.sol', sources[0]['browser/Untitled.sol'], ['test1', 'test2'], function () {
@@ -198,6 +219,24 @@ contract ENS is AbstractENS {
     }
 }`
 
+var assetsTestContract = `import "./contract.sol";
+contract Assets {
+
+    function add(uint8 _numProposals) {
+        proposals.length = _numProposals;
+    }
+}
+`
+
+var gmbhTestContract = `
+contract gmbh {
+
+    function register(uint8 _numProposals) {
+        proposals.length = _numProposals;
+    }
+}
+`
+
 var sources = [
   {
     'browser/Untitled.sol': {content: 'contract test1 {} contract test2 {}'}
@@ -217,5 +256,12 @@ var sources = [
     'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'},
     'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS},
     'github.com/ethereum/ens/contracts/AbstractENS.sol': {content: abstractENS}
+  },
+  {
+    'localhost/src/gmbh/company.sol': {content: assetsTestContract}
+  },
+  {
+    'localhost/src/gmbh/company.sol': {content: assetsTestContract},
+    'localhost/src/gmbh/contract.sol': {content: gmbhTestContract}
   }
 ]

From ad42c7c8c19945d7e20ce879a7de5b783056db9b Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 13:43:05 +0100
Subject: [PATCH 12/16] move tests

---
 contracts/src/gmbh/company.sol             |  2 +-
 contracts/src/gmbh/contract.sol            |  2 +-
 test-browser/tests/sharedFolderExplorer.js | 44 ++++++++++++++++++++
 test-browser/tests/simpleContract.js       | 48 +---------------------
 4 files changed, 47 insertions(+), 49 deletions(-)

diff --git a/contracts/src/gmbh/company.sol b/contracts/src/gmbh/company.sol
index 9e488c000e..3161bf74dd 100644
--- a/contracts/src/gmbh/company.sol
+++ b/contracts/src/gmbh/company.sol
@@ -1,6 +1,6 @@
 import "./contract.sol";
 contract Assets {
-
+    uint[] proposals;
     function add(uint8 _numProposals) {
         proposals.length = _numProposals;
     }
diff --git a/contracts/src/gmbh/contract.sol b/contracts/src/gmbh/contract.sol
index 27ea2cb127..011523e562 100644
--- a/contracts/src/gmbh/contract.sol
+++ b/contracts/src/gmbh/contract.sol
@@ -1,5 +1,5 @@
 contract gmbh {
-
+    uint[] proposals;
     function register(uint8 _numProposals) {
         proposals.length = _numProposals;
     }
diff --git a/test-browser/tests/sharedFolderExplorer.js b/test-browser/tests/sharedFolderExplorer.js
index 47bd572672..574e8beb80 100644
--- a/test-browser/tests/sharedFolderExplorer.js
+++ b/test-browser/tests/sharedFolderExplorer.js
@@ -3,9 +3,34 @@ var contractHelper = require('../helpers/contracts')
 var init = require('../helpers/init')
 var sauce = require('./sauce')
 
+
+var assetsTestContract = `import "./contract.sol";
+contract Assets {
+    uint[] proposals;
+    function add(uint8 _numProposals) {
+        proposals.length = _numProposals;
+    }
+}
+`
+
+var gmbhTestContract = `
+contract gmbh {
+    uint[] proposals;
+    function register(uint8 _numProposals) {
+        proposals.length = _numProposals;
+    }
+}
+`
 var sources = [
   {
     'localhost/folder1/contract2.sol': {content: 'contract test2 { function get () returns (uint) { return 11; }}'}
+  },
+  {
+    'localhost/src/gmbh/company.sol': {content: assetsTestContract}
+  },
+  {
+    'localhost/src/gmbh/company.sol': {content: assetsTestContract},
+    'localhost/src/gmbh/contract.sol': {content: gmbhTestContract}
   }
 ]
 
@@ -92,6 +117,9 @@ function runTests (browser, testData) {
         done()
       })
     })
+    .perform(function (done) {
+      testImportFromRemixd(browser, () => { done() })
+    })
     .perform(function () {
       browser.click('[data-path="localhost"]') // collapse and expand
         .waitForElementNotVisible('[data-path="localhost/folder1"]')
@@ -107,3 +135,19 @@ function runTests (browser, testData) {
         .end()
     })
 }
+
+function testImportFromRemixd (browser, callback) {
+  browser
+    .waitForElementVisible('[data-path="localhost/src"]', 100000)
+    .click('[data-path="localhost/src"]')
+    .waitForElementVisible('[data-path="localhost/src/gmbh"]', 100000)
+    .click('[data-path="localhost/src/gmbh"]')
+    .waitForElementVisible('[data-path="localhost/src/gmbh/company.sol"]', 100000)
+    .click('[data-path="localhost/src/gmbh/company.sol"]')
+    .pause(500)
+    .perform(() => {
+      contractHelper.verifyContract(browser, ['Assets', 'gmbh'], function () {
+        callback()
+      })
+    })
+}
diff --git a/test-browser/tests/simpleContract.js b/test-browser/tests/simpleContract.js
index aa7aae59ed..ef08304112 100644
--- a/test-browser/tests/simpleContract.js
+++ b/test-browser/tests/simpleContract.js
@@ -28,8 +28,7 @@ function runTests (browser) {
       async.waterfall([function (callback) { callback(null, browser) },
         testSimpleContract,
         testSuccessImport,
-        testFailedImport, /* testGitHubImport */
-        testImportFromRemixd
+        testFailedImport /* testGitHubImport */
       ],
       function () {
         browser.end()
@@ -37,26 +36,6 @@ function runTests (browser) {
     })
 }
 
-function testImportFromRemixd (browser, callback) {
-  browser.click('.websocketconn')
-    .waitForElementVisible('#modal-footer-ok', 10000)
-    .click('#modal-footer-ok')
-    .waitForElementVisible('[data-path="localhost"]', 100000)
-    .click('[data-path="localhost"]')
-    .waitForElementVisible('[data-path="localhost/src"]', 100000)
-    .click('[data-path="localhost/src"]')
-    .waitForElementVisible('[data-path="localhost/src/gmbh"]', 100000)
-    .click('[data-path="localhost/src/gmbh"]')
-    .waitForElementVisible('[data-path="localhost/src/gmbh/company.sol"]', 100000)
-    .click('[data-path="localhost/src/gmbh/company.sol"]')
-    .perform(() => {
-      contractHelper.verifyContract(browser, ['Assets', 'gmbh'], function () {
-        browser.click('.websocketconn')
-        callback(null, browser)
-      })
-    })
-}
-
 function testSimpleContract (browser, callback) {
   console.log('testSimpleContract')
   contractHelper.testContracts(browser, 'Untitled.sol', sources[0]['browser/Untitled.sol'], ['test1', 'test2'], function () {
@@ -219,24 +198,6 @@ contract ENS is AbstractENS {
     }
 }`
 
-var assetsTestContract = `import "./contract.sol";
-contract Assets {
-
-    function add(uint8 _numProposals) {
-        proposals.length = _numProposals;
-    }
-}
-`
-
-var gmbhTestContract = `
-contract gmbh {
-
-    function register(uint8 _numProposals) {
-        proposals.length = _numProposals;
-    }
-}
-`
-
 var sources = [
   {
     'browser/Untitled.sol': {content: 'contract test1 {} contract test2 {}'}
@@ -256,12 +217,5 @@ var sources = [
     'browser/Untitled4.sol': {content: 'import "github.com/ethereum/ens/contracts/ENS.sol"; contract test7 {}'},
     'github.com/ethereum/ens/contracts/ENS.sol': {content: ENS},
     'github.com/ethereum/ens/contracts/AbstractENS.sol': {content: abstractENS}
-  },
-  {
-    'localhost/src/gmbh/company.sol': {content: assetsTestContract}
-  },
-  {
-    'localhost/src/gmbh/company.sol': {content: assetsTestContract},
-    'localhost/src/gmbh/contract.sol': {content: gmbhTestContract}
   }
 ]

From 660308469f9109ae5b6a800c03bdf6027900043f Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 14:40:16 +0100
Subject: [PATCH 13/16] standard

---
 test-browser/tests/sharedFolderExplorer.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test-browser/tests/sharedFolderExplorer.js b/test-browser/tests/sharedFolderExplorer.js
index 574e8beb80..b2b859ff6e 100644
--- a/test-browser/tests/sharedFolderExplorer.js
+++ b/test-browser/tests/sharedFolderExplorer.js
@@ -3,7 +3,6 @@ var contractHelper = require('../helpers/contracts')
 var init = require('../helpers/init')
 var sauce = require('./sauce')
 
-
 var assetsTestContract = `import "./contract.sol";
 contract Assets {
     uint[] proposals;

From 055ad8bf1e5531427bb9b4177da040e9d014d9c3 Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 15:03:01 +0100
Subject: [PATCH 14/16] typo

---
 src/app/panels/file-panel.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/panels/file-panel.js b/src/app/panels/file-panel.js
index 55cde39bab..1e3910f708 100644
--- a/src/app/panels/file-panel.js
+++ b/src/app/panels/file-panel.js
@@ -169,7 +169,7 @@ function filepanel (appAPI, filesProvider) {
           }
           var success = files.set(name, event.target.result)
           if (!success) modalDialogCustom.alert('Failed to create file ' + name)
-          else self.events.trigger('focus', [name])
+          else self.event.trigger('focus', [name])
         }
         fileReader.readAsText(file)
       }

From 0c0c8a2e592d80ac0ff0854c5dd4fd1953d783b7 Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 15:40:39 +0100
Subject: [PATCH 15/16] add pause before verifying contract

---
 test-browser/tests/sharedFolderExplorer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-browser/tests/sharedFolderExplorer.js b/test-browser/tests/sharedFolderExplorer.js
index b2b859ff6e..9eb553dd1e 100644
--- a/test-browser/tests/sharedFolderExplorer.js
+++ b/test-browser/tests/sharedFolderExplorer.js
@@ -143,7 +143,7 @@ function testImportFromRemixd (browser, callback) {
     .click('[data-path="localhost/src/gmbh"]')
     .waitForElementVisible('[data-path="localhost/src/gmbh/company.sol"]', 100000)
     .click('[data-path="localhost/src/gmbh/company.sol"]')
-    .pause(500)
+    .pause(1000)
     .perform(() => {
       contractHelper.verifyContract(browser, ['Assets', 'gmbh'], function () {
         callback()

From cb227132bce6cc72217f8c11bbde77528284ac8b Mon Sep 17 00:00:00 2001
From: yann300 
Date: Wed, 14 Feb 2018 17:15:19 +0100
Subject: [PATCH 16/16] run browser test in serie

---
 ci/browser_tests.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/ci/browser_tests.sh b/ci/browser_tests.sh
index da6092f4b9..e0e42fc9e1 100755
--- a/ci/browser_tests.sh
+++ b/ci/browser_tests.sh
@@ -30,11 +30,11 @@ while [ ! -f "$SAUCECONNECT_READYFILE" ]; do
   sleep .5
 done
 
-# npm run nightwatch_remote_chrome || TEST_EXITCODE=1
-# npm run nightwatch_remote_firefox || TEST_EXITCODE=1
-# npm run nightwatch_remote_safari || TEST_EXITCODE=1
+npm run nightwatch_remote_chrome || TEST_EXITCODE=1
+npm run nightwatch_remote_firefox || TEST_EXITCODE=1
+npm run nightwatch_remote_safari || TEST_EXITCODE=1
 # npm run nightwatch_remote_ie || TEST_EXITCODE=1
-npm run nightwatch_remote_parallel || TEST_EXITCODE=1
+# npm run nightwatch_remote_parallel || TEST_EXITCODE=1
 
 node ci/sauceDisconnect.js "$SAUCECONNECT_USERNAME" "$SAUCECONNECT_ACCESSKEY" "$SAUCECONNECT_JOBIDENTIFIER"