set path for UT context menu

pull/5370/head
aniket-engg 3 years ago committed by Aniket
parent 6a7d0b77e0
commit 0914dd533d
  1. 11
      apps/remix-ide/src/app/tabs/test-tab.js
  2. 344
      libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx

@ -8,7 +8,7 @@ import { ViewPlugin } from '@remixproject/engine-web'
import helper from '../../lib/helper' import helper from '../../lib/helper'
import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity' import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity'
var tooltip = require('../ui/tooltip') // var tooltip = require('../ui/tooltip')
var Renderer = require('../ui/renderer') var Renderer = require('../ui/renderer')
var { UnitTestRunner, assertLibCode } = require('@remix-project/remix-tests') var { UnitTestRunner, assertLibCode } = require('@remix-project/remix-tests')
@ -28,10 +28,8 @@ module.exports = class TestTab extends ViewPlugin {
super(profile) super(profile)
this.compileTab = compileTab this.compileTab = compileTab
this.contentImport = contentImport this.contentImport = contentImport
this._view = { el: null }
this.fileManager = fileManager this.fileManager = fileManager
this.filePanel = filePanel this.filePanel = filePanel
this.data = {}
this.appManager = appManager this.appManager = appManager
this.renderer = new Renderer(this) this.renderer = new Renderer(this)
this.testRunner = new UnitTestRunner() this.testRunner = new UnitTestRunner()
@ -56,7 +54,7 @@ module.exports = class TestTab extends ViewPlugin {
async setTestFolderPath (event) { async setTestFolderPath (event) {
if (event.path.length > 0) { if (event.path.length > 0) {
await this.setCurrentPath(event.path[0]) this.renderComponent(event.path[0])
} }
} }
@ -89,7 +87,6 @@ module.exports = class TestTab extends ViewPlugin {
} }
listenToEvents () { listenToEvents () {
this.on('filePanel', 'workspaceCreated', async () => { this.on('filePanel', 'workspaceCreated', async () => {
this.createTestLibs() this.createTestLibs()
}) })
@ -140,9 +137,9 @@ module.exports = class TestTab extends ViewPlugin {
return this.element return this.element
} }
renderComponent () { renderComponent (testDirPath) {
ReactDOM.render( ReactDOM.render(
<SolidityUnitTesting testTab={this} helper={helper} /> <SolidityUnitTesting testTab={this} helper={helper} initialPath={testDirPath} />
, this.element) , this.element)
} }
} }

@ -8,7 +8,7 @@ import './css/style.css'
const _paq = (window as any)._paq = (window as any)._paq || [] // eslint-disable-line const _paq = (window as any)._paq = (window as any)._paq || [] // eslint-disable-line
/* eslint-disable-next-line */ /* eslint-disable-next-line */
export interface SolidityUnitTestingProps {} export interface SolidityUnitTestingProps { }
interface TestObject { interface TestObject {
fileName: string fileName: string
@ -17,7 +17,7 @@ interface TestObject {
export const SolidityUnitTesting = (props: Record<string, any>) => { export const SolidityUnitTesting = (props: Record<string, any>) => {
const {helper, testTab} = props const { helper, testTab, initialPath } = props
const { testTabLogic } = testTab const { testTabLogic } = testTab
const [defaultPath, setDefaultPath] = useState('tests') const [defaultPath, setDefaultPath] = useState('tests')
@ -30,14 +30,14 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
const [checkSelectAll, setCheckSelectAll] = useState(true) const [checkSelectAll, setCheckSelectAll] = useState(true)
const [testsOutput, setTestsOutput] = useState<Element[]>([]) const [testsOutput, setTestsOutput] = useState<Element[]>([])
const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true) const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true)
const [progressBarHidden, setProgressBarHidden] = useState(true) const [progressBarHidden, setProgressBarHidden] = useState(true)
const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState(true) const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState(true)
let [testFiles, setTestFiles] = useState<TestObject[]>([]) // eslint-disable-line let [testFiles, setTestFiles] = useState<TestObject[]>([]) // eslint-disable-line
const [pathOptions, setPathOptions] = useState(['']) const [pathOptions, setPathOptions] = useState([''])
const [inputPathValue, setInputPathValue] = useState('tests') const [inputPathValue, setInputPathValue] = useState('tests')
let [readyTestsNumber, setReadyTestsNumber] = useState(0) // eslint-disable-line let [readyTestsNumber, setReadyTestsNumber] = useState(0) // eslint-disable-line
@ -55,9 +55,9 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
let runningTestFileName: any let runningTestFileName: any
const filesContent: any = {} const filesContent: any = {}
const testsResultByFilename:Record<string, any> = {} const testsResultByFilename: Record<string, any> = {}
const trimTestDirInput = (input:string) => { const trimTestDirInput = (input: string) => {
if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/') if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/')
else return input.trim() else return input.trim()
} }
@ -71,21 +71,21 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
} }
const updateForNewCurrent = async (file = null) => { const updateForNewCurrent = async (file = null) => {
// Ensure that when someone clicks on compilation error and that opens a new file // Ensure that when someone clicks on compilation error and that opens a new file
// Test result, which is compilation error in this case, is not cleared // Test result, which is compilation error in this case, is not cleared
if (currentErrors) { if (currentErrors) {
if (Array.isArray(currentErrors) && currentErrors.length > 0) { if (Array.isArray(currentErrors) && currentErrors.length > 0) {
const errFiles = currentErrors.map(err => { if (err.sourceLocation && err.sourceLocation.file) return err.sourceLocation.file }) // eslint-disable-line const errFiles = currentErrors.map(err => { if (err.sourceLocation && err.sourceLocation.file) return err.sourceLocation.file }) // eslint-disable-line
if (errFiles.includes(file)) return if (errFiles.includes(file)) return
} else if (currentErrors.sourceLocation && currentErrors.sourceLocation.file && currentErrors.sourceLocation.file === file) return } else if (currentErrors.sourceLocation && currentErrors.sourceLocation.file && currentErrors.sourceLocation.file === file) return
} }
// if current file is changed while debugging and one of the files imported in test file are opened // if current file is changed while debugging and one of the files imported in test file are opened
// do not clear the test results in SUT plugin // do not clear the test results in SUT plugin
if (isDebugging && testTab.allFilesInvolved.includes(file)) return if (isDebugging && testTab.allFilesInvolved.includes(file)) return
allTests.current = [] allTests.current = []
updateTestFileList() updateTestFileList()
clearResults() clearResults()
try { try {
testTabLogic.getTests(async (error: any, tests: any) => { testTabLogic.getTests(async (error: any, tests: any) => {
// if (error) return tooltip(error) // if (error) return tooltip(error)
allTests.current = tests allTests.current = tests
@ -94,8 +94,8 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
if (!areTestsRunning) await updateRunAction(file) if (!areTestsRunning) await updateRunAction(file)
}) })
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} }
} }
/** /**
@ -109,6 +109,10 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
await updateForNewCurrent() await updateForNewCurrent()
} }
useEffect(() => {
if (initialPath) setCurrentPath(initialPath)
}, [initialPath]) // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => { useEffect(() => {
updateDirList('/') updateDirList('/')
updateForNewCurrent() updateForNewCurrent()
@ -132,7 +136,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
setCurrentPath(defaultPath) setCurrentPath(defaultPath)
}) })
testTab.fileManager.events.on('noFileSelected', () => {}) // eslint-disable-line testTab.fileManager.events.on('noFileSelected', () => { }) // eslint-disable-line
testTab.fileManager.events.on('currentFileChanged', (file: any, provider: any) => updateForNewCurrent(file)) testTab.fileManager.events.on('currentFileChanged', (file: any, provider: any) => updateForNewCurrent(file))
}, []) // eslint-disable-line }, []) // eslint-disable-line
@ -182,7 +186,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
} }
} }
const handleEnter = async(e:any) => { const handleEnter = async (e: any) => {
let inputPath = e.target.value let inputPath = e.target.value
inputPath = helper.removeMultipleSlashes(trimTestDirInput(inputPath)) inputPath = helper.removeMultipleSlashes(trimTestDirInput(inputPath))
setInputPathValue(inputPath) setInputPathValue(inputPath)
@ -194,7 +198,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
} }
} }
const handleCreateFolder = async() => { const handleCreateFolder = async () => {
let inputPath = trimTestDirInput(inputPathValue) let inputPath = trimTestDirInput(inputPathValue)
let path = helper.removeMultipleSlashes(inputPath) let path = helper.removeMultipleSlashes(inputPath)
if (path !== '/') path = helper.removeTrailingSlashes(path) if (path !== '/') path = helper.removeTrailingSlashes(path)
@ -266,7 +270,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
if (withoutLabel) { if (withoutLabel) {
const contractCard: any = ( const contractCard: any = (
<div id={runningTestFileName} data-id="testTabSolidityUnitTestsOutputheader" className="pt-1"> <div id={runningTestFileName} data-id="testTabSolidityUnitTestsOutputheader" className="pt-1">
<span className="font-weight-bold">{contract ? contract: ''} ({filename})</span> <span className="font-weight-bold">{contract ? contract : ''} ({filename})</span>
</div> </div>
) )
setTestsOutput(prevCards => ([...prevCards, contractCard])) setTestsOutput(prevCards => ([...prevCards, contractCard]))
@ -278,7 +282,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
title="At least one contract test failed" title="At least one contract test failed"
> >
FAIL FAIL
</div>) </div>)
else label = (<div else label = (<div
className="alert-success d-inline-block mb-1 mr-1 p-1 passed_{runningTestFileName}" className="alert-success d-inline-block mb-1 mr-1 p-1 passed_{runningTestFileName}"
title="All contract tests passed" title="All contract tests passed"
@ -303,17 +307,17 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
// show filename and contract // show filename and contract
renderContract(filename, contract, index) renderContract(filename, contract, index)
// show tests // show tests
for(const test of tests) { for (const test of tests) {
if(!test.rendered) { if (!test.rendered) {
let debugBtn let debugBtn
if (test.debugTxHash) { if (test.debugTxHash) {
const { web3, debugTxHash } = test const { web3, debugTxHash } = test
debugBtn = ( debugBtn = (
<div id={test.value.replaceAll(' ', '_')} className="btn border btn btn-sm ml-1" style={{ cursor: 'pointer' }} title="Start debugging" onClick={() => startDebug(debugTxHash, web3)}> <div id={test.value.replaceAll(' ', '_')} className="btn border btn btn-sm ml-1" style={{ cursor: 'pointer' }} title="Start debugging" onClick={() => startDebug(debugTxHash, web3)}>
<i className="fas fa-bug"></i> <i className="fas fa-bug"></i>
</div> </div>
) )
} }
if (test.type === 'testPass') { if (test.type === 'testPass') {
if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value)
const testPassCard: any = ( const testPassCard: any = (
@ -325,71 +329,71 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
> >
<div className="d-flex my-1 align-items-start justify-content-between"> <div className="d-flex my-1 align-items-start justify-content-between">
<span > {test.value}</span> <span > {test.value}</span>
{debugBtn} {debugBtn}
</div> </div>
</div> </div>
) )
setTestsOutput(prevCards => ([...prevCards, testPassCard])) setTestsOutput(prevCards => ([...prevCards, testPassCard]))
test.rendered = true test.rendered = true
} else if (test.type === 'testFailure') { } else if (test.type === 'testFailure') {
if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value)
if (!test.assertMethod) { if (!test.assertMethod) {
const testFailCard1: any = (<div const testFailCard1: any = (<div
className="bg-light mb-2 px-2 testLog d-flex flex-column text-danger border-0" className="bg-light mb-2 px-2 testLog d-flex flex-column text-danger border-0"
id={"UTContext" + test.context} id={"UTContext" + test.context}
onClick={() => highlightLocation(test.location, test.filename)} onClick={() => highlightLocation(test.location, test.filename)}
> >
<div className="d-flex my-1 align-items-start justify-content-between"> <div className="d-flex my-1 align-items-start justify-content-between">
<span> {test.value}</span> <span> {test.value}</span>
{debugBtn} {debugBtn}
</div> </div>
<span className="text-dark">Error Message:</span> <span className="text-dark">Error Message:</span>
<span className="pb-2 text-break">"{test.errMsg}"</span> <span className="pb-2 text-break">"{test.errMsg}"</span>
</div>) </div>)
setTestsOutput(prevCards => ([...prevCards, testFailCard1])) setTestsOutput(prevCards => ([...prevCards, testFailCard1]))
} else { } else {
const preposition = test.assertMethod === 'equal' || test.assertMethod === 'notEqual' ? 'to' : '' const preposition = test.assertMethod === 'equal' || test.assertMethod === 'notEqual' ? 'to' : ''
const method = test.assertMethod === 'ok' ? '' : test.assertMethod const method = test.assertMethod === 'ok' ? '' : test.assertMethod
const expected = test.assertMethod === 'ok' ? '\'true\'' : test.expected const expected = test.assertMethod === 'ok' ? '\'true\'' : test.expected
const testFailCard2: any = (<div const testFailCard2: any = (<div
className="bg-light mb-2 px-2 testLog d-flex flex-column text-danger border-0" className="bg-light mb-2 px-2 testLog d-flex flex-column text-danger border-0"
id={"UTContext" + test.context} id={"UTContext" + test.context}
onClick={() => highlightLocation(test.location, test.filename)} onClick={() => highlightLocation(test.location, test.filename)}
> >
<div className="d-flex my-1 align-items-start justify-content-between"> <div className="d-flex my-1 align-items-start justify-content-between">
<span> {test.value}</span> <span> {test.value}</span>
{debugBtn} {debugBtn}
</div> </div>
<span className="text-dark">Error Message:</span> <span className="text-dark">Error Message:</span>
<span className="pb-2 text-break">"{test.errMsg}"</span> <span className="pb-2 text-break">"{test.errMsg}"</span>
<span className="text-dark">Assertion:</span> <span className="text-dark">Assertion:</span>
<div className="d-flex flex-wrap"> <div className="d-flex flex-wrap">
<span>Expected value should be</span> <span>Expected value should be</span>
<div className="mx-1 font-weight-bold">{method}</div> <div className="mx-1 font-weight-bold">{method}</div>
<div>{preposition} {expected}</div> <div>{preposition} {expected}</div>
</div> </div>
<span className="text-dark">Received value:</span> <span className="text-dark">Received value:</span>
<span>{test.returned}</span> <span>{test.returned}</span>
<span className="text-dark text-sm pb-2">Skipping the remaining tests of the function.</span> <span className="text-dark text-sm pb-2">Skipping the remaining tests of the function.</span>
</div>) </div>)
setTestsOutput(prevCards => ([...prevCards, testFailCard2])) setTestsOutput(prevCards => ([...prevCards, testFailCard2]))
} }
test.rendered = true test.rendered = true
} else if (test.type === 'logOnly') { } else if (test.type === 'logOnly') {
if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value)
test.rendered = true test.rendered = true
} }
} }
} }
} }
const showTestsResult = () => { const showTestsResult = () => {
const filenames = Object.keys(testsResultByFilename) const filenames = Object.keys(testsResultByFilename)
for(const filename of filenames) { for (const filename of filenames) {
const fileTestsResult = testsResultByFilename[filename] const fileTestsResult = testsResultByFilename[filename]
const contracts = Object.keys(fileTestsResult) const contracts = Object.keys(fileTestsResult)
for(const contract of contracts) { for (const contract of contracts) {
if(contract && contract !== 'summary' && contract !== 'errors') { if (contract && contract !== 'summary' && contract !== 'errors') {
runningTestFileName = cleanFileName(filename, contract) runningTestFileName = cleanFileName(filename, contract)
const tests = fileTestsResult[contract] const tests = fileTestsResult[contract]
if (tests?.length) { if (tests?.length) {
@ -402,19 +406,19 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
const errors = fileTestsResult['errors'] const errors = fileTestsResult['errors']
if (errors && errors.errors) { if (errors && errors.errors) {
errors.errors.forEach((err: any) => { errors.errors.forEach((err: any) => {
const errorCard: any = <Renderer message={err.formattedMessage || err.message} plugin={testTab} opt={{ type: err.severity, errorType: err.type }} /> const errorCard: any = <Renderer message={err.formattedMessage || err.message} plugin={testTab} opt={{ type: err.severity, errorType: err.type }} />
setTestsOutput(prevCards => ([...prevCards, errorCard])) setTestsOutput(prevCards => ([...prevCards, errorCard]))
}) })
} else if (errors && Array.isArray(errors) && (errors[0].message || errors[0].formattedMessage)) { } else if (errors && Array.isArray(errors) && (errors[0].message || errors[0].formattedMessage)) {
errors.forEach((err) => { errors.forEach((err) => {
const errorCard: any = <Renderer message={err.formattedMessage || err.message} plugin={testTab} opt={{ type: err.severity, errorType: err.type }} /> const errorCard: any = <Renderer message={err.formattedMessage || err.message} plugin={testTab} opt={{ type: err.severity, errorType: err.type }} />
setTestsOutput(prevCards => ([...prevCards, errorCard])) setTestsOutput(prevCards => ([...prevCards, errorCard]))
}) })
} else if (errors && !errors.errors && !Array.isArray(errors)) { } else if (errors && !errors.errors && !Array.isArray(errors)) {
// To track error like this: https://github.com/ethereum/remix/pull/1438 // To track error like this: https://github.com/ethereum/remix/pull/1438
const errorCard: any = <Renderer message={errors.formattedMessage || errors.message} plugin={testTab} opt={{ type: 'error' }} /> const errorCard: any = <Renderer message={errors.formattedMessage || errors.message} plugin={testTab} opt={{ type: 'error' }} />
setTestsOutput(prevCards => ([...prevCards, errorCard])) setTestsOutput(prevCards => ([...prevCards, errorCard]))
} }
} }
} }
// show summary // show summary
@ -429,17 +433,17 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
setTestsOutput(prevCards => ([...prevCards, summaryCard])) setTestsOutput(prevCards => ([...prevCards, summaryCard]))
fileTestsResult['summary']['rendered'] = true fileTestsResult['summary']['rendered'] = true
} }
} }
} }
const testCallback = (result: any) => { const testCallback = (result: any) => {
if(result.filename) { if (result.filename) {
if(!testsResultByFilename[result.filename]) { if (!testsResultByFilename[result.filename]) {
testsResultByFilename[result.filename] = {} testsResultByFilename[result.filename] = {}
testsResultByFilename[result.filename]['summary'] = {} testsResultByFilename[result.filename]['summary'] = {}
} }
if(result.type === 'contract') { if (result.type === 'contract') {
testsResultByFilename[result.filename][result.value]= {} testsResultByFilename[result.filename][result.value] = {}
testsResultByFilename[result.filename][result.value] = [] testsResultByFilename[result.filename][result.value] = []
} else { } else {
// Set that this test is not rendered on UI // Set that this test is not rendered on UI
@ -469,17 +473,17 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
if (result) { if (result) {
const totalTime = parseFloat(result.totalTime).toFixed(2) const totalTime = parseFloat(result.totalTime).toFixed(2)
const testsSummary = { filename, passed: result.totalPassing, failed: result.totalFailing, timeTaken: totalTime, rendered: false } const testsSummary = { filename, passed: result.totalPassing, failed: result.totalFailing, timeTaken: totalTime, rendered: false }
testsResultByFilename[filename]['summary']= testsSummary testsResultByFilename[filename]['summary'] = testsSummary
showTestsResult() showTestsResult()
} else if (_errors) { } else if (_errors) {
if(!testsResultByFilename[filename]) { if (!testsResultByFilename[filename]) {
testsResultByFilename[filename] = {} testsResultByFilename[filename] = {}
} }
testsResultByFilename[filename]['errors'] = _errors testsResultByFilename[filename]['errors'] = _errors
setTestsExecutionStoppedErrorHidden(false) setTestsExecutionStoppedErrorHidden(false)
showTestsResult() showTestsResult()
} }
if (hasBeenStopped.current && (readyTestsNumber !== runningTestsNumber)) { if (hasBeenStopped.current && (readyTestsNumber !== runningTestsNumber)) {
// if all tests has been through before stopping no need to print this. // if all tests has been through before stopping no need to print this.
setTestsExecutionStoppedHidden(false) setTestsExecutionStoppedHidden(false)
@ -557,7 +561,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
}) })
} }
const updateRunAction = async (currentFile : any = null) => { const updateRunAction = async (currentFile: any = null) => {
const isSolidityActive = await testTab.appManager.isActive('solidity') const isSolidityActive = await testTab.appManager.isActive('solidity')
if (!isSolidityActive || !selectedTests.current?.length) { if (!isSolidityActive || !selectedTests.current?.length) {
setDisableRunButton(true) setDisableRunButton(true)
@ -581,7 +585,7 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
return selectedTestsList.map(testFileObj => testFileObj.fileName) return selectedTestsList.map(testFileObj => testFileObj.fileName)
} }
const toggleCheckbox = (eChecked: any, index:any) => { const toggleCheckbox = (eChecked: any, index: any) => {
testFiles[index].checked = eChecked testFiles[index].checked = eChecked
setTestFiles(testFiles) setTestFiles(testFiles)
selectedTests.current = getCurrentSelectedTests() selectedTests.current = getCurrentSelectedTests()
@ -599,10 +603,10 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
} }
const checkAll = (event: any) => { const checkAll = (event: any) => {
testFiles.forEach((testFileObj) => testFileObj.checked = event.target.checked) testFiles.forEach((testFileObj) => testFileObj.checked = event.target.checked)
setTestFiles(testFiles) setTestFiles(testFiles)
setCheckSelectAll(event.target.checked) setCheckSelectAll(event.target.checked)
if(event.target.checked) { if (event.target.checked) {
selectedTests.current = getCurrentSelectedTests() selectedTests.current = getCurrentSelectedTests()
setDisableRunButton(false) setDisableRunButton(false)
} else { } else {
@ -612,28 +616,28 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
} }
const updateTestFileList = () => { const updateTestFileList = () => {
if(allTests.current?.length) { if (allTests.current?.length) {
testFiles = allTests.current.map((testFile: any) => { return {'fileName': testFile, 'checked': true }}) testFiles = allTests.current.map((testFile: any) => { return { 'fileName': testFile, 'checked': true } })
setCheckSelectAll(true) setCheckSelectAll(true)
} }
else else
testFiles = [] testFiles = []
setTestFiles(testFiles) setTestFiles(testFiles)
} }
return ( return (
<div className="px-2" id="testView"> <div className="px-2" id="testView">
<div className="infoBox"> <div className="infoBox">
<p className="text-lg"> Test your smart contract in Solidity.</p> <p className="text-lg"> Test your smart contract in Solidity.</p>
<p> Select directory to load and generate test files.</p> <p> Select directory to load and generate test files.</p>
<label>Test directory:</label> <label>Test directory:</label>
<div> <div>
<div className="d-flex p-2"> <div className="d-flex p-2">
<datalist id="utPathList">{ <datalist id="utPathList">{
pathOptions.map(function (path) { pathOptions.map(function (path) {
return <option key={path}>{path}</option> return <option key={path}>{path}</option>
}) })
} }
</datalist> </datalist>
<input <input
placeholder={defaultPath} placeholder={defaultPath}
@ -644,8 +648,8 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
name="utPath" name="utPath"
value={inputPathValue} value={inputPathValue}
title="Press 'Enter' to change the path for test files." title="Press 'Enter' to change the path for test files."
style= {{ backgroundImage: "var(--primary)"}} style={{ backgroundImage: "var(--primary)" }}
onKeyUp= {handleTestDirInput} onKeyUp={handleTestDirInput}
onChange={handleEnter} onChange={handleEnter}
/> />
<button <button
@ -657,65 +661,65 @@ export const SolidityUnitTesting = (props: Record<string, any>) => {
> >
Create Create
</button> </button>
</div>
</div> </div>
</div> </div>
<div> </div>
<div className="d-flex p-2"> <div>
<button <div className="d-flex p-2">
className="btn border w-50" <button
data-id="testTabGenerateTestFile" className="btn border w-50"
title="Generate sample test file." data-id="testTabGenerateTestFile"
disabled={disableGenerateButton} title="Generate sample test file."
onClick={() => { disabled={disableGenerateButton}
testTabLogic.generateTestFile() onClick={() => {
updateForNewCurrent() testTabLogic.generateTestFile()
}} updateForNewCurrent()
> }}
Generate >
</button> Generate
<a className="btn border text-decoration-none pr-0 d-flex w-50 ml-2" title="Check out documentation." target="__blank" href="https://remix-ide.readthedocs.io/en/latest/unittesting.html#test-directory"> </button>
<label className="btn p-1 ml-2 m-0">How to use...</label> <a className="btn border text-decoration-none pr-0 d-flex w-50 ml-2" title="Check out documentation." target="__blank" href="https://remix-ide.readthedocs.io/en/latest/unittesting.html#test-directory">
</a> <label className="btn p-1 ml-2 m-0">How to use...</label>
</div> </a>
<div className="d-flex p-2"> </div>
<button id="runTestsTabRunAction" title={runButtonTitle} data-id="testTabRunTestsTabRunAction" className="w-50 btn btn-primary" disabled={disableRunButton} onClick={runTests}> <div className="d-flex p-2">
<span className="fas fa-play ml-2"></span> <button id="runTestsTabRunAction" title={runButtonTitle} data-id="testTabRunTestsTabRunAction" className="w-50 btn btn-primary" disabled={disableRunButton} onClick={runTests}>
<label className="labelOnBtn btn btn-primary p-1 ml-2 m-0">Run</label> <span className="fas fa-play ml-2"></span>
</button> <label className="labelOnBtn btn btn-primary p-1 ml-2 m-0">Run</label>
<button id="runTestsTabStopAction" data-id="testTabRunTestsTabStopAction" className="w-50 pl-2 ml-2 btn btn-secondary" disabled={disableStopButton} title="Stop running tests" onClick={stopTests}> </button>
<span className="fas fa-stop ml-2"></span> <button id="runTestsTabStopAction" data-id="testTabRunTestsTabStopAction" className="w-50 pl-2 ml-2 btn btn-secondary" disabled={disableStopButton} title="Stop running tests" onClick={stopTests}>
<label className="labelOnBtn btn btn-secondary p-1 ml-2 m-0" id="runTestsTabStopActionLabel">{stopButtonLabel}</label> <span className="fas fa-stop ml-2"></span>
</button> <label className="labelOnBtn btn btn-secondary p-1 ml-2 m-0" id="runTestsTabStopActionLabel">{stopButtonLabel}</label>
</div> </button>
<div className="d-flex align-items-center mx-3 pb-2 mt-2 border-bottom"> </div>
<input id="checkAllTests" <div className="d-flex align-items-center mx-3 pb-2 mt-2 border-bottom">
type="checkbox" <input id="checkAllTests"
data-id="testTabCheckAllTests" type="checkbox"
onClick={checkAll} data-id="testTabCheckAllTests"
checked={checkSelectAll} onClick={checkAll}
onChange={() => {}} // eslint-disable-line checked={checkSelectAll}
/> onChange={() => { }} // eslint-disable-line
<label className="text-nowrap pl-2 mb-0" htmlFor="checkAllTests"> Select all </label> />
</div> <label className="text-nowrap pl-2 mb-0" htmlFor="checkAllTests"> Select all </label>
<div className="testList py-2 mt-0 border-bottom">{testFiles?.length ? testFiles.map((testFileObj: any, index) => { </div>
const elemId = `singleTest${testFileObj.fileName}` <div className="testList py-2 mt-0 border-bottom">{testFiles?.length ? testFiles.map((testFileObj: any, index) => {
return ( const elemId = `singleTest${testFileObj.fileName}`
<div className="d-flex align-items-center py-1" key={index}> return (
<input className="singleTest" id={elemId} onChange={(e) => toggleCheckbox(e.target.checked, index)} type="checkbox" checked={testFileObj.checked}/> <div className="d-flex align-items-center py-1" key={index}>
<label className="singleTestLabel text-nowrap pl-2 mb-0" htmlFor={elemId}>{testFileObj.fileName}</label> <input className="singleTest" id={elemId} onChange={(e) => toggleCheckbox(e.target.checked, index)} type="checkbox" checked={testFileObj.checked} />
</div> <label className="singleTestLabel text-nowrap pl-2 mb-0" htmlFor={elemId}>{testFileObj.fileName}</label>
) </div>
}) )
: "No test file available" } </div> })
<div className="align-items-start flex-column mt-2 mx-3 mb-0"> : "No test file available"} </div>
<span className='text-info h6' hidden={progressBarHidden}>Progress: {readyTestsNumber} finished (of {runningTestsNumber})</span> <div className="align-items-start flex-column mt-2 mx-3 mb-0">
<label className="text-warning h6" data-id="testTabTestsExecutionStopped" hidden={testsExecutionStoppedHidden}>The test execution has been stopped</label> <span className='text-info h6' hidden={progressBarHidden}>Progress: {readyTestsNumber} finished (of {runningTestsNumber})</span>
<label className="text-danger h6" data-id="testTabTestsExecutionStoppedError" hidden={testsExecutionStoppedErrorHidden}>The test execution has been stopped because of error(s) in your test file</label> <label className="text-warning h6" data-id="testTabTestsExecutionStopped" hidden={testsExecutionStoppedHidden}>The test execution has been stopped</label>
</div> <label className="text-danger h6" data-id="testTabTestsExecutionStoppedError" hidden={testsExecutionStoppedErrorHidden}>The test execution has been stopped because of error(s) in your test file</label>
<div>{testsOutput}</div>
</div> </div>
<div>{testsOutput}</div>
</div> </div>
</div>
) )
} }

Loading…
Cancel
Save