var Spooky = require('spooky'); var path = require('path'); var phantom_path = require('phantomjs').path; var casper_path = path.resolve(__dirname, 'node_modules/casperjs/bin/casperjs'); process.env['PHANTOMJS_EXECUTABLE'] = phantom_path; var casper_opts = { child: { transport: 'http', command: casper_path }, casper: { logLevel: 'debug', verbose: true } } var provide_emitter = function(file_paths) { var spooky = new Spooky(casper_opts, function(err) { if (err) { if (err.stack) console.warn(err.stack); else console.warn(err); return; } spooky.start('about:blank'); file_paths.forEach(function(file_path, path_ind) { spooky.thenOpen('file://'+file_path); spooky.then([{ path_ind: path_ind }, function() { var res_json = { file_ind: path_ind } 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_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.duration = this.evaluate(function() { return document.querySelector('li.duration em').textContent }); res_json.suites = this.evaluate(function() { var traverse_node = function(elem) { if (elem.classList.contains('suite')) { var res = { type: 'suite', name: elem.querySelector('h1').textContent, has_subfailures: elem.querySelectorAll('li.test.fail').length > 0, } var child_elems = elem.querySelector('ul').children; res.children = Array.prototype.map.call(child_elems, traverse_node); return res; } else { var h2_content = elem.querySelector('h2').childNodes; var res = { type: 'test', text: h2_content[0].textContent, } if (elem.classList.contains('pass')) { res.pass = true; res.slow = !elem.classList.contains('fast'); res.duration = h2_content[1].textContent; } else { res.error = elem.querySelector('pre.error').textContent; } return res; } } var top_suites = document.querySelectorAll('#mocha-report > li.suite'); return Array.prototype.map.call(top_suites, traverse_node); }); res_json.replay = this.evaluate(function() { return document.querySelector('a.replay').textContent }); this.emit('test_ready', res_json); }]); }); spooky.run(); }); return spooky; } module.exports = { provide_emitter: provide_emitter, name: 'SpookyJS (CapserJS on PhantomJS)' }