Merge pull request #283 from ethereum/testAutomation

automate ui testing
pull/1/head
chriseth 8 years ago committed by GitHub
commit d1acbc3459
  1. 41
      ci/makeMockCompiler.js
  2. 1
      src/app/editor.js
  3. 62
      src/app/example-contracts.js
  4. 7
      test-browser/helpers/applytestmode.js
  5. 39
      test-browser/helpers/contracts.js
  6. 7
      test-browser/helpers/init.js
  7. 79
      test-browser/mockcompiler/requests.js
  8. 39
      test-browser/tests/ballot.js
  9. 5
      test-browser/tests/debugger.js
  10. 5
      test-browser/tests/new-file-test.js
  11. 32
      test-browser/tests/simpleContract.js
  12. 6
      test-browser/tests/smoke-test.js

@ -4,20 +4,37 @@ var fs = require('fs')
var solc = require('solc/wrapper') var solc = require('solc/wrapper')
var soljson = require('../soljson') var soljson = require('../soljson')
var compiler = solc(soljson) var compiler = solc(soljson)
var inputs = require('../test-browser/mockcompiler/requests.js')
var compilationResult = gatherCompilationResults(inputs)
replaceSolCompiler(compilationResult)
function gatherCompilationResults (sol) { gatherCompilationResults(function (error, data) {
var compilationResult = {} if (error) {
for (var k in sol) { console.log(error)
var item = sol[k] process.exit(1)
var result = compile(item, 1) } else {
compilationResult[result.key] = result replaceSolCompiler(data)
result = compile(item, 0)
compilationResult[result.key] = result
} }
return compilationResult })
function gatherCompilationResults (callback) {
var compilationResult = {}
fs.readdir('./test-browser/tests', 'utf8', function (error, filenames) {
if (error) {
console.log(error)
process.exit(1)
} else {
filenames.map(function (item, i) {
var testDef = require('../test-browser/tests/' + item)
if ('@sources' in testDef) {
var source = testDef['@sources']()
var result = compile(source, 1)
compilationResult[result.key] = result
result = compile(source, 0)
compilationResult[result.key] = result
}
})
callback(null, compilationResult)
}
})
} }
function compile (source, optimization) { function compile (source, optimization) {

@ -12,6 +12,7 @@ function Editor (loadingFromGist, storage) {
var SOL_CACHE_FILE = null var SOL_CACHE_FILE = null
var editor = ace.edit('input') var editor = ace.edit('input')
document.getElementById('input').editor = editor // required to access the editor during tests
var sessions = {} var sessions = {}
var sourceAnnotations = [] var sourceAnnotations = []

@ -1,67 +1,67 @@
'use strict' 'use strict'
var ballot = `pragma solidity ^0.4.0 var ballot = `pragma solidity ^0.4.0;
contract Ballot { contract Ballot {
struct Voter { struct Voter {
uint weight uint weight;
bool voted bool voted;
uint8 vote uint8 vote;
address delegate address delegate;
} }
struct Proposal { struct Proposal {
uint voteCount uint voteCount;
} }
address chairperson address chairperson;
mapping(address => Voter) voters mapping(address => Voter) voters;
Proposal[] proposals Proposal[] proposals;
/// Create a new ballot with $(_numProposals) different proposals. /// Create a new ballot with $(_numProposals) different proposals.
function Ballot(uint8 _numProposals) { function Ballot(uint8 _numProposals) {
chairperson = msg.sender chairperson = msg.sender;
voters[chairperson].weight = 1 voters[chairperson].weight = 1;
proposals.length = _numProposals proposals.length = _numProposals;
} }
/// Give $(voter) the right to vote on this ballot. /// Give $(voter) the right to vote on this ballot.
/// May only be called by $(chairperson). /// May only be called by $(chairperson).
function giveRightToVote(address voter) { function giveRightToVote(address voter) {
if (msg.sender != chairperson || voters[voter].voted) return if (msg.sender != chairperson || voters[voter].voted) return;
voters[voter].weight = 1 voters[voter].weight = 1;
} }
/// Delegate your vote to the voter $(to). /// Delegate your vote to the voter $(to).
function delegate(address to) { function delegate(address to) {
Voter sender = voters[msg.sender] // assigns reference Voter sender = voters[msg.sender]; // assigns reference
if (sender.voted) return if (sender.voted) return;
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
to = voters[to].delegate to = voters[to].delegate;
if (to == msg.sender) return if (to == msg.sender) return;
sender.voted = true sender.voted = true;
sender.delegate = to sender.delegate = to;
Voter delegate = voters[to] Voter delegate = voters[to];
if (delegate.voted) if (delegate.voted)
proposals[delegate.vote].voteCount += sender.weight proposals[delegate.vote].voteCount += sender.weight;
else else
delegate.weight += sender.weight delegate.weight += sender.weight;
} }
/// Give a single vote to proposal $(proposal). /// Give a single vote to proposal $(proposal).
function vote(uint8 proposal) { function vote(uint8 proposal) {
Voter sender = voters[msg.sender] Voter sender = voters[msg.sender];
if (sender.voted || proposal >= proposals.length) return if (sender.voted || proposal >= proposals.length) return;
sender.voted = true sender.voted = true;
sender.vote = proposal sender.vote = proposal;
proposals[proposal].voteCount += sender.weight proposals[proposal].voteCount += sender.weight;
} }
function winningProposal() constant returns (uint8 winningProposal) { function winningProposal() constant returns (uint8 winningProposal) {
uint256 winningVoteCount = 0 uint256 winningVoteCount = 0;
for (uint8 proposal = 0; proposal < proposals.length; proposal++) for (uint8 proposal = 0; proposal < proposals.length; proposal++)
if (proposals[proposal].voteCount > winningVoteCount) { if (proposals[proposal].voteCount > winningVoteCount) {
winningVoteCount = proposals[proposal].voteCount winningVoteCount = proposals[proposal].voteCount;
winningProposal = proposal winningProposal = proposal;
} }
} }
}` }`

@ -0,0 +1,7 @@
/**
* This script is injected by NightWatch just before starting test
*
*/
console.log('applying test mode')
document.getElementById('input').editor.setBehavioursEnabled(false) // disable bracket auto-match (i.e. automatic injection of closing brackets and other things), so we can enter raw source code.
console.log('test mode applied')

@ -1,25 +1,26 @@
'use strict' 'use strict'
module.exports = { module.exports = {
checkCompiledContracts: function (browser, compiled, callback) { checkCompiledContracts: checkCompiledContracts,
browser.execute(function () { testContracts: testContracts
var contracts = document.querySelectorAll('.udapp .contract') }
var ret = []
for (var k in contracts) { function checkCompiledContracts (browser, compiled, callback) {
var el = contracts[k] browser.elements('css selector', '.udapp .contract .title', function (elements) {
if (el.querySelector) { elements.value.map(function (item, i) {
ret.push({ browser.elementIdText(item.ELEMENT, function (text) {
name: el.querySelector('.title').innerText.replace(el.querySelector('.size').innerText, '').replace(/(\t)|(\r)|(\n)/g, '') // IE/firefox add \r\n browser.assert.equal(text.value.split('\n')[0], compiled[i])
})
}
}
return ret
}, [''], function (result) {
browser.assert.equal(result.value.length, compiled.length)
result.value.map(function (item, i) {
browser.assert.equal(item.name, compiled[i])
}) })
callback()
}) })
} callback()
})
}
function testContracts (browser, contractCode, compiledContractNames, callback) {
browser
.clearValue('#input textarea')
.click('.newFile')
.setValue('#input textarea', contractCode, function () {})
.waitForElementPresent('.contract .create', 2000)
checkCompiledContracts(browser, compiledContractNames, callback)
} }

@ -0,0 +1,7 @@
module.exports = function (browser, callback) {
browser
.url('http://127.0.0.1:8080/#version=builtin')
.injectScript('test-browser/helpers/applytestmode.js', function () {
callback()
})
}

@ -1,79 +0,0 @@
'use strict'
module.exports = {
'testSimpleContract': {
'sources': {
'Untitled': 'contract test1 {} contract test2 {}'
}
},
'ballot': {
'sources': {
'Untitled': `pragma solidity ^0.4.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) {
chairperson = msg.sender
voters[chairperson].weight = 1
proposals.length = _numProposals
}
/// Give $(voter) the right to vote on this ballot.
/// May only be called by $(chairperson).
function giveRightToVote(address voter) {
if (msg.sender != chairperson || voters[voter].voted) return
voters[voter].weight = 1
}
/// Delegate your vote to the voter $(to).
function delegate(address to) {
Voter 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 delegate = voters[to]
if (delegate.voted)
proposals[delegate.vote].voteCount += sender.weight
else
delegate.weight += sender.weight
}
/// Give a single vote to proposal $(proposal).
function vote(uint8 proposal) {
Voter sender = voters[msg.sender]
if (sender.voted || proposal >= proposals.length) return
sender.voted = true
sender.vote = proposal
proposals[proposal].voteCount += sender.weight
}
function winningProposal() constant returns (uint8 winningProposal) {
uint256 winningVoteCount = 0
for (uint8 proposal = 0; proposal < proposals.length; proposal++)
if (proposals[proposal].voteCount > winningVoteCount) {
winningVoteCount = proposals[proposal].voteCount
winningProposal = proposal
}
}
}
`
}
}
}

@ -1,35 +1,30 @@
'use strict' 'use strict'
var contractHelper = require('../helpers/contracts')
var examples = require('../../src/app/example-contracts')
var init = require('../helpers/init')
var testData = require('../mockcompiler/requests') var sources = {
// var contractHelper = require('../helpers/contracts') 'sources': {
'Untitled': examples.ballot.content
}
}
module.exports = { module.exports = {
before: function (browser, done) {
init(browser, done)
},
'@sources': function () {
return sources
},
'Ballot': function (browser) { 'Ballot': function (browser) {
runTests(browser, testData) runTests(browser)
} }
} }
function runTests (browser, testData) { function runTests (browser, testData) {
browser browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('.newFile', 10000) .waitForElementVisible('.newFile', 10000)
browser.assert.notEqual(testData, null) contractHelper.testContracts(browser, sources.sources.Untitled, ['Ballot'], function () {
// TODO add Ballot tests. -> setValue('#input textarea', ... ) is not working properly with that contract.
/*
testBallot(browser, testData.ballot.sources.Untitled, function () {
browser.end() browser.end()
}); })
*/
}
/*
function testBallot (browser, contract, callback) {
browser
.click('.newFile')
.clearValue('#input textarea')
.setValue('#input textarea', contract, function () {
browser.pause('10000')
contractHelper.checkCompiledContracts(browser, ['Ballot'], callback)
})
} }
*/

@ -1,9 +1,12 @@
'use strict' 'use strict'
var init = require('../helpers/init')
module.exports = { module.exports = {
before: function (browser, done) {
init(browser, done)
},
'Debugger Render': function (browser) { 'Debugger Render': function (browser) {
browser browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementPresent('#debugger', 10000) .waitForElementPresent('#debugger', 10000)
.waitForElementPresent('#debugger #slider', 10000) .waitForElementPresent('#debugger #slider', 10000)
.end() .end()

@ -1,9 +1,12 @@
'use strict' 'use strict'
var init = require('../helpers/init')
module.exports = { module.exports = {
before: function (browser, done) {
init(browser, done)
},
'New file test': function (browser) { 'New file test': function (browser) {
browser browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('.newFile', 10000) .waitForElementVisible('.newFile', 10000)
.click('.newFile') .click('.newFile')
.pause('10000') .pause('10000')

@ -1,29 +1,29 @@
'use strict' 'use strict'
var testData = require('../mockcompiler/requests')
var contractHelper = require('../helpers/contracts') var contractHelper = require('../helpers/contracts')
var init = require('../helpers/init')
var sources = {
'sources': {
'Untitled': 'contract test1 {} contract test2 {}'
}
}
module.exports = { module.exports = {
before: function (browser, done) {
init(browser, done)
},
'@sources': function () {
return sources
},
'Simple Contract': function (browser) { 'Simple Contract': function (browser) {
runTests(browser, testData) runTests(browser)
} }
} }
function runTests (browser, testData) { function runTests (browser) {
browser browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('.newFile', 10000) .waitForElementVisible('.newFile', 10000)
browser.assert.notEqual(testData, null) contractHelper.testContracts(browser, sources.sources.Untitled, ['test1', 'test2'], function () {
testSimpleContract(browser, testData.testSimpleContract.sources.Untitled, function () {
browser.end() browser.end()
}) })
} }
function testSimpleContract (browser, contract, callback) {
browser
.click('.newFile')
.clearValue('#input textarea')
.setValue('#input textarea', contract)
.pause('5000')
contractHelper.checkCompiledContracts(browser, ['test1', 'test2'], callback)
}

@ -1,9 +1,13 @@
'use strict' 'use strict'
var init = require('../helpers/init')
module.exports = { module.exports = {
before: function (browser, done) {
browser
init(browser, done)
},
'Smoke test': function (browser) { 'Smoke test': function (browser) {
browser browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('#righthand-panel', 10000) .waitForElementVisible('#righthand-panel', 10000)
.pause('10000') .pause('10000')
.assert.containsText('#righthand-panel', 'Solidity version') .assert.containsText('#righthand-panel', 'Solidity version')

Loading…
Cancel
Save