Merge pull request #273 from ethereum/fixBrowserTests

use mock compiler during browser tests
pull/1/head
chriseth 8 years ago committed by GitHub
commit 373be1c7c0
  1. 6
      ci/browser_tests.sh
  2. 56
      ci/makeMockCompiler.js
  3. 7
      nightwatch.js
  4. 5
      package.json
  5. 23
      test-browser/helpers/contracts.js
  6. 41
      test-browser/mockcompiler/compiler.js
  7. 77
      test-browser/mockcompiler/requests.js
  8. 31
      test-browser/tests/ballot.js
  9. 2
      test-browser/tests/debugger.js
  10. 2
      test-browser/tests/new-file-test.js
  11. 28
      test-browser/tests/simpleContract.js
  12. 2
      test-browser/tests/smoke-test.js

@ -1,6 +1,8 @@
#!/usr/bin/env bash
SC_VERSION="4.3.16"
set -e
SC_VERSION="4.4.0"
SAUCECONNECT_URL="https://saucelabs.com/downloads/sc-$SC_VERSION-linux.tar.gz"
SAUCECONNECT_USERNAME="chriseth"
SAUCECONNECT_ACCESSKEY="b781828a-9e9c-43d8-89d4-2fbb879595ca"
@ -8,7 +10,7 @@ SAUCECONNECT_JOBIDENTIFIER="browsersolidity_tests_${TRAVIS_JOB_NUMBER}"
SAUCECONNECT_READYFILE="sc.ready"
TEST_EXITCODE=0
npm run build
node ci/makeMockCompiler.js
npm run serve &
wget "$SAUCECONNECT_URL"

@ -0,0 +1,56 @@
var fs = require('fs');
var solc = require('solc/wrapper');
var soljson = require('../soljson');
var compiler = solc(soljson);
var inputs = require('../test-browser/mockcompiler/requests.js');
var compilationResult = gatherCompilationResults(inputs);
replaceSolCompiler(compilationResult);
function gatherCompilationResults (sol) {
var compilationResult = {};
for (var k in sol) {
var item = sol[k];
var result = compile(item, 1);
compilationResult[result.key] = result;
result = compile(item, 0);
compilationResult[result.key] = result;
}
return compilationResult;
}
function compile (source, optimization) {
var missingInputs = [];
var result = compiler.compile(source, optimization, function (path) {
missingInputs.push(path);
});
var key = optimization.toString();
for (var k in source.sources) {
key += k + source.sources[k];
}
key = key.replace(/(\t)|(\n)|( )/g, '');
return {
key: key,
source: source,
optimization: optimization,
missingInputs: missingInputs,
result: result
};
}
function replaceSolCompiler (results) {
fs.readFile('./test-browser/mockcompiler/compiler.js', 'utf8', function (error, data) {
if (error) {
console.log(error);
process.exit(1);
return;
}
data = data + '\n\nvar mockData = ' + JSON.stringify(results) + ';\n';
fs.writeFile('./soljson.js', data, 'utf8', function (error) {
if (error) {
console.log(error);
process.exit(1);
return;
}
});
});
}

@ -3,7 +3,7 @@
var TRAVIS_JOB_NUMBER = process.env.TRAVIS_JOB_NUMBER
module.exports = {
'src_folders': ['test-browser'],
'src_folders': ['test-browser/tests'],
'output_folder': 'reports',
'custom_commands_path': '',
'custom_assertions_path': '',
@ -50,7 +50,8 @@ module.exports = {
'desiredCapabilities': {
'browserName': 'safari',
'javascriptEnabled': true,
'platform': 'MAC',
'platform': 'OS X 10.10',
'version': '8.0',
'acceptSslCerts': true,
'build': 'build-' + TRAVIS_JOB_NUMBER,
'tunnel-identifier': 'browsersolidity_tests_' + TRAVIS_JOB_NUMBER
@ -62,6 +63,8 @@ module.exports = {
'browserName': 'internet explorer',
'javascriptEnabled': true,
'acceptSslCerts': true,
'platform': 'WIN8.1',
'version': '11',
'build': 'build-' + TRAVIS_JOB_NUMBER,
'tunnel-identifier': 'browsersolidity_tests_' + TRAVIS_JOB_NUMBER
}

@ -8,7 +8,7 @@
"browser-test-remote-firefox": "nightwatch --config nightwatch.js --env default",
"browser-test-remote-ie": "nightwatch --config nightwatch.js --env ie",
"browser-test-remote-safari": "nightwatch --config nightwatch.js --env safari",
"build": "mkdir -p build; browserify src/index.js -g yo-yoify -o build/app.js",
"build": "mkdir -p build; browserify src/index.js -g yo-yoify -o build/app.js; babel --plugins babel-plugin-transform-es2015-template-literals,babel-plugin-transform-es2015-block-scoping build/app.js --out-file build/app.js",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='assets/css/font-awesome.min.css' assets/css/",
"downloadsolc": "rm soljson.js; wget https://ethereum.github.io/solc-bin/soljson.js",
"lint": "semistandard",
@ -16,6 +16,9 @@
"test": "node test/index.js"
},
"devDependencies": {
"babel-cli": "^6.16.0",
"babel-plugin-transform-es2015-block-scoping": "^6.15.0",
"babel-plugin-transform-es2015-template-literals": "^6.8.0",
"brace": "^0.8.0",
"browserify": "^13.0.0",
"csslint": "^1.0.2",

@ -0,0 +1,23 @@
module.exports = {
checkCompiledContracts: function (browser, compiled, callback) {
browser.execute(function () {
var contracts = document.querySelectorAll('.udapp .contract');
var ret = [];
for (var k in contracts) {
var el = contracts[k];
if (el.querySelector) {
ret.push({
name: el.querySelector('.title').innerText.replace(el.querySelector('.size').innerText, '').replace(/(\t)|(\r)|(\n)/g, '') // IE/firefox add \r\n
});
}
}
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();
});
}
};

@ -0,0 +1,41 @@
var Module = { // eslint-disable-line
cwrap: function () { return arguments[0] === 'version' ? version : compile; },
writeStringToMemory: function () {},
setValue: function () {},
Pointer_stringify: function () {},
Runtime: {
addFunction: function () {},
removeFunction: function () {}
},
_compileJSONMulti: {},
_compileJSONCallback: {},
_compileJSON: {}
};
function compile (source, optimization, missingInputs) {
if (typeof source === 'string') {
source = JSON.parse(source);
}
var key = optimization.toString();
for (var k in source.sources) {
key += k + source.sources[k];
}
key = key.replace(/(\t)|(\n)|( )/g, '');
var data = mockData[key]; // eslint-disable-line
if (data === undefined) {
return JSON.stringify({
errors: ['mock compiler: source not found']
});
} else {
data.missingInputs.map(function (item, i) {
if (missingInputs) {
missingInputs(item);
}
});
}
return JSON.stringify(data.result);
}
function version () {
return 'mock compiler';
}

@ -0,0 +1,77 @@
module.exports = {
'testSimpleContract': {
'sources': {
'Untitled1': 'contract test1 {} contract test2 {}'
}
},
'ballot': {
'sources': {
'Untitled1': `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;
}
}
}
`
}
}
};

@ -0,0 +1,31 @@
'use strict';
var testData = require('../mockcompiler/requests');
// var contractHelper = require('../helpers/contracts');
module.exports = {
'Ballot': function (browser) {
runTests(browser, testData);
}
};
function runTests (browser, testData) {
browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('.newFile', 10000);
browser.assert.notEqual(testData, null);
// TODO add Ballot tests. -> setValue('#input textarea', ... ) is not working properly with that contract.
/* testBallot(browser, testData.ballot.sources.Untitled1, function () {
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);
});
}*/

@ -3,7 +3,7 @@
module.exports = {
'Debugger Render': function (browser) {
browser
.url('http://127.0.0.1:8080')
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementPresent('#debugger', 10000)
.waitForElementPresent('#debugger #slider', 10000)
.end();

@ -3,7 +3,7 @@
module.exports = {
'New file test': function (browser) {
browser
.url('http://127.0.0.1:8080')
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('.newFile', 10000)
.click('.newFile')
.pause('10000')

@ -0,0 +1,28 @@
'use strict';
var testData = require('../mockcompiler/requests');
var contractHelper = require('../helpers/contracts');
module.exports = {
'Simple Contract': function (browser) {
runTests(browser, testData);
}
};
function runTests (browser, testData) {
browser
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('.newFile', 10000);
browser.assert.notEqual(testData, null);
testSimpleContract(browser, testData.testSimpleContract.sources.Untitled1, function () {
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);
}

@ -3,7 +3,7 @@
module.exports = {
'Smoke test': function (browser) {
browser
.url('http://127.0.0.1:8080')
.url('http://127.0.0.1:8080/#version=builtin')
.waitForElementVisible('#righthand-panel', 10000)
.pause('10000')
.assert.containsText('#righthand-panel', 'Solidity version')
Loading…
Cancel
Save