Fixed bugs associated to remixd test failing

pull/5370/head
ioedeveloper 3 years ago
parent 35855096a8
commit 521e04c442
  1. 1
      apps/remix-ide-e2e/src/tests/remixd.test.ts
  2. 21
      apps/remix-ide/src/app/files/fileManager.js
  3. 25
      apps/remix-ide/src/app/panels/tab-proxy.js
  4. 1
      libs/remix-ui/helper/src/lib/remix-ui-helper.ts
  5. 152
      libs/remix-ui/workspace/src/lib/actions/events.ts
  6. 14
      libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
  7. 9
      libs/remix-ui/workspace/src/lib/components/file-label.tsx
  8. 16
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts

@ -153,7 +153,6 @@ function runTests (browser: NightwatchBrowser) {
.clickLaunchIcon('filePanel')
.waitForElementVisible('[data-path="folder1"]')
.click('[data-path="folder1"]')
.click('[data-path="folder1"]') // click twice because remixd does not return nested folder details after update
.waitForElementVisible('[data-path="folder1/contract1.sol"]')
.waitForElementVisible('[data-path="folder1/renamed_contract_' + browserName + '.sol"]') // check if renamed file is preset
.waitForElementNotPresent('[data-path="folder1/contract_' + browserName + '.sol"]') // check if renamed (old) file is not present

@ -469,16 +469,19 @@ class FileManager extends Plugin {
}
closeFile (name) {
delete this.openedFiles[name]
if (!Object.keys(this.openedFiles).length) {
this._deps.config.set('currentFile', '')
return new Promise((resolve) => {
delete this.openedFiles[name]
if (!Object.keys(this.openedFiles).length) {
this._deps.config.set('currentFile', '')
// TODO: Only keep `this.emit` (issue#2210)
this.emit('noFileSelected')
this.events.emit('noFileSelected')
}
// TODO: Only keep `this.emit` (issue#2210)
this.emit('noFileSelected')
this.events.emit('noFileSelected')
}
// TODO: Only keep `this.emit` (issue#2210)
this.emit('fileClosed', name)
this.events.emit('fileClosed', name)
this.emit('fileClosed', name)
this.events.emit('fileClosed', name)
resolve(true)
})
}
currentPath () {

@ -44,19 +44,32 @@ export class TabProxy extends Plugin {
fileManager.events.on('fileRemoved', (name) => {
const workspace = this.fileManager.currentWorkspace()
workspace ? this.removeTab(workspace + '/' + name) : this.removeTab(this.fileManager.mode + '/' + name)
if (this.fileManager.mode === 'browser') {
name = name.startsWith(workspace + '/') ? name : workspace + '/' + name
this.removeTab(name)
} else {
name = name.startsWith(this.fileManager.mode + '/') ? name : this.fileManager.mode + '/' + name
this.removeTab(name)
}
})
fileManager.events.on('fileClosed', (name) => {
const workspace = this.fileManager.currentWorkspace()
workspace ? this.removeTab(workspace + '/' + name) : this.removeTab(this.fileManager.mode + '/' + name)
if (this.fileManager.mode === 'browser') {
name = name.startsWith(workspace + '/') ? name : workspace + '/' + name
this.removeTab(name)
} else {
name = name.startsWith(this.fileManager.mode + '/') ? name : this.fileManager.mode + '/' + name
this.removeTab(name)
}
})
fileManager.events.on('currentFileChanged', (file) => {
const workspace = this.fileManager.currentWorkspace()
if (workspace) {
if (this.fileManager.mode === 'browser') {
const workspacePath = workspace + '/' + file
if (this._handlers[workspacePath]) {
@ -72,7 +85,7 @@ export class TabProxy extends Plugin {
this.event.emit('closeFile', file)
})
} else {
const path = this.fileManager.mode + '/' + file
const path = file.startsWith(this.fileManager.mode + '/') ? file : this.fileManager.mode + '/' + file
if (this._handlers[path]) {
this._view.filetabs.activateTab(path)
@ -92,7 +105,7 @@ export class TabProxy extends Plugin {
fileManager.events.on('fileRenamed', (oldName, newName, isFolder) => {
const workspace = this.fileManager.currentWorkspace()
if (workspace) {
if (this.fileManager.mode === 'browser') {
if (isFolder) {
for (const tab of this.loadedTabs) {
if (tab.name.indexOf(workspace + '/' + oldName + '/') === 0) {
@ -115,7 +128,7 @@ export class TabProxy extends Plugin {
return
}
// should change the tab title too
this.renameTab(this.fileManager.mode + '/' + oldName, workspace + '/' + newName)
this.renameTab(this.fileManager.mode + '/' + oldName, this.fileManager.mode + '/' + newName)
}
})

@ -1,4 +1,5 @@
export const extractNameFromKey = (key: string): string => {
if (!key) return
const keyPath = key.split('/')
return keyPath[keyPath.length - 1]

@ -4,8 +4,6 @@ import { action } from '../types'
import { displayNotification, displayPopUp, fileAddedSuccess, fileRemovedSuccess, fileRenamedSuccess, folderAddedSuccess, loadLocalhostError, loadLocalhostRequest, loadLocalhostSuccess, removeContextMenuItem, rootFolderChangedSuccess, setContextMenuItem, setMode, setReadOnlyMode } from './payload'
import { addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile } from './workspace'
const queuedEvents = []
const pendingEvents = {}
const LOCALHOST = ' - connect to localhost - '
let plugin, dispatch: React.Dispatch<any>
@ -37,74 +35,82 @@ export const listenOnPluginEvents = (filePanelPlugin) => {
})
plugin.on('remixd', 'rootFolderChanged', async (path: string) => {
await executeEvent('rootFolderChanged', path)
setTimeout(() => rootFolderChanged(path), 0)
})
}
export const listenOnProviderEvents = (provider) => async (reducerDispatch: React.Dispatch<any>) => {
dispatch = reducerDispatch
provider.event.on('fileAdded', async (filePath: string) => {
await executeEvent('fileAdded', filePath)
provider.event.on('fileAdded', (filePath: string) => {
setTimeout(() => fileAdded(filePath), 0)
})
provider.event.on('folderAdded', async (folderPath: string) => {
provider.event.on('folderAdded', (folderPath: string) => {
if (folderPath.indexOf('/.workspaces') === 0) return
await executeEvent('folderAdded', folderPath)
setTimeout(() => folderAdded(folderPath), 0)
})
provider.event.on('fileRemoved', async (removePath: string) => {
await executeEvent('fileRemoved', removePath)
provider.event.on('fileRemoved', (removePath: string) => {
setTimeout(() => fileRemoved(removePath), 0)
})
provider.event.on('fileRenamed', async (oldPath: string, newPath: string) => {
await executeEvent('fileRenamed', oldPath, newPath)
provider.event.on('fileRenamed', (oldPath: string) => {
setTimeout(() => fileRenamed(oldPath), 0)
})
provider.event.on('disconnected', async () => {
plugin.fileManager.setMode('browser')
dispatch(setMode('browser'))
dispatch(loadLocalhostError('Remixd disconnected!'))
const workspaceProvider = plugin.fileProviders.workspace
provider.event.on('disconnected', () => {
setTimeout(async () => {
plugin.fileManager.setMode('browser')
dispatch(setMode('browser'))
dispatch(loadLocalhostError('Remixd disconnected!'))
const workspaceProvider = plugin.fileProviders.workspace
await switchToWorkspace(workspaceProvider.workspace)
await switchToWorkspace(workspaceProvider.workspace)
}, 0)
})
provider.event.on('connected', async () => {
plugin.fileManager.setMode('localhost')
dispatch(setMode('localhost'))
fetchWorkspaceDirectory('/')
dispatch(loadLocalhostSuccess())
setTimeout(() => {
plugin.fileManager.setMode('localhost')
dispatch(setMode('localhost'))
fetchWorkspaceDirectory('/')
dispatch(loadLocalhostSuccess())
}, 0)
})
provider.event.on('loadingLocalhost', async () => {
await switchToWorkspace(LOCALHOST)
dispatch(loadLocalhostRequest())
setTimeout(async () => {
await switchToWorkspace(LOCALHOST)
dispatch(loadLocalhostRequest())
}, 0)
})
provider.event.on('fileExternallyChanged', async (path: string, file: { content: string }) => {
const config = plugin.registry.get('config').api
const editor = plugin.registry.get('editor').api
if (config.get('currentFile') === path && editor.currentContent() !== file.content) {
if (provider.isReadOnly(path)) return editor.setText(file.content)
dispatch(displayNotification(
path + ' changed',
'This file has been changed outside of Remix IDE.',
'Replace by the new content', 'Keep the content displayed in Remix',
() => {
editor.setText(file.content)
}
))
}
setTimeout(() => {
const config = plugin.registry.get('config').api
const editor = plugin.registry.get('editor').api
if (config.get('currentFile') === path && editor.currentContent() !== file.content) {
if (provider.isReadOnly(path)) return editor.setText(file.content)
dispatch(displayNotification(
path + ' changed',
'This file has been changed outside of Remix IDE.',
'Replace by the new content', 'Keep the content displayed in Remix',
() => {
editor.setText(file.content)
}
))
}
}, 0)
})
provider.event.on('fileRenamedError', async () => {
dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel'))
setTimeout(() => dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel')), 0)
})
provider.event.on('readOnlyModeChanged', (mode: boolean) => {
dispatch(setReadOnlyMode(mode))
setTimeout(() => dispatch(setReadOnlyMode(mode)), 0)
})
}
@ -172,71 +178,3 @@ const fileRenamed = async (oldPath: string) => {
const rootFolderChanged = async (path) => {
await dispatch(rootFolderChangedSuccess(path))
}
const executeEvent = async (eventName: 'fileAdded' | 'folderAdded' | 'fileRemoved' | 'fileRenamed' | 'rootFolderChanged', ...args) => {
if (Object.keys(pendingEvents).length) {
return queuedEvents.push({ eventName, path: args[0] })
}
pendingEvents[eventName + args[0]] = { eventName, path: args[0] }
switch (eventName) {
case 'fileAdded':
setTimeout(() => {
fileAdded(args[0])
}, 0)
delete pendingEvents[eventName + args[0]]
if (queuedEvents.length) {
const next = queuedEvents.pop()
await executeEvent(next.eventName, next.path)
}
break
case 'folderAdded':
setTimeout(() => {
folderAdded(args[0])
}, 0)
delete pendingEvents[eventName + args[0]]
if (queuedEvents.length) {
const next = queuedEvents.pop()
await executeEvent(next.eventName, next.path)
}
break
case 'fileRemoved':
setTimeout(() => {
fileRemoved(args[0])
}, 0)
delete pendingEvents[eventName + args[0]]
if (queuedEvents.length) {
const next = queuedEvents.pop()
await executeEvent(next.eventName, next.path)
}
break
case 'fileRenamed':
setTimeout(() => {
fileRenamed(args[0])
}, 0)
delete pendingEvents[eventName + args[0]]
if (queuedEvents.length) {
const next = queuedEvents.pop()
await executeEvent(next.eventName, next.path)
}
break
case 'rootFolderChanged':
setTimeout(() => {
rootFolderChanged(args[0])
}, 0)
delete pendingEvents[eventName + args[0]]
if (queuedEvents.length) {
const next = queuedEvents.pop()
await executeEvent(next.eventName, next.path)
}
break
}
}

@ -304,14 +304,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
} else {
// editRef.current.textContent = state.focusEdit.lastEdit
setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
}
} else {
if (state.focusEdit.lastEdit === content) {
// editRef.current.textContent = content
return setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
@ -329,15 +327,15 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
} else {
if (hasReservedKeyword(content)) {
// editRef.current.textContent = state.focusEdit.lastEdit
props.modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, 'Close', () => {})
} else {
const oldPath: string = state.focusEdit.element
const oldName = extractNameFromKey(oldPath)
const newPath = oldPath.replace(oldName, content)
if (state.focusEdit.element) {
const oldPath: string = state.focusEdit.element
const oldName = extractNameFromKey(oldPath)
const newPath = oldPath.replace(oldName, content)
// editRef.current.textContent = extractNameFromKey(oldPath)
renamePath(oldPath, newPath)
renamePath(oldPath, newPath)
}
}
}
setState(prevState => {

@ -17,7 +17,6 @@ export const FileLabel = (props: FileLabelProps) => {
const { file, focusEdit, editModeOff } = props
const [isEditable, setIsEditable] = useState<boolean>(false)
const labelRef = useRef(null)
const [defaultValue, setDefaultValue] = useState<string>(null)
useEffect(() => {
if (focusEdit.element && file.path) {
@ -33,22 +32,18 @@ export const FileLabel = (props: FileLabelProps) => {
}
}, [isEditable])
useEffect(() => {
if (labelRef.current) setDefaultValue(labelRef.current.innerText)
}, [labelRef.current])
const handleEditInput = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.which === 13) {
event.preventDefault()
editModeOff(labelRef.current.innerText)
labelRef.current.innerText = defaultValue
labelRef.current.innerText = file.name
}
}
const handleEditBlur = (event: React.SyntheticEvent) => {
event.stopPropagation()
editModeOff(labelRef.current.innerText)
labelRef.current.innerText = defaultValue
labelRef.current.innerText = file.name
}
return (

@ -614,7 +614,13 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s
if (prevFiles) {
prevFiles.child = _.merge(normalize(payload.fileTree, payload.path, payload.type), prevFiles.child)
if (deletePath) delete prevFiles.child[deletePath]
if (deletePath) {
if (deletePath.endsWith('/blank')) delete prevFiles.child[deletePath]
else {
deletePath = extractNameFromKey(deletePath)
delete prevFiles.child[deletePath]
}
}
files = _.set(files, _path, prevFiles)
} else if (payload.fileTree && payload.path) {
files = { [payload.path]: normalize(payload.fileTree, payload.path, payload.type) }
@ -635,7 +641,13 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s
if (prevFiles) {
prevFiles.child = _.merge(normalize(payload.fileTree, payload.path, payload.type), prevFiles.child)
if (deletePath) delete prevFiles.child[deletePath]
if (deletePath) {
if (deletePath.endsWith('/blank')) delete prevFiles.child[deletePath]
else {
deletePath = extractNameFromKey(deletePath)
delete prevFiles.child[deletePath]
}
}
files = _.set(files, _path, prevFiles)
} else {
files = { [payload.path]: normalize(payload.fileTree, payload.path, payload.type) }

Loading…
Cancel
Save