tests(coverage): Add coveralls coverage
This commit is contained in:
Родитель
dc04a1ac8a
Коммит
11d4b7832f
|
@ -8,6 +8,8 @@ env:
|
|||
- DISABLE_ROUTE_LOGGING=true
|
||||
|
||||
before_install:
|
||||
# npm shrinkwrap broken on 1.4, see npm/issues/5787, 5920, 5692, downgrade:
|
||||
- npm install -g npm@1.3
|
||||
- sudo apt-get install libgmp3-dev
|
||||
- "export DISPLAY=:99.0"
|
||||
- "sh -e /etc/init.d/xvfb start"
|
||||
|
@ -32,7 +34,7 @@ install:
|
|||
- LOG_LEVEL=error npm start &
|
||||
- cd ..
|
||||
- npm start &
|
||||
- sleep 10
|
||||
- sleep 20
|
||||
|
||||
# now run the tests!
|
||||
script:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Firefox Accounts Content Server
|
||||
|
||||
Travis Tests: [![Build Status: Travis](https://travis-ci.org/mozilla/fxa-content-server.svg?branch=master)](https://travis-ci.org/mozilla/fxa-content-server)
|
||||
[![Coverage Status](https://img.shields.io/coveralls/mozilla/fxa-content-server.svg)](https://coveralls.io/r/mozilla/fxa-content-server)
|
||||
Functional Tests: <a href='http://qa.stage.mozaws.net:8080/job/fxa.content-server-tests.dev/'><img src='http://qa.stage.mozaws.net:8080/job/fxa.content-server-tests.dev/badge/icon' alt='Build Status: Functional Tests' height='13'></a>
|
||||
|
||||
Static server that hosts Firefox Account sign up, sign in, email verification, etc. flows.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Based on bower_components/blanket/src/reporters/lcov_reporter.js
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
//lcov_reporter
|
||||
(function () {
|
||||
//takes the option: toHTML {boolean}
|
||||
|
||||
var appendHtml = function (filename, data, toHTML) {
|
||||
|
||||
var str = '';
|
||||
str += 'SF:app/' + filename + '\n';
|
||||
|
||||
data.source.forEach(function (line, num) {
|
||||
// increase the line number, as JS arrays are zero-based
|
||||
num++;
|
||||
|
||||
if (data[num] !== undefined) {
|
||||
str += 'DA:' + num + ',' + data[num] + '\n';
|
||||
}
|
||||
});
|
||||
|
||||
str += 'end_of_record\n';
|
||||
/* jshint camelcase: false */
|
||||
window._$blanket_LCOV = (window._$blanket_LCOV || '') + str;
|
||||
};
|
||||
|
||||
/* global blanket */
|
||||
blanket.customReporter = function (coverageData, options) {
|
||||
var toHTML = true;
|
||||
if (typeof options !== 'undefined' && typeof options.toHTML !== 'undefined') {
|
||||
toHTML = options.toHTML;
|
||||
}
|
||||
for (var filename in coverageData.files) {
|
||||
var data = coverageData.files[filename];
|
||||
appendHtml(filename, data, toHTML);
|
||||
}
|
||||
};
|
||||
})();
|
|
@ -61,6 +61,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"awsbox": "0.7.0",
|
||||
"coveralls": "2.11.1",
|
||||
"execSync": "1.0.1-pre",
|
||||
"firefox-profile": "0.3.3",
|
||||
"grunt-blanket-mocha": "0.4.1",
|
||||
|
|
|
@ -152,8 +152,7 @@ var conf = module.exports = convict({
|
|||
coverage: {
|
||||
globalThreshold: 90,
|
||||
threshold: 50,
|
||||
// Ignore oauth scripts until tests are enabled (issue #1141)
|
||||
excludeFiles: ['/scripts/../tests/', '/scripts/vendor/', 'oauth', '/scripts/../bower_components/']
|
||||
excludeFiles: ['/scripts/../tests/', '/scripts/vendor/', '/scripts/../bower_components/', 'require_config']
|
||||
}
|
||||
},
|
||||
i18n: {
|
||||
|
|
|
@ -31,8 +31,12 @@
|
|||
<script>
|
||||
/* global blanket */
|
||||
if (window.PHANTOMJS) {
|
||||
blanket.options('reporter', '/bower_components/blanket/src/grunt-reporter.js');
|
||||
blanket.options('reporter', '/bower_components/blanket/src/grunt-reporter.js');
|
||||
}
|
||||
if (window.location.search.indexOf('travis') >= 0) {
|
||||
blanket.options('reporter', '/tests/lib/blanket_lcov.js');
|
||||
}
|
||||
|
||||
</script>
|
||||
{{/check_coverage}}
|
||||
</body>
|
||||
|
|
|
@ -7,75 +7,137 @@ define([
|
|||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'intern/dojo/node!../../server/lib/configuration',
|
||||
'require'
|
||||
], function (intern, registerSuite, assert, config, require) {
|
||||
'intern/dojo/Deferred',
|
||||
'require',
|
||||
'intern/node_modules/dojo/has!host-node?intern/node_modules/dojo/node!child_process'
|
||||
], function (intern, registerSuite, assert, config, Deferred, require, child_process) {
|
||||
'use strict';
|
||||
|
||||
/* global process */
|
||||
var travis = process && process.env.TRAVIS_COMMIT;
|
||||
var url = intern.config.fxaContentRoot + 'tests/index.html?coverage';
|
||||
if (travis) {
|
||||
url += '&travis=true';
|
||||
}
|
||||
var bodyText;
|
||||
var MOCHA_LOADER_SLEEP = 15000;
|
||||
|
||||
registerSuite({
|
||||
name: 'mocha tests',
|
||||
|
||||
'run the mocha tests': function () {
|
||||
// timeout after 200 seconds
|
||||
this.timeout = 200000;
|
||||
var self = this;
|
||||
// timeout after 300 seconds
|
||||
this.timeout = 300000;
|
||||
|
||||
return this.get('remote')
|
||||
.setFindTimeout(this.timeout)
|
||||
.get(require.toUrl(url))
|
||||
.setFindTimeout(intern.config.pageLoadTimeout)
|
||||
.refresh()
|
||||
// let the mocha reporter load up
|
||||
.sleep(MOCHA_LOADER_SLEEP)
|
||||
// wait for the tests to complete
|
||||
.findById('total-failures')
|
||||
.getVisibleText()
|
||||
.then(function (text) {
|
||||
if (text !== '0') {
|
||||
console.log(bodyText);
|
||||
}
|
||||
assert.equal(text, '0');
|
||||
})
|
||||
.end()
|
||||
//
|
||||
// Save the body text in case there are any errors
|
||||
.findByCssSelector('body')
|
||||
.getVisibleText()
|
||||
.then(function (text) {
|
||||
bodyText = text;
|
||||
})
|
||||
.then(function (text) {
|
||||
bodyText = text;
|
||||
})
|
||||
.end()
|
||||
|
||||
// Check for any failures, if there is a failure, print the
|
||||
// test log and fail.
|
||||
.findById('total-failures')
|
||||
.getVisibleText()
|
||||
.then(function (text) {
|
||||
if (text !== '0') {
|
||||
console.log(bodyText);
|
||||
}
|
||||
assert.equal(text, '0');
|
||||
})
|
||||
.end()
|
||||
|
||||
// check for code coverage now.
|
||||
|
||||
|
||||
// check for the grand total
|
||||
.findByCssSelector('.grand-total .rs')
|
||||
.getVisibleText()
|
||||
.then(function (text) {
|
||||
text = text.replace('%', '').trim();
|
||||
var covered = parseFloat(text);
|
||||
assert.ok(covered > config.get('tests.coverage.globalThreshold'),
|
||||
'code coverage is insufficient at ' + text + '%');
|
||||
})
|
||||
.end()
|
||||
|
||||
// any individual failures?
|
||||
.setFindTimeout(3000)
|
||||
.findByCssSelector('.bl-error .bl-file a')
|
||||
.then(
|
||||
function() {
|
||||
throw new Error('Blanket.js Errors');
|
||||
},
|
||||
function(err) {
|
||||
// No Blanket.js errors
|
||||
assert.strictEqual(err.name, 'NoSuchElement', 'Error was: ' + err.message);
|
||||
.then(function () {
|
||||
if (travis) {
|
||||
return sendCoverageToCoveralls(self);
|
||||
} else {
|
||||
return validateCoverageLocally(self);
|
||||
}
|
||||
)
|
||||
.end();
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Sends test coverage data to https://coveralls.io
|
||||
* This runs with Travis CI. It pipes "coverageData" gathered from "_$blanket_LCOV" LCOV reporter.
|
||||
*
|
||||
* @param {Test} context
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
function sendCoverageToCoveralls(context) {
|
||||
var dfd = new Deferred();
|
||||
var spawn = child_process.spawn;
|
||||
|
||||
console.log('Sending code coverage to coveralls.io');
|
||||
context.get('remote')
|
||||
// get code coverage data
|
||||
.execute(function () {
|
||||
/* global window */
|
||||
return window._$blanket_LCOV;
|
||||
}, [])
|
||||
.then(function (coverageData) {
|
||||
var child = spawn('node', ['node_modules/coveralls/bin/coveralls.js']);
|
||||
child.on('error', function (err) {
|
||||
throw err;
|
||||
});
|
||||
child.stderr.pipe(process.stdout);
|
||||
child.stdout.pipe(process.stdout);
|
||||
|
||||
child.on('exit', function () {
|
||||
console.log('Code coverage sent');
|
||||
dfd.resolve();
|
||||
});
|
||||
child.stdin.write(coverageData);
|
||||
child.stdin.end();
|
||||
});
|
||||
|
||||
return dfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the grand-total code coverage, looks for blanket.js errors
|
||||
*
|
||||
* @param {Test} context
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
function validateCoverageLocally(context) {
|
||||
var dfd = new Deferred();
|
||||
|
||||
console.log('Validating code coverage...');
|
||||
context
|
||||
.get('remote')
|
||||
.findByCssSelector('.grand-total .rs')
|
||||
.getVisibleText()
|
||||
.then(function (text) {
|
||||
text = text.replace('%', '').trim();
|
||||
var covered = parseFloat(text);
|
||||
assert.ok(covered > config.get('tests.coverage.globalThreshold'),
|
||||
'code coverage is insufficient at ' + text + '%');
|
||||
})
|
||||
.end()
|
||||
|
||||
// any individual failures?
|
||||
.setFindTimeout(3000)
|
||||
.findByCssSelector('.bl-error .bl-file a')
|
||||
.then(
|
||||
function () {
|
||||
throw new Error('Blanket.js Errors');
|
||||
},
|
||||
function (err) {
|
||||
// No Blanket.js errors
|
||||
assert.strictEqual(err.name, 'NoSuchElement', 'Error was: ' + err.message);
|
||||
dfd.resolve();
|
||||
}
|
||||
)
|
||||
.end();
|
||||
|
||||
return dfd;
|
||||
}
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче