head.ready(function(){
var redrawTestrun = function(testrun) {
// rerender the suite based on the updated data
testrun.html(Mustache.to_html("\
\
\
Test Run Started [{{timestamp}}] - {{status}} \
{{#running}} \
{{currentTest}} \
{{/running}} \
\
\
{{testCount}} total test(s): \
{{#hasfailures}} \
{{failedCount}} failure(s) \
{{#showfaults}} \
Hide Failures \
{{/showfaults}} \
{{^showfaults}} \
Show Failures \
{{/showfaults}} \
{{/hasfailures}} \
{{^hasfailures}} \
no failures \
{{/hasfailures}} \
\
{{#showfaults}} \
\
\
{{#faults}} \
\
{{test}} \
{{detail}} \
\
{{/faults}} \
\
{{#showfaultdetail}} \
{{faultdetail}} \
{{/showfaultdetail}} \
\
{{/showfaults}} \
", testrun.data()));
};
$('testruns').delegate('a.showFaults', 'click', function(){
var testrun = $(this).closest('testrun');
testrun.data().showfaults = true;
redrawTestrun(testrun);
return false;
});
$('testruns').delegate('a.hideFaults', 'click', function(){
var testrun = $(this).closest('testrun');
testrun.data().showfaults = false;
redrawTestrun(testrun);
return false;
});
$('testruns').delegate('fault', 'click', function(){
var testrun = $(this).closest('testrun');
testrun.data().faultdetail = $(this).find('detail').html();
testrun.data().showfaultdetail = true;
// mark only this fault as selected - TODO must be a better way to do this
_.each(testrun.data().faults, function(fault) { fault.selected = false; });
var details = testrun.find('detail');
var matchingFault = _.detect(details, function(detail) { return $(detail).html() === testrun.data().faultdetail; });
var matchingFaultIdx = _.indexOf(details, matchingFault);
testrun.data().faults[matchingFaultIdx].selected = true;
redrawTestrun(testrun);
return false;
});
// TODO don't assume localhost
var socket = new WebSocket('ws://localhost:9021/');
var suites = {};
var templates = {
"Test::Unit::UI::TestRunnerMediator::STARTED":
"[{{timestamp}}]Test Suite Started",
"Test::Unit::TestCase::STARTED":
"[{{timestamp}}]Test Started: {{args}}",
"FAULT":
"[{{timestamp}}]{{args}}",
"Test::Unit::TestCase::FINISHED":
"[{{timestamp}}]Test Completed: {{args}}",
"Test::Unit::UI::TestRunnerMediator::FINISHED":
"[{{timestamp}}]Test Suite Completed in {{args}} seconds"
};
socket.onopen = function (e) {
// should indicate that we're connected
};
socket.onclose = function (e) {
// should indicate that we're disconnected and maybe try to reconnect
};
socket.onmessage = function(jsonMessage) {
if (jsonMessage && jsonMessage.data) {
var message = $.parseJSON(jsonMessage.data);
if (_.isEqual(message, ['backfilling'])) {
$('appstatus').attr('class', 'backfilling');
} else if (_.isEqual(message,['realtime'])) {
$('appstatus').attr('class', 'realtime');
} else {
// append message to event log
message.timestamp = new Date(message.milliseconds).toLocaleTimeString();
var template = templates[message.event];
$('eventlog')
.append(Mustache.to_html(template, message))
.scrollTop($('eventlog').attr('scrollHeight') - $('eventlog').height());
// find or create the corresponding suite
var guid = message.guid;
if ($('#' + guid).length == 0) {
$('testruns').prepend('');
}
// update its data based on the event
var testrun = $('#' + guid);
var testrunData = testrun.data();
if (message.event === "Test::Unit::UI::TestRunnerMediator::STARTED") {
testrunData.guid = guid;
testrunData.timestamp = new Date(message.milliseconds).toLocaleTimeString();
testrunData.status = 'Initializing';
testrunData.testCount = 0;
testrunData.failedCount = 0;
testrunData.hasfailures = false;
testrunData.faults = [];
testrunData.showfaults = false;
} else if (message.event === "Test::Unit::TestCase::STARTED") {
testrunData.status = 'Running';
testrunData.currentTest = message.args;
testrunData.running = true;
} else if (message.event === "FAULT") {
testrunData.failedCount += 1;
testrunData.hasfailures = true;
testrunData.faults.push({test: testrunData.currentTest, detail: message.args});
} else if (message.event === "Test::Unit::TestCase::FINISHED") {
testrunData.running = false;
testrunData.testCount += 1;
} else if (message.event === "Test::Unit::UI::TestRunnerMediator::FINISHED") {
if (testrunData.failedCount == 0) {
testrunData.status = 'Success';
} else {
testrunData.status = 'Failed';
}
}
redrawTestrun(testrun);
}
}
};
});