diff --git a/apps/remix-ide-e2e/src/examples/example-contracts.ts b/apps/remix-ide-e2e/src/examples/example-contracts.ts index 6f1a43d19a..1247244df0 100644 --- a/apps/remix-ide-e2e/src/examples/example-contracts.ts +++ b/apps/remix-ide-e2e/src/examples/example-contracts.ts @@ -215,6 +215,72 @@ contract Ballot { } ` +const ballot_0_4_11 = `pragma solidity >=0.4.10 <0.7.0; +contract Ballot { + + struct Voter { + uint weight; + bool voted; + uint8 vote; + address delegate; + } + struct Proposal { + uint voteCount; + } + + address chairperson; + mapping(address => Voter) voters; + Proposal[] proposals; + + /// Create a new ballot with $(_numProposals) different proposals. + function Ballot (uint8 _numProposals) public { + chairperson = msg.sender; + voters[chairperson].weight = 1; + proposals.length = _numProposals; + } + + /// Give $(toVoter) the right to vote on this ballot. + /// May only be called by $(chairperson). + function giveRightToVote(address toVoter) public { + if (msg.sender != chairperson || voters[toVoter].voted) return; + voters[toVoter].weight = 1; + } + + /// Delegate your vote to the voter $(to). + function delegate(address to) public { + Voter storage sender = voters[msg.sender]; // assigns reference + if (sender.voted) return; + while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) + to = voters[to].delegate; + if (to == msg.sender) return; + sender.voted = true; + sender.delegate = to; + Voter storage delegateTo = voters[to]; + if (delegateTo.voted) + proposals[delegateTo.vote].voteCount += sender.weight; + else + delegateTo.weight += sender.weight; + } + + /// Give a single vote to proposal $(toProposal). + function vote(uint8 toProposal) public { + Voter storage sender = voters[msg.sender]; + if (sender.voted || toProposal >= proposals.length) return; + sender.voted = true; + sender.vote = toProposal; + proposals[toProposal].voteCount += sender.weight; + } + + function winningProposal() public returns (uint8 _winningProposal) { + uint256 winningVoteCount = 0; + for (uint8 prop = 0; prop < proposals.length; prop++) + if (proposals[prop].voteCount > winningVoteCount) { + winningVoteCount = proposals[prop].voteCount; + _winningProposal = prop; + } + } +}` + const ballotTest = `pragma solidity >=0.4.22 <0.7.0; import "remix_tests.sol"; // this import is automatically injected by Remix. import "../3_Ballot.sol"; @@ -245,5 +311,6 @@ export default { storage: { name: '1_Storage.sol', content: storage }, owner: { name: '2_Owner.sol', content: owner }, ballot: { name: '3_Ballot.sol', content: ballot }, + ballot_0_4_11: { name: 'ballot_0_4_11.sol', content: ballot_0_4_11 }, ballot_test: { name: 'tests/4_Ballot_test.sol', content: ballotTest } } diff --git a/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts b/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts new file mode 100644 index 0000000000..8cd7f71afa --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.ts @@ -0,0 +1,167 @@ +'use strict' + +import { NightwatchBrowser } from 'nightwatch' +import init from '../helpers/init' +import sauce from './sauce' +import examples from '../examples/example-contracts' + +const sources = [ + {'browser/Untitled.sol': { content: examples.ballot_0_4_11.content }} +] + +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + init(browser, done, null, false) + }, + '@sources': function () { + return sources + }, + 'Compile Ballot with compiler version 0.4.11': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .clickLaunchIcon('solidity') + .setSolidityCompilerVersion('soljson-v0.4.11+commit.68ef5810.js') + .waitForElementVisible('[for="autoCompile"]') + .click('[for="autoCompile"]') + .verify.elementPresent('[data-id="compilerContainerAutoCompile"]:checked') + .testContracts('Untitled.sol', sources[0]['browser/Untitled.sol'], ['Ballot']) + + }, + + 'Deploy Ballot': function (browser: NightwatchBrowser) { + browser.pause(500) + .testContracts('Untitled.sol', sources[0]['browser/Untitled.sol'], ['Ballot']) + .clickLaunchIcon('udapp') + .selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') + .setValue('input[placeholder="uint8 _numProposals"]', '2') + .click('*[data-id="Deploy - transact (not payable)"]') + .waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]') + .click('*[data-id="universalDappUiTitleExpander"]') + .clickFunction('delegate - transact (not payable)', {types: 'address to', values: '"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"'}) + .testFunction('0x41fab8ea5b1d9fba5e0a6545ca1a2d62fff518578802c033c2b9a031a01c31b3', + { + status: '0x1 Transaction mined and execution succeed', + 'transaction hash': '0x41fab8ea5b1d9fba5e0a6545ca1a2d62fff518578802c033c2b9a031a01c31b3', + 'decoded input': { 'address to': '0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB' } + }) + }, + + 'Debug Ballot / delegate': function (browser: NightwatchBrowser) { + browser.pause(500) + .click('*[data-id="txLoggerDebugButton0x41fab8ea5b1d9fba5e0a6545ca1a2d62fff518578802c033c2b9a031a01c31b3"]') + .pause(2000) + .click('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]') + .pause(2000) + .goToVMTraceStep(20) + .pause(1000) + .checkVariableDebug('callstackpanel', ["0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"]) + }, + + 'Access Ballot via at address': function (browser: NightwatchBrowser) { + browser.clickLaunchIcon('udapp') + .click('*[data-id="universalDappUiUdappClose"]') + .addFile('ballot.abi', { content: ballotABI }) + .addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3B', true, false) + .clickLaunchIcon('fileExplorers') + .addAtAddressInstance('0x692a70D2e424a56D2C6C27aA97D1a86395877b3A', true, true) + .pause(500) + .waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]') + .click('*[data-id="universalDappUiTitleExpander"]') + .clickFunction('delegate - transact (not payable)', {types: 'address to', values: '"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db"'}) + .testFunction('0xca58080c8099429caeeffe43b8104df919c2c543dceb9edf9242fa55f045c803', + { + status: '0x1 Transaction mined and execution succeed', + 'transaction hash': '0xca58080c8099429caeeffe43b8104df919c2c543dceb9edf9242fa55f045c803', + 'decoded input': { 'address to': '0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB' } + }) + }, + + 'Deploy and use Ballot using external web3': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="settingsWeb3Mode"]') + .modalFooterOKClick() + .clickLaunchIcon('solidity') + .testContracts('Untitled.sol', sources[0]['browser/Untitled.sol'], ['Ballot']) + .clickLaunchIcon('udapp') + .setValue('input[placeholder="uint8 _numProposals"]', '2') + .click('*[data-id="Deploy - transact (not payable)"]') + .clickInstance(0) + .click('*[data-id="terminalClearConsole"]') + .clickFunction('delegate - transact (not payable)', {types: 'address to', values: '0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c'}) + .journalLastChildIncludes('Ballot.delegate(address)') + .journalLastChildIncludes('data: 0x5c1...a733c') + .end() + }, + + tearDown: sauce +} + +const ballotABI = `[ + { + "constant": false, + "inputs": [ + { + "name": "to", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "payable": false, + "type": "function", + "stateMutability": "nonpayable" + }, + { + "constant": false, + "inputs": [], + "name": "winningProposal", + "outputs": [ + { + "name": "_winningProposal", + "type": "uint8" + } + ], + "payable": false, + "type": "function", + "stateMutability": "nonpayable" + }, + { + "constant": false, + "inputs": [ + { + "name": "toVoter", + "type": "address" + } + ], + "name": "giveRightToVote", + "outputs": [], + "payable": false, + "type": "function", + "stateMutability": "nonpayable" + }, + { + "constant": false, + "inputs": [ + { + "name": "toProposal", + "type": "uint8" + } + ], + "name": "vote", + "outputs": [], + "payable": false, + "type": "function", + "stateMutability": "nonpayable" + }, + { + "inputs": [ + { + "name": "_numProposals", + "type": "uint8" + } + ], + "payable": false, + "type": "constructor", + "stateMutability": "nonpayable" + } +]` diff --git a/package.json b/package.json index 5bd6ec2249..8345788e37 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "nightwatch_local_firefox": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --env=firefox", "nightwatch_local_chrome": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --env=chrome", "nightwatch_local_ballot": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --filePath=dist/apps/remix-ide-e2e/src/tests/ballot.test.js --env=chrome", + "nightwatch_local_ballot_0_4_11": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --filePath=dist/apps/remix-ide-e2e/src/tests/ballot_0_4_11.test.js --env=chrome", "nightwatch_local_usingWorker": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --filePath=dist/apps/remix-ide-e2e/src/tests/usingWebWorker.test.js --env=chrome", "nightwatch_local_libraryDeployment": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --filePath=dist/apps/remix-ide-e2e/src/tests/libraryDeployment.test.js --env=chrome", "nightwatch_local_solidityImport": "nx build remix-ide-e2e; nx e2e remix-ide-e2e --filePath=dist/apps/remix-ide-e2e/src/tests/solidityImport.test.js --env=chrome",