Merge branch 'master' of https://github.com/ethereum/remix-project into indexdb

pull/5370/head
bunsenstraat 3 years ago
commit de402bb813
  1. 55
      apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts
  2. 14
      apps/remix-ide/src/app/tabs/test-tab.js
  3. 9
      libs/remix-tests/src/testRunner.ts

@ -90,11 +90,10 @@ module.exports = {
.waitForElementContainsText('*[data-id="testTabTestsExecutionStopped"]', 'The test execution has been stopped', 60000)
},
'Should fail on compilation': function (browser: NightwatchBrowser) {
'Should fail on compilation, open file on error click, not disappear error': function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
.addFile('tests/compilationError_test.sol', sources[0]['compilationError_test.sol'])
.clickLaunchIcon('filePanel')
.openFile('tests/compilationError_test.sol')
.click('div[title="default_workspace/tests/compilationError_test.sol"] span[class="close"]')
.clickLaunchIcon('solidityUnitTesting')
.pause(2000)
.click('*[data-id="testTabCheckAllTests"]')
@ -102,6 +101,12 @@ module.exports = {
.scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]')
.waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'SyntaxError: No visibility specified', 120000)
.waitForElementContainsText('*[data-id="testTabTestsExecutionStoppedError"]', 'The test execution has been stopped because of error(s) in your test file', 120000)
.click('*[data-id="tests/compilationError_test.sol"]')
.pause(1000)
.getEditorValue((content) => browser.assert.ok(content.indexOf('contract failOnCompilation {') !== -1))
// Verify that compilation error is still present after a file is opened
// usually, tests result is cleared on opening a new file
.verify.elementPresent('*[data-id="tests/compilationError_test.sol"]')
},
'Should fail on deploy': function (browser: NightwatchBrowser) {
@ -207,6 +212,23 @@ module.exports = {
.removeFile('tests/hhLogs_test.sol', 'workspace_new')
},
'Solidity Unit tests with hardhat console log for EVM revert': function (browser: NightwatchBrowser) {
browser
.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
.addFile('tests/ballotFailedLog_test.sol', sources[0]['tests/ballotFailedLog_test.sol'])
.clickLaunchIcon('solidityUnitTesting')
.waitForElementVisible('*[id="singleTesttests/4_Ballot_test.sol"]', 60000)
.click('*[id="singleTesttests/4_Ballot_test.sol"]')
.click('#runTestsTabRunAction')
.pause(2000)
.waitForElementVisible('*[data-id="testTabSolidityUnitTestsOutputheader"]', 120000)
.waitForElementContainsText('#solidityUnittestsOutput', 'tests/ballotFailedLog_test.sol', 60000)
.assert.containsText('#journal > div:nth-child(6) > span > div', 'Check winning proposal:')
.assert.containsText('#journal > div:nth-child(6) > span > div', 'Inside checkWinningProposal')
.openFile('tests/ballotFailedLog_test.sol')
.removeFile('tests/ballotFailedLog_test.sol', 'workspace_new')
},
'Debug failed test using debugger': function (browser: NightwatchBrowser) {
browser
.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
@ -424,7 +446,7 @@ const sources = [
},
'compilationError_test.sol': {
content: `
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
contract failOnCompilation {
fallback() {
@ -483,6 +505,31 @@ const sources = [
}
}`
},
'tests/ballotFailedLog_test.sol': {
content: `// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "remix_tests.sol"; // this import is automatically injected by Remix.
import "../contracts/3_Ballot.sol";
import "hardhat/console.sol";
contract BallotTest {
bytes32[] proposalNames;
Ballot ballotToTest;
function beforeAll () public {
proposalNames.push(bytes32("candidate1"));
ballotToTest = new Ballot(proposalNames);
}
function checkWinningProposal () public {
console.log("Inside checkWinningProposal");
ballotToTest.vote(1); // This will revert the transaction
}
}`
},
'tests/hhLogs_test.sol': {
content: `// SPDX-License-Identifier: GPL-3.0

@ -44,6 +44,7 @@ module.exports = class TestTab extends ViewPlugin {
this.offsetToLineColumnConverter = offsetToLineColumnConverter
this.allFilesInvolved = []
this.isDebugging = false
this.currentErrors = []
appManager.event.on('activate', (name) => {
if (name === 'solidity') this.updateRunAction()
@ -117,6 +118,14 @@ module.exports = class TestTab extends ViewPlugin {
}
async updateForNewCurrent (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
if (this.currentErrors) {
if (Array.isArray(this.currentErrors) && this.currentErrors.length > 0) {
const errFiles = this.currentErrors.map(err => { if (err.sourceLocation && err.sourceLocation.file) return err.sourceLocation.file })
if (errFiles.includes(file)) return
} else if (this.currentErrors.sourceLocation && this.currentErrors.sourceLocation.file && this.currentErrors.sourceLocation.file === file) return
}
// 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
if (this.isDebugging && this.allFilesInvolved.includes(file)) return
@ -377,12 +386,13 @@ module.exports = class TestTab extends ViewPlugin {
this.testsOutput.hidden = false
if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) {
this.testCallback({ type: 'contract', filename })
this.currentErrors = _errors.errors
this.setHeader(false)
}
if (_errors && _errors.errors) {
_errors.errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity }))
_errors.errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity, errorType: err.type }))
} else if (_errors && Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage)) {
_errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity }))
_errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity, errorType: err.type }))
} else if (_errors && !_errors.errors && !Array.isArray(_errors)) {
// To track error like this: https://github.com/ethereum/remix/pull/1438
this.renderer.error(_errors.formattedMessage || _errors.message, this.testsOutput, { type: 'error' })

@ -232,6 +232,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
testCallback(undefined, resp)
async.eachOfLimit(runList, 1, function (func, index, next) {
let sender: string | null = null
let hhLogs
if (func.signature) {
sender = getOverridedSender(contractDetails.userdoc, func.signature, contractDetails.evm.methodIdentifiers)
if (opts.accounts && sender) {
@ -293,7 +294,6 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
sendParams.gas = 10000000 * 8
method.send(sendParams).on('receipt', async (receipt) => {
try {
let hhLogs
if (web3.eth && web3.eth.getHHLogsForTx) hhLogs = await web3.eth.getHHLogsForTx(receipt.transactionHash)
const time: number = (Date.now() - startTime) / 1000.0
const assertionEventHashes = assertionEvents.map(e => Web3.utils.sha3(e.name + '(' + e.params.join() + ')'))
@ -366,7 +366,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
console.error(err)
return next(err)
}
}).on('error', function (err: Error) {
}).on('error', async (err: Error) => {
const time: number = (Date.now() - startTime) / 1000.0
const resp: TestResultInterface = {
type: 'testFailure',
@ -377,6 +377,11 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
context: testName,
web3
}
if (err.message.includes('Transaction has been reverted by the EVM')) {
const txHash = JSON.parse(err.message.replace('Transaction has been reverted by the EVM:', '')).transactionHash
if (web3.eth && web3.eth.getHHLogsForTx) hhLogs = await web3.eth.getHHLogsForTx(txHash)
if (hhLogs) resp.hhLogs = hhLogs
}
testCallback(undefined, resp)
failureNum += 1
timePassed += time

Loading…
Cancel
Save