@@ -147,33 +147,98 @@ module.exports = {
147147 . waitForElementContainsText ( '.contextview .type' , 'uint256' )
148148 . waitForElementContainsText ( '.contextview .name' , 'number' )
149149 . click ( '.contextview [data-action="previous"]' ) // declaration
150+ . pause ( 1000 )
150151 . execute ( ( ) => {
151152 return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
152153 } , [ ] , ( result ) => {
153154 console . log ( 'result' , result )
154155 browser . assert . equal ( result . value , '180' )
155156 } )
156157 . click ( '.contextview [data-action="next"]' ) // back to the initial state
158+ . pause ( 1000 )
157159 . execute ( ( ) => {
158160 return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
159161 } , [ ] , ( result ) => {
160162 console . log ( 'result' , result )
161163 browser . assert . equal ( result . value , '323' )
162164 } )
163165 . click ( '.contextview [data-action="next"]' ) // next reference
166+ . pause ( 1000 )
164167 . execute ( ( ) => {
165168 return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
166169 } , [ ] , ( result ) => {
167170 console . log ( 'result' , result )
168171 browser . assert . equal ( result . value , '489' )
169172 } )
170173 . click ( '.contextview [data-action="gotoref"]' ) // back to the declaration
174+ . pause ( 1000 )
171175 . execute ( ( ) => {
172176 return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
173177 } , [ ] , ( result ) => {
174178 console . log ( 'result' , result )
175179 browser . assert . equal ( result . value , '180' )
176180 } )
181+ } ,
182+
183+ 'Should display the context view, loop over "Owner" by switching file #group2' : function ( browser : NightwatchBrowser ) {
184+ browser
185+ . clickLaunchIcon ( 'solidity' )
186+ . click ( '[for="autoCompile"]' ) // disable auto compile
187+ . openFile ( 'contracts' )
188+ . openFile ( 'contracts/3_Ballot.sol' )
189+ . waitForElementVisible ( '#editorView' )
190+ . setEditorValue ( BallotWithARefToOwner )
191+ . clickLaunchIcon ( 'solidity' )
192+ . click ( '*[data-id="compilerContainerCompileBtn"]' ) // compile
193+ . pause ( 2000 )
194+ . execute ( ( ) => {
195+ ( document . getElementById ( 'editorView' ) as any ) . gotoLine ( 14 , 6 )
196+ } , [ ] , ( ) => { } )
197+ . waitForElementVisible ( '.contextview' )
198+ . waitForElementContainsText ( '.contextview .type' , 'ContractDefinition' )
199+ . waitForElementContainsText ( '.contextview .name' , 'Owner' )
200+ . click ( '.contextview [data-action="next"]' )
201+ . pause ( 1000 )
202+ . execute ( ( ) => {
203+ return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
204+ } , [ ] , ( result ) => {
205+ console . log ( 'result' , result )
206+ browser . assert . equal ( result . value , '1061' )
207+ } )
208+ . click ( '.contextview [data-action="next"]' )
209+ . pause ( 1000 )
210+ . execute ( ( ) => {
211+ return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
212+ } , [ ] , ( result ) => {
213+ console . log ( 'result' , result )
214+ browser . assert . equal ( result . value , '122' )
215+ } )
216+ . currentSelectedFileIs ( '2_Owner.sol' ) // make sure the current file has been properly changed
217+ . click ( '.contextview [data-action="next"]' )
218+ . pause ( 1000 )
219+ . execute ( ( ) => {
220+ return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
221+ } , [ ] , ( result ) => {
222+ console . log ( 'result' , result )
223+ browser . assert . equal ( result . value , '211' )
224+ } )
225+ . click ( '.contextview [data-action="next"]' )
226+ . currentSelectedFileIs ( '3_Ballot.sol' )
227+ . pause ( 1000 )
228+ . execute ( ( ) => {
229+ return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
230+ } , [ ] , ( result ) => {
231+ console . log ( 'result' , result )
232+ browser . assert . equal ( result . value , '1061' )
233+ } )
234+ . click ( '.contextview [data-action="gotoref"]' ) // go to the declaration
235+ . pause ( 1000 )
236+ . execute ( ( ) => {
237+ return ( document . getElementById ( 'editorView' ) as any ) . getCursorPosition ( )
238+ } , [ ] , ( result ) => {
239+ console . log ( 'result' , result )
240+ browser . assert . equal ( result . value , '122' )
241+ } )
177242 . end ( )
178243 }
179244}
@@ -281,3 +346,149 @@ contract Storage {
281346 return number;
282347 }
283348}`
349+
350+ const BallotWithARefToOwner = `
351+
352+
353+ // SPDX-License-Identifier: GPL-3.0
354+
355+ pragma solidity >=0.7.0 <0.9.0;
356+
357+ import "./2_Owner.sol";
358+
359+ /**
360+ * @title Ballot
361+ * @dev Implements voting process along with vote delegation
362+ */
363+ contract Ballot {
364+ Owner c;
365+ struct Voter {
366+ uint weight; // weight is accumulated by delegation
367+ bool voted; // if true, that person already voted
368+ address delegate; // person delegated to
369+ uint vote; // index of the voted proposal
370+ }
371+
372+ struct Proposal {
373+ // If you can limit the length to a certain number of bytes,
374+ // always use one of bytes1 to bytes32 because they are much cheaper
375+ bytes32 name; // short name (up to 32 bytes)
376+ uint voteCount; // number of accumulated votes
377+ }
378+
379+ address public chairperson;
380+
381+ mapping(address => Voter) public voters;
382+
383+ Proposal[] public proposals;
384+
385+ /**
386+ * @dev Create a new ballot to choose one of 'proposalNames'.
387+ * @param proposalNames names of proposals
388+ */
389+ constructor(bytes32[] memory proposalNames) {
390+ c = new Owner();
391+ chairperson = msg.sender;
392+ voters[chairperson].weight = 1;
393+
394+ for (uint i = 0; i < proposalNames.length; i++) {
395+ // 'Proposal({...})' creates a temporary
396+ // Proposal object and 'proposals.push(...)'
397+ // appends it to the end of 'proposals'.
398+ proposals.push(Proposal({
399+ name: proposalNames[i],
400+ voteCount: 0
401+ }));
402+ }
403+ }
404+
405+ /**
406+ * @dev Give 'voter' the right to vote on this ballot. May only be called by 'chairperson'.
407+ * @param voter address of voter
408+ */
409+ function giveRightToVote(address voter) public {
410+ require(
411+ msg.sender == chairperson,
412+ "Only chairperson can give right to vote."
413+ );
414+ require(
415+ !voters[voter].voted,
416+ "The voter already voted."
417+ );
418+ require(voters[voter].weight == 0);
419+ voters[voter].weight = 1;
420+ }
421+
422+ /**
423+ * @dev Delegate your vote to the voter 'to'.
424+ * @param to address to which vote is delegated
425+ */
426+ function delegate(address to) public {
427+ Voter storage sender = voters[msg.sender];
428+ require(!sender.voted, "You already voted.");
429+ require(to != msg.sender, "Self-delegation is disallowed.");
430+
431+ while (voters[to].delegate != address(0)) {
432+ to = voters[to].delegate;
433+
434+ // We found a loop in the delegation, not allowed.
435+ require(to != msg.sender, "Found loop in delegation.");
436+ }
437+ sender.voted = true;
438+ sender.delegate = to;
439+ Voter storage delegate_ = voters[to];
440+ if (delegate_.voted) {
441+ // If the delegate already voted,
442+ // directly add to the number of votes
443+ proposals[delegate_.vote].voteCount += sender.weight;
444+ } else {
445+ // If the delegate did not vote yet,
446+ // add to her weight.
447+ delegate_.weight += sender.weight;
448+ }
449+ }
450+
451+ /**
452+ * @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'.
453+ * @param proposal index of proposal in the proposals array
454+ */
455+ function vote(uint proposal) public {
456+ Voter storage sender = voters[msg.sender];
457+ require(sender.weight != 0, "Has no right to vote");
458+ require(!sender.voted, "Already voted.");
459+ sender.voted = true;
460+ sender.vote = proposal;
461+
462+ // If 'proposal' is out of the range of the array,
463+ // this will throw automatically and revert all
464+ // changes.
465+ proposals[proposal].voteCount += sender.weight;
466+ }
467+
468+ /**
469+ * @dev Computes the winning proposal taking all previous votes into account.
470+ * @return winningProposal_ index of winning proposal in the proposals array
471+ */
472+ function winningProposal() public view
473+ returns (uint winningProposal_)
474+ {
475+ uint winningVoteCount = 0;
476+ for (uint p = 0; p < proposals.length; p++) {
477+ if (proposals[p].voteCount > winningVoteCount) {
478+ winningVoteCount = proposals[p].voteCount;
479+ winningProposal_ = p;
480+ }
481+ }
482+ }
483+
484+ /**
485+ * @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then
486+ * @return winnerName_ the name of the winner
487+ */
488+ function winnerName() public view
489+ returns (bytes32 winnerName_)
490+ {
491+ winnerName_ = proposals[winningProposal()].name;
492+ }
493+ }
494+ `
0 commit comments