'
);
this.layer.appendTo(targetEl);
return true;
},
});
// default template used for display. Note we use classes here - not IDs.
// This way multiple instances can be on the same page at once.
var html = ['
',
'
UserAgent
',
'
',
'',
'Running...',
'
',
'
',
'
',
'
'].join('');
/**
BrowserLogger logs output to the HTML display in a browser.
@extends Ct.DefaultLogger
*/
Ct.BrowserLogger = utils.extend(Ct.DefaultLogger,
/** @scope Ct.DummyLogger.prototype */{
name: 'better-browser',
init: function() {
Ct.DefaultLogger.prototype.init.apply(this, arguments);
this.plans = [];
this.status = {
passed: 0,
failed: 0,
errors: 0,
warnings: 0,
tests: 0,
assertions: 0
};
},
setupDisplay: function() {
if (this._displayWasSetup) { return; }
this._displayWasSetup = true ;
var layer, logger;
layer = this.layer = $(html);
$('body').append(layer);
// write in the user agent
layer.find('.useragent').text(navigator.userAgent);
// listen to change event
this.checkboxLayer = layer.find('.hide-passed input[type=checkbox]');
logger = this;
this.checkboxLayer.change(function() {
logger.hidePassedTestsDidChange(logger.checkboxLayer.attr('checked'));
});
},
hidePassedTestsDidChange: function(aFlag) {
this.setupDisplay();
if (aFlag) { this.layer.find('ul.detail').addClass('hide-passed'); }
else { this.layer.find('ul.detail').removeClass('hide-passed'); }
},
summarize: function(final){
var status = this.status,
statusMsg = '',
hasErrors, key;
if (!final) { statusMsg += 'Running... '; }
statusMsg += 'Completed '+status.assertions+' assertions in '+status.tests+' tests: '+
''+status.passed+' passed'
hasErrors = (status.failed + status.errors + status.warnings)>0;
if (hasErrors) {
for(key in status) {
if (!status.hasOwnProperty(key) || (key==='passed')) continue;
if ((key==='tests') || (key==='assertions')) continue;
statusMsg += ''+status[key]+' '+key+'';
}
}
this.layer.find('.final-status').html(statusMsg);
if (final) {
var checkbox = this.layer.find('.hide-passed input');
if (hasErrors) {
checkbox.attr('disabled', false).attr('checked', true);
this.hidePassedTestsDidChange(true);
} else {
checkbox.attr('disabled', true).attr('checked', false);
this.hidePassedTestsDidChange(false);
}
}
},
incrementStatus: function(status){
if (this.status[status] !== undefined) { this.status[status]++; }
this.status.assertions++;
this.summarize();
},
// ..........................................................
// CORE API - Overide in your subclass
//
begin: function(planName) {
this.setupDisplay();
var plan = new PlanEntry(this, planName);
this.plans.push(plan);
this.currentPlan = plan;
plan.render(this.layer.find('ul.detail'));
},
end: function(planName) {
this.currentPlan = null;
this.summarize(true);
},
add: function(status, testInfo, message) {
var plan = this.currentPlan;
if (!plan) throw "add called outside of plan";
// NOTE: We only ever have one module right now. If we allow further nesting at some point we
// need to change the way this behaves.
var testName = testInfo.testName,
moduleName = testInfo.moduleNames[0] || 'default';
plan.module(moduleName).test(testName).add(status, message);
}
});
// make available to those directly importing this module
exports = __module.exports= Ct.BrowserLogger;
exports.BrowserLogger = Ct.BrowserLogger;