From c6e642afe0145c282faeae0db37ce6b7507187d1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 8 Feb 2018 18:43:22 +0100 Subject: [PATCH 01/11] fix basicReadOnlyExplorer --- src/app/files/basicReadOnlyExplorer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/files/basicReadOnlyExplorer.js b/src/app/files/basicReadOnlyExplorer.js index a9178702ab..48a8841e1e 100644 --- a/src/app/files/basicReadOnlyExplorer.js +++ b/src/app/files/basicReadOnlyExplorer.js @@ -27,7 +27,8 @@ class BasicReadOnlyExplorer { } get (path, cb) { - var content = this.files[path] + var unprefixedPath = this.removePrefix(path) + var content = this.files[unprefixedPath] if (!content) { content = this.files[this.type + '/' + this.normalizedNames[path]] } @@ -48,6 +49,7 @@ class BasicReadOnlyExplorer { try { // lazy try to format JSON content = JSON.stringify(JSON.parse(content), null, '\t') } catch (e) {} + if (!rawPath) rawPath = path // splitting off the path in a tree structure, the json tree is used in `resolveDirectory` var split = path var folder = false From e0546174f7451c7506920bc0510feb3588a83a10 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 8 Feb 2018 18:43:37 +0100 Subject: [PATCH 02/11] add tooltip --- src/app/files/file-explorer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index 53c689e8a4..98b50cf05c 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -6,6 +6,7 @@ var modalDialogCustom = require('../ui/modal-dialog-custom') var remixLib = require('remix-lib') var EventManager = remixLib.EventManager var contextMenu = require('../ui/contextMenu') +var addTooltip = require('../ui/tooltip') var helper = require('../../lib/helper') var styleGuide = remixLib.ui.themeChooser @@ -163,11 +164,12 @@ function fileExplorer (appAPI, files) { self.treeView.event.register('leafRightClick', function (key, data, label, event) { contextMenu(event, { 'Rename': () => { - if (self.files.readonly) return + if (self.files.readonly) { return addTooltip('cannot rename. ' + self.files.type + ' is a read only explorer') } var name = label.querySelector('label[data-path="' + key + '"]') if (name) editModeOn(name) }, 'Delete': () => { + if (self.files.readonly) { return addTooltip('cannot delete. ' + self.files.type + ' is a read only explorer') } modalDialogCustom.confirm(null, 'Do you want to delete this file?', () => { files.remove(key) }, () => {}) } }) From 51253452f73f83bb5a925d530964fdf926df6369 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 8 Feb 2018 18:43:50 +0100 Subject: [PATCH 03/11] fix tabs nav --- src/app/files/fileManager.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/files/fileManager.js b/src/app/files/fileManager.js index 2569ebcf12..7614ed6779 100644 --- a/src/app/files/fileManager.js +++ b/src/app/files/fileManager.js @@ -114,8 +114,6 @@ class FileManager { return $(this).find('.name').text() === newfile }) if (active.length) active.addClass('active') - else this.switchFile() - // $('#input').toggle(active) $('#output').toggle(active) } From e2328bed7166d7d3fe0d843798691720d65a901a Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 8 Feb 2018 18:44:07 +0100 Subject: [PATCH 04/11] ensure remixd connected --- src/app/files/shared-folder.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/files/shared-folder.js b/src/app/files/shared-folder.js index e76fd0d84f..00e87011f8 100644 --- a/src/app/files/shared-folder.js +++ b/src/app/files/shared-folder.js @@ -49,8 +49,10 @@ module.exports = class SharedFolder { } init (cb) { - this._isReady = true - cb() + this._remixd.ensureSocket((error) => { + this._isReady = !error + cb(error) + }) } // @TODO: refactor all `this._remixd.call(....)` uses into `this.remixd[api](...)` From 5dd36768e31ca29dea849a3e8ad19591832e4af1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 8 Feb 2018 18:53:19 +0100 Subject: [PATCH 05/11] fix BasicReadOnlyExplorer --- src/app/files/basicReadOnlyExplorer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/files/basicReadOnlyExplorer.js b/src/app/files/basicReadOnlyExplorer.js index 48a8841e1e..de0f62a041 100644 --- a/src/app/files/basicReadOnlyExplorer.js +++ b/src/app/files/basicReadOnlyExplorer.js @@ -23,7 +23,8 @@ class BasicReadOnlyExplorer { exists (path) { if (!this.files) return false - return this.files[path] !== undefined + var unprefixedPath = this.removePrefix(path) + return this.files[unprefixedPath] !== undefined } get (path, cb) { From ad7da9a65104e50411cb4cc42e02fd965dfd93c9 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 8 Feb 2018 18:53:35 +0100 Subject: [PATCH 06/11] z-index on context menu --- src/app/ui/contextMenu.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/ui/contextMenu.js b/src/app/ui/contextMenu.js index baa729cb21..9f18d9046c 100644 --- a/src/app/ui/contextMenu.js +++ b/src/app/ui/contextMenu.js @@ -13,6 +13,7 @@ var css = csjs` width:150px; background: ${styles.appProperties.solidBorderBox_BackgroundColor}; border-radius: 2px; + z-index: 1000; } .liitem From 4f7ffa3bd0002670386a937f77958dd09a65991b Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 9 Feb 2018 12:42:32 +0100 Subject: [PATCH 07/11] test contracts --- contracts/folder1/contract_chrome_toremove.sol | 1 + contracts/folder1/contract_firefox_toremove.sol | 1 + 2 files changed, 2 insertions(+) create mode 100644 contracts/folder1/contract_chrome_toremove.sol create mode 100644 contracts/folder1/contract_firefox_toremove.sol diff --git a/contracts/folder1/contract_chrome_toremove.sol b/contracts/folder1/contract_chrome_toremove.sol new file mode 100644 index 0000000000..04f9b2eb26 --- /dev/null +++ b/contracts/folder1/contract_chrome_toremove.sol @@ -0,0 +1 @@ +contract test2 { function get () returns (uint) { return 11; }} \ No newline at end of file diff --git a/contracts/folder1/contract_firefox_toremove.sol b/contracts/folder1/contract_firefox_toremove.sol new file mode 100644 index 0000000000..04f9b2eb26 --- /dev/null +++ b/contracts/folder1/contract_firefox_toremove.sol @@ -0,0 +1 @@ +contract test2 { function get () returns (uint) { return 11; }} \ No newline at end of file From 4a63ffdd6ce701783857447e1b8bdb00926b165e Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 9 Feb 2018 12:42:49 +0100 Subject: [PATCH 08/11] improve file name editing --- src/app/files/file-explorer.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index 98b50cf05c..b66c568ab5 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -220,13 +220,21 @@ function fileExplorer (appAPI, files) { }) var textUnderEdit = null - var textInRename = false + + function selectElementContents (el) { + var range = document.createRange() + range.selectNodeContents(el) + var sel = window.getSelection() + sel.removeAllRanges() + sel.addRange(range) + } function editModeOn (label) { textUnderEdit = label.innerText label.setAttribute('contenteditable', true) label.classList.add(css.rename) label.focus() + selectElementContents(label) } function editModeOff (event) { @@ -251,8 +259,7 @@ function fileExplorer (appAPI, files) { } if (event.which === 13) event.preventDefault() - if (!textInRename && (event.type === 'blur' || event.which === 27 || event.which === 13) && label.getAttribute('contenteditable')) { - textInRename = true + if (event.type === 'blur' || event.which === 13 && label.getAttribute('contenteditable')) { var isFolder = label.className.indexOf('folder') !== -1 var save = textUnderEdit !== label.innerText if (save) { @@ -260,7 +267,6 @@ function fileExplorer (appAPI, files) { } label.removeAttribute('contenteditable') label.classList.remove(css.rename) - textInRename = false } } } From da4d28f4acc00b852dea891a4d25e0f2d94100f8 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 9 Feb 2018 12:42:59 +0100 Subject: [PATCH 09/11] fix context menu on firefox --- src/app/ui/contextMenu.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/app/ui/contextMenu.js b/src/app/ui/contextMenu.js index 9f18d9046c..6491725446 100644 --- a/src/app/ui/contextMenu.js +++ b/src/app/ui/contextMenu.js @@ -43,9 +43,17 @@ var css = csjs` module.exports = (event, items) => { event.preventDefault() + + function hide (event, force) { + if (force || (event.target !== container)) { + container.parentElement.removeChild(container) + } + window.removeEventListener('click', hide) + } + var menu = Object.keys(items).map((item, index) => { - var current = yo`
  • ${item}
  • ` - current.onclick = () => items[item]() + var current = yo`` + current.onclick = () => { hide(null, true); items[item]() } return current }) var container = yo`
    ` @@ -53,12 +61,8 @@ module.exports = (event, items) => { container.style.top = event.pageY + 'px' container.style.display = 'block' - function hide (event) { - if (event.target !== container) { - container.parentElement.removeChild(container) - } - window.removeEventListener('click', hide) - } - window.addEventListener('click', hide) document.querySelector('body').appendChild(container) + setTimeout(() => { + window.addEventListener('click', hide) + }, 500) } From e00a7f88126d16449867e3193a4907f5740be97e Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 9 Feb 2018 12:43:21 +0100 Subject: [PATCH 10/11] test: add rename/remove file --- test-browser/helpers/contracts.js | 79 ++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/test-browser/helpers/contracts.js b/test-browser/helpers/contracts.js index 3239e84bad..65c7877970 100644 --- a/test-browser/helpers/contracts.js +++ b/test-browser/helpers/contracts.js @@ -17,7 +17,10 @@ module.exports = { createContract, modalFooterOKClick, setEditorValue, - getEditorValue + getEditorValue, + testEditorValue, + renameFile, + removeFile } function getCompiledContracts (browser, compiled, callback) { @@ -184,6 +187,13 @@ function getEditorValue (callback) { return this } +function testEditorValue (testvalue, callback) { + this.getEditorValue((value) => { + this.assert.equal(testvalue, value) + callback() + }) +} + function modalFooterOKClick () { this.perform((client, done) => { this.execute(function () { @@ -215,6 +225,73 @@ function addFile (browser, name, content, done) { }) } +function renameFile (browser, path, newFileName, renamedPath, done) { + browser.execute(function (path) { + function contextMenuClick (element) { + var evt = element.ownerDocument.createEvent('MouseEvents') + var RIGHT_CLICK_BUTTON_CODE = 2 // the same for FF and IE + evt.initMouseEvent('contextmenu', true, true, + element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, + false, false, false, RIGHT_CLICK_BUTTON_CODE, null) + if (document.createEventObject) { + // dispatch for IE + return element.fireEvent('onclick', evt) + } else { + // dispatch for firefox + others + return !element.dispatchEvent(evt) + } + } + contextMenuClick(document.querySelector('[data-path="' + path + '"]')) + }, [path], function (result) { + browser + .click('#menuitemrename') + .perform((client, doneSetValue) => { + browser.execute(function (path, addvalue) { + document.querySelector('[data-path="' + path + '"]').innerHTML = addvalue + }, [path, newFileName], () => { + doneSetValue() + }) + }) + .click('body') // blur + .pause(500) + .click('#modal-footer-ok') + .waitForElementNotPresent('[data-path="' + path + '"]') + .waitForElementPresent('[data-path="' + renamedPath + '"]') + .perform(() => { + done() + }) + }) +} + +function removeFile (browser, path, done) { + browser.execute(function (path, value) { + function contextMenuClick (element) { + var evt = element.ownerDocument.createEvent('MouseEvents') + var RIGHT_CLICK_BUTTON_CODE = 2 // the same for FF and IE + evt.initMouseEvent('contextmenu', true, true, + element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, + false, false, false, RIGHT_CLICK_BUTTON_CODE, null) + if (document.createEventObject) { + // dispatch for IE + return element.fireEvent('onclick', evt) + } else { + // dispatch for firefox + others + return !element.dispatchEvent(evt) + } + } + contextMenuClick(document.querySelector('[data-path="' + path + '"]')) + }, [path], function (result) { + browser + .click('#menuitemdelete') + .pause(500) + .click('#modal-footer-ok') + .waitForElementNotPresent('[data-path="' + path + '"]') + .perform((client) => { + done() + }) + }) +} + function useFilter (browser, filter, test, done) { if (browser.options.desiredCapabilities.browserName === 'chrome') { // nightwatch deos not handle well that part.... works locally done() From 8d5d03980c378b2423fc8ccf5fbb4dd854606d9e Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 9 Feb 2018 12:44:03 +0100 Subject: [PATCH 11/11] add tests --- test-browser/helpers/contracts.js | 5 +- test-browser/tests/sharedFolderExplorer.js | 66 ++++++++++++++++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/test-browser/helpers/contracts.js b/test-browser/helpers/contracts.js index 65c7877970..6d01addfa9 100644 --- a/test-browser/helpers/contracts.js +++ b/test-browser/helpers/contracts.js @@ -149,12 +149,13 @@ function testFunction (fnFullName, txHash, log, expectedInput, expectedReturn, e return this } -function setEditorValue (value) { +function setEditorValue (value, callback) { this.perform((client, done) => { this.execute(function (value) { document.getElementById('input').editor.session.setValue(value) }, [value], function (result) { done() + if (callback) callback() }) }) return this @@ -286,7 +287,7 @@ function removeFile (browser, path, done) { .pause(500) .click('#modal-footer-ok') .waitForElementNotPresent('[data-path="' + path + '"]') - .perform((client) => { + .perform(() => { done() }) }) diff --git a/test-browser/tests/sharedFolderExplorer.js b/test-browser/tests/sharedFolderExplorer.js index 439d4beabf..47bd572672 100644 --- a/test-browser/tests/sharedFolderExplorer.js +++ b/test-browser/tests/sharedFolderExplorer.js @@ -23,6 +23,12 @@ module.exports = { } function runTests (browser, testData) { + browser.testFunction = contractHelper.testFunction + browser.clickFunction = contractHelper.clickFunction + browser.setEditorValue = contractHelper.setEditorValue + browser.modalFooterOKClick = contractHelper.modalFooterOKClick + browser.getEditorValue = contractHelper.getEditorValue + browser.testEditorValue = contractHelper.testEditorValue var browserName = browser.options.desiredCapabilities.browserName if (browserName === 'safari' || browserName === 'internet explorer') { console.log('do not run remixd test for ' + browserName + ': sauce labs doesn\'t seems to handle websocket') @@ -38,14 +44,66 @@ function runTests (browser, testData) { .click('[data-path="localhost"]') .waitForElementVisible('[data-path="localhost/folder1"]') .click('[data-path="localhost/folder1"]') + .waitForElementVisible('[data-path="localhost/contract1.sol"]') .assert.containsText('[data-path="localhost/contract1.sol"]', 'contract1.sol') .assert.containsText('[data-path="localhost/contract2.sol"]', 'contract2.sol') .assert.containsText('[data-path="localhost/folder1/contract1.sol"]', 'contract1.sol') - .assert.containsText('[data-path="localhost/folder1/contract2.sol"]', 'contract2.sol') + .assert.containsText('[data-path="localhost/folder1/contract2.sol"]', 'contract2.sol') // load and test sub folder .click('[data-path="localhost/folder1/contract2.sol"]') - .waitForElementPresent('#compileTabView select option', 50000, true, function () { - contractHelper.verifyContract(browser, ['test2'], function () { - browser.click('.websocketconn').end() + .click('[data-path="localhost/folder1/contract1.sol"]') // open localhost/folder1/contract1.sol + .pause(1000) + .perform(function (done) { // check the content and replace by another + browser.testEditorValue('contract test1 { function get () returns (uint) { return 10; }}', () => { + console.log('testEditorValue') + done() }) }) + .perform(function (done) { + browser.setEditorValue('contract test1Changed { function get () returns (uint) { return 10; }}', () => { + console.log('setEditorValue') + done() + }) + }) + .perform(function (done) { + browser.testEditorValue('contract test1Changed { function get () returns (uint) { return 10; }}', () => { + console.log('testEditorValue') + done() + }) + }) + .perform(function (done) { + browser.setEditorValue('contract test1 { function get () returns (uint) { return 10; }}', () => { + console.log('setEditorValue') + done() + }) + }) + .click('[data-path="localhost/folder1/contract_' + browserName + '.sol"]') // rename a file and check + .pause(1000) + .perform(function (done) { + contractHelper.renameFile(browser, 'localhost/folder1/contract_' + browserName + '.sol', 'renamed_contract_' + browserName + '.sol', + 'localhost/folder1/renamed_contract_' + browserName + '.sol', () => { + console.log('tested file renaming') + done() + }) + }) + .pause(1000) + .perform(function (done) { // remove a file and check + contractHelper.removeFile(browser, 'localhost/folder1/contract_' + browserName + '_toremove.sol', () => { + console.log('tested file removing') + done() + }) + }) + .perform(function () { + browser.click('[data-path="localhost"]') // collapse and expand + .waitForElementNotVisible('[data-path="localhost/folder1"]') + .click('[data-path="localhost"]') + .waitForElementVisible('[data-path="localhost/folder1"]') + .click('[data-path="localhost/folder1"]') + .waitForElementVisible('[data-path="localhost/folder1/contract1.sol"]') + .waitForElementVisible('[data-path="localhost/folder1/renamed_contract_' + browserName + '.sol"]') // check if renamed file is preset + .waitForElementNotPresent('[data-path="localhost/folder1/contract_' + browserName + '.sol"]') // check if renamed (old) file is not present + .waitForElementNotPresent('[data-path="localhost/folder1/contract_' + browserName + '_toremove.sol"]') // check if removed (old) file is not present + .click('[data-path="localhost/folder1/renamed_contract_' + browserName + '.sol"]') + .click('.websocketconn') + .end() + }) }