// jsUnitNav4.js -- In-document unit testing with submitable results.
// (Not just for Netscape 4, this file name is anachronistic.)

// requires: ResultsForm.js

var FORCE_ARRAY=true;		// get test functions from arrayTestFunctionNames[] -- no auto detect
var fails=0;
var errors=0;
var currentTest="";
var totalAsserts;
var totalTests;
var totalFails;
var totalErrors;
var totalWarns;
var reporter;
var reportedAsserts;

//function assertNav4() {
//	var m,b;
//	assertNumber++;
//	switch (arguments.length) {
//	case 1:
//		m=currentTest+' assert #'+assertNumber.toString()+' failed';
//		b=arguments[0];
//		break;
//	case 2:
//		m=currentTest+' assert #'+assertNumber.toString()+' failed: "'+arguments[0]+'"';
//		b=arguments[1];
//	default:
//		b=false;
//		m=currentTest+' assert #'+assertNumber.toString()+' wrong number of arguments: '+arguments.length.toString;
//	}
//	if (!b) {
//	}
//}
//if (is_nav4) {
//	// var assert=assertNav4;
//}
//
//function assertEqualsNav4() {
//	/// todo
//}	       
//if (is_nav4) {
//	// assertEquals=assertEqualsNav4;
//}

function nav4Throw(e) {
	if (e.isJsUnitException) {
		var m;
		if (e.comment == null) {
			m="! "+currentTest+" fail: "+e.jsUnitMessage;
		}
		else {
			m='! '+currentTest+' '+e.comment+': '+e.jsUnitMessage;
		}
		if (document
		 && document.theform
		 && document.theform.popfail
		 && document.theform.popfail.checked) {
			alert(m);
		}
		reporter(m);
		fails++;
	}
	else if (e.description != null) {
		reporter('E '+currentTest+" #"+assertNumber.toString()+' '+e.description);
		errors++;
	}
	else {
		var ps="";
		for (var p in e) {
			ps+=p+' ';
		}
		reporter('? exception...'+ps);
	}
}

function WindowError(msg,url,lineno) {
	var e=new Object;
	e.description="Browser Error: '"+msg+"' in "+url+" line "+lineno;
	thrower(e);
	return true;
}

function InterestedInInforms() {
	if (document
	 && document.theform
	 && document.theform.showinform
	 && document.theform.showinform.checked !== null
	 && !document.theform.showinform.checked) {
		return false;
	}
	return true;
}
var InterestedInWarns=InterestedInInforms;
var InterestedInDebugs=InterestedInInforms;

function nav4Debug(p1,p2) {
	if (InterestedInDebugs()) {
		reporter('d '+p1);
	}
}

function nav4Warn(p1,p2) {
	if (InterestedInWarns()) {
		reporter('w '+p1);
		totalWarns++;
	}
}
function nav4Inform(p1,p2) {
	if (InterestedInInforms()) {
		reporter('i '+p1);
	}
}

function inittheguy() {
	thrower=nav4Throw;
	tracer=new Object();
	tracer.warn=nav4Warn;
	tracer.inform=nav4Inform;
	tracer.debug=nav4Debug;
//	window.onerror=WindowError;
}

function fintheguy() {
//	window.onerror=passthru;
}

function passthru() {
	return false;
}

function assertRegEquals(s,r) {
	switch (arguments.length) {
	case 2:
	case 3:
		var s=arguments[arguments.length-2];
		var r=arguments[arguments.length-1];
		if (typeof(r) == "string") {
			r=new RegExp(r);
		}
		if (typeof(r) == "undefined") {
			r = /(undefined regular expression)/;
		}
		assert("#"+assertNumber.toString()+" "+s+" vs. "+r.toString(),r.test(s));
		break;
	default:
		fail("assertRegEquals (#"+assertNumber.toString()
		    +") with  "+arguments.length.toString()+" parameter(s)");
		break;
	}
}

function assertExampleArgs(what,args) {
	var s=args[0];
	if (!assert('#'+assertNumber.toString()+' example string should not be null',s != null)) return false;
	for (var i=1 ; i < args.length ; i++) {
		if (s == args[i]) {
			inform(currentTest+' (#'+GetAssertCount().toString()+') '+what+' example '
					+i.toString()+': "'+s.toString()+'"');
			return true;
		}
	}
	warn(currentTest+' (#'+GetAssertCount().toString()+') '+what+': "'+s.toString()+'" ('+typeof(s)+')');
	return false;
}

function assertExamples() {
	return assertExampleArgs("",arguments);
}

function assertException(codestg,re) {
	if (is_exceptions) {
		var caught=false;
		var msg;
		eval(
			"try{"
				+codestg
			+"}"
			+"catch(e){"
				+"msg=(e.message ? e.message : e.description);"
				+"caught=true"
			+"}"
		);
		assert("expected exception: '"+codestg+"'",caught);
		if (re != null) {
			DontCountNextAssert();
			assert("expected exception message would match "+re.toString()
					+" but it's '"+msg+"'",re.test(msg));
		}
	}
	else {
		CountAnAssert();
	}
}

function assertNoException(codestg) {
	if (is_exceptions) {
		var caught=false;
		var msg;
		eval(
			"try{"
				+codestg
			+"}"
			+"catch(e){"
				+"msg=(e.message ? e.message : e.description);"
				+"caught=true"
			+"}"
		);
		assert("unexpected exception in '"+codestg+"': "+msg,!caught);
	}
	else {
		CountAnAssert();
	}
}

function reportclear() {
	if (document
	 && document.theform
	 && document.theform.report
	 && document.theform.report.value) {
		document.theform.report.value="";
	}
}

function reportline(m) {
	if ((/^\# /).test(m)) {
		if (document
		 && document.theform
		 && document.theform.reportpass
		 && !document.theform.reportpass.checked) {
		}
		else {
			document.theform.report.value+=m+"\n";
		}
	}
	else {
		document.theform.report.value+=m+"\n";
	}
}

function reportbottom() {
	if (document
	&& document.theform
	&& document.theform.report) {	
		document.theform.report.select();
		document.theform.report.focus();
	}
}

function setup(p) {
	currentTest=p;
	fails=0;
	errors=0;
	setUp();
}

function teardown(p) {
	tearDown();
	if (fails == 0 && errors == 0) {
		reporter(". "+p+': '+GetAssertCount().toString()+' passed.');
	}
	else {
		reporter("##"+p+": "+fails.toString()+" fails and "+errors.toString()+
				 " errors out of "+GetAssertCount().toString()+" tests.");
	}
	totalAsserts+=GetAssertCount();
	totalTests++;
	totalFails+=fails;
	totalErrors+=errors;
	currentTest="";
}

var dStart;

function sotests() {
	totalAsserts=0;
	reportedAsserts;
	totalTests=0;
	totalFails=0;
	totalErrors=0;
	totalWarns=0;
	document.theform.statusbox.value="";
	dStart=new Date();
}

function progress(testfname) {
	var msg=plural(totalAsserts,"assert")+", "
	       +plural(totalTests,  "test")+".   "
	       +plural(totalFails,  "fail")+", "
	       +plural(totalErrors, "err");
	if (InterestedInWarns()) {
		msg+=", "+plural(totalWarns,"warn");
	}
	var dNow=new Date();
	var secElapsed=(dNow.getTime()-dStart.getTime())/1000.0;
	msg+="   "+secElapsed.toString()+" sec";
	if (testfname == null || testfname == "") {
		msg+="   Done.";
	}
	else {
		msg+="   "+testfname;
	}
	StatusBox(msg);
}

function eotests() {
	progress();
}

function errorDuringTest(msg,url,lineno) {
	alert('JavaScript Error: '+msg+' in line '+lineno.toString()+' of '+url);
	error('JavaScript Error: '+msg+' in line '+lineno.toString()+' of '+url);
	return true;
}

function exceptionDuringTest(e) {
	error('JavaScript Exception: '+(e.message ? e.message : e.description));
}

function dotest(p) {
	progress(p+'...');
	setup(p);
	if (window[p] == null) {
		error("There is no function '"+p+"'");
	}
	else {
		if (is_exceptions) {
			eval(
				"try {"+
					"window[p]()"+
				"}"+
				"catch(e) {"+
					"exceptionDuringTest(e);"+
				"}"+
				"finally {"+
					"teardown(p);"+
					"progress(p+'.');"+
				"}"
			);
			return;
		}
		else {
			//var oldonerror=window.onerror;
			//window.onerror=errorDuringTest;
			window[p]();
			//window.onerror=oldonerror;
		}
	}
	teardown(p);
	progress(p+'.');
}

function doalltests() {
	reportclear();
	sotests();
	for (p in window) {
		if (/^test/.test(p) && typeof (window[p]) == "function") {
			dotest(p);
		}
	}
	eotests();	
	reportbottom();
}

function dolonetest(p) {
	sotests();
	dotest(p);
	eotests();
	reportbottom();
}

//function informNav4(m) {
//	if (document
//	 && document.theform
//	 && document.theform.showinform
//	 && document.theform.showinform.checked) {
//		reporter(m);
//	}
//}
//if (is_nav4) {
//	// var inform=informNav4;
//}

function jsnLoadBody() {
	reportclear();
}

var arrayHaveAlready=[
	"IE 4.01 / Windows 95 (thanks, anonymous)",
	"IE 4.01 / Windows NT (thanks, Paul R.)",
	"IE 5.0 / Windows 95",
	"IE 5.0 / Windows 98",
	"IE 5.0 / Mac (thanks, Suzanne and Raelene)",
	"IE 5.14 / Mac (thanks, Alessandro, Susann and Arnold)",
	"IE 5.5 / Windows 98 (thanks, Paul R.)",
	"IE 5.5 / Windows NT (thanks, Matthew P.)",
	"IE 6.0 / Windows 98",
	"IE 6.0 / Windows NT (thanks, Tessa)",
	"IE 6.0 / Windows 2000 (thanks, Paul S.)",
	"IE 7.0 / Windows XP (thanks, Hannah)",
	"IE 8.0 / Windows XP (thanks, Hannah)",
	"Netscape 4.75 / Linux (thanks, Roger)",
	"Netscape 4.76 / Mac (thanks, Robert)",
	"Netscape 4.7c / Mac (thanks, Suzanne)",
	"Netscape 4.77 / Linux -- testing in progress (thanks, Jesper)",
	"Netscape 4.78 / Mac (thanks, Cathy)",
	"Netscape 4.79 / Windows 98",
	"Netscape 4.79 / Windows NT (thanks, Tessa)",
	"Netscape 4.8 / Windows 2000",
	"Netscape 6.2rv0.9 / Windows 98 (thanks, Ken)",
	"Netscape 6.2.1rv0.9 / Mac (thanks, Karen)",
	"Netscape 6.2.2rv0.9 / Mac (thanks, Karen)",
	"Netscape 6.2.2rv0.9 / Linux (thanks, Roger)",
	"Netscape 6.2.3rv0.9 / Windows 98",
	"Netscape 7.1 / Windows 2000",
	"Mozilla 0.9.8 / Linux (thanks, Paul R.)",
	"Mozilla 1.0rc1 / Linux (thanks, Jesper)",
	"Mozilla 1.0rc3 / Linux (thanks, Jesper)",
	"Mozilla 1.0rc3 / Windows 98",
	"Mozilla 1.0.0 / Windows 2000 (thanks, Paul R.)",
	"Mozilla 1.0.0 / Mac (thanks, Karen)",
	"Mozilla 1.1a / Windows 2000 (thanks, Paul R.)",
	"Mozilla 1.5 / Windows 2000",
	"Opera 6.00 / Windows NT (thanks, Tessa)",
	"Opera 6.03 / Windows 98",
	"Opera 7.21 / Windows 2000",
	"Opera 8.54 / Windows 2000",
	"Opera 9.51 / Windows 2000",
	"Opera 9.52 / Windows 2000",
	"Opera 9.60 / Windows 2000",
	"OmniWeb 4.1-v410 / Mac (thanks, anonymous)",
	"AOL 5.0 / Windows 98 (thanks, Dad, thanks, Phyllis)",
	"Safari 3.0.3 / Windows 2000",
	"Safari 3.1.2 / Windows XP (thanks, Hannah)",
	"Safari 3.1.2 / Mac (thanks, Matt)",
	"Chrome 0.3 / Windows XP (thanks, Steve Erbach, Hannah)",
	"Firefox 1.0 / Windows 2000",
	"Firefox 2.0.0.15 / Mac (thanks, Matt)",
	"Firefox 2.0.0.16 / Windows XP (thanks, Hannah)",
	"Firefox 2.0.0.17 / Windows 2000",
	"Firefox 3.0.1 / Windows 2000",
	"Firefox 3.0.1 / Windows XP",
	"Firefox 3.0.1 / Linux (thanks, Patty)",
	"Firefox 3.0.1 / Windows XP",
	"Firefox 3.0.3 / Linux (thanks, Lyle)",
	"Firefox 3.0.3 / Windows 2000",
	"Firefox 3.0.3 / Windows XP (thanks, Hannah)",
	"Firefox 3.0.4 / Windows 2000",
	"Firefox 3.1b1 / Windows Vista (thanks, Steve Erbach)"
];	

function havealready() {
	var me=whoami();
	for (var i=0 ; i < arrayHaveAlready.length ; i++) {
		var v=arrayHaveAlready[i].replace(/ \(.*\)/,"");
		if (me == v) {
			return true;
			}
	}
	return false;
}

function earlyaction() {
}

///////////// from UnitRunner.js

function EXPERIMENTAL_getTestFunctionNamesInLoadedTestPage(windowTarget) {
	var testFunctionNames=new Array();
	var a=new Array();
    for (var i in windowTarget) {
		push(a,i);
        if (i.substring(0, 4)=="test" && typeof(windowTarget[i])=="function")
            push(testFunctionNames, i);
    }
    if (testFunctionNames.length == 0) {
		alert(a.join());
		var scriptsInTestFrame=windowTarget.document.scripts;
		if (scriptsInTestFrame != null) {
			for (var i=0; i<scriptsInTestFrame.length; i++) {
				var someNames=this._extractTestFunctionNamesFromScript(scriptsInTestFrame[i]);
				if (someNames)
					testFunctionNames=testFunctionNames.concat(someNames);
			}
		}
    }
	return testFunctionNames;
}

var fnsource="";

function getTestFunctionNamesInLoadedTestPage(windowTarget) {
	var testFunctionNames=new Array();
	var scriptsInTestFrame=windowTarget.document.scripts;
	if (FORCE_ARRAY) {
	}
	else if (is_mac && is_ie5_1_) {
	}
    else if (scriptsInTestFrame != null) {
		for (var i=0; i<scriptsInTestFrame.length; i++) {
            var someNames=this._extractTestFunctionNamesFromScript(scriptsInTestFrame[i]);
			if (someNames) {
				testFunctionNames=testFunctionNames.concat(someNames);
		        fnsource="document.scripts";
			}
        }
	} 
	else {
        for (var i in windowTarget) {
			if (i.substring(0, 4)=="test") { // this if must come first to avoid crashing
			                                 // Mozilla on typeof(Window.fullScreen) or something
	            if (typeof(windowTarget[i])=="function") {
					push(testFunctionNames, i);
			        fnsource="properties in window";
				}
			}
        }
    }
    if (arrayTestFunctionNames != null) {
		if (testFunctionNames.length == 0) {
			testFunctionNames=arrayTestFunctionNames;		// help for Opera, Konqueror
			fnsource="array";
		}
		else {
			for (var ig=0 ; ig < testFunctionNames.length ; ig++) {
				if (ig >= arrayTestFunctionNames.length
				 || testFunctionNames[ig] != arrayTestFunctionNames[ig]) {
					warn('Function '+(ig+1).toString()
						+' is '+testFunctionNames[ig]
						+' not '+arrayTestFunctionNames[ig]);
					break;
				}
			}
		}
    }
	return testFunctionNames;
}

function exportTestFunctionNames(testFunctionNames)
{
	pre();
	wln();
	wln('var arrayTestFunctionNames=[');
	for (var i=0 ; i < testFunctionNames.length ; i++) {
		w('     "'+testFunctionNames[i]+'"');
		if (i < testFunctionNames.length-1) {
			w(',');
		}
		wln();
	}
	wln('];');
	wln();
	slashpre();
}

function _extractTestFunctionNamesFromScript(aScript) {
	var retval;
	if (!(/string/).test(typeof(aScript.text))) {
		warn('aScript.text: '+typeof(aScript.text));
		return null;
	}
	var remainingScriptToInspect=aScript.text;
	if (!(/function|object/).test(typeof(remainingScriptToInspect.indexOf))) {
		warn('remainingScriptToInspect.indexOf: '+typeof(remainingScriptToInspect.indexOf));
		return null;
	}
    var currentIndex=remainingScriptToInspect.indexOf("function test");
	while (currentIndex!=-1) {
		if (!retval) retval=new Array();
		if (!(/function|object/).test(typeof(remainingScriptToInspect.substring))) {
			warn('remainingScriptToInspect.substring: '+typeof(remainingScriptToInspect.substring));
			return null;
		}
		var fragment=remainingScriptToInspect.substring(currentIndex, remainingScriptToInspect.length);
		if (!(/function|object/).test(typeof(retval.concat))) {
			warn('retval.concat: '+typeof(retval.concat));
			return null;
		}
		if (!(/function|object/).test(typeof(fragment.indexOf))) {
			warn('fragment.indexOf: '+typeof(fragment.indexOf));
			return null;
		}
		retval=retval.concat(fragment.substring(9, fragment.indexOf("(")));
		if (!(/function|object/).test(typeof(remainingScriptToInspect.substring))) {
			warn('remainingScriptToInspect.substring: '+typeof(remainingScriptToInspect.substring));
			return null;
		}
        remainingScriptToInspect=remainingScriptToInspect.substring(currentIndex+12, remainingScriptToInspect.length);
		if (!(/function|object/).test(typeof(remainingScriptToInspect.indexOf))) {
			warn('remainingScriptToInspect.indexOf: '+typeof(remainingScriptToInspect.indexOf));
			return null;
		}
        currentIndex=remainingScriptToInspect.indexOf("function test");
	}
	return retval;
}

/////////////////// from UnitUtility.js

function push(anArray, anObject) {
        anArray[anArray.length]=anObject;
}
function pop(anArray) {
        if (anArray.length>=1) {
                delete anArray[anArray.length - 1];
                anArray.length--;
        }
}

// writeRunner() ///////////////////////////////////////////////////////////////////////////////////

function writeRunner() {
	DEBUG_ALERTS=(/\?.*debug/i).test(document.URL);      // e.g. testfunctions.html?debug
	// FORCE_ARRAY=(/\?.*\barray\b/i).test(document.URL);   // e.g. testfunctions.html?array -- DISABLED -- ALWAYS ON
	if (/\?.*\bquiet\b/.test(document.URL)) {
	}
	else if (/\?.*\bconsole\b/.test(document.URL)) {
		Console();
	}
	else if (/\?.*\bexport\b/.test(document.URL)) {
		ExportReport();
	}
	else if (/\?.*\bbody\b/.test(document.URL)) {
		RunBody();
	}
	else {
		ReportForm();
	}
}

// exportReport() ////////////////////////

function ExportReport() {
	var testFunctionNames=getTestFunctionNamesInLoadedTestPage(window);
	if (testFunctionNames.length == 0) {
		wlb("(no test functions)");
	}
	else {
		exportTestFunctionNames(testFunctionNames);
	}
}

// Console() ///////////////////////////////////////////////////////////////////////////////////
	
function Console() {	
	inittheguy();
	reporter=reportline;
	
	wlb('<form name=theform id=form>');
	wln('<input type="button" value="Run All" onclick="doalltests()" />');
	wln('<input type="checkbox" name=showinform id=showinform checked="checked" />show inform'); // todo: other show's
	wln('<input type="checkbox" name=popfail id=showinform />popup failures');
	wln('<input type="checkbox" name=reportpass id=reportpass />pass detail');
	wln('<input type="reset" value="Clear" />');
	wlb('');
	wlb('<textarea name=report id=report cols=80 rows=10 wrap=soft></textarea>');
	wlb('<input id=statusbox name=statusbox type="text" size="60" />');
	wlb('Run Individual Tests:');
	for (p in window) {
		if (/^test/.test(p)) { //  && typeof (window[p]) == "function") {
			//wln('<input type="checkbox" name="checkbox_'+p+'" />');
			wln('<input type="button" onclick="dolonetest(\''+p+'\')" value="'+p+'" />');
			//wln('<span style="color:red">'+p+'</span>');
			//wlb('');
		}
	}
	wlb('<\/form>');
	if (false) {
		wln('textarea members: ');
		for (pt in document.theform.report) {
			wln(pt);
		}
		wlb('');
		wln('textarea.constructor members: ');
		for (pt in document.theform.report.constructor) {
			wln(pt);
		}
		wlb('');
		wln('textarea.constructor.prototype members: ');
		for (pt in document.theform.report.constructor.prototype) {
			wln(pt);
		}
		wlb('');
		wln('textarea.prototype members: ');
		for (pt in document.theform.report.prototype) {
			wln(pt);
		}
	}
}

// RunBody ///////////////////////////////////////////////////////////////////////////////////

var StartString="Your Browser";
var EndString="The End";

function SubmitterRoutine() {
	var longstg=document.jsutreport.captured.value;
	if (RegExp(StartString).test(longstg)
	 && RegExp(EndString).test(longstg)) {
		return true;
	}
	return confirm("Doesn't appear you captured the WHOLE page."
	             + "  Are you sure you want to submit?\n"
	             + "If not, please click Cancel, and copy & paste "
	             + "all the text on this page (between Your Browser and The End) into"
	             + " the big edit box.");
}

var safety=false;

function RunBodyReporter(m) {
	var type=m.substring(0,2);
	var detail=m.substring(2);
	switch (type) {
	case '# ':
		if (!safety) {
			w('<small><small>');
		}
		safety=true;
		break;
	default:
		if (safety) {
			w('<br /><\/small><\/small>');
		}
		safety=false;
		break;
	}
	switch (type) {
	case '# ':
		w(detail+' ');
		break;
	case '! ':
		wln('<font color=#993300>'+detail+'<br /></font>');
		break;
	case 'E ':
		wln('<font color=#FF0033>'+detail+'<br /></font>');
		break;
	default:
		wlb(m);
		break;
	}
}

function RunBody() {
	wln("<font color="+(havealready() ? "black" : "green")+">");
	wln("<b>"+StartString+": "+whoami()+"<\/b>&nbsp;&nbsp;&nbsp;");
	if (!havealready()) wlb(" -- Untested version!  Please submit a report!  "
	                       +'See <a href="#below">below<\/a>.');
	wln("<\/font>");
		wlb('<small>Agent: "'+navigator.userAgent+'"<\/small>');

	wln('<form name=theform id=form>');
	wln('Totals: <input id=statusbox name=statusbox type="text" size="60" />');
	wlb('<\/form>');

	inittheguy();
	sotests();	
	reporter=RunBodyReporter;
	reportclear();	
	var testFunctions=getTestFunctionNamesInLoadedTestPage(window);
	for (var itest=0 ; itest < testFunctions.length ; itest++) {
		//RunBodyReporter(testFunctions[itest]);
		dotest(testFunctions[itest]);
	}
	eotests();
	reporter('  '+EndString+'.');
	fintheguy();
	
	if (havealready() && totalFails == 0 && totalErrors == 0 && totalWarns == 0) {
		wlb('Thanks for checking!  I have already tested this configuration.'); //+\'\\n\\n\'+FormSubmit().toString()
	}
	else {
		wln('<form name="jsutreport" id="jsutreport" onsubmit="return SubmitterRoutine();" '
		   +'action="http://www.visibone.com/cgibin/TFmail.pl" method="POST">');
		wln('<input type="hidden" name="_config" value="jsunit" />');
		wln("<a name=below>");
		wln('<p><a name=below><font color=green>Please submit a report!'
           +"  I'd sure like to see these results.<\/font><\/a><br />");
		wln('<b>Copy<\/b> & <b>Paste<\/b> the contents of this page into this box (added comments welcome):<br />');
		   //+'1. Click body of this page.  2.Edit | Select All  3. Copy '
		   //+'4. Click white box. 5. Paste<br />');
		wln('<textarea cols="80" rows="15" name="captured" id="captured" wrap="soft"><\/textarea><br />');
		wlb('Name:<input type="text" name="name" id="realname" />'
		   +'&nbsp;&nbsp;&nbsp;Email:<input type="text" name="email" id="email" />'
		   +'(private, strictly for communicating about this test)');
		wln('<input type="btnSubmit" value="btnSubmit" />');
		wln('<\/form>');
	}
}


// ReportForm ///////////////////////////////////////////////////////////////////////////////////

//function readystatechange(elem) {
//	alert(elem.name+" state: "+elem.readyState+" ("+document);
//}
//function rscDocument() {
//	alert("document state: "+document.readyState);
//}
//document.onreadystatechange=rscDocument;

//function totalschange(elem) {
//	alert('Totals now "'+elem.value+'"');
//}

function RunTests() {
	inittheguy();
	sotests();	
	reporter=reportline;
	reportclear();	
	reporter(document.title);
	reporter('For '+whoami());
	
	var testFunctions=getTestFunctionNamesInLoadedTestPage(window);
	
	for (var itest=0 ; itest < testFunctions.length ; itest++) {
		if (testFunctions[itest] != null) {
			dotest(testFunctions[itest]);
		}
	}
	eotests();
	fintheguy();

	if (document 
	 && document.theform
	 && document.theform.realname
	 && typeof(document.theform.realname) == "function") {
		document.theform.realname.focus();
	}
	var amsg="";	
	if (havealready() && totalFails == 0 && totalErrors == 0 && totalWarns == 0) {
		if (testFunctions.length == 0 && is_opera) {
			amsg+="Opera doesn't seem to have enough capabilities to run "
			     +"these tests, thanks for trying anyway.";
		}
		else {
			amsg="All tests passed!  Thanks for checking.  "
			    +"We've already tested this configuration, "
			    +"so no need to submit the results.";
			if (testFunctions.length == 0) {
				amsg+="\n\nZero tests means either the browser doesn't have enough capabilities "
				         +"to run these tests, or it had problems with the JavaScript.  Please "
				         +"try to enable JavaScript errors or console or debugging, "
				         +"or try another test.";
			}
		}
	}
	else {
		var nprobs=totalErrors+totalFails+totalWarns;
		if (nprobs == 0) {
			amsg+="All tests passed!";
		}
		else {
			amsg+="The tests uncovered "+plural(nprobs,"issue")+"!";
		}
		amsg+='\n\nPlease submit these results.'
           +"  I'd sure like to see them.";
	}
	alert(amsg);
}

// see ResultsForm.js for ResultsForm() function

function ReportForm() {
	wln("<font color="+(havealready() ? "black" : "green")+">");
	wln("<b>Your Browser: "+whoami()+"<\/b>&nbsp;&nbsp;&nbsp;");
	if (!havealready()) wlb(" -- Untested version!  Please run the tests and submit a report!");
	wln("<\/font>");
	wlb('<small>Agent: "'+navigator.userAgent+'"<\/small>');

	ResultsForm("jsunit",'Test Results:',true);

	if (document.theform) {
		//document.theform.reset(); // in N4 this actually takes effect AFTER subsequent filling in of fields
		if (document.theform.report) {
			// Turns off scrolling and generates a message document.theform.report.disabled=true;
		}
		if (document.theform.btnSubmit) {
			// Opera 5 won't enable again: document.theform.btnSubmit.disabled=true;
		}
	}
}
