diff --git a/backend/nodejute/jute/actions.js b/backend/nodejute/jute/actions.js index d09ba88..5ace5be 100644 --- a/backend/nodejute/jute/actions.js +++ b/backend/nodejute/jute/actions.js @@ -55,11 +55,11 @@ module.exports = { res.end(JSON.stringify({ redirect_run_tests: '/jute_docs/run_tests.html' })); } else { // keep party going - hub.emit('action:' + action); + hub.emit('action:' + action, req, res); } }); - hub.emit('action:prune', action); + hub.emit('action:prune', action, req, res); }); } }; diff --git a/backend/nodejute/jute/actions/clearResults.js b/backend/nodejute/jute/actions/clearResults.js index 9ef2609..540c2e0 100644 --- a/backend/nodejute/jute/actions/clearResults.js +++ b/backend/nodejute/jute/actions/clearResults.js @@ -41,12 +41,12 @@ module.exports = { // Events I care about hub.addListener('action:clear_results', clearResults); - function clearResults() { + function clearResults(req, res) { var exec = require('child_process').exec; try { exec("/bin/rm -rf " + hub.config.outputDir + '/*'); } catch(e) {} - hub.cache.res.end('OK'); + res.end('OK'); } } }; diff --git a/backend/nodejute/jute/actions/clearTests.js b/backend/nodejute/jute/actions/clearTests.js index 94ae12a..8e497e3 100644 --- a/backend/nodejute/jute/actions/clearTests.js +++ b/backend/nodejute/jute/actions/clearTests.js @@ -41,9 +41,9 @@ module.exports = { // Events I care about hub.addListener('action:clear_tests', clearTests); - function clearTests() { + function clearTests(req, res) { hub.cache.tests_to_run = []; - hub.cache.res.end('OK'); + res.end('OK'); } } }; diff --git a/backend/nodejute/jute/actions/common.js b/backend/nodejute/jute/actions/common.js index e07f27b..5f84b3f 100644 --- a/backend/nodejute/jute/actions/common.js +++ b/backend/nodejute/jute/actions/common.js @@ -36,10 +36,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. module.exports = { Create: function(hub) { - var cache = hub.cache; - return { - browserName: function() { - var req = cache.req; + var cache = hub.cache, + common = { + browserName: function(req) { return [req.headers['user-agent'], req.connection.remoteAddress].join('---'); }, @@ -64,7 +63,7 @@ module.exports = { dumpFile: function(vars, dataKey, filename, component) { var baseOutputDir = hub.config.outputDir, path = require('path'), - dir = path.join(baseOutputDir, (this.makeSaneNames(component))[0]); + dir = path.join(baseOutputDir, (common.makeSaneNames(component))[0]); data = vars[dataKey], fullFile = path.join(dir, filename), fs = require('fs') @@ -102,26 +101,19 @@ module.exports = { b.sid = test.seleniumID; - // Look good for out foto!! - b.windowMaximize(function(err, body, req) { + //b.chain.windowFocus().getEval("window.moveTo(1,0); window.resizeTo(screen.availWidth, screen.availHeight);").windowMaximize().end(function(err) { + b.chain.windowFocus().getEval("window.moveTo(1,0); window.resizeTo(screen.availWidth, screen.availHeight);").end(function(err) { if (!err) { - b.windowFocus(function(err, body, req) { + b.command('captureScreenshotToString', [], function(err, body, res) { if (!err) { - b.command('captureScreenshotToString', [], function(err, body, res) { - if (!err) { - var bb = new Buffer(body, 'base64'); - fs.writeFileSync(filename, bb, 0, bb.length); - this.addTestOutput(test, "Took snapshot: " + filename); - } else { - hub.emit(hub.log, hub.ERROR, 'SNAP ERROR: ' + err); - } - }); - } else { - hub.emit(hub.log, hub.ERROR, 'FOCUS ERROR: ' + err); + var bb = new Buffer(body, 'base64'); + fs.writeFileSync(filename, bb, 0, bb.length); + common.addTestOutput(test, "Took snapshot: " + filename); } + hub.emit('action:doneDone', err, test); }); } else { - hub.emit(hub.log, hub.ERROR, 'MAX ERROR: ' + err); + hub.emit('action:doneDone', err, test); } }); }, @@ -142,13 +134,13 @@ module.exports = { } } }, - badUnitTest: function(test) { + badUnitTest: function(req, test) { // Dump a FAILED XML file // Use test file name as the NAME of this test (vs. component name from test itself) var parts = test.url.split('/'); var name = parts.pop(); name = name.replace(/\..*$/, ''); // get rid of suffix - var names = this.makeSaneNames(this.browserName()); + var names = common.makeSaneNames(common.browserName(req)); var err = 'Test Timed Out: Most likely a Javascript parsing error - try loading URL in your browser', err = err.replace('BROWSER', names[1]); err = err.replace('URL', test.url); @@ -156,13 +148,14 @@ module.exports = { var msg = "Dumped error unit test file " + name + " / " + names[0] + " (from " + test.url + ")"; hub.emit(hub.log, hub.ERROR, msg); - this.addTestOutput(test, msg); - - this.dumpFile(params, 'results', names[0] + '-test.xml', name); - this.dumpFile({ output: test.output }, 'output', names[0] + '.txt', name); + common.addTestOutput(test, msg); + common.dumpFile(params, 'results', names[0] + '-test.xml', name); + common.dumpFile({ output: test.output }, 'output', names[0] + '.txt', name); } }; + + return common; } }; diff --git a/backend/nodejute/jute/actions/getTest.js b/backend/nodejute/jute/actions/getTest.js index 5ba53c8..deaac7e 100644 --- a/backend/nodejute/jute/actions/getTest.js +++ b/backend/nodejute/jute/actions/getTest.js @@ -44,10 +44,8 @@ module.exports = { // Events I care about hub.addListener('action:get_test', getTest); - function getTest() { - var req = cache.req, - res = cache.res, - browser = req.session.uuid, + function getTest(req, res) { + var browser = req.session.uuid, bName = common.browserName(req), now = new Date().getTime(), testURL; @@ -67,7 +65,7 @@ module.exports = { // must be something wrong with it - pop it var error = 'Skipping bad test: ' + test.url + ': we thought it was running!'; hub.emit(hub.LOG, hub.ERROR, error); - common.badUnitTest(test); + common.badUnitTest(req, test); cache.tests_to_run.splice(i, 1); i--; continue; @@ -102,7 +100,7 @@ module.exports = { // No tests for me - end if we're a Selenium browser if (req.session.selenium) { // Selenium job all done!! - hub.emit('seleniumTestsFinished', browser); + hub.emit('seleniumTestsFinished'); } // ONLY USE HTML FOR NOW UNTIL THE PAGE IS SMARTER... diff --git a/backend/nodejute/jute/actions/heartBeat.js b/backend/nodejute/jute/actions/heartBeat.js index 0ddc25d..0800355 100644 --- a/backend/nodejute/jute/actions/heartBeat.js +++ b/backend/nodejute/jute/actions/heartBeat.js @@ -42,9 +42,8 @@ module.exports = { // Events I care about hub.addListener('action:heart_beat', heartBeat); - function heartBeat() { - var req = cache.req, res = cache.res, - id = req.session.uuid; + function heartBeat(req, res) { + var id = req.session.uuid; // Update heartbeat time if (!cache.browsers[id]) { @@ -52,14 +51,14 @@ module.exports = { } cache.browsers[id].heart_beat = new Date().getTime(); - cache.browsers[id].name = common.browserName(); + cache.browsers[id].name = common.browserName(req); hub.once('action:checkedResults', function(results) { results.current_status = { browsers: cache.browsers, tests_to_run: cache.tests_to_run }; results.config = hub.config; res.end(JSON.stringify(results)); }); - hub.emit('action:checkResults'); + hub.emit('action:checkResults', req, res); } } }; diff --git a/backend/nodejute/jute/actions/pop.js b/backend/nodejute/jute/actions/pop.js index 31cb3d0..b5bf2ea 100644 --- a/backend/nodejute/jute/actions/pop.js +++ b/backend/nodejute/jute/actions/pop.js @@ -43,9 +43,9 @@ module.exports = { // THIS IS DANGEROUS!!! // Take off top test whatever it is - function pop() { + function pop(req, res) { hub.cache.tests_to_run.shift(); - hub.emit('action:status'); + hub.emit('action:status', req, res); } } }; diff --git a/backend/nodejute/jute/actions/prune.js b/backend/nodejute/jute/actions/prune.js index 08f6ee3..25e2eff 100644 --- a/backend/nodejute/jute/actions/prune.js +++ b/backend/nodejute/jute/actions/prune.js @@ -46,19 +46,19 @@ module.exports = { // Events I care about hub.addListener('action:prune', prune); - function prune(doing_what) { + function prune(doing_what, req) { var redirect; if (doing_what != 'status') { - prune_browsers(); - redirect = prune_tests(doing_what); + prune_browsers(req); + redirect = prune_tests(doing_what, req); hub.emit('pruneDone', redirect); } } - function prune_tests(doing_what) { + function prune_tests(doing_what, req) { var now = new Date().getTime(), - browser = cache.req.session.uuid, test, + browser = req.session.uuid, test, timeStarted ; @@ -75,33 +75,15 @@ module.exports = { cache.tests_to_run.splice(i, 1); - common.badUnitTest(test); + common.badUnitTest(req, test); - /* - if (cache.browsers[browser]) { - cache.browsers[browser].heart_beat = now; - cache.browsers[browser].get_test = now; - return 1; //Redirect! - } - */ } - } else { - /* - // make sure browser is still requesting tests - if (cache.browsers[browser]) { - var last_got_test = cache.browsers[browser].get_test; - if (doing_what != 'get_test' && (now - last_got_test > TEST_TIME_THRESHOLD)) { - hub.emit(hub.LOG, hub.ERROR, "Been too long since you've requested a test: " + browser + " - Kicking iframe..."); - return 1; // Redirect!! - } - } - */ } } } - function prune_browsers() { - var now = new Date().getTime(), me = cache.req.session.uuid, + function prune_browsers(req) { + var now = new Date().getTime(), me = req.session.uuid, sys = require('sys'); for (browser in cache.browsers) { @@ -119,7 +101,7 @@ module.exports = { hub.emit(hub.LOG, hub.ERROR, "Deleting this test that was part of lost browser: " + sys.inspect(test)); cache.tests_to_run.splice(i, 1); i--; // fake a perl 'redo'!! Otherwise we might skip over something! - common.badUnitTest(test); + common.badUnitTest(req, test); } } } diff --git a/backend/nodejute/jute/actions/runTest.js b/backend/nodejute/jute/actions/runTest.js index 3754dea..f691fa8 100644 --- a/backend/nodejute/jute/actions/runTest.js +++ b/backend/nodejute/jute/actions/runTest.js @@ -43,17 +43,16 @@ module.exports = { // Events I care about hub.addListener('action:run_test', runTest); - function runTest() { + function runTest(req, res) { var uuid = require('node-uuid'), path = require('path'), fs = require('fs'), - obj = cache.req.body, + obj = req.body, sys = require('sys'), tests, multipleFromUI = false, capture = false, exec = require('child_process').exec, - errors = [], - res = cache.res + errors = [] ; hub.emit(hub.LOG, hub.INFO, sys.inspect(obj)); @@ -142,7 +141,7 @@ module.exports = { } else { if (multipleFromUI) { // Only run these tests in THIS browser from the UI - test_obj.browser = cache.req.session.uuid; + test_obj.browser = req.session.uuid; common.addTestOutput(test_obj, 'Multiple in this browser test'); @@ -177,7 +176,7 @@ module.exports = { } }); - hub.emit('action:seleniumStart'); + hub.emit('action:seleniumStart', req, res); } else { // UI wants to run multiple tests - redirect to it! if (multipleFromUI) { diff --git a/backend/nodejute/jute/actions/startSelenium.js b/backend/nodejute/jute/actions/startSelenium.js index 8c61e76..374c6c3 100644 --- a/backend/nodejute/jute/actions/startSelenium.js +++ b/backend/nodejute/jute/actions/startSelenium.js @@ -45,17 +45,22 @@ module.exports = { // Events I care about hub.addListener('action:seleniumStart', startSelenium); - function startSelenium() { + function startSelenium(req, res) { var soda = require('soda'), cb, - req = cache.req, - res = cache.res, body = req.body, + browser + ; + + try { browser = soda.createClient({ url: 'http://' + (hub.config.host ? hub.config.host + ':' + hub.config.port : req.headers.host), host: body.sel_host, browser: body.sel_browser }) - ; + } catch(e) { + hub.emit('action:seleniumDone', 'Cannot connect to Selenium server at ' + body.sel_host + ': ' + e); + return; + } // Give Selenium 1000 minutes to finish - should be good - 16 hours baby! req.socket.setTimeout(60000000, function() { @@ -80,22 +85,23 @@ module.exports = { }; cb = hub.once('seleniumTestsFinished', cb); + var oo; browser. chain. session(). - open('/?selenium=' + body.uuid, function(err, body, req) { body.seleniumID = browser.sid }). + open('/?selenium=' + body.uuid). waitForPageToLoad(10000). end(function(err) { if (err) { var msg = 'Error starting/waiting for Selenium page to load: ' + err; hub.emit('seleniumTestsFinished', err); } else { - hub.emit(hub.LOG, hub.INFO, "Selenium up and running!"); + hub.emit(hub.LOG, hub.INFO, "Selenium up and running: " + browser.sid); // If this is one of the tests that are going to run in thie // Selenium session, tag it with the Selenium token cache.tests_to_run.forEach(function(test) { if (test.browser === body.uuid) { - test.seleniumID = body.seleniumID; + test.seleniumID = browser.sid; } }); diff --git a/backend/nodejute/jute/actions/status.js b/backend/nodejute/jute/actions/status.js index bd6465c..7bc5f35 100644 --- a/backend/nodejute/jute/actions/status.js +++ b/backend/nodejute/jute/actions/status.js @@ -43,11 +43,11 @@ module.exports = { // Events I care about hub.addListener('action:checkResults', checkResults); - hub.addListener('action:status', function() { + hub.addListener('action:status', function(req, res) { hub.once('action:checkedResults', function(results) { results.current_status = { browsers: cache.browsers, tests_to_run: cache.tests_to_run }; results.config = hub.config; - cache.res.end(JSON.stringify(results)); + res.end(JSON.stringify(results)); }); hub.emit('action:checkResults'); }); diff --git a/backend/nodejute/jute/actions/testReport.js b/backend/nodejute/jute/actions/testReport.js index fa50801..abd9202 100644 --- a/backend/nodejute/jute/actions/testReport.js +++ b/backend/nodejute/jute/actions/testReport.js @@ -43,9 +43,9 @@ module.exports = { // Events I care about hub.addListener('action:test_report', testReport); - function testReport() { - var req = cache.req, obj = req.body, succeeded = true, - names = common.makeSaneNames(common.browserName()), + function testReport(req, res) { + var obj = req.body, succeeded = true, + names = common.makeSaneNames(common.browserName(req)), filename = names[0], pkgname = names[1], now = new Date().getTime(), output = '', exec = require('child_process').exec @@ -90,24 +90,39 @@ module.exports = { if (test.browser == req.session.uuid) { // This is the test that just finished + hub.once('action:doneDone', function(err, test) { + if (err) { + hub.emit(hub.log, hub.ERROR, err); + } else { + hub.emit(hub.log, hub.INFO, 'Test finished: ' + test.url); + } + common.dumpFile({ output: test.output }, 'output', path.basename(names[0], 'xml') + 'txt', obj.name); + res.end('OK'); + }); + + // Clear this test out common.addTestOutput(test, output); - if (test.snapshot && req.session.selenium) { - common.takeSeleniumSnapshot(test, path.join(names[1], path.basename(names[0], 'xml')) + 'png'); - } - common.addTestOutput(test, obj.name + " finished - it " + (succeeded ? 'SUCCEEDED' : 'FAILED') + ' - it took ' + (now - test.running) + "ms\n"); - common.dumpFile({ output: test.output }, 'output', path.basename(names[0], 'xml') + 'txt', obj.name); cache.tests_to_run.splice(i, 1); + + // Take a snapshot & wait or we're done - always if 'snapshot' is set otherwise + // only if a test fails + if ((!succeeded || test.snapshot) && req.session.selenium) { + common.takeSeleniumSnapshot(test, path.join(names[1], path.basename(names[0], 'xml')) + 'png'); + } else { + hub.emit('action:doneDone', null, test); + } break; } } + if (!totalTests) { // A single browser test output += obj.name + " finished - it " + (succeeded ? 'SUCCEEDED' : 'FAILED') + "\n"; common.dumpFile({ output: output }, 'output', path.basename(names[0], 'xml') + 'txt', obj.name); + res.end('OK'); } - cache.res.end('OK'); } } }; diff --git a/backend/nodejute/jute/server.js b/backend/nodejute/jute/server.js index 1b78e1b..c660726 100644 --- a/backend/nodejute/jute/server.js +++ b/backend/nodejute/jute/server.js @@ -71,10 +71,6 @@ Create: function(hub) { sess.selenium = req.query.selenium ? true: false; } - // stash of req/res - hub.cache.req = req; - hub.cache.res = res; - next(); } , connect.logger(hub.config.logFormat) @@ -85,7 +81,7 @@ Create: function(hub) { }); app.all(/\/jute\/_([^\?]+)/, function(req, res, next){ // A JUTE action - GET - hub.emit('action', req.params[0]);//, req, res); + hub.emit('action', req.params[0], req, res); }); app.get('/', function(req, res, next){ // Serve from '/'