Add Gruntfile for browser build and testing

This commit is contained in:
Ritchie Martori 2014-01-28 18:11:50 -08:00
parent 766981ebba
commit 41bc8a3172
3 changed files with 216 additions and 1 deletions

108
Gruntfile.js Normal file
View File

@ -0,0 +1,108 @@
/*global module:false*/
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
// Task configuration.
uglify: {
options: {
banner: '<%= banner %>'
},
dist: {
src: '<%= concat.dist.dest %>',
dest: 'dist/<%= pkg.name %>.min.js'
}
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
unused: true,
boss: true,
eqnull: true,
browser: true,
globals: {
jQuery: true
}
},
gruntfile: {
src: 'Gruntfile.js'
},
lib_test: {
src: ['lib/**/*.js', 'test/**/*.js']
}
},
watch: {
gruntfile: {
files: '<%= jshint.gruntfile.src %>',
tasks: ['jshint:gruntfile']
},
lib_test: {
files: '<%= jshint.lib_test.src %>',
tasks: ['jshint:lib_test']
}
},
browserify: {
dist: {
files: {
'dist/loopback.js': ['index.js'],
},
options: {
}
}
},
mochaSelenium: {
options: {
// Mocha options
reporter: 'spec',
timeout: 30e3,
// Toggles wd's promises API, default:false
usePromises: false
},
firefox: {
src: ['test/*.js']
// firefox is the default browser, so no browserName option required
},
chrome: {
src: ['test/*.js'],
options: {
// Chrome browser must be installed from Chromedriver support
browserName: 'chrome'
}
},
phantomjs: {
src: ['test/*.js'],
options: {
// phantomjs must be in the $PATH when invoked
browserName: 'phantomjs'
}
}
}
});
// todo appium
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-mocha-selenium');
// Default task.
grunt.registerTask('default', ['jshint', 'uglify']);
};

104
bin/test-browser.js Normal file
View File

@ -0,0 +1,104 @@
#!/usr/bin/env node
var path = require('path');
var spawn = require('child_process').spawn;
var wd = require('wd');
var devserver = require('./dev-server.js');
var SELENIUM_PATH = '../node_modules/.bin/start-selenium';
var testUrl = 'http://127.0.0.1:8000/tests/test.html';
var testTimeout = 2 * 60 * 1000;
var currentTest = '';
var results = {};
var client = {};
var browsers = [
'firefox',
// Temporarily disable safari until it is fixed (#1068)
// 'safari',
'chrome'
];
// Don't do it on trais
if (process.env.TRAVIS) {
console.log('skipping tests on travis');
process.exit(0)
}
var numBrowsers = browsers.length;
var finishedBrowsers = 0;
function startServers(callback) {
// Starts the file and CORS proxy
devserver.start();
// Start selenium
var started = false;
var selenium = spawn(path.resolve(__dirname, SELENIUM_PATH));
selenium.stdout.on('data', function(data) {
if (!started &&
/Started org.openqa.jetty.jetty.servlet.ServletHandler/.test(data)) {
started = true;
callback();
}
});
}
function testsComplete() {
var passed = Object.keys(results).length && Object.keys(results).every(function(x) {
return !results[x].failed;
});
if (passed) {
console.log('Woot, all ' + Object.keys(results).length + ' tests passed');
process.exit(0);
} else if (!Object.keys(results).length) {
console.error('no tests ran');
process.exit(4);
} else {
console.error('we ran ' + Object.keys(results).length + ' tests and ' + results[x].failed + ' failed');
process.exit(1);
}
}
function startTest() {
if (numBrowsers === finishedBrowsers) {
return testsComplete();
}
if (!browsers.length) {
return;
}
var currentTest = browsers.pop();
console.log('[' + currentTest + '] starting');
var client = wd.promiseChainRemote();
client.init({
browserName: currentTest
}).get(testUrl).setAsyncScriptTimeout(testTimeout)
.executeAsync('var cb = arguments[arguments.length - 1];QUnit.done(function( report ) {cb(report)});')
.then(function (result) {
finishedBrowsers++;
if (!result.failed) {
console.log('[' + currentTest + '] passed ' + result.passed + ' of ' + result.total + ' tests');
} else {
console.log('[' + currentTest + '] failed ' + result.failed + ' of ' + result.total + ' tests');
return client.quit().then(function() {
process.exit(2);
})
}
results[currentTest] = result;
}).quit()
.then(startTest,function(e) {
console.error(e);
console.error('Doh, tests failed');
client.quit();
process.exit(3);
});
}
startServers(function() {
startTest();
});

View File

@ -46,7 +46,10 @@
"watchify": "~0.4.1",
"uglify-js": "~2.4.6",
"jshint": "~2.3.0",
"browserify": "~3.14.1"
"browserify": "~3.14.1",
"grunt": "~0.4.2",
"grunt-browserify": "~1.3.0",
"grunt-mocha-selenium": "~0.7.0"
},
"repository": {
"type": "git",