terminal updates

pull/1342/head
davidzagi93@gmail.com 3 years ago
parent caeb5f027e
commit 32bf5bce1c
  1. 1
      apps/remix-ide-e2e/src/commands/journalLastChildIncludes.ts
  2. 8
      apps/remix-ide-e2e/src/tests/editor.spec.ts
  3. 2
      apps/remix-ide-e2e/src/tests/fileManager_api.spec.ts
  4. 1
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  5. 4
      apps/remix-ide/src/app.js
  6. 20
      apps/remix-ide/src/app/panels/terminal.js
  7. 2
      libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx
  8. 32
      libs/remix-ui/terminal/src/lib/actions/terminalAction.ts
  9. 2
      libs/remix-ui/terminal/src/lib/components/Context.tsx
  10. 15
      libs/remix-ui/terminal/src/lib/components/RenderCall.tsx
  11. 16
      libs/remix-ui/terminal/src/lib/components/RenderKnownTransactions.tsx
  12. 15
      libs/remix-ui/terminal/src/lib/components/RenderUnknownTransactions.tsx
  13. 2
      libs/remix-ui/terminal/src/lib/components/Table.tsx
  14. 48
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  15. 4
      libs/remix-ui/terminal/src/lib/utils/utils.ts

@ -10,7 +10,6 @@ class JournalLastChildIncludes extends EventEmitter {
.waitForElementVisible('*[data-id="terminalJournal"]', 10000)
.pause(1000)
.getText('*[data-id="terminalJournal"]', (result) => {
this.api.pause(5000)
console.log('JournalLastChildIncludes', result.value)
if (typeof result.value === 'string' && result.value.indexOf(val) === -1) return this.api.assert.fail(`wait for ${val} in ${result.value}`)
else this.api.assert.ok(true, `<*[data-id="terminalJournal"]> contains ${val}.`)

@ -92,13 +92,13 @@ module.exports = {
.openFile('sourcehighlight.js')
.executeScript('remix.exeCurrent()')
.editorScroll('down', 60)
.pause(5000)
.pause(1000)
.waitForElementPresent('.highlightLine32', 60000)
.pause(5000)
.pause(1000)
.checkElementStyle('.highlightLine32', 'background-color', 'rgb(8, 108, 181)')
.pause(5000)
.pause(1000)
.waitForElementPresent('.highlightLine40', 60000)
.pause(5000)
.pause(1000)
.checkElementStyle('.highlightLine40', 'background-color', 'rgb(8, 108, 181)')
.waitForElementPresent('.highlightLine50', 60000)
.checkElementStyle('.highlightLine50', 'background-color', 'rgb(8, 108, 181)')

@ -11,7 +11,7 @@ module.exports = {
browser
.addFile('file.js', { content: executeFile })
.executeScript('remix.exeCurrent()')
.pause(5000)
.pause(1000)
.waitForElementContainsText('*[data-id="terminalJournal"]', 'file.js', 60000)
},

@ -53,7 +53,6 @@ module.exports = {
'Call web3.eth.getAccounts() using JavaScript VM': function (browser: NightwatchBrowser) {
browser
.executeScript('web3.eth.getAccounts()')
// .waitForElementContainsText('*[data-id="terminalJournal"]', '"0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db", "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB", "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C"', 80000)
.waitForElementContainsText('*[data-id="terminalJournal"]', '["0x5B38Da6a701c568545dCfcB03FcB875f56beddC4","0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2","0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c","0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db","0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB","0x617F2E2fD72FD9D5503197092aC168c91465E7f2","0x17F6AD8Ef982297579C203069C1DbfFE4348c372","0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C","0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678","0x03C6FcED478cBbC9a4FAB34eF9f40767739D1Ff7","0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C","0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC","0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB","0x583031D1113aD414F02576BD6afaBfb302140225","0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', 80000)
},

@ -287,8 +287,6 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
registry.put({ api: offsetToLineColumnConverter, name: 'offsettolinecolumnconverter' })
// -------------------Terminal----------------------------------------
// move this up for *** level so as to access it in the terminal
makeUdapp(blockchain, compilersArtefacts, (domEl) => terminal.logHtml(domEl))
const terminal = new Terminal(
{ appManager, blockchain },
@ -302,11 +300,9 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
return height - newpos
}
},
{ config: registry.get('config').api },
registry
)
// previous *** level for makeUdapp method
const contextualListener = new ContextualListener({ editor })
engine.register([

@ -4,18 +4,18 @@ import ReactDOM from 'react-dom'
import { RemixUiTerminal } from '@remix-ui/terminal' // eslint-disable-line
import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json'
var vm = require('vm')
var EventManager = require('../../lib/events')
const vm = require('vm')
const EventManager = require('../../lib/events')
var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI')
var AutoCompletePopup = require('../ui/auto-complete-popup')
const CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI')
const AutoCompletePopup = require('../ui/auto-complete-popup')
import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line
var globalRegistry = require('../../global/registry')
var SourceHighlighter = require('../../app/editor/sourceHighlighter')
var GistHandler = require('../../lib/gist-handler')
const globalRegistry = require('../../global/registry')
const SourceHighlighter = require('../../app/editor/sourceHighlighter')
const GistHandler = require('../../lib/gist-handler')
var KONSOLES = []
const KONSOLES = []
function register (api) { KONSOLES.push(api) }
@ -29,7 +29,7 @@ const profile = {
}
class Terminal extends Plugin {
constructor (opts, api, config, registry) {
constructor (opts, api, registry) {
super(profile)
this.fileImport = new CompilerImports()
this.gistHandler = new GistHandler()
@ -60,7 +60,7 @@ class Terminal extends Plugin {
this.vm = vm
this._api = api
this._opts = opts
this.config = config
this.config = registry.get('config').api
this.version = packageJson.version
this.data = {
lineLength: opts.lineLength || 80, // ????

@ -193,7 +193,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
row = location.start.line
column = location.start.column
locationString = row + 1 + ':' + column + ':'
fileName = Object.keys(lastCompilationResult.contracts)[file]
fileName = Object.keys(lastCompilationResult.sources)[file]
}
warningCount++
const msg = message(result.name, item.warning, item.more, fileName, locationString)

@ -110,30 +110,30 @@ export const listenOnNetworkAction = async (event, isListening) => {
event.trigger('listenOnNetWork', [isListening])
}
export const initListeningOnNetwork = (props, dispatch: React.Dispatch<any>) => {
props.txListener.event.register(NEW_BLOCK, (block) => {
export const initListeningOnNetwork = (plugins, dispatch: React.Dispatch<any>) => {
plugins.txListener.event.register(NEW_BLOCK, (block) => {
if (!block.transactions || (block.transactions && !block.transactions.length)) {
dispatch({ type: EMPTY_BLOCK, payload: { message: 0 } })
}
})
props.txListener.event.register(KNOWN_TRANSACTION, () => {
plugins.txListener.event.register(KNOWN_TRANSACTION, () => {
})
props.txListener.event.register(NEW_CALL, (tx, receipt) => {
log(props, tx, receipt, dispatch)
plugins.txListener.event.register(NEW_CALL, (tx, receipt) => {
log(plugins, tx, receipt, dispatch)
// log(this, tx, null)
})
props.txListener.event.register(NEW_TRANSACTION, (tx, receipt) => {
log(props, tx, receipt, dispatch)
plugins.txListener.event.register(NEW_TRANSACTION, (tx, receipt) => {
log(plugins, tx, receipt, dispatch)
})
const log = async (props, tx, receipt, dispatch: React.Dispatch<any>) => {
const resolvedTransaction = await props.txListener.resolvedTransaction(tx.hash)
const log = async (plugins, tx, receipt, dispatch: React.Dispatch<any>) => {
const resolvedTransaction = await plugins.txListener.resolvedTransaction(tx.hash)
if (resolvedTransaction) {
let compiledContracts = null
if (props._deps.compilersArtefacts.__last) {
compiledContracts = await props._deps.compilersArtefacts.__last.getContracts()
if (plugins._deps.compilersArtefacts.__last) {
compiledContracts = await plugins._deps.compilersArtefacts.__last.getContracts()
}
await props.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, async (error, logs) => {
await plugins.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, async (error, logs) => {
if (!error) {
await dispatch({ type: KNOWN_TRANSACTION, payload: { message: [{ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }] } })
}
@ -143,10 +143,10 @@ export const initListeningOnNetwork = (props, dispatch: React.Dispatch<any>) =>
}
}
props.txListener.event.register('debuggingRequested', async (hash) => {
plugins.txListener.event.register('debuggingRequested', async (hash) => {
// TODO should probably be in the run module
if (!await props.options.appManager.isActive('debugger')) await props.options.appManager.activatePlugin('debugger')
props.call('menuicons', 'select', 'debugger')
props.call('debugger', 'debug', hash)
if (!await plugins.options.appManager.isActive('debugger')) await plugins.options.appManager.activatePlugin('debugger')
plugins.call('menuicons', 'select', 'debugger')
plugins.call('debugger', 'debug', hash)
})
}

@ -2,7 +2,7 @@ import React from 'react' // eslint-disable-line
import helper from 'apps/remix-ide/src/lib/helper'
const remixLib = require('@remix-project/remix-lib')
var typeConversion = remixLib.execution.typeConversion
const typeConversion = remixLib.execution.typeConversion
const Context = ({ opts, blockchain }) => {
const data = opts.tx || ''

@ -6,27 +6,18 @@ import showTable from './Table'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
const remixLib = require('@remix-project/remix-lib')
var typeConversion = remixLib.execution.typeConversion
const typeConversion = remixLib.execution.typeConversion
const RenderCall = ({ tx, resolvedData, logs, index, plugin, showTableHash, txDetails }) => {
const [hideModal, setHideModal] = useState(true)
const RenderCall = ({ tx, resolvedData, logs, index, plugin, showTableHash, txDetails, modal }) => {
const to = resolvedData.contractName + '.' + resolvedData.fn
const from = tx.from ? tx.from : ' - '
const input = tx.input ? helper.shortenHexData(tx.input) : ''
const txType = 'call'
const handleHideModal = () => {
setHideModal(false)
}
const debug = (event, tx) => {
event.stopPropagation()
if (tx.isCall && tx.envMode !== 'vm') {
return <ModalDialog
hide={hideModal}
handleHide={ handleHideModal }
message="Cannot debug this call. Debugging calls is only possible in JavaScript VM mode."
/>
modal('VM mode', 'Cannot debug this call. Debugging calls is only possible in JavaScript VM mode.', 'Ok', true, () => {}, 'Cancel', () => {})
} else {
plugin.event.trigger('debuggingRequested', [tx.hash])
}

@ -8,21 +8,11 @@ import showTable from './Table'
const remixLib = require('@remix-project/remix-lib')
const typeConversion = remixLib.execution.typeConversion
const RenderKnownTransactions = ({ tx, receipt, resolvedData, logs, index, plugin, showTableHash, txDetails }) => {
const [hideModal, setHideModal] = useState(true)
const handleHideModal = () => {
setHideModal(false)
}
const RenderKnownTransactions = ({ tx, receipt, resolvedData, logs, index, plugin, showTableHash, txDetails, modal }) => {
const debug = (event, tx) => {
event.stopPropagation()
if (tx.isCall && tx.envMode !== 'vm') {
return (<ModalDialog
hide={hideModal}
handleHide={ handleHideModal }
message="Cannot debug this call. Debugging calls is only possible in JavaScript VM mode."
/>)
modal('VM mode', 'Cannot debug this call. Debugging calls is only possible in JavaScript VM mode.', 'Ok', true, () => {}, 'Cancel', () => {})
} else {
plugin.event.trigger('debuggingRequested', [tx.hash])
}
@ -30,7 +20,6 @@ const RenderKnownTransactions = ({ tx, receipt, resolvedData, logs, index, plugi
const from = tx.from
const to = resolvedData.contractName + '.' + resolvedData.fn
// const obj = { from, to }
const txType = 'knownTx'
const options = { from, to, tx }
return (
@ -43,7 +32,6 @@ const RenderKnownTransactions = ({ tx, receipt, resolvedData, logs, index, plugi
</div>
<i className = {`terminal_arrow fas ${(showTableHash.includes(tx.hash)) ? 'fa-angle-up' : 'fa-angle-down'}`}></i>
</div>
{ console.log({ showTableHash: showTableHash.includes(tx.hash) })}
{showTableHash.includes(tx.hash) ? showTable({
hash: tx.hash,
status: receipt !== null ? receipt.status : null,

@ -4,29 +4,18 @@ import CheckTxStatus from './ChechTxStatus' // eslint-disable-line
import Context from './Context' // eslint-disable-line
import showTable from './Table'
const RenderUnKnownTransactions = ({ tx, receipt, index, plugin, showTableHash, txDetails }) => {
const [hideModal, setHideModal] = useState(true)
const RenderUnKnownTransactions = ({ tx, receipt, index, plugin, showTableHash, txDetails, modal }) => {
const debug = (event, tx) => {
event.stopPropagation()
if (tx.isCall && tx.envMode !== 'vm') {
return (<ModalDialog
hide={hideModal}
handleHide={ handleHideModal }
message="Cannot debug this call. Debugging calls is only possible in JavaScript VM mode."
/>)
modal('VM mode', 'Cannot debug this call. Debugging calls is only possible in JavaScript VM mode.', 'Ok', true, () => {}, 'Cancel', () => {})
} else {
plugin.event.trigger('debuggingRequested', [tx.hash])
}
}
const handleHideModal = () => {
setHideModal(false)
}
const from = tx.from
const to = tx.to
// const obj = { from, to }
const txType = 'unknown' + (tx.isCall ? 'Call' : 'Tx')
const options = { from, to, tx }
return (

@ -3,7 +3,7 @@ import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line
import helper from 'apps/remix-ide/src/lib/helper'
const remixLib = require('@remix-project/remix-lib')
var typeConversion = remixLib.execution.typeConversion
const typeConversion = remixLib.execution.typeConversion
const showTable = (opts, showTableHash) => {
let msg = ''

@ -4,6 +4,8 @@ import { initialState, registerCommandReducer, addCommandHistoryReducer, registe
import { getKeyOf, getValueOf, Objectfilter, matched } from './utils/utils'
import {allCommands, allPrograms} from './commands' // eslint-disable-line
import TerminalWelcomeMessage from './terminalWelcome' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import './remix-ui-terminal.css'
import vm from 'vm'
@ -34,6 +36,17 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [newstate, dispatch] = useReducer(registerCommandReducer, initialState)
const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState)
const [, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState)
const [toaster, setToaster] = useState(false)
const [toastProvider, setToastProvider] = useState({ show: false, fileName: '' })
const [modalState, setModalState] = useState({
message: '',
title: '',
okLabel: '',
cancelLabel: '',
hide: true,
cancelFn: () => {},
handleHide: () => {}
})
const [clearConsole, setClearConsole] = useState(false)
const [paste, setPaste] = useState(false)
@ -102,12 +115,12 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
useEffect(() => {
scrollToBottom()
}, [newstate.journalBlocks.length, logHtmlResponse.length])
}, [newstate.journalBlocks.length, logHtmlResponse.length, toaster])
function execute (file, cb) {
function _execute (content, cb) {
if (!content) {
// toolTip('no content to execute')
setToaster(true)
if (cb) cb()
return
}
@ -125,6 +138,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
if (!provider) {
// toolTip(`provider for path ${file} not found`)
setToastProvider({ show: true, fileName: file })
if (cb) cb()
return
}
@ -183,7 +197,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
setToggleDownUp('fa-angle-double-up')
event.trigger('resize', [])
} else {
const terminalTopOffset = config.config.get('terminal-top-offset')
const terminalTopOffset = config.get('terminal-top-offset')
event.trigger('resize', [terminalTopOffset])
setToggleDownUp('fa-angle-double-down')
}
@ -295,7 +309,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
}
})
}, [onMouseMove, onMouseUp])
React.useEffect(() => {
if (panelRef) {
@ -401,6 +415,14 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
}
}
const modal = (title: string, message: string, okLabel: string, hide: boolean, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
setModalState(prevState => ({ ...prevState, message, okLabel, okFn, cancelLabel, cancelFn, hide }))
}
const handleHideModal = () => {
setModalState(prevState => ({ ...prevState, hide: true }))
}
const txDetails = (event, tx) => {
if (showTableHash.includes(tx.hash)) {
const index = showTableHash.indexOf(tx.hash)
@ -467,12 +489,10 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
<div className="search">
<i className="fas fa-search searchIcon bg-light" aria-hidden="true"></i>
<input
// spellcheck = "false"
onChange={(event) => setSearchInput(event.target.value.trim()) }
type="text"
className="border filter form-control"
id="searchInput"
// onkeydown=${filter}
placeholder="Search with transaction hash or address"
data-id="terminalInputSearch" />
</div>
@ -502,11 +522,11 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
)
} else if (x.name === UNKNOWN_TRANSACTION) {
return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => {
return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`} key={index}> { <RenderUnKnownTransactions tx={trans.tx} receipt={trans.receipt} index={index} plugin={props.plugin} showTableHash={showTableHash} txDetails={txDetails} />} </div>)
return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`} key={index}> { <RenderUnKnownTransactions tx={trans.tx} receipt={trans.receipt} index={index} plugin={props.plugin} showTableHash={showTableHash} txDetails={txDetails} modal={modal}/>} </div>)
})
} else if (x.name === KNOWN_TRANSACTION) {
return x.message.map((trans) => {
return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`} key={index}> { trans.tx.isCall ? <RenderCall tx={trans.tx} resolvedData={trans.resolvedData} logs={trans.logs} index={index} plugin={props.plugin} showTableHash={showTableHash} txDetails={txDetails} /> : (<RenderKnownTransactions tx = { trans.tx } receipt = { trans.receipt } resolvedData = { trans.resolvedData } logs = {trans.logs } index = { index } plugin = { props.plugin } showTableHash = { showTableHash } txDetails = { txDetails } />) } </div>)
return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`} key={index}> { trans.tx.isCall ? <RenderCall tx={trans.tx} resolvedData={trans.resolvedData} logs={trans.logs} index={index} plugin={props.plugin} showTableHash={showTableHash} txDetails={txDetails} modal={modal}/> : (<RenderKnownTransactions tx = { trans.tx } receipt = { trans.receipt } resolvedData = { trans.resolvedData } logs = {trans.logs } index = { index } plugin = { props.plugin } showTableHash = { showTableHash } txDetails = { txDetails } modal={modal}/>) } </div>)
})
} else if (Array.isArray(x.message)) {
return x.message.map((msg, i) => {
@ -536,7 +556,17 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
</div>
</div>
</div>
<ModalDialog
title={ modalState.title }
message={ modalState.message }
hide={ modalState.hide }
okLabel={ modalState.okLabel }
cancelLabel={ modalState.cancelLabel }
cancelFn={ modalState.cancelFn }
handleHide={ handleHideModal }
/>
{toaster && <Toaster message="no content to execute"/>}
{toastProvider && <Toaster message={`provider for path ${toastProvider.fileName} not found`} />}
</div>
)
}

@ -31,11 +31,11 @@ const findDeep = (object, fn, found = { break: false, value: undefined }) => {
export const find = (args, query) => {
query = query.trim()
var isMatch = !!findDeep(args, function check (value) {
const isMatch = !!findDeep(args, function check (value) {
if (value === undefined || value === null) return false
if (typeof value === 'function') return false
if (typeof value === 'object') return false
var contains = String(value).indexOf(query.trim()) !== -1
const contains = String(value).indexOf(query.trim()) !== -1
return contains
})
return isMatch

Loading…
Cancel
Save