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 (Object.keys(filesList).length === 0) {
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"
let data
try {
data = await this.call('source-verification', 'fetch', contractAddress, name.toLowerCase())
data = await this.call('source-verification', 'fetchByNetwork', contractAddress, name.toLowerCase())
} 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)
return localCompilation()
}

@ -12,16 +12,40 @@ class SourceHighlighters {
highlight (position, filePath, hexColor, from) {
try {
if (!this.highlighters[from]) this.highlighters[from] = new SourceHighlighter()
this.highlighters[from].currentSourceLocation(null)
this.highlighters[from].currentSourceLocationFromfileName(position, filePath, hexColor)
if (!this.highlighters[from]) this.highlighters[from] = []
const sourceHighlight = new SourceHighlighter()
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) {
throw e
}
}
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) {
provider.exists(filename, (error, exist) => {
if (error) return console.log(error)
this._deps.fileManager.switchFile(filename)
this._deps.fileManager.open(filename)
jumpToLine(lineColumn)
})
}

@ -79,6 +79,7 @@ class Editor extends Plugin {
this.emptySession = this._createSession('')
this.modes = {
sol: 'ace/mode/solidity',
yul: 'ace/mode/solidity',
mvir: 'ace/mode/move',
js: 'ace/mode/javascript',
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.fullLineMarker) this._deps.editor.removeMarker(this.fullLineMarker, this.source)
this.statementMarker = null
@ -39,8 +39,9 @@ class SourceHighlighter {
this.source = null
if (lineColumnPos) {
this.source = filePath
if (this._deps.config.get('currentFile') !== this.source) {
this._deps.fileManager.switchFile(this.source)
if (this._deps.fileManager.currentFile() !== this.source) {
await this._deps.fileManager.open(this.source)
this.source = this._deps.fileManager.currentFile()
}
const css = csjs`

@ -60,7 +60,7 @@ function fileExplorer (localRegistry, files, menuItems) {
}
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}` })
@ -234,11 +234,16 @@ function fileExplorer (localRegistry, files, menuItems) {
const currentFoldername = extractNameFromKey(key)
modalDialogCustom.confirm(`Confirm to delete folder`, `Are you sure you want to delete ${currentFoldername} folder?`,
() => {
if (!files.remove(key)) {
async () => {
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.`)
} else {
self.updatePath('browser')
const { type } = fileManager.currentFileProvider()
self.updatePath(type)
}
}, () => {})
}
@ -275,9 +280,16 @@ function fileExplorer (localRegistry, files, menuItems) {
modalDialogCustom.confirm(
`Delete file`, `Are you sure you want to delete ${currentFilename} file?`,
() => {
files.remove(key)
self.updatePath('browser')
async () => {
const fileManager = self._deps.fileManager
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
modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => {
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)
const fileManager = self._deps.fileManager
const createFile = await fileManager.writeFile(newName, '')
if (!self.files.set(newName, '')) {
if (!createFile) {
tooltip('Failed to create file ' + newName)
} else {
self._deps.fileManager.switchFile(newName)
await fileManager.open(newName)
if (newName.includes('_test.sol')) {
self.events.trigger('newTestFileCreated', [newName])
}

@ -23,12 +23,19 @@ const profile = {
icon: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjk2IDM4NHE0MCAwIDY4IDI4dDI4IDY4djEyMTZxMCA0MC0yOCA2OHQtNjggMjhoLTk2MHEtNDAgMC02OC0yOHQtMjgtNjh2LTI4OGgtNTQ0cS00MCAwLTY4LTI4dC0yOC02OHYtNjcycTAtNDAgMjAtODh0NDgtNzZsNDA4LTQwOHEyOC0yOCA3Ni00OHQ4OC0yMGg0MTZxNDAgMCA2OCAyOHQyOCA2OHYzMjhxNjgtNDAgMTI4LTQwaDQxNnptLTU0NCAyMTNsLTI5OSAyOTloMjk5di0yOTl6bS02NDAtMzg0bC0yOTkgMjk5aDI5OXYtMjk5em0xOTYgNjQ3bDMxNi0zMTZ2LTQxNmgtMzg0djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djY0MGg1MTJ2LTI1NnEwLTQwIDIwLTg4dDQ4LTc2em05NTYgODA0di0xMTUyaC0zODR2NDE2cTAgNDAtMjggNjh0LTY4IDI4aC00MTZ2NjQwaDg5NnoiLz48L3N2Zz4=',
permission: true,
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'
}
// File System profile
// - methods: ['getFolder', 'getCurrentFile', 'getFile', 'setFile', 'switchFile']
const errorMsg = {
ENOENT: 'No such file or directory',
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 {
constructor (editor) {
@ -42,6 +49,202 @@ class FileManager extends Plugin {
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 () {
this._deps = {
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('errored', (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) {
@ -71,7 +279,7 @@ class FileManager extends Plugin {
delete this.openedFiles[oldName]
this.openedFiles[newName] = newName
}
this.switchFile(newName)
this.openFile(newName)
} else {
var newFocus
for (var k in this.openedFiles) {
@ -85,7 +293,7 @@ class FileManager extends Plugin {
}
}
if (newFocus) {
this.switchFile(newFocus)
this.openFile(newFocus)
}
}
// TODO: Only keep `this.emit` (issue#2210)
@ -129,15 +337,10 @@ class FileManager extends Plugin {
return path ? path[1] : null
}
getCurrentFile () {
const path = this.currentFile()
if (!path) throw new Error('No file selected')
return path
}
getFile (path) {
getFileContent (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
return new Promise((resolve, reject) => {
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) {
const canCall = await this.askUserPermission('setFile', '')
const canCall = await this.askUserPermission('writeFile', '')
if (canCall) {
this._setFileInternal(path, content)
// inform the user about modification after permission is granted and even if permission was saved before
toaster(yo`
<div>
@ -167,12 +369,12 @@ class FileManager extends Plugin {
`, '', { time: 3000 })
}
}
this._setFileInternal(path, content)
return await this._setFileInternal(path, content)
}
_setFileInternal (path, content) {
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 : Change Provider to Promise
return new Promise((resolve, reject) => {
@ -189,11 +391,10 @@ class FileManager extends Plugin {
if (fileProvider) {
helper.createNonClashingNameWithPrefix(path, fileProvider, '', (error, copyName) => {
if (error) {
console.log('createNonClashingNameWithPrefix', error)
copyName = path + '.' + this.currentRequest.from
}
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)
this.emit('fileRemoved', path)
this.events.emit('fileRemoved', path)
this.switchFile()
this.openFile()
}
unselectCurrentFile () {
@ -227,16 +428,19 @@ class FileManager extends Plugin {
this.events.emit('noFileSelected')
}
switchFile (file) {
const _switchFile = (file) => {
openFile (file) {
const _openFile = (file) => {
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.openedFiles[file] = file
this.fileProviderOf(file).get(file, (error, content) => {
provider.get(file, (error, content) => {
if (error) {
console.log(error)
} else {
if (this.fileProviderOf(file).isReadOnly(file)) {
if (provider.isReadOnly(file)) {
this.editor.openReadOnly(file, content)
} else {
this.editor.open(file, content)
@ -247,14 +451,14 @@ class FileManager extends Plugin {
}
})
}
if (file) return _switchFile(file)
if (file) return _openFile(file)
else {
var browserProvider = this._deps.filesProviders['browser']
browserProvider.resolveDirectory('browser', (error, filesProvider) => {
if (error) console.error(error)
var fileList = Object.keys(filesProvider)
if (fileList.length) {
_switchFile(browserProvider.type + '/' + fileList[0])
_openFile(browserProvider.type + '/' + fileList[0])
} else {
// TODO: Only keep `this.emit` (issue#2210)
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) {
return this._deps.filesProviders[name]
}

@ -66,12 +66,12 @@ class FileProvider {
exists (path, cb) {
// todo check the type (directory/file) as well #2386
// 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) {
var unprefixedpath = this.removePrefix(path)
return window.remixFileSystem.existsSync(unprefixedpath)
return path === this.type ? true : window.remixFileSystem.existsSync(unprefixedpath)
}
init (cb) {
@ -94,19 +94,8 @@ class FileProvider {
var unprefixedpath = this.removePrefix(path)
var exists = window.remixFileSystem.existsSync(unprefixedpath)
if (exists && window.remixFileSystem.readFileSync(unprefixedpath, 'utf8') === content) return true
if (!exists && unprefixedpath.indexOf('/') !== -1) {
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)])
}
})
this.createDir(path)
}
try {
window.remixFileSystem.writeFileSync(unprefixedpath, content)
@ -123,6 +112,22 @@ class FileProvider {
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
addExternal (path, content, url) {
if (url) this.addNormalizedName(path, url)
@ -134,7 +139,14 @@ class FileProvider {
}
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)
try {
if (!stat.isDirectory()) {
window.remixFileSystem.unlinkSync(path, console.log)
this.event.trigger('fileRemoved', [this._normalizePath(path)])
return true
return this.removeFile(path)
} else {
const items = window.remixFileSystem.readdirSync(path)
if (items.length !== 0) {
@ -158,8 +168,7 @@ class FileProvider {
if (window.remixFileSystem.statSync(curPath).isDirectory()) { // delete folder
this.remove(curPath)
} else { // delete file
window.remixFileSystem.unlinkSync(curPath, console.log)
this.event.trigger('fileRemoved', [this._normalizePath(path)])
this.removeFile(curPath)
}
})
if (window.remixFileSystem.readdirSync(path).length === 0) window.remixFileSystem.rmdirSync(path, console.log)
@ -176,6 +185,15 @@ class FileProvider {
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) {
var unprefixedoldPath = this.removePrefix(oldPath)
var unprefixednewPath = this.removePrefix(newPath)

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

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

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

@ -141,7 +141,7 @@ class CompilerContainer {
// Load solc compiler version according to pragma in contract file
_setCompilerVersionFromPragma (filename) {
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)
if (pragmaArr && pragmaArr.length === 1) {
const pragmaStr = pragmaArr[0].replace('pragma solidity', '').trim()

@ -319,7 +319,7 @@ class Recorder {
helper.createNonClashingName(newFile, fileProvider, (error, newFile) => {
if (error) return cb('Failed to create file. ' + newFile + ' ' + error)
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) => {
let context = selectExEnv.options[selectExEnv.selectedIndex].value
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) => {
if (alertMsg) addTooltip(alertMsg)
this.setFinalContext()

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

@ -289,7 +289,7 @@ module.exports = class TestTab extends ViewPlugin {
}
async testFromPath (path) {
const fileContent = await this.fileManager.getFile(path)
const fileContent = await this.fileManager.readFile(path)
return this.testFromSource(fileContent, path)
}
@ -323,7 +323,7 @@ module.exports = class TestTab extends ViewPlugin {
return
}
this.resultStatistics.hidden = false
this.fileManager.getFile(testFilePath).then((content) => {
this.fileManager.readFile(testFilePath).then((content) => {
const runningTest = {}
runningTest[testFilePath] = { content }
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
const fileNameToImport = splittedFileName[splittedFileName.length - 1]
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 = []
let files
try {
files = await this.fileManager.getFolder(path)
files = await this.fileManager.readdir(path)
} catch (e) {
cb(e.message)
}

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

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

@ -11,6 +11,7 @@ class Remixd {
this.callid = 0
this.socket = null
this.connected = false
this.receiveResponse()
}
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) {
function remixdDialog () {
return yo`<div>Connection to Remixd closed. Localhost connection not available anymore.</div>`
@ -87,16 +99,24 @@ class Remixd {
}
call (service, fn, args, callback) {
return new Promise((resolve, reject) => {
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) {
var data = this.format(service, fn, args)
this.callbacks[data.id] = callback
this.socket.send(JSON.stringify(data))
resolve(data.id)
} 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) {

@ -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) {
browser
.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')
.click('span[class^=dropdownCaret]')
.click('#homeItem')

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

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

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

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

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

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

@ -115,6 +115,8 @@ function runTests (browser, testData) {
})
.clickLaunchIcon('fileExplorers')
.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/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

@ -90,7 +90,7 @@ module.exports = {
'Should deploy contract on Goerli Test Network using MetaMask': function (browser) {
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('fileExplorers')
.switchFile('browser/Greet.sol')
.openFile('browser/Greet.sol')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[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) {
browser.waitForElementPresent('*[data-id="runTabSelectAccount"] option')
.clickLaunchIcon('fileExplorers')
.switchFile('browser/Greet.sol')
.openFile('browser/Greet.sol')
.clickLaunchIcon('udapp')
.waitForElementPresent('*[data-id="Deploy - transact (not payable)"]')
.click('*[data-id="Deploy - transact (not payable)"]')
@ -149,7 +149,6 @@ module.exports = {
.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.')
.modalFooterCancelClick()
.end()
},
/*
@ -159,7 +158,6 @@ module.exports = {
* - 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) {
browser.waitForElementPresent('*[data-id="remixIdeSidePanel"]')
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
@ -178,15 +176,13 @@ module.exports = {
.waitForElementPresent('*[data-id="settingsNetworkEnv"]')
.assert.containsText('*[data-id="settingsNetworkEnv"]', 'Ropsten (3) network')
.clickLaunchIcon('debugger')
.setValue('*[data-id="debuggerTransactionInput"]', '0x5db1b4212e4f83e36bf5bc306888df50f01a73708a71322bdc6f39a76a7ebdaa') // debug tx
.setValue('*[data-id="debuggerTransactionInput"]', '0x959371506b8f6223d71c709ac2eb2d0158104dca2d76ca949f1662712cf0e6db') // debug tx
.click('*[data-id="debuggerTransactionStartButton"]')
.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')
.end()
},
*/
tearDown: sauce
}

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

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

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

@ -57,7 +57,7 @@ module.exports = {
'Async/Await Script': function (browser) {
browser
.addFile('asyncAwait.js', { content: asyncAwait })
.switchFile('browser/asyncAwait.js')
.openFile('browser/asyncAwait.js')
.executeScript(`remix.execute('browser/asyncAwait.js')`)
.journalLastChild('Waiting Promise')
.pause(5500)
@ -67,7 +67,7 @@ module.exports = {
'Call Remix File Manager from a script': function (browser) {
browser
.addFile('asyncAwaitWithFileManagerAccess.js', { content: asyncAwaitWithFileManagerAccess })
.switchFile('browser/asyncAwaitWithFileManagerAccess.js')
.openFile('browser/asyncAwaitWithFileManagerAccess.js')
.pause(5000)
.executeScript(`remix.execute('browser/asyncAwaitWithFileManagerAccess.js')`)
.pause(6000)
@ -108,7 +108,7 @@ const asyncAwaitWithFileManagerAccess = `
var run = async () => {
console.log('Waiting Promise')
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)
}

16891
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -128,8 +128,7 @@
},
"dependencies": {
"@remixproject/engine": "^0.2.3",
"http-server": "^0.11.1",
"remixd": "0.1.8-alpha.10"
"http-server": "^0.11.1"
},
"devDependencies": {
"@babel/core": "^7.4.5",
@ -152,7 +151,6 @@
"babel-eslint": "^10.0.0",
"babel-plugin-fast-async": "^6.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-yo-yoify": "^2.0.0",
"babelify": "^10.0.0",
"brace": "^0.8.0",
"browserify": "^16.2.3",
@ -171,15 +169,6 @@
"exorcist": "^0.4.0",
"fast-async": "^7.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",
"nanohtml": "^1.6.3",
"nightwatch": "^1.3.5",
@ -196,7 +185,7 @@
"remix-solidity": "0.3.30",
"remix-tabs": "1.0.48",
"remix-tests": "0.1.33",
"remixd": "0.1.8-alpha.10",
"remixd": "0.1.8-alpha.16",
"request": "^2.83.0",
"rimraf": "^2.6.1",
"selenium-standalone": "^6.17.0",
@ -209,10 +198,20 @@
"typescript": "~3.8.3",
"uglify-js": "^2.8.16",
"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",
"web3": "1.2.4",
"webworkify": "^1.2.1",
"yo-yo": "^1.2.2",
"yo-yoify": "^3.7.3"
"webworkify": "^1.2.1"
}
}

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