Merge pull request #4 from ethereum/update-remixide

Update Remix-IDE
pull/7/head
David Disu 5 years ago committed by GitHub
commit 1934b687c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 76
      README.md
  2. 84
      apps/remix-ide/nightwatch.js~36bc4ab5a5b52c76327ec5b5f7a8896938b18525
  3. 20465
      apps/remix-ide/package-lock.json
  4. 2
      apps/remix-ide/src/app.js
  5. 4
      apps/remix-ide/src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js
  6. 32
      apps/remix-ide/src/app/editor/SourceHighlighters.js
  7. 2
      apps/remix-ide/src/app/editor/contextView.js
  8. 1
      apps/remix-ide/src/app/editor/editor.js
  9. 7
      apps/remix-ide/src/app/editor/sourceHighlighter.js
  10. 34
      apps/remix-ide/src/app/files/file-explorer.js
  11. 272
      apps/remix-ide/src/app/files/fileManager.js
  12. 58
      apps/remix-ide/src/app/files/fileProvider.js
  13. 39
      apps/remix-ide/src/app/files/remixDProvider.js
  14. 2
      apps/remix-ide/src/app/panels/main-view.js
  15. 8
      apps/remix-ide/src/app/panels/tab-proxy.js
  16. 2
      apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js
  17. 2
      apps/remix-ide/src/app/tabs/runTab/model/recorder.js
  18. 2
      apps/remix-ide/src/app/tabs/runTab/settings.js
  19. 6
      apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js
  20. 4
      apps/remix-ide/src/app/tabs/test-tab.js
  21. 4
      apps/remix-ide/src/app/tabs/testTab/testTab.js
  22. 2
      apps/remix-ide/src/app/ui/renderer.js
  23. 4
      apps/remix-ide/src/lib/cmdInterpreterAPI.js
  24. 24
      apps/remix-ide/src/lib/remixd.js
  25. 26
      apps/remix-ide/test-browser/commands/openFile.js
  26. 2
      apps/remix-ide/test-browser/tests/defaultLayout.test.js
  27. 14
      apps/remix-ide/test-browser/tests/editor.test.js
  28. 6
      apps/remix-ide/test-browser/tests/generalSettings.test.js
  29. 10
      apps/remix-ide/test-browser/tests/gist.test.js
  30. 8
      apps/remix-ide/test-browser/tests/libraryDeployment.test.js
  31. 2
      apps/remix-ide/test-browser/tests/pluginManager.test.js
  32. 6
      apps/remix-ide/test-browser/tests/publishContract.test.js
  33. 2
      apps/remix-ide/test-browser/tests/remixd.test.js
  34. 12
      apps/remix-ide/test-browser/tests/runAndDeploy.js
  35. 2
      apps/remix-ide/test-browser/tests/signingMessage.test.js
  36. 2
      apps/remix-ide/test-browser/tests/solidityImport.test.js
  37. 10
      apps/remix-ide/test-browser/tests/solidityUnittests.test.js
  38. 6
      apps/remix-ide/test-browser/tests/terminal.test.js
  39. 16891
      package-lock.json
  40. 31
      package.json
  41. 1
      soljson.js

@ -1,76 +0,0 @@
# RemixProject
This project was generated using [Nx](https://nx.dev).
<p align="center"><img src="https://raw.githubusercontent.com/nrwl/nx/master/nx-logo.png" width="450"></p>
🔎 **Nx is a set of Extensible Dev Tools for Monorepos.**
## Adding capabilities to your workspace
Nx supports many plugins which add capabilities for developing different types of applications and different tools.
These capabilities include generating applications, libraries, etc as well as the devtools to test, and build projects as well.
Below are some plugins which you can add to your workspace:
- [React](https://reactjs.org)
- `npm install --save-dev @nrwl/react`
- Web (no framework frontends)
- `npm install --save-dev @nrwl/web`
- [Angular](https://angular.io)
- `npm install --save-dev @nrwl/angular`
- [Nest](https://nestjs.com)
- `npm install --save-dev @nrwl/nest`
- [Express](https://expressjs.com)
- `npm install --save-dev @nrwl/express`
- [Node](https://nodejs.org)
- `npm install --save-dev @nrwl/node`
## Generate an application
Run `nx g @nrwl/react:app my-app` to generate an application.
> You can use any of the plugins above to generate applications as well.
When using Nx, you can create multiple applications and libraries in the same workspace.
## Generate a library
Run `nx g @nrwl/react:lib my-lib` to generate a library.
> You can also use any of the plugins above to generate libraries as well.
Libraries are sharable across libraries and applications. They can be imported from `@remix-project/mylib`.
## Development server
Run `nx serve my-app` for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `nx g @nrwl/react:component my-component --project=my-app` to generate a new component.
## Build
Run `nx build my-app` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests
Run `nx test my-app` to execute the unit tests via [Jest](https://jestjs.io).
Run `nx affected:test` to execute the unit tests affected by a change.
## Running end-to-end tests
Run `ng e2e my-app` to execute the end-to-end tests via [Cypress](https://www.cypress.io).
Run `nx affected:e2e` to execute the end-to-end tests affected by a change.
## Understand your workspace
Run `nx dep-graph` to see a diagram of the dependencies of your projects.
## Further help
Visit the [Nx Documentation](https://nx.dev) to learn more.

@ -1,84 +0,0 @@
'use strict'
require('@babel/register')()
const crxFile = require('fs').readFileSync('test-browser/extensions/chrome/metamask.crx')
const metamaskExtension = new Buffer.from(crxFile).toString('base64') // eslint-disable-line
module.exports = {
'src_folders': ['test-browser/tests'],
'output_folder': 'reports/tests',
'custom_commands_path': ['test-browser/commands'],
'custom_assertions_path': '',
'page_objects_path': '',
'globals_path': '',
'test_settings': {
'default': {
'selenium_port': 4444,
'selenium_host': 'localhost',
'globals': {
'waitForConditionTimeout': 10000,
'asyncHookTimeout': 100000
},
'screenshots': {
'enabled': true,
'path': './reports/screenshots',
'on_failure': true,
'on_error': true
},
'desiredCapabilities': {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true
},
'exclude': ['tests/runAndDeploy.js']
},
'chrome': {
'desiredCapabilities': {
'browserName': 'chrome',
'javascriptEnabled': true,
'acceptSslCerts': true,
'goog:chromeOptions': {
'args': ['window-size=2560,1440', 'start-fullscreen']
}
}
},
'chrome-runAndDeploy': {
'desiredCapabilities': {
'browserName': 'chrome',
'javascriptEnabled': true,
'acceptSslCerts': true,
'goog:chromeOptions': {
'args': ['window-size=2560,1440', 'start-fullscreen'],
'extensions': [metamaskExtension]
}
}
},
'safari': {
'desiredCapabilities': {
'browserName': 'safari',
'javascriptEnabled': true,
'acceptSslCerts': true
}
},
'ie': {
'desiredCapabilities': {
'browserName': 'internet explorer',
'javascriptEnabled': true,
'acceptSslCerts': true
}
},
'firefox': {
'desiredCapabilities': {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true
}
}
}
}

File diff suppressed because it is too large Load Diff

@ -419,7 +419,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
if (error) console.error(error) if (error) console.error(error)
if (Object.keys(filesList).length === 0) { if (Object.keys(filesList).length === 0) {
for (let file in examples) { for (let file in examples) {
fileManager.setFile(examples[file].name, examples[file].content) fileManager.writeFile(examples[file].name, examples[file].content)
} }
} }
}) })

@ -73,9 +73,9 @@ export default class FetchAndCompile extends Plugin {
name === 'main' ? 'mainnet' : name // source-verifier api expect "mainnet" and not "main" name === 'main' ? 'mainnet' : name // source-verifier api expect "mainnet" and not "main"
let data let data
try { try {
data = await this.call('source-verification', 'fetch', contractAddress, name.toLowerCase()) data = await this.call('source-verification', 'fetchByNetwork', contractAddress, name.toLowerCase())
} catch (e) { } catch (e) {
setTimeout(_ => this.emit('sourceVerificationNotAvailable'), 0) setTimeout(_ => this.emit('notFound', contractAddress), 0) // plugin framework returns a time out error although it actually didn't find the source...
this.unresolvedAddresses.push(contractAddress) this.unresolvedAddresses.push(contractAddress)
return localCompilation() return localCompilation()
} }

@ -12,16 +12,40 @@ class SourceHighlighters {
highlight (position, filePath, hexColor, from) { highlight (position, filePath, hexColor, from) {
try { try {
if (!this.highlighters[from]) this.highlighters[from] = new SourceHighlighter() if (!this.highlighters[from]) this.highlighters[from] = []
this.highlighters[from].currentSourceLocation(null) const sourceHighlight = new SourceHighlighter()
this.highlighters[from].currentSourceLocationFromfileName(position, filePath, hexColor) if (
!this.highlighters[from].length ||
(this.highlighters[from].length && !this.highlighters[from].find((el) => {
return el.source === filePath && el.position === position
}))
) {
sourceHighlight.currentSourceLocationFromfileName(position, filePath, hexColor)
this.highlighters[from].push(sourceHighlight)
}
} catch (e) { } catch (e) {
throw e throw e
} }
} }
discardHighlight (from) { discardHighlight (from) {
if (this.highlighters[from]) this.highlighters[from].currentSourceLocation(null) if (this.highlighters[from]) {
for (const index in this.highlighters[from]) this.highlighters[from][index].currentSourceLocation(null)
}
this.highlighters[from] = []
}
discardHighlightAt (line, filePath, from) {
if (this.highlighters[from]) {
for (const index in this.highlighters[from]) {
const highlight = this.highlighters[from][index]
if (highlight.source === filePath &&
(highlight.position.start.line === line || highlight.position.end.line === line)) {
highlight.currentSourceLocation(null)
this.highlighters[from].splice(index, 1)
}
}
}
} }
} }

@ -112,7 +112,7 @@ class ContextView {
if (provider) { if (provider) {
provider.exists(filename, (error, exist) => { provider.exists(filename, (error, exist) => {
if (error) return console.log(error) if (error) return console.log(error)
this._deps.fileManager.switchFile(filename) this._deps.fileManager.open(filename)
jumpToLine(lineColumn) jumpToLine(lineColumn)
}) })
} }

@ -79,6 +79,7 @@ class Editor extends Plugin {
this.emptySession = this._createSession('') this.emptySession = this._createSession('')
this.modes = { this.modes = {
sol: 'ace/mode/solidity', sol: 'ace/mode/solidity',
yul: 'ace/mode/solidity',
mvir: 'ace/mode/move', mvir: 'ace/mode/move',
js: 'ace/mode/javascript', js: 'ace/mode/javascript',
py: 'ace/mode/python', py: 'ace/mode/python',

@ -31,7 +31,7 @@ class SourceHighlighter {
} }
} }
currentSourceLocationFromfileName (lineColumnPos, filePath, style) { async currentSourceLocationFromfileName (lineColumnPos, filePath, style) {
if (this.statementMarker) this._deps.editor.removeMarker(this.statementMarker, this.source) if (this.statementMarker) this._deps.editor.removeMarker(this.statementMarker, this.source)
if (this.fullLineMarker) this._deps.editor.removeMarker(this.fullLineMarker, this.source) if (this.fullLineMarker) this._deps.editor.removeMarker(this.fullLineMarker, this.source)
this.statementMarker = null this.statementMarker = null
@ -39,8 +39,9 @@ class SourceHighlighter {
this.source = null this.source = null
if (lineColumnPos) { if (lineColumnPos) {
this.source = filePath this.source = filePath
if (this._deps.config.get('currentFile') !== this.source) { if (this._deps.fileManager.currentFile() !== this.source) {
this._deps.fileManager.switchFile(this.source) await this._deps.fileManager.open(this.source)
this.source = this._deps.fileManager.currentFile()
} }
const css = csjs` const css = csjs`

@ -60,7 +60,7 @@ function fileExplorer (localRegistry, files, menuItems) {
} }
self.events.register('focus', function (path) { self.events.register('focus', function (path) {
self._deps.fileManager.switchFile(path) self._deps.fileManager.open(path)
}) })
self._components.registry.put({ api: self, name: `fileexplorer/${self.files.type}` }) self._components.registry.put({ api: self, name: `fileexplorer/${self.files.type}` })
@ -234,11 +234,16 @@ function fileExplorer (localRegistry, files, menuItems) {
const currentFoldername = extractNameFromKey(key) const currentFoldername = extractNameFromKey(key)
modalDialogCustom.confirm(`Confirm to delete folder`, `Are you sure you want to delete ${currentFoldername} folder?`, modalDialogCustom.confirm(`Confirm to delete folder`, `Are you sure you want to delete ${currentFoldername} folder?`,
() => { async () => {
if (!files.remove(key)) { const fileManager = self._deps.fileManager
const removeFolder = await fileManager.remove(key)
if (!removeFolder) {
tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`)
} else { } else {
self.updatePath('browser') const { type } = fileManager.currentFileProvider()
self.updatePath(type)
} }
}, () => {}) }, () => {})
} }
@ -275,9 +280,16 @@ function fileExplorer (localRegistry, files, menuItems) {
modalDialogCustom.confirm( modalDialogCustom.confirm(
`Delete file`, `Are you sure you want to delete ${currentFilename} file?`, `Delete file`, `Are you sure you want to delete ${currentFilename} file?`,
() => { async () => {
files.remove(key) const fileManager = self._deps.fileManager
self.updatePath('browser') const removeFile = await fileManager.remove(key)
if (!removeFile) {
tooltip(`Failed to remove file ${key}.`)
} else {
const { type } = fileManager.currentFileProvider()
self.updatePath(type)
}
}, },
() => {} () => {}
) )
@ -578,13 +590,15 @@ fileExplorer.prototype.createNewFile = function (parentFolder = 'browser') {
let self = this let self = this
modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => {
if (!input) input = 'New file' if (!input) input = 'New file'
helper.createNonClashingName(parentFolder + '/' + input, self.files, (error, newName) => { helper.createNonClashingName(parentFolder + '/' + input, self.files, async (error, newName) => {
if (error) return tooltip('Failed to create file ' + newName + ' ' + error) if (error) return tooltip('Failed to create file ' + newName + ' ' + error)
const fileManager = self._deps.fileManager
const createFile = await fileManager.writeFile(newName, '')
if (!self.files.set(newName, '')) { if (!createFile) {
tooltip('Failed to create file ' + newName) tooltip('Failed to create file ' + newName)
} else { } else {
self._deps.fileManager.switchFile(newName) await fileManager.open(newName)
if (newName.includes('_test.sol')) { if (newName.includes('_test.sol')) {
self.events.trigger('newTestFileCreated', [newName]) self.events.trigger('newTestFileCreated', [newName])
} }

@ -23,12 +23,19 @@ const profile = {
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjk2IDM4NHE0MCAwIDY4IDI4dDI4IDY4djEyMTZxMCA0MC0yOCA2OHQtNjggMjhoLTk2MHEtNDAgMC02OC0yOHQtMjgtNjh2LTI4OGgtNTQ0cS00MCAwLTY4LTI4dC0yOC02OHYtNjcycTAtNDAgMjAtODh0NDgtNzZsNDA4LTQwOHEyOC0yOCA3Ni00OHQ4OC0yMGg0MTZxNDAgMCA2OCAyOHQyOCA2OHYzMjhxNjgtNDAgMTI4LTQwaDQxNnptLTU0NCAyMTNsLTI5OSAyOTloMjk5di0yOTl6bS02NDAtMzg0bC0yOTkgMjk5aDI5OXYtMjk5em0xOTYgNjQ3bDMxNi0zMTZ2LTQxNmgtMzg0djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djY0MGg1MTJ2LTI1NnEwLTQwIDIwLTg4dDQ4LTc2em05NTYgODA0di0xMTUyaC0zODR2NDE2cTAgNDAtMjggNjh0LTY4IDI4aC00MTZ2NjQwaDg5NnoiLz48L3N2Zz4=', icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjk2IDM4NHE0MCAwIDY4IDI4dDI4IDY4djEyMTZxMCA0MC0yOCA2OHQtNjggMjhoLTk2MHEtNDAgMC02OC0yOHQtMjgtNjh2LTI4OGgtNTQ0cS00MCAwLTY4LTI4dC0yOC02OHYtNjcycTAtNDAgMjAtODh0NDgtNzZsNDA4LTQwOHEyOC0yOCA3Ni00OHQ4OC0yMGg0MTZxNDAgMCA2OCAyOHQyOCA2OHYzMjhxNjgtNDAgMTI4LTQwaDQxNnptLTU0NCAyMTNsLTI5OSAyOTloMjk5di0yOTl6bS02NDAtMzg0bC0yOTkgMjk5aDI5OXYtMjk5em0xOTYgNjQ3bDMxNi0zMTZ2LTQxNmgtMzg0djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djY0MGg1MTJ2LTI1NnEwLTQwIDIwLTg4dDQ4LTc2em05NTYgODA0di0xMTUyaC0zODR2NDE2cTAgNDAtMjggNjh0LTY4IDI4aC00MTZ2NjQwaDg5NnoiLz48L3N2Zz4=',
permission: true, permission: true,
version: packageJson.version, version: packageJson.version,
methods: ['getFolder', 'getCurrentFile', 'getFile', 'setFile', 'switchFile'], methods: ['file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'rename', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile'],
kind: 'file-system' kind: 'file-system'
} }
const errorMsg = {
// File System profile ENOENT: 'No such file or directory',
// - methods: ['getFolder', 'getCurrentFile', 'getFile', 'setFile', 'switchFile'] EISDIR: 'Path is a directory',
ENOTDIR: 'Path is not on a directory',
EEXIST: 'File already exists',
EPERM: 'Permission denied'
}
const createError = (err) => {
return new Error(`${errorMsg[err.code]} ${err.message || ''}`)
}
class FileManager extends Plugin { class FileManager extends Plugin {
constructor (editor) { constructor (editor) {
@ -42,6 +49,202 @@ class FileManager extends Plugin {
this.init() this.init()
} }
/**
* Emit error if path doesn't exist
* @param {string} path path of the file/directory
* @param {string} message message to display if path doesn't exist.
*/
async _handleExists (path, message) {
const exists = await this.exists(path)
if (!exists) {
throw createError({ code: 'ENOENT', message })
}
}
/**
* Emit error if path is not a file
* @param {string} path path of the file/directory
* @param {string} message message to display if path is not a file.
*/
async _handleIsFile (path, message) {
const isFile = await this.isFile(path)
if (!isFile) {
throw createError({ code: 'EISDIR', message })
}
}
/**
* Emit error if path is not a directory
* @param {string} path path of the file/directory
* @param {string} message message to display if path is not a directory.
*/
async _handleIsDir (path, message) {
const isDir = await this.isDirectory(path)
if (!isDir) {
throw createError({ code: 'ENOTDIR', message })
}
}
/** The current opened file */
file () {
const file = this.currentFile()
if (!file) throw createError({ code: 'ENOENT', message: 'No file selected' })
return file
}
/**
* Verify if the path exists (directory or file)
* @param {string} path path of the directory or file
* @returns {boolean} true if the path exists
*/
exists (path) {
const provider = this.fileProviderOf(path)
const result = provider.exists(path, (err, result) => {
if (err) return false
return result
})
return result
}
/**
* Verify if the path provided is a file
* @param {string} path path of the directory or file
* @returns {boolean} true if path is a file.
*/
isFile (path) {
const provider = this.fileProviderOf(path)
const result = provider.isFile(path)
return result
}
/**
* Verify if the path provided is a directory
* @param {string} path path of the directory
* @returns {boolean} true if path is a directory.
*/
isDirectory (path) {
const provider = this.fileProviderOf(path)
const result = provider.isDirectory(path)
return result
}
/**
* Open the content of the file in the context (eg: Editor)
* @param {string} path path of the file
* @returns {void}
*/
async open (path) {
await this._handleExists(path, `Cannot open file ${path}`)
await this._handleIsFile(path, `Cannot open file ${path}`)
return this.openFile(path)
}
/**
* Set the content of a specific file
* @param {string} path path of the file
* @param {string} data content to write on the file
* @returns {void}
*/
async writeFile (path, data) {
if (await this.exists(path)) {
await this._handleIsFile(path, `Cannot write file ${path}`)
return await this.setFileContent(path, data)
} else {
return await this.setFileContent(path, data)
}
}
/**
* Return the content of a specific file
* @param {string} path path of the file
* @returns {string} content of the file
*/
async readFile (path) {
await this._handleExists(path, `Cannot read file ${path}`)
await this._handleIsFile(path, `Cannot read file ${path}`)
return this.getFileContent(path)
}
/**
* Upsert a file with the content of the source file
* @param {string} src path of the source file
* @param {string} dest path of the destrination file
* @returns {void}
*/
async copyFile (src, dest) {
await this._handleExists(src, `Cannot copy from ${src}`)
await this._handleIsFile(src, `Cannot copy from ${src}`)
await this._handleIsFile(dest, `Cannot paste content into ${dest}`)
const content = await this.readFile(src)
await this.writeFile(dest, content)
}
/**
* Change the path of a file/directory
* @param {string} oldPath current path of the file/directory
* @param {string} newPath new path of the file/directory
* @returns {void}
*/
async rename (oldPath, newPath) {
await this.__handleExists(oldPath, `Cannot rename ${oldPath}`)
const isFile = await this.isFile(oldPath)
this.fileRenamedEvent(oldPath, newPath, !isFile)
}
/**
* Create a directory
* @param {string} path path of the new directory
* @returns {void}
*/
async mkdir (path) {
if (await this.exists(path)) {
throw createError({ code: 'EEXIST', message: `Cannot create directory ${path}` })
}
const provider = this.fileProviderOf(path)
provider.createDir(path)
}
/**
* Get the list of files in the directory
* @param {string} path path of the directory
* @returns {string[]} list of the file/directory name in this directory
*/
async readdir (path) {
await this._handleExists(path)
await this._handleIsDir(path)
return new Promise((resolve, reject) => {
const provider = this.fileProviderOf(path)
provider.resolveDirectory(path, (error, filesProvider) => {
if (error) reject(error)
resolve(filesProvider)
})
})
}
/**
* Removes a file or directory recursively
* @param {string} path path of the directory/file to remove
* @returns {void}
*/
async remove (path) {
await this._handleExists(path, `Cannot remove file or directory ${path}`)
const provider = this.fileProviderOf(path)
return await provider.remove(path)
}
init () { init () {
this._deps = { this._deps = {
config: this._components.registry.get('config').api, config: this._components.registry.get('config').api,
@ -56,6 +259,11 @@ class FileManager extends Plugin {
this._deps.localhostExplorer.event.register('fileRemoved', (path) => { this.fileRemovedEvent(path) }) this._deps.localhostExplorer.event.register('fileRemoved', (path) => { this.fileRemovedEvent(path) })
this._deps.localhostExplorer.event.register('errored', (event) => { this.removeTabsOf(this._deps.localhostExplorer) }) this._deps.localhostExplorer.event.register('errored', (event) => { this.removeTabsOf(this._deps.localhostExplorer) })
this._deps.localhostExplorer.event.register('closed', (event) => { this.removeTabsOf(this._deps.localhostExplorer) }) this._deps.localhostExplorer.event.register('closed', (event) => { this.removeTabsOf(this._deps.localhostExplorer) })
this.getCurrentFile = this.file
this.getFile = this.readFile
this.getFolder = this.readdir
this.setFile = this.writeFile
this.switchFile = this.open
} }
fileChangedEvent (path) { fileChangedEvent (path) {
@ -71,7 +279,7 @@ class FileManager extends Plugin {
delete this.openedFiles[oldName] delete this.openedFiles[oldName]
this.openedFiles[newName] = newName this.openedFiles[newName] = newName
} }
this.switchFile(newName) this.openFile(newName)
} else { } else {
var newFocus var newFocus
for (var k in this.openedFiles) { for (var k in this.openedFiles) {
@ -85,7 +293,7 @@ class FileManager extends Plugin {
} }
} }
if (newFocus) { if (newFocus) {
this.switchFile(newFocus) this.openFile(newFocus)
} }
} }
// TODO: Only keep `this.emit` (issue#2210) // TODO: Only keep `this.emit` (issue#2210)
@ -129,15 +337,10 @@ class FileManager extends Plugin {
return path ? path[1] : null return path ? path[1] : null
} }
getCurrentFile () { getFileContent (path) {
const path = this.currentFile()
if (!path) throw new Error('No file selected')
return path
}
getFile (path) {
const provider = this.fileProviderOf(path) const provider = this.fileProviderOf(path)
if (!provider) throw new Error(`${path} not available`)
if (!provider) throw createError({ code: 'ENOENT', message: `${path} not available` })
// TODO: change provider to Promise // TODO: change provider to Promise
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (this.currentFile() === path) return resolve(this.editor.currentContent()) if (this.currentFile() === path) return resolve(this.editor.currentContent())
@ -148,11 +351,10 @@ class FileManager extends Plugin {
}) })
} }
async setFile (path, content) { async setFileContent (path, content) {
if (this.currentRequest) { if (this.currentRequest) {
const canCall = await this.askUserPermission('setFile', '') const canCall = await this.askUserPermission('writeFile', '')
if (canCall) { if (canCall) {
this._setFileInternal(path, content)
// inform the user about modification after permission is granted and even if permission was saved before // inform the user about modification after permission is granted and even if permission was saved before
toaster(yo` toaster(yo`
<div> <div>
@ -167,12 +369,12 @@ class FileManager extends Plugin {
`, '', { time: 3000 }) `, '', { time: 3000 })
} }
} }
this._setFileInternal(path, content) return await this._setFileInternal(path, content)
} }
_setFileInternal (path, content) { _setFileInternal (path, content) {
const provider = this.fileProviderOf(path) const provider = this.fileProviderOf(path)
if (!provider) throw new Error(`${path} not availble`) if (!provider) throw createError({ code: 'ENOENT', message: `${path} not available` })
// TODO : Add permission // TODO : Add permission
// TODO : Change Provider to Promise // TODO : Change Provider to Promise
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -189,11 +391,10 @@ class FileManager extends Plugin {
if (fileProvider) { if (fileProvider) {
helper.createNonClashingNameWithPrefix(path, fileProvider, '', (error, copyName) => { helper.createNonClashingNameWithPrefix(path, fileProvider, '', (error, copyName) => {
if (error) { if (error) {
console.log('createNonClashingNameWithPrefix', error)
copyName = path + '.' + this.currentRequest.from copyName = path + '.' + this.currentRequest.from
} }
this._setFileInternal(copyName, content) this._setFileInternal(copyName, content)
this.switchFile(copyName) this.openFile(copyName)
}) })
} }
} }
@ -216,7 +417,7 @@ class FileManager extends Plugin {
// TODO: Only keep `this.emit` (issue#2210) // TODO: Only keep `this.emit` (issue#2210)
this.emit('fileRemoved', path) this.emit('fileRemoved', path)
this.events.emit('fileRemoved', path) this.events.emit('fileRemoved', path)
this.switchFile() this.openFile()
} }
unselectCurrentFile () { unselectCurrentFile () {
@ -227,16 +428,19 @@ class FileManager extends Plugin {
this.events.emit('noFileSelected') this.events.emit('noFileSelected')
} }
switchFile (file) { openFile (file) {
const _switchFile = (file) => { const _openFile = (file) => {
this.saveCurrentFile() this.saveCurrentFile()
const provider = this.fileProviderOf(file)
if (!provider) return console.error(`no provider for ${file}`)
file = provider.getPathFromUrl(file) || file // in case an external URL is given as input, we resolve it to the right internal path
this._deps.config.set('currentFile', file) this._deps.config.set('currentFile', file)
this.openedFiles[file] = file this.openedFiles[file] = file
this.fileProviderOf(file).get(file, (error, content) => { provider.get(file, (error, content) => {
if (error) { if (error) {
console.log(error) console.log(error)
} else { } else {
if (this.fileProviderOf(file).isReadOnly(file)) { if (provider.isReadOnly(file)) {
this.editor.openReadOnly(file, content) this.editor.openReadOnly(file, content)
} else { } else {
this.editor.open(file, content) this.editor.open(file, content)
@ -247,14 +451,14 @@ class FileManager extends Plugin {
} }
}) })
} }
if (file) return _switchFile(file) if (file) return _openFile(file)
else { else {
var browserProvider = this._deps.filesProviders['browser'] var browserProvider = this._deps.filesProviders['browser']
browserProvider.resolveDirectory('browser', (error, filesProvider) => { browserProvider.resolveDirectory('browser', (error, filesProvider) => {
if (error) console.error(error) if (error) console.error(error)
var fileList = Object.keys(filesProvider) var fileList = Object.keys(filesProvider)
if (fileList.length) { if (fileList.length) {
_switchFile(browserProvider.type + '/' + fileList[0]) _openFile(browserProvider.type + '/' + fileList[0])
} else { } else {
// TODO: Only keep `this.emit` (issue#2210) // TODO: Only keep `this.emit` (issue#2210)
this.emit('noFileSelected') this.emit('noFileSelected')
@ -264,18 +468,6 @@ class FileManager extends Plugin {
} }
} }
getFolder (path) {
// TODO : Change provider with promise
return new Promise((resolve, reject) => {
const provider = this.fileProviderOf(path)
if (!provider) return reject(`provider for path ${path} not found`)
provider.resolveDirectory(path, (error, filesProvider) => {
if (error) reject(error)
resolve(filesProvider)
})
})
}
getProvider (name) { getProvider (name) {
return this._deps.filesProviders[name] return this._deps.filesProviders[name]
} }

@ -66,12 +66,12 @@ class FileProvider {
exists (path, cb) { exists (path, cb) {
// todo check the type (directory/file) as well #2386 // todo check the type (directory/file) as well #2386
// currently it is not possible to have a file and folder with same path // currently it is not possible to have a file and folder with same path
cb(null, this._exists(path)) return cb(null, this._exists(path))
} }
_exists (path) { _exists (path) {
var unprefixedpath = this.removePrefix(path) var unprefixedpath = this.removePrefix(path)
return window.remixFileSystem.existsSync(unprefixedpath) return path === this.type ? true : window.remixFileSystem.existsSync(unprefixedpath)
} }
init (cb) { init (cb) {
@ -94,19 +94,8 @@ class FileProvider {
var unprefixedpath = this.removePrefix(path) var unprefixedpath = this.removePrefix(path)
var exists = window.remixFileSystem.existsSync(unprefixedpath) var exists = window.remixFileSystem.existsSync(unprefixedpath)
if (exists && window.remixFileSystem.readFileSync(unprefixedpath, 'utf8') === content) return true if (exists && window.remixFileSystem.readFileSync(unprefixedpath, 'utf8') === content) return true
if (!exists && unprefixedpath.indexOf('/') !== -1) { if (!exists && unprefixedpath.indexOf('/') !== -1) {
const paths = unprefixedpath.split('/') this.createDir(path)
paths.pop() // last element should the filename
if (paths.length && paths[0] === '') paths.shift()
let currentCheck = ''
paths.forEach((value) => {
currentCheck = currentCheck + '/' + value
if (!window.remixFileSystem.existsSync(currentCheck)) {
window.remixFileSystem.mkdirSync(currentCheck)
this.event.trigger('folderAdded', [this._normalizePath(currentCheck)])
}
})
} }
try { try {
window.remixFileSystem.writeFileSync(unprefixedpath, content) window.remixFileSystem.writeFileSync(unprefixedpath, content)
@ -123,6 +112,22 @@ class FileProvider {
return true return true
} }
createDir (path, cb) {
var unprefixedpath = this.removePrefix(path)
const paths = unprefixedpath.split('/')
paths.pop() // last element should the filename
if (paths.length && paths[0] === '') paths.shift()
let currentCheck = ''
paths.forEach((value) => {
currentCheck = currentCheck + '/' + value
if (!window.remixFileSystem.existsSync(currentCheck)) {
window.remixFileSystem.mkdirSync(currentCheck)
this.event.trigger('folderAdded', [this._normalizePath(currentCheck)])
}
})
if (cb) cb()
}
// this will not add a folder as readonly but keep the original url to be able to restore it later // this will not add a folder as readonly but keep the original url to be able to restore it later
addExternal (path, content, url) { addExternal (path, content, url) {
if (url) this.addNormalizedName(path, url) if (url) this.addNormalizedName(path, url)
@ -134,7 +139,14 @@ class FileProvider {
} }
isDirectory (path) { isDirectory (path) {
return window.remixFileSystem.statSync(path).isDirectory() const unprefixedpath = this.removePrefix(path)
return path === this.type ? true : window.remixFileSystem.statSync(unprefixedpath).isDirectory()
}
isFile (path) {
path = this.removePrefix(path)
return window.remixFileSystem.statSync(path).isFile()
} }
/** /**
@ -147,9 +159,7 @@ class FileProvider {
const stat = window.remixFileSystem.statSync(path) const stat = window.remixFileSystem.statSync(path)
try { try {
if (!stat.isDirectory()) { if (!stat.isDirectory()) {
window.remixFileSystem.unlinkSync(path, console.log) return this.removeFile(path)
this.event.trigger('fileRemoved', [this._normalizePath(path)])
return true
} else { } else {
const items = window.remixFileSystem.readdirSync(path) const items = window.remixFileSystem.readdirSync(path)
if (items.length !== 0) { if (items.length !== 0) {
@ -158,8 +168,7 @@ class FileProvider {
if (window.remixFileSystem.statSync(curPath).isDirectory()) { // delete folder if (window.remixFileSystem.statSync(curPath).isDirectory()) { // delete folder
this.remove(curPath) this.remove(curPath)
} else { // delete file } else { // delete file
window.remixFileSystem.unlinkSync(curPath, console.log) this.removeFile(curPath)
this.event.trigger('fileRemoved', [this._normalizePath(path)])
} }
}) })
if (window.remixFileSystem.readdirSync(path).length === 0) window.remixFileSystem.rmdirSync(path, console.log) if (window.remixFileSystem.readdirSync(path).length === 0) window.remixFileSystem.rmdirSync(path, console.log)
@ -176,6 +185,15 @@ class FileProvider {
return true return true
} }
removeFile (path) {
path = this.removePrefix(path)
if (window.remixFileSystem.existsSync(path) && !window.remixFileSystem.statSync(path).isDirectory()) {
window.remixFileSystem.unlinkSync(path, console.log)
this.event.trigger('fileRemoved', [this._normalizePath(path)])
return true
} else return false
}
rename (oldPath, newPath, isFolder) { rename (oldPath, newPath, isFolder) {
var unprefixedoldPath = this.removePrefix(oldPath) var unprefixedoldPath = this.removePrefix(oldPath)
var unprefixednewPath = this.removePrefix(newPath) var unprefixednewPath = this.removePrefix(newPath)

@ -81,11 +81,20 @@ module.exports = class RemixDProvider {
// //
// this.remixd.exists(path, (error, isValid) => {}) // this.remixd.exists(path, (error, isValid) => {})
exists (path, cb) { async exists (path, cb) {
var unprefixedpath = this.removePrefix(path) const unprefixedpath = this.removePrefix(path)
this._remixd.call('sharedfolder', 'exists', {path: unprefixedpath}, (error, result) => { const callId = await this._remixd.call('sharedfolder', 'exists', {path: unprefixedpath})
cb(error, result) const result = await this._remixd.receiveResponse(callId)
})
return cb(null, result)
}
getNormalizedName (path) {
return path
}
getPathFromUrl (path) {
return path
} }
get (path, cb) { get (path, cb) {
@ -117,9 +126,9 @@ module.exports = class RemixDProvider {
return this._readOnlyMode || this._readOnlyFiles[path] === 1 return this._readOnlyMode || this._readOnlyFiles[path] === 1
} }
remove (path) { async remove (path) {
var unprefixedpath = this.removePrefix(path) var unprefixedpath = this.removePrefix(path)
this._remixd.call('sharedfolder', 'remove', {path: unprefixedpath}, (error, result) => { const callId = await this._remixd.call('sharedfolder', 'remove', {path: unprefixedpath}, (error, result) => {
if (error) console.log(error) if (error) console.log(error)
var path = this.type + '/' + unprefixedpath var path = this.type + '/' + unprefixedpath
delete this.filesContent[path] delete this.filesContent[path]
@ -127,6 +136,8 @@ module.exports = class RemixDProvider {
this.event.trigger('fileRemoved', [path]) this.event.trigger('fileRemoved', [path])
}) })
}) })
return await this._remixd.receiveResponse(callId)
} }
rename (oldPath, newPath, isFolder) { rename (oldPath, newPath, isFolder) {
@ -167,6 +178,20 @@ module.exports = class RemixDProvider {
path = self.removePrefix(path) path = self.removePrefix(path)
self.remixd.dir(path, callback) self.remixd.dir(path, callback)
} }
async isDirectory (path) {
const unprefixedpath = this.removePrefix(path)
const callId = await this._remixd.call('sharedfolder', 'isDirectory', {path: unprefixedpath})
return await this._remixd.receiveResponse(callId)
}
async isFile (path) {
const unprefixedpath = this.removePrefix(path)
const callId = await this._remixd.call('sharedfolder', 'isFile', {path: unprefixedpath})
return await this._remixd.receiveResponse(callId)
}
} }
function remixapi (remixd, self) { function remixapi (remixd, self) {

@ -61,7 +61,7 @@ export class MainView {
self._view.mainPanel.style.display = 'none' self._view.mainPanel.style.display = 'none'
self._components.contextView.show() self._components.contextView.show()
}) })
self.tabProxy.event.on('switchFile', (file) => { self.tabProxy.event.on('openFile', (file) => {
self._view.editor.style.display = 'block' self._view.editor.style.display = 'block'
self._view.mainPanel.style.display = 'none' self._view.mainPanel.style.display = 'none'
self._components.contextView.show() self._components.contextView.show()

@ -34,8 +34,8 @@ export class TabProxy {
return return
} }
this.addTab(file, '', () => { this.addTab(file, '', () => {
this.fileManager.switchFile(file) this.fileManager.open(file)
this.event.emit('switchFile', file) this.event.emit('openFile', file)
}, },
() => { () => {
this.fileManager.closeFile(file) this.fileManager.closeFile(file)
@ -47,8 +47,8 @@ export class TabProxy {
if (isFolder) return if (isFolder) return
// should change the tab title too // should change the tab title too
this.addTab(newName, '', () => { this.addTab(newName, '', () => {
this.fileManager.switchFile(newName) this.fileManager.open(newName)
this.event.emit('switchFile', newName) this.event.emit('openFile', newName)
}, },
() => { () => {
this.fileManager.closeFile(newName) this.fileManager.closeFile(newName)

@ -141,7 +141,7 @@ class CompilerContainer {
// Load solc compiler version according to pragma in contract file // Load solc compiler version according to pragma in contract file
_setCompilerVersionFromPragma (filename) { _setCompilerVersionFromPragma (filename) {
if (!this.data.allversions) return if (!this.data.allversions) return
this.compileTabLogic.fileManager.getFile(filename).then(data => { this.compileTabLogic.fileManager.readFile(filename).then(data => {
const pragmaArr = data.match(/(pragma solidity (.+?);)/g) const pragmaArr = data.match(/(pragma solidity (.+?);)/g)
if (pragmaArr && pragmaArr.length === 1) { if (pragmaArr && pragmaArr.length === 1) {
const pragmaStr = pragmaArr[0].replace('pragma solidity', '').trim() const pragmaStr = pragmaArr[0].replace('pragma solidity', '').trim()

@ -319,7 +319,7 @@ class Recorder {
helper.createNonClashingName(newFile, fileProvider, (error, newFile) => { helper.createNonClashingName(newFile, fileProvider, (error, newFile) => {
if (error) return cb('Failed to create file. ' + newFile + ' ' + error) if (error) return cb('Failed to create file. ' + newFile + ' ' + error)
if (!fileProvider.set(newFile, txJSON)) return cb('Failed to create file ' + newFile) if (!fileProvider.set(newFile, txJSON)) return cb('Failed to create file ' + newFile)
this.fileManager.switchFile(newFile) this.fileManager.open(newFile)
}) })
}) })
} }

@ -178,7 +178,7 @@ class SettingsUI {
selectExEnv.addEventListener('change', (event) => { selectExEnv.addEventListener('change', (event) => {
let context = selectExEnv.options[selectExEnv.selectedIndex].value let context = selectExEnv.options[selectExEnv.selectedIndex].value
this.blockchain.changeExecutionContext(context, () => { this.blockchain.changeExecutionContext(context, () => {
modalDialogCustom.prompt('External node request', this.web3ProviderDialogBody(), 'http://localhost:8545', (target) => { modalDialogCustom.prompt('External node request', this.web3ProviderDialogBody(), 'http://127.0.0.1:8545', (target) => {
this.blockchain.setProviderFromEndpoint(target, context, (alertMsg) => { this.blockchain.setProviderFromEndpoint(target, context, (alertMsg) => {
if (alertMsg) addTooltip(alertMsg) if (alertMsg) addTooltip(alertMsg)
this.setFinalContext() this.setFinalContext()

@ -108,9 +108,9 @@ staticAnalysisView.prototype.run = function () {
if (!this.view) { if (!this.view) {
return return
} }
const highlightLocation = (location, fileName) => { const highlightLocation = async (location, fileName) => {
// await this.analysisModule.call('editor', 'highlight', location, fileName) @todo(#2834) use this after fixing the issue await this.analysisModule.call('editor', 'discardHighlight')
this.sourceHighlighter.currentSourceLocationFromfileName(location, fileName) await this.analysisModule.call('editor', 'highlight', location, fileName)
} }
const selected = this.selectedModules() const selected = this.selectedModules()
const warningContainer = $('#staticanalysisresult') const warningContainer = $('#staticanalysisresult')

@ -289,7 +289,7 @@ module.exports = class TestTab extends ViewPlugin {
} }
async testFromPath (path) { async testFromPath (path) {
const fileContent = await this.fileManager.getFile(path) const fileContent = await this.fileManager.readFile(path)
return this.testFromSource(fileContent, path) return this.testFromSource(fileContent, path)
} }
@ -323,7 +323,7 @@ module.exports = class TestTab extends ViewPlugin {
return return
} }
this.resultStatistics.hidden = false this.resultStatistics.hidden = false
this.fileManager.getFile(testFilePath).then((content) => { this.fileManager.readFile(testFilePath).then((content) => {
const runningTest = {} const runningTest = {}
runningTest[testFilePath] = { content } runningTest[testFilePath] = { content }
const {currentVersion, evmVersion, optimize} = this.compileTab.getCurrentCompilerConfig() const {currentVersion, evmVersion, optimize} = this.compileTab.getCurrentCompilerConfig()

@ -19,7 +19,7 @@ class TestTabLogic {
// This should be updated to pass complete path, if test file comes from different directory/path // This should be updated to pass complete path, if test file comes from different directory/path
const fileNameToImport = splittedFileName[splittedFileName.length - 1] const fileNameToImport = splittedFileName[splittedFileName.length - 1]
if (!fileProvider.set(newFile, this.generateTestContractSample(fileNameToImport))) return modalDialogCustom.alert('Failed to create test file ' + newFile) if (!fileProvider.set(newFile, this.generateTestContractSample(fileNameToImport))) return modalDialogCustom.alert('Failed to create test file ' + newFile)
this.fileManager.switchFile(newFile) this.fileManager.open(newFile)
}) })
} }
@ -31,7 +31,7 @@ class TestTabLogic {
const tests = [] const tests = []
let files let files
try { try {
files = await this.fileManager.getFolder(path) files = await this.fileManager.readdir(path)
} catch (e) { } catch (e) {
cb(e.message) cb(e.message)
} }

@ -41,7 +41,7 @@ Renderer.prototype._errorClick = function (errFile, errLine, errCol) {
if (provider) { if (provider) {
provider.exists(errFile, (error, exist) => { provider.exists(errFile, (error, exist) => {
if (error) return console.log(error) if (error) return console.log(error)
self._deps.fileManager.switchFile(errFile) self._deps.fileManager.open(errFile)
editor.gotoLine(errLine, errCol) editor.gotoLine(errLine, errCol)
}) })
} }

@ -151,7 +151,7 @@ class CmdInterpreterAPI {
toolTip(`Unable to load ${url}: ${err}`) toolTip(`Unable to load ${url}: ${err}`)
if (cb) cb(err) if (cb) cb(err)
} else { } else {
self._deps.fileManager.setFile(type + '/' + cleanUrl, content) self._deps.fileManager.writeFile(type + '/' + cleanUrl, content)
try { try {
content = JSON.parse(content) content = JSON.parse(content)
async.eachOfSeries(content.sources, (value, file, callbackSource) => { async.eachOfSeries(content.sources, (value, file, callbackSource) => {
@ -164,7 +164,7 @@ class CmdInterpreterAPI {
return callbackSource(`Cannot retrieve the content of ${url}: ${error}`) return callbackSource(`Cannot retrieve the content of ${url}: ${error}`)
} else { } else {
try { try {
await self._deps.fileManager.setFile(type + '/' + cleanUrl, content) await self._deps.fileManager.writeFile(type + '/' + cleanUrl, content)
callbackSource() callbackSource()
} catch (e) { } catch (e) {
callbackSource(e.message) callbackSource(e.message)

@ -11,6 +11,7 @@ class Remixd {
this.callid = 0 this.callid = 0
this.socket = null this.socket = null
this.connected = false this.connected = false
this.receiveResponse()
} }
online () { online () {
@ -74,6 +75,17 @@ class Remixd {
}) })
} }
async receiveResponse (requestId) {
return new Promise((resolve, reject) => {
this.event.register('replied', (data) => {
if (data.id === requestId) {
if (data.error) reject(data.error)
else resolve(data.result)
}
})
})
}
errored (event) { errored (event) {
function remixdDialog () { function remixdDialog () {
return yo`<div>Connection to Remixd closed. Localhost connection not available anymore.</div>` return yo`<div>Connection to Remixd closed. Localhost connection not available anymore.</div>`
@ -87,16 +99,24 @@ class Remixd {
} }
call (service, fn, args, callback) { call (service, fn, args, callback) {
return new Promise((resolve, reject) => {
this.ensureSocket((error) => { this.ensureSocket((error) => {
if (error) return callback(error) if (error) {
callback && typeof callback === 'function' && callback(error)
reject(error)
return
}
if (this.socket && this.socket.readyState === this.socket.OPEN) { if (this.socket && this.socket.readyState === this.socket.OPEN) {
var data = this.format(service, fn, args) var data = this.format(service, fn, args)
this.callbacks[data.id] = callback this.callbacks[data.id] = callback
this.socket.send(JSON.stringify(data)) this.socket.send(JSON.stringify(data))
resolve(data.id)
} else { } else {
callback('Socket not ready. state:' + this.socket.readyState) callback && typeof callback === 'function' && callback('Socket not ready. state:' + this.socket.readyState)
reject('Socket not ready. state:' + this.socket.readyState)
} }
}) })
})
} }
ensureSocket (cb) { ensureSocket (cb) {

@ -0,0 +1,26 @@
const EventEmitter = require('events')
class OpenFile extends EventEmitter {
command (name) {
this.api.perform((done) => {
openFile(this.api, name, () => {
done()
this.emit('complete')
})
})
return this
}
}
// click on fileExplorer can toggle it. We go through settings to be sure FE is open
function openFile (browser, name, done) {
browser.clickLaunchIcon('settings').clickLaunchIcon('fileExplorers')
.waitForElementVisible('li[key="' + name + '"]')
.click('li[key="' + name + '"]')
.pause(2000)
.perform(() => {
done()
})
}
module.exports = OpenFile

@ -66,7 +66,7 @@ module.exports = {
'Switch Tabs using tabs icon': function (browser) { 'Switch Tabs using tabs icon': function (browser) {
browser browser
.waitForElementVisible('div[data-id="filePanelFileExplorerTree"]') .waitForElementVisible('div[data-id="filePanelFileExplorerTree"]')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.assert.containsText('div[title="browser/3_Ballot.sol"]', '3_Ballot.sol') .assert.containsText('div[title="browser/3_Ballot.sol"]', '3_Ballot.sol')
.click('span[class^=dropdownCaret]') .click('span[class^=dropdownCaret]')
.click('#homeItem') .click('#homeItem')

@ -10,7 +10,7 @@ module.exports = {
'Should zoom in editor': function (browser) { 'Should zoom in editor': function (browser) {
browser.waitForElementVisible('div[data-id="mainPanelPluginsContainer"]') browser.waitForElementVisible('div[data-id="mainPanelPluginsContainer"]')
.switchFile('browser/1_Storage.sol') .openFile('browser/1_Storage.sol')
.waitForElementVisible('*[data-id="editorInput"]') .waitForElementVisible('*[data-id="editorInput"]')
.checkElementStyle('*[data-id="editorInput"]', 'font-size', '12px') .checkElementStyle('*[data-id="editorInput"]', 'font-size', '12px')
.click('*[data-id="tabProxyZoomIn"]') .click('*[data-id="tabProxyZoomIn"]')
@ -74,7 +74,7 @@ module.exports = {
'Should highlight source code': function (browser) { 'Should highlight source code': function (browser) {
browser.addFile('sourcehighlight.js', sourcehighlightScript) browser.addFile('sourcehighlight.js', sourcehighlightScript)
.switchFile('browser/sourcehighlight.js') .openFile('browser/sourcehighlight.js')
.executeScript('remix.exeCurrent()') .executeScript('remix.exeCurrent()')
.editorScroll('down', 60) .editorScroll('down', 60)
.waitForElementPresent('.highlightLine32') .waitForElementPresent('.highlightLine32')
@ -87,10 +87,9 @@ module.exports = {
'Should remove 1 highlight from source code': function (browser) { 'Should remove 1 highlight from source code': function (browser) {
browser.addFile('removeSourcehighlightScript.js', removeSourcehighlightScript) browser.addFile('removeSourcehighlightScript.js', removeSourcehighlightScript)
.switchFile('browser/removeSourcehighlightScript.js') .openFile('browser/removeSourcehighlightScript.js')
.executeScript('remix.exeCurrent()') .executeScript('remix.exeCurrent()')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.editorScroll('down', 60)
.waitForElementNotPresent('.highlightLine32') .waitForElementNotPresent('.highlightLine32')
.checkElementStyle('.highlightLine40', 'background-color', 'rgb(8, 108, 181)') .checkElementStyle('.highlightLine40', 'background-color', 'rgb(8, 108, 181)')
.checkElementStyle('.highlightLine50', 'background-color', 'rgb(8, 108, 181)') .checkElementStyle('.highlightLine50', 'background-color', 'rgb(8, 108, 181)')
@ -98,10 +97,9 @@ module.exports = {
'Should remove all highlights from source code': function (browser) { 'Should remove all highlights from source code': function (browser) {
browser.addFile('removeAllSourcehighlightScript.js', removeAllSourcehighlightScript) browser.addFile('removeAllSourcehighlightScript.js', removeAllSourcehighlightScript)
.switchFile('browser/removeAllSourcehighlightScript.js') .openFile('browser/removeAllSourcehighlightScript.js')
.executeScript('remix.exeCurrent()') .executeScript('remix.exeCurrent()')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.editorScroll('down', 60)
.waitForElementNotPresent('.highlightLine32') .waitForElementNotPresent('.highlightLine32')
.waitForElementNotPresent('.highlightLine40') .waitForElementNotPresent('.highlightLine40')
.waitForElementNotPresent('.highlightLine50') .waitForElementNotPresent('.highlightLine50')

@ -31,14 +31,14 @@ module.exports = {
.waitForElementVisible('*[data-id="settingsTabGenerateContractMetadata"]', 5000) .waitForElementVisible('*[data-id="settingsTabGenerateContractMetadata"]', 5000)
.click('*[data-id="settingsTabGenerateContractMetadata"]') .click('*[data-id="settingsTabGenerateContractMetadata"]')
.click('*[data-id="verticalIconsFileExplorerIcons"]') .click('*[data-id="verticalIconsFileExplorerIcons"]')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.click('*[data-id="verticalIconsKindsolidity"]') .click('*[data-id="verticalIconsKindsolidity"]')
.pause(2000) .pause(2000)
.click('*[data-id="compilerContainerCompileBtn"]') .click('*[data-id="compilerContainerCompileBtn"]')
.pause(3000) .pause(3000)
.click('*[data-id="verticalIconsKindfileExplorers"]') .click('*[data-id="verticalIconsKindfileExplorers"]')
.switchFile('browser/artifacts') .openFile('browser/artifacts')
.switchFile('browser/artifacts/Ballot.json') .openFile('browser/artifacts/Ballot.json')
}, },
'Should add new github access token': function (browser) { 'Should add new github access token': function (browser) {

@ -44,9 +44,9 @@ module.exports = {
browser browser
.modalFooterCancelClick() .modalFooterCancelClick()
.executeScript(`remix.loadgist('${gistid}')`) .executeScript(`remix.loadgist('${gistid}')`)
.perform((done) => { if (runtimeBrowser === 'chrome') { browser.switchFile('browser/gists') } done() }) .perform((done) => { if (runtimeBrowser === 'chrome') { browser.openFile('browser/gists') } done() })
.switchFile(`browser/gists/${gistid}`) .openFile(`browser/gists/${gistid}`)
.switchFile(`browser/gists/${gistid}/1_Storage.sol`) .openFile(`browser/gists/${gistid}/1_Storage.sol`)
.perform(done) .perform(done)
} }
}) })
@ -86,8 +86,8 @@ module.exports = {
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', testData.validGistId) .setValue('*[data-id="modalDialogCustomPromptText"]', testData.validGistId)
.modalFooterOKClick() .modalFooterOKClick()
.switchFile(`browser/gists/${testData.validGistId}`) .openFile(`browser/gists/${testData.validGistId}`)
.switchFile(`browser/gists/${testData.validGistId}/ApplicationRegistry`) .openFile(`browser/gists/${testData.validGistId}/ApplicationRegistry`)
.waitForElementVisible(`div[title='browser/gists/${testData.validGistId}/ApplicationRegistry']`) .waitForElementVisible(`div[title='browser/gists/${testData.validGistId}/ApplicationRegistry']`)
.assert.containsText(`div[title='browser/gists/${testData.validGistId}/ApplicationRegistry'] > span`, 'ApplicationRegistry') .assert.containsText(`div[title='browser/gists/${testData.validGistId}/ApplicationRegistry'] > span`, 'ApplicationRegistry')
.end() .end()

@ -59,7 +59,7 @@ module.exports = {
function checkDeployShouldFail (browser, callback) { function checkDeployShouldFail (browser, callback) {
let config let config
browser.switchFile('browser/artifacts').switchFile('browser/artifacts/test.json') browser.openFile('browser/artifacts').openFile('browser/artifacts/test.json')
.getEditorValue((content) => { .getEditorValue((content) => {
config = JSON.parse(content) config = JSON.parse(content)
config.deploy['VM:-'].autoDeployLib = false config.deploy['VM:-'].autoDeployLib = false
@ -67,7 +67,7 @@ function checkDeployShouldFail (browser, callback) {
.perform(() => { .perform(() => {
browser.setEditorValue(JSON.stringify(config)) browser.setEditorValue(JSON.stringify(config))
}) })
.switchFile('browser/Untitled5.sol') .openFile('browser/Untitled5.sol')
.selectContract('test') // deploy lib .selectContract('test') // deploy lib
.createContract('') .createContract('')
.assert.containsText('div[class^="terminal"]', '<address> is not a valid address') .assert.containsText('div[class^="terminal"]', '<address> is not a valid address')
@ -77,7 +77,7 @@ function checkDeployShouldFail (browser, callback) {
function checkDeployShouldSucceed (browser, address, callback) { function checkDeployShouldSucceed (browser, address, callback) {
let addressRef let addressRef
let config let config
browser.switchFile('browser/artifacts').switchFile('browser/artifacts/test.json') browser.openFile('browser/artifacts').openFile('browser/artifacts/test.json')
.getEditorValue((content) => { .getEditorValue((content) => {
config = JSON.parse(content) config = JSON.parse(content)
config.deploy['VM:-'].autoDeployLib = false config.deploy['VM:-'].autoDeployLib = false
@ -86,7 +86,7 @@ function checkDeployShouldSucceed (browser, address, callback) {
.perform(() => { .perform(() => {
browser.setEditorValue(JSON.stringify(config)) browser.setEditorValue(JSON.stringify(config))
}) })
.switchFile('browser/Untitled5.sol') .openFile('browser/Untitled5.sol')
.selectContract('test') // deploy lib .selectContract('test') // deploy lib
.createContract('') .createContract('')
.getAddressAtPosition(1, (address) => { .getAddressAtPosition(1, (address) => {

@ -66,7 +66,7 @@ module.exports = {
.assert.containsText('*[data-id="pluginManagerSettingsPermissionForm"]', 'No Permission requested yet') .assert.containsText('*[data-id="pluginManagerSettingsPermissionForm"]', 'No Permission requested yet')
.modalFooterOKClick() .modalFooterOKClick()
.click('*[data-id="verticalIconsFileExplorerIcons"]') .click('*[data-id="verticalIconsFileExplorerIcons"]')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.click('*[plugin="ZoKrates"]') .click('*[plugin="ZoKrates"]')
.pause(5000) .pause(5000)
.frame(0) .frame(0)

@ -13,7 +13,7 @@ module.exports = {
browser browser
.waitForElementVisible('#icon-panel', 10000) .waitForElementVisible('#icon-panel', 10000)
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.verifyContracts(['Ballot']) .verifyContracts(['Ballot'])
.click('#publishOnIpfs') .click('#publishOnIpfs')
.getModalBody((value, done) => { .getModalBody((value, done) => {
@ -37,7 +37,7 @@ module.exports = {
browser browser
.waitForElementVisible('#icon-panel') .waitForElementVisible('#icon-panel')
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/1_Storage.sol') .openFile('browser/1_Storage.sol')
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.waitForElementVisible('*[data-id="contractDropdownIpfsCheckbox"]') .waitForElementVisible('*[data-id="contractDropdownIpfsCheckbox"]')
.click('*[data-id="contractDropdownIpfsCheckbox"]') .click('*[data-id="contractDropdownIpfsCheckbox"]')
@ -49,7 +49,7 @@ module.exports = {
'Should remember choice after page refresh': function (browser) { 'Should remember choice after page refresh': function (browser) {
browser browser
.refresh() .refresh()
.switchFile('browser/1_Storage.sol') .openFile('browser/1_Storage.sol')
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.waitForElementVisible('*[data-id="contractDropdownIpfsCheckbox"]') .waitForElementVisible('*[data-id="contractDropdownIpfsCheckbox"]')
.verify.elementPresent('*[data-id="contractDropdownIpfsCheckbox"]:checked') .verify.elementPresent('*[data-id="contractDropdownIpfsCheckbox"]:checked')

@ -115,6 +115,8 @@ function runTests (browser, testData) {
}) })
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.waitForElementVisible('[data-path="localhost/folder1"]') .waitForElementVisible('[data-path="localhost/folder1"]')
.click('[data-path="localhost/folder1"]')
.click('[data-path="localhost/folder1"]') // click twice because remixd does not return nested folder details after update
.waitForElementVisible('[data-path="localhost/folder1/contract1.sol"]') .waitForElementVisible('[data-path="localhost/folder1/contract1.sol"]')
.waitForElementVisible('[data-path="localhost/folder1/renamed_contract_' + browserName + '.sol"]') // check if renamed file is preset .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 + '.sol"]') // check if renamed (old) file is not present

@ -90,7 +90,7 @@ module.exports = {
'Should deploy contract on Goerli Test Network using MetaMask': function (browser) { 'Should deploy contract on Goerli Test Network using MetaMask': function (browser) {
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option') browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/Greet.sol') .openFile('browser/Greet.sol')
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]') .waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]') .click('*[data-id="Deploy - transact (not payable)"]')
@ -141,7 +141,7 @@ module.exports = {
'Should deploy contract on Ethereum Main Network using MetaMask': function (browser) { 'Should deploy contract on Ethereum Main Network using MetaMask': function (browser) {
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option') browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/Greet.sol') .openFile('browser/Greet.sol')
.clickLaunchIcon('udapp') .clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]') .waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]') .click('*[data-id="Deploy - transact (not payable)"]')
@ -149,7 +149,6 @@ module.exports = {
.waitForElementPresent('*[data-id="modalDialogContainer"]') .waitForElementPresent('*[data-id="modalDialogContainer"]')
.assert.containsText('*[data-id="modalDialogModalBody"]', 'You are creating a transaction on the main network. Click confirm if you are sure to continue.') .assert.containsText('*[data-id="modalDialogModalBody"]', 'You are creating a transaction on the main network. Click confirm if you are sure to continue.')
.modalFooterCancelClick() .modalFooterCancelClick()
.end()
}, },
/* /*
@ -159,7 +158,6 @@ module.exports = {
* - Ropsten node for retrieving the trace and storage * - Ropsten node for retrieving the trace and storage
* *
*/ */
/* to readd when the source verify is stable
'Should debug Ropsten transaction with source highlighting using the source verifier service and MetaMask': function (browser) { 'Should debug Ropsten transaction with source highlighting using the source verifier service and MetaMask': function (browser) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]') browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
@ -178,15 +176,13 @@ module.exports = {
.waitForElementPresent('*[data-id="settingsNetworkEnv"]') .waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Ropsten (3) network') .assert.containsText('*[data-id="settingsNetworkEnv"]', 'Ropsten (3) network')
.clickLaunchIcon('debugger') .clickLaunchIcon('debugger')
.setValue('*[data-id="debuggerTransactionInput"]', '0x5db1b4212e4f83e36bf5bc306888df50f01a73708a71322bdc6f39a76a7ebdaa') // debug tx .setValue('*[data-id="debuggerTransactionInput"]', '0x959371506b8f6223d71c709ac2eb2d0158104dca2d76ca949f1662712cf0e6db') // debug tx
.click('*[data-id="debuggerTransactionStartButton"]') .click('*[data-id="debuggerTransactionStartButton"]')
.waitForElementVisible('*[data-id="treeViewDivto"]', 30000) .waitForElementVisible('*[data-id="treeViewDivto"]', 30000)
.assert.containsText('*[data-id="stepdetail"]', 'loaded address: 0x96d87AB604AEC7FB26C2E046CA5e6eBBB9D8b74D') .assert.containsText('*[data-id="stepdetail"]', 'loaded address: 0x3c943Fb816694d7D1f4C738e3e7823818a88DD6C')
.assert.containsText('*[data-id="solidityLocals"]', 'to: 0x6C3CCC7FBA111707D5A1AAF2758E9D4F4AC5E7B1') .assert.containsText('*[data-id="solidityLocals"]', 'to: 0x6C3CCC7FBA111707D5A1AAF2758E9D4F4AC5E7B1')
.end() .end()
}, },
*/
tearDown: sauce tearDown: sauce
} }

@ -23,7 +23,7 @@ module.exports = {
browser.assert.ok(typeof signature.value === 'string', 'type of signature.value must be String') browser.assert.ok(typeof signature.value === 'string', 'type of signature.value must be String')
}) })
.addFile('signMassage.sol', sources[0]['browser/signMassage.sol']) .addFile('signMassage.sol', sources[0]['browser/signMassage.sol'])
.switchFile('browser/signMassage.sol') .openFile('browser/signMassage.sol')
.pause(5000) .pause(5000)
.selectContract('ECVerify') .selectContract('ECVerify')
.createContract('') .createContract('')

@ -15,7 +15,7 @@ module.exports = {
'Test Success Import': function (browser) { 'Test Success Import': function (browser) {
browser.addFile('Untitled1.sol', sources[1]['browser/Untitled1.sol']) browser.addFile('Untitled1.sol', sources[1]['browser/Untitled1.sol'])
.addFile('Untitled2.sol', sources[1]['browser/Untitled2.sol']) .addFile('Untitled2.sol', sources[1]['browser/Untitled2.sol'])
.switchFile('browser/Untitled1.sol') .openFile('browser/Untitled1.sol')
.verifyContracts(['test6', 'test4', 'test5']) .verifyContracts(['test6', 'test4', 'test5'])
}, },

@ -27,7 +27,7 @@ module.exports = {
'Should generate test file': function (browser) { 'Should generate test file': function (browser) {
browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]') browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]')
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/simple_storage.sol') .openFile('browser/simple_storage.sol')
.click('*[data-id="verticalIconsKindsolidityUnitTesting"]') .click('*[data-id="verticalIconsKindsolidityUnitTesting"]')
.waitForElementPresent('*[data-id="testTabGenerateTestFile"]') .waitForElementPresent('*[data-id="testTabGenerateTestFile"]')
.click('*[data-id="testTabGenerateTestFile"]') .click('*[data-id="testTabGenerateTestFile"]')
@ -100,7 +100,7 @@ module.exports = {
browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]') browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]')
.addFile('compilationError_test.sol', sources[0]['browser/compilationError_test.sol']) .addFile('compilationError_test.sol', sources[0]['browser/compilationError_test.sol'])
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/compilationError_test.sol') .openFile('browser/compilationError_test.sol')
.clickLaunchIcon('solidityUnitTesting') .clickLaunchIcon('solidityUnitTesting')
.click('*[data-id="testTabCheckAllTests"]') .click('*[data-id="testTabCheckAllTests"]')
.clickElementAtPosition('.singleTestLabel', 3) .clickElementAtPosition('.singleTestLabel', 3)
@ -115,7 +115,7 @@ module.exports = {
browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]') browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]')
.addFile('deployError_test.sol', sources[0]['browser/deployError_test.sol']) .addFile('deployError_test.sol', sources[0]['browser/deployError_test.sol'])
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/deployError_test.sol') .openFile('browser/deployError_test.sol')
.clickLaunchIcon('solidityUnitTesting') .clickLaunchIcon('solidityUnitTesting')
.click('*[data-id="testTabCheckAllTests"]') .click('*[data-id="testTabCheckAllTests"]')
.clickElementAtPosition('.singleTestLabel', 4) .clickElementAtPosition('.singleTestLabel', 4)
@ -129,7 +129,7 @@ module.exports = {
browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]') browser.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]')
.addFile('methodFailure_test.sol', sources[0]['browser/methodFailure_test.sol']) .addFile('methodFailure_test.sol', sources[0]['browser/methodFailure_test.sol'])
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/methodFailure_test.sol') .openFile('browser/methodFailure_test.sol')
.clickLaunchIcon('solidityUnitTesting') .clickLaunchIcon('solidityUnitTesting')
.click('*[data-id="testTabCheckAllTests"]') .click('*[data-id="testTabCheckAllTests"]')
.clickElementAtPosition('.singleTestLabel', 5) .clickElementAtPosition('.singleTestLabel', 5)
@ -150,7 +150,7 @@ function runTests (browser) {
browser browser
.waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]') .waitForElementPresent('*[data-id="verticalIconsKindfileExplorers"]')
.clickLaunchIcon('fileExplorers') .clickLaunchIcon('fileExplorers')
.switchFile('browser/3_Ballot.sol') .openFile('browser/3_Ballot.sol')
.clickLaunchIcon('solidityUnitTesting') .clickLaunchIcon('solidityUnitTesting')
.pause(500) .pause(500)
.scrollAndClick('#runTestsTabRunAction') .scrollAndClick('#runTestsTabRunAction')

@ -57,7 +57,7 @@ module.exports = {
'Async/Await Script': function (browser) { 'Async/Await Script': function (browser) {
browser browser
.addFile('asyncAwait.js', { content: asyncAwait }) .addFile('asyncAwait.js', { content: asyncAwait })
.switchFile('browser/asyncAwait.js') .openFile('browser/asyncAwait.js')
.executeScript(`remix.execute('browser/asyncAwait.js')`) .executeScript(`remix.execute('browser/asyncAwait.js')`)
.journalLastChild('Waiting Promise') .journalLastChild('Waiting Promise')
.pause(5500) .pause(5500)
@ -67,7 +67,7 @@ module.exports = {
'Call Remix File Manager from a script': function (browser) { 'Call Remix File Manager from a script': function (browser) {
browser browser
.addFile('asyncAwaitWithFileManagerAccess.js', { content: asyncAwaitWithFileManagerAccess }) .addFile('asyncAwaitWithFileManagerAccess.js', { content: asyncAwaitWithFileManagerAccess })
.switchFile('browser/asyncAwaitWithFileManagerAccess.js') .openFile('browser/asyncAwaitWithFileManagerAccess.js')
.pause(5000) .pause(5000)
.executeScript(`remix.execute('browser/asyncAwaitWithFileManagerAccess.js')`) .executeScript(`remix.execute('browser/asyncAwaitWithFileManagerAccess.js')`)
.pause(6000) .pause(6000)
@ -108,7 +108,7 @@ const asyncAwaitWithFileManagerAccess = `
var run = async () => { var run = async () => {
console.log('Waiting Promise') console.log('Waiting Promise')
var result = await p() var result = await p()
let text = await remix.call('fileManager', 'getFile', 'browser/3_Ballot.sol') let text = await remix.call('fileManager', 'readFile', 'browser/3_Ballot.sol')
console.log('result - ', text) console.log('result - ', text)
} }

16891
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -128,8 +128,7 @@
}, },
"dependencies": { "dependencies": {
"@remixproject/engine": "^0.2.3", "@remixproject/engine": "^0.2.3",
"http-server": "^0.11.1", "http-server": "^0.11.1"
"remixd": "0.1.8-alpha.10"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.4.5", "@babel/core": "^7.4.5",
@ -152,7 +151,6 @@
"babel-eslint": "^10.0.0", "babel-eslint": "^10.0.0",
"babel-plugin-fast-async": "^6.1.2", "babel-plugin-fast-async": "^6.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-yo-yoify": "^2.0.0",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"brace": "^0.8.0", "brace": "^0.8.0",
"browserify": "^16.2.3", "browserify": "^16.2.3",
@ -171,15 +169,6 @@
"exorcist": "^0.4.0", "exorcist": "^0.4.0",
"fast-async": "^7.0.6", "fast-async": "^7.0.6",
"fast-levenshtein": "^2.0.6", "fast-levenshtein": "^2.0.6",
"ganache-cli": "^6.8.1",
"gists": "^1.0.1",
"ipfs-mini": "^1.1.5",
"is-electron": "^2.2.0",
"javascript-serialize": "^1.6.1",
"jquery": "^3.3.1",
"js-base64": "^2.1.9",
"js-beautify": "1.6.14",
"minixhr": "^3.2.2",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"nanohtml": "^1.6.3", "nanohtml": "^1.6.3",
"nightwatch": "^1.3.5", "nightwatch": "^1.3.5",
@ -196,7 +185,7 @@
"remix-solidity": "0.3.30", "remix-solidity": "0.3.30",
"remix-tabs": "1.0.48", "remix-tabs": "1.0.48",
"remix-tests": "0.1.33", "remix-tests": "0.1.33",
"remixd": "0.1.8-alpha.10", "remixd": "0.1.8-alpha.16",
"request": "^2.83.0", "request": "^2.83.0",
"rimraf": "^2.6.1", "rimraf": "^2.6.1",
"selenium-standalone": "^6.17.0", "selenium-standalone": "^6.17.0",
@ -209,10 +198,20 @@
"typescript": "~3.8.3", "typescript": "~3.8.3",
"uglify-js": "^2.8.16", "uglify-js": "^2.8.16",
"vm-browserify": "0.0.4", "vm-browserify": "0.0.4",
"yo-yo": "^1.2.2",
"yo-yoify": "^3.7.3",
"babel-plugin-yo-yoify": "^2.0.0",
"ganache-cli": "^6.8.1",
"gists": "^1.0.1",
"ipfs-mini": "^1.1.5",
"is-electron": "^2.2.0",
"javascript-serialize": "^1.6.1",
"jquery": "^3.3.1",
"js-base64": "^2.1.9",
"js-beautify": "1.6.14",
"minixhr": "^3.2.2",
"watchify": "^3.9.0", "watchify": "^3.9.0",
"web3": "1.2.4", "web3": "1.2.4",
"webworkify": "^1.2.1", "webworkify": "^1.2.1"
"yo-yo": "^1.2.2",
"yo-yoify": "^3.7.3"
} }
} }

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save