Support Skipped Tests and Fix JSHint Issues
The test runner now will not break when Mocha skips tests, and will properly report them. Additionally, several JSHint warnings were fixed, and a `--debug` option was added to see output from the provider.
This commit is contained in:
parent
b514e264b9
commit
fcfd5fa986
@ -3,7 +3,7 @@ var path = require('path');
|
|||||||
|
|
||||||
var phantom_path = require('phantomjs').path;
|
var phantom_path = require('phantomjs').path;
|
||||||
var casper_path = path.resolve(__dirname, 'node_modules/casperjs/bin/casperjs');
|
var casper_path = path.resolve(__dirname, 'node_modules/casperjs/bin/casperjs');
|
||||||
process.env['PHANTOMJS_EXECUTABLE'] = phantom_path;
|
process.env.PHANTOMJS_EXECUTABLE = phantom_path;
|
||||||
var casper_opts = {
|
var casper_opts = {
|
||||||
child: {
|
child: {
|
||||||
transport: 'http',
|
transport: 'http',
|
||||||
@ -13,7 +13,7 @@ var casper_opts = {
|
|||||||
logLevel: 'debug',
|
logLevel: 'debug',
|
||||||
verbose: true
|
verbose: true
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
var provide_emitter = function(file_paths) {
|
var provide_emitter = function(file_paths) {
|
||||||
var spooky = new Spooky(casper_opts, function(err) {
|
var spooky = new Spooky(casper_opts, function(err) {
|
||||||
@ -29,22 +29,24 @@ var provide_emitter = function(file_paths) {
|
|||||||
spooky.then([{ path_ind: path_ind }, function() {
|
spooky.then([{ path_ind: path_ind }, function() {
|
||||||
var res_json = {
|
var res_json = {
|
||||||
file_ind: path_ind
|
file_ind: path_ind
|
||||||
}
|
};
|
||||||
|
|
||||||
res_json.num_tests = this.evaluate(function() { return document.querySelectorAll('li.test').length });
|
res_json.num_tests = this.evaluate(function() { return document.querySelectorAll('li.test').length; });
|
||||||
res_json.num_passes = this.evaluate(function() { return document.querySelectorAll('li.test.pass').length });
|
res_json.num_passes = this.evaluate(function() { return document.querySelectorAll('li.test.pass').length; });
|
||||||
res_json.num_fails = this.evaluate(function() { return document.querySelectorAll('li.test.fail').length });
|
res_json.num_fails = this.evaluate(function() { return document.querySelectorAll('li.test.fail').length; });
|
||||||
res_json.num_slow = this.evaluate(function() { return document.querySelectorAll('li.test.pass:not(.fast)').length });
|
res_json.num_slow = this.evaluate(function() { return document.querySelectorAll('li.test.pass:not(.fast):not(.pending)').length; });
|
||||||
res_json.duration = this.evaluate(function() { return document.querySelector('li.duration em').textContent });
|
res_json.num_skipped = this.evaluate(function () { return document.querySelectorAll('li.test.pending').length; });
|
||||||
|
res_json.duration = this.evaluate(function() { return document.querySelector('li.duration em').textContent; });
|
||||||
|
|
||||||
res_json.suites = this.evaluate(function() {
|
res_json.suites = this.evaluate(function() {
|
||||||
var traverse_node = function(elem) {
|
var traverse_node = function(elem) {
|
||||||
|
var res;
|
||||||
if (elem.classList.contains('suite')) {
|
if (elem.classList.contains('suite')) {
|
||||||
var res = {
|
res = {
|
||||||
type: 'suite',
|
type: 'suite',
|
||||||
name: elem.querySelector('h1').textContent,
|
name: elem.querySelector('h1').textContent,
|
||||||
has_subfailures: elem.querySelectorAll('li.test.fail').length > 0,
|
has_subfailures: elem.querySelectorAll('li.test.fail').length > 0,
|
||||||
}
|
};
|
||||||
|
|
||||||
var child_elems = elem.querySelector('ul').children;
|
var child_elems = elem.querySelector('ul').children;
|
||||||
res.children = Array.prototype.map.call(child_elems, traverse_node);
|
res.children = Array.prototype.map.call(child_elems, traverse_node);
|
||||||
@ -52,28 +54,35 @@ var provide_emitter = function(file_paths) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var h2_content = elem.querySelector('h2').childNodes;
|
var h2_content = elem.querySelector('h2').childNodes;
|
||||||
var res = {
|
res = {
|
||||||
type: 'test',
|
type: 'test',
|
||||||
text: h2_content[0].textContent,
|
text: h2_content[0].textContent,
|
||||||
}
|
};
|
||||||
|
|
||||||
if (elem.classList.contains('pass')) {
|
if (elem.classList.contains('pass')) {
|
||||||
res.pass = true;
|
res.pass = true;
|
||||||
|
if (elem.classList.contains('pending')) {
|
||||||
|
res.slow = false;
|
||||||
|
res.skipped = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
res.slow = !elem.classList.contains('fast');
|
res.slow = !elem.classList.contains('fast');
|
||||||
|
res.skipped = false;
|
||||||
res.duration = h2_content[1].textContent;
|
res.duration = h2_content[1].textContent;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
res.error = elem.querySelector('pre.error').textContent;
|
res.error = elem.querySelector('pre.error').textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
var top_suites = document.querySelectorAll('#mocha-report > li.suite');
|
var top_suites = document.querySelectorAll('#mocha-report > li.suite');
|
||||||
return Array.prototype.map.call(top_suites, traverse_node);
|
return Array.prototype.map.call(top_suites, traverse_node);
|
||||||
});
|
});
|
||||||
|
|
||||||
res_json.replay = this.evaluate(function() { return document.querySelector('a.replay').textContent });
|
res_json.replay = this.evaluate(function() { return document.querySelector('a.replay').textContent; });
|
||||||
|
|
||||||
this.emit('test_ready', res_json);
|
this.emit('test_ready', res_json);
|
||||||
}]);
|
}]);
|
||||||
@ -82,9 +91,9 @@ var provide_emitter = function(file_paths) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return spooky;
|
return spooky;
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
provide_emitter: provide_emitter,
|
provide_emitter: provide_emitter,
|
||||||
name: 'SpookyJS (CapserJS on PhantomJS)'
|
name: 'SpookyJS (CapserJS on PhantomJS)'
|
||||||
}
|
};
|
||||||
|
@ -5,7 +5,7 @@ var path = require('path');
|
|||||||
|
|
||||||
var make_list = function(val) {
|
var make_list = function(val) {
|
||||||
return val.split(',');
|
return val.split(',');
|
||||||
}
|
};
|
||||||
|
|
||||||
program
|
program
|
||||||
.option('-t, --tests <testlist>', 'Run the specified html-file-based test(s). \'testlist\' should be a comma-separated list', make_list, [])
|
.option('-t, --tests <testlist>', 'Run the specified html-file-based test(s). \'testlist\' should be a comma-separated list', make_list, [])
|
||||||
@ -16,6 +16,7 @@ program
|
|||||||
.option('-p, --provider <name>', 'Use the given provider (defaults to "casper"). Currently, may be "casper" or "zombie"', 'casper')
|
.option('-p, --provider <name>', 'Use the given provider (defaults to "casper"). Currently, may be "casper" or "zombie"', 'casper')
|
||||||
.option('-g, --generate-html', 'Instead of running the tests, just return the path to the generated HTML file, then wait for user interaction to exit (should be used with -i)')
|
.option('-g, --generate-html', 'Instead of running the tests, just return the path to the generated HTML file, then wait for user interaction to exit (should be used with -i)')
|
||||||
.option('-o, --output-html', 'Instead of running the tests, just output the generated HTML source to STDOUT (should be used with -i)')
|
.option('-o, --output-html', 'Instead of running the tests, just output the generated HTML source to STDOUT (should be used with -i)')
|
||||||
|
.option('-d, --debug', 'Show debug output (the "console" event) from the provider')
|
||||||
.parse(process.argv);
|
.parse(process.argv);
|
||||||
|
|
||||||
var file_paths = [];
|
var file_paths = [];
|
||||||
@ -26,13 +27,15 @@ if (program.autoInject) {
|
|||||||
temp.track();
|
temp.track();
|
||||||
|
|
||||||
var template = {
|
var template = {
|
||||||
header: "<html>\n<head>\n<meta charset='utf-8' />\<link rel='stylesheet' href='node_modules/mocha/mocha.css'/>\n</head>\n<body><div id='mocha'></div>",
|
header: "<html>\n<head>\n<meta charset='utf-8' />\n<link rel='stylesheet' href='" + path.resolve(__dirname, 'node_modules/mocha/mocha.css') + "'/>\n</head>\n<body><div id='mocha'></div>",
|
||||||
script_tag: function(p) { return "<script src='" + p + "'></script>" },
|
script_tag: function(p) { return "<script src='" + p + "'></script>"; },
|
||||||
footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__']);\nmocha.run();\n</script>\n</body>\n</html>"
|
footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__']);\nmocha.run();\n</script>\n</body>\n</html>"
|
||||||
};
|
};
|
||||||
|
|
||||||
template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/chai/chai.js'));
|
template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/chai/chai.js'));
|
||||||
template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/mocha/mocha.js'));
|
template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/mocha/mocha.js'));
|
||||||
|
template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/sinon/pkg/sinon.js'));
|
||||||
|
template.header += "\n" + template.script_tag(path.resolve(__dirname, 'node_modules/sinon-chai/lib/sinon-chai.js'));
|
||||||
template.header += "\n<script>mocha.setup('bdd');</script>";
|
template.header += "\n<script>mocha.setup('bdd');</script>";
|
||||||
|
|
||||||
|
|
||||||
@ -137,8 +140,8 @@ if (!program.outputHtml && !program.generateHtml) {
|
|||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
||||||
cursor.write(''+test_json.num_tests+' tests run, ')
|
|
||||||
cursor
|
cursor
|
||||||
|
.write(''+test_json.num_tests+' tests run, ')
|
||||||
.green()
|
.green()
|
||||||
.write(''+test_json.num_passes+' passed');
|
.write(''+test_json.num_passes+' passed');
|
||||||
if (test_json.num_slow > 0) {
|
if (test_json.num_slow > 0) {
|
||||||
@ -157,9 +160,16 @@ if (!program.outputHtml && !program.generateHtml) {
|
|||||||
cursor
|
cursor
|
||||||
.red()
|
.red()
|
||||||
.write(''+test_json.num_fails+' failed');
|
.write(''+test_json.num_fails+' failed');
|
||||||
|
if (test_json.num_skipped > 0) {
|
||||||
cursor
|
cursor
|
||||||
.reset()
|
.reset()
|
||||||
.write(' -- duration: '+test_json.duration+"\n");
|
.write(', ')
|
||||||
|
.grey()
|
||||||
|
.write(''+test_json.num_skipped+' skipped');
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
.reset()
|
||||||
|
.write(' -- duration: '+test_json.duration+"s\n");
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
||||||
@ -168,7 +178,7 @@ if (!program.outputHtml && !program.generateHtml) {
|
|||||||
if (node.type == 'suite') {
|
if (node.type == 'suite') {
|
||||||
if (!node.has_subfailures && !program.printAll) return;
|
if (!node.has_subfailures && !program.printAll) return;
|
||||||
|
|
||||||
if (indentation == 0) {
|
if (indentation === 0) {
|
||||||
cursor.bold();
|
cursor.bold();
|
||||||
console.log(node.name);
|
console.log(node.name);
|
||||||
console.log(Array(node.name.length+1).join('-'));
|
console.log(Array(node.name.length+1).join('-'));
|
||||||
@ -195,17 +205,25 @@ if (!program.outputHtml && !program.generateHtml) {
|
|||||||
cursor.magenta();
|
cursor.magenta();
|
||||||
console.log('- failed: '+node.text+test_json.replay);
|
console.log('- failed: '+node.text+test_json.replay);
|
||||||
cursor.red();
|
cursor.red();
|
||||||
console.log(' '+node.error.split("\n")[0]); // the split is to avoid a weird thing where in PhantomJS, we get a stack trace too
|
console.log(' '+node.error.split("\n")[0]); // the split is to avoid a weird thing where in PhantomJS where we get a stack trace too
|
||||||
cursor.reset();
|
cursor.reset();
|
||||||
console.log('');
|
console.log('');
|
||||||
}
|
}
|
||||||
else if (program.printAll) {
|
else if (program.printAll) {
|
||||||
|
if (node.skipped) {
|
||||||
|
cursor
|
||||||
|
.grey()
|
||||||
|
.write('- skipped: '+node.text);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (node.slow) cursor.yellow();
|
if (node.slow) cursor.yellow();
|
||||||
else cursor.green();
|
else cursor.green();
|
||||||
|
|
||||||
cursor
|
cursor
|
||||||
.write('- pass: '+node.text)
|
.write('- pass: '+node.text)
|
||||||
.grey()
|
.grey()
|
||||||
.write(' ('+node.duration+') ');
|
.write(' ('+node.duration+') ');
|
||||||
|
}
|
||||||
/*if (node.slow) cursor.yellow();
|
/*if (node.slow) cursor.yellow();
|
||||||
else cursor.green();*/
|
else cursor.green();*/
|
||||||
cursor
|
cursor
|
||||||
@ -215,23 +233,25 @@ if (!program.outputHtml && !program.generateHtml) {
|
|||||||
console.log('');
|
console.log('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
for (var i = 0; i < test_json.suites.length; i++) {
|
for (var i = 0; i < test_json.suites.length; i++) {
|
||||||
traverse_tree(0, test_json.suites[i]);
|
traverse_tree(0, test_json.suites[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_json.num_fails == 0) {
|
if (test_json.num_fails === 0) {
|
||||||
cursor.fg.green();
|
cursor.fg.green();
|
||||||
console.log('all tests passed :-)');
|
console.log('all tests passed :-)');
|
||||||
cursor.reset();
|
cursor.reset();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*provider.on('console', function(line) {
|
if (program.debug) {
|
||||||
//console.log(line);
|
provider.on('console', function(line) {
|
||||||
});*/
|
console.log(line);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*gprom.finally(function(ph) {
|
/*gprom.finally(function(ph) {
|
||||||
ph.exit();
|
ph.exit();
|
||||||
|
@ -18,16 +18,18 @@ var provide_emitter = function(file_paths) {
|
|||||||
res_json.num_fails = browser.querySelectorAll('li.test.fail').length;
|
res_json.num_fails = browser.querySelectorAll('li.test.fail').length;
|
||||||
res_json.num_passes = browser.querySelectorAll('li.test.pass').length;
|
res_json.num_passes = browser.querySelectorAll('li.test.pass').length;
|
||||||
res_json.num_slow = browser.querySelectorAll('li.test.pass:not(.fast)').length;
|
res_json.num_slow = browser.querySelectorAll('li.test.pass:not(.fast)').length;
|
||||||
|
res_json.num_skipped = browser.querySelectorAll('li.test.pending').length;
|
||||||
res_json.duration = browser.text('li.duration em');
|
res_json.duration = browser.text('li.duration em');
|
||||||
|
|
||||||
var traverse_node = function(elem) {
|
var traverse_node = function(elem) {
|
||||||
var classList = elem.className.split(' ');
|
var classList = elem.className.split(' ');
|
||||||
|
var res;
|
||||||
if (classList.indexOf('suite') > -1) {
|
if (classList.indexOf('suite') > -1) {
|
||||||
var res = {
|
res = {
|
||||||
type: 'suite',
|
type: 'suite',
|
||||||
name: elem.querySelector('h1').textContent,
|
name: elem.querySelector('h1').textContent,
|
||||||
has_subfailures: elem.querySelectorAll('li.test.fail').length > 0
|
has_subfailures: elem.querySelectorAll('li.test.fail').length > 0
|
||||||
}
|
};
|
||||||
|
|
||||||
var child_elems = elem.querySelector('ul').children;
|
var child_elems = elem.querySelector('ul').children;
|
||||||
res.children = Array.prototype.map.call(child_elems, traverse_node);
|
res.children = Array.prototype.map.call(child_elems, traverse_node);
|
||||||
@ -35,23 +37,30 @@ var provide_emitter = function(file_paths) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var h2_content = elem.querySelector('h2').childNodes;
|
var h2_content = elem.querySelector('h2').childNodes;
|
||||||
var res = {
|
res = {
|
||||||
type: 'test',
|
type: 'test',
|
||||||
text: h2_content[0].textContent
|
text: h2_content[0].textContent
|
||||||
}
|
};
|
||||||
|
|
||||||
if (classList.indexOf('pass') > -1) {
|
if (classList.indexOf('pass') > -1) {
|
||||||
res.pass = true;
|
res.pass = true;
|
||||||
|
if (classList.indexOf('pending') > -1) {
|
||||||
|
res.slow = false;
|
||||||
|
res.skipped = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
res.slow = classList.indexOf('fast') < 0;
|
res.slow = classList.indexOf('fast') < 0;
|
||||||
|
res.skipped = false;
|
||||||
res.duration = h2_content[1].textContent;
|
res.duration = h2_content[1].textContent;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
res.error = elem.querySelector('pre.error').textContent;
|
res.error = elem.querySelector('pre.error').textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
var top_suites = browser.querySelectorAll('#mocha-report > li.suite');
|
var top_suites = browser.querySelectorAll('#mocha-report > li.suite');
|
||||||
res_json.suites = Array.prototype.map.call(top_suites, traverse_node);
|
res_json.suites = Array.prototype.map.call(top_suites, traverse_node);
|
||||||
@ -65,9 +74,9 @@ var provide_emitter = function(file_paths) {
|
|||||||
}, Q(new Browser()));
|
}, Q(new Browser()));
|
||||||
|
|
||||||
return emitter;
|
return emitter;
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
provide_emitter: provide_emitter,
|
provide_emitter: provide_emitter,
|
||||||
name: 'ZombieJS'
|
name: 'ZombieJS'
|
||||||
}
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user