text: //base test functions
  
  function forEach(iterable, fn, bind){
  	for (var i = 0, j = iterable.length; i < j; i++) fn.call(bind, iterable[i], i, iterable);
  };
  
  //test start
  
  window.onload = function(){
  	
  	var frameworks = {};
  	
  	forEach(document.getElementsByTagName('iframe'), function(iframe){
  		frameworks[iframe.name] = {
  			'test': window.frames[iframe.name].test,
  			'selectors': []
  		};
  	});
  	
  	var tbody = document.getElementById('tbody');
  	var tfoot = document.getElementById('tfoot');
  	var lastrow = tfoot.getElementsByTagName('tr')[0];
  	
  	var controls = document.getElementById('controls');
  	
  	var links = controls.getElementsByTagName('a');
  	
  	var start = links[1];
  	var stop = links[0];
  	
  	start.onclick = function(){
  		testRunner();
  		return false;
  	};
  	
  	stop.onclick = function(){
  		clearTimeout(timer);
  		timer = null;
  		return false;
  	};
  	
  	var score = [];
  	var scores = {};
  	
  	var frxi = 0;
  	for (var name in frameworks){
  		var framework = frameworks[name];
  		forEach(window.selectors, function(selector){
  			framework.selectors.push(selector);
  		});
  		scores[name] = lastrow.getElementsByTagName('td')[frxi];
  		score[name] = 0;
  		frxi++;
  	}
  	
  	var tests = [];
  
  	forEach(window.selectors, function(selector, i){
  		var frxi = 0;
  		var row = tbody.getElementsByTagName('tr')[i];
  		for (var name in frameworks){
  			var framework = frameworks[name];
  			var cell = row.getElementsByTagName('td')[frxi];
  			tests.push({
  				'execute': framework.test,
  				'selector': framework.selectors[i],
  				'name': name,
  				'row': row,
  				'cell' : cell
  			});
  			frxi++;
  		}
  	});
  	
  	var timer = null;
  	
  	var testRunner = function(){
  		var test = tests.shift();
  		if (!test) return;
  		var results = test.execute(test.selector);
  		test.cell.className = 'test';
  		test.cell.innerHTML = results.time + ' ms | ' + results.found + ' found';
  		test.cell.speed = results.time;
  		if (results.error){
  			test.cell.innerHTML = results.time + ' ms | <span class="exception" title="' + results.error + '">error returned</a>';
  			test.cell.className += ' exception';
  			test.cell.found = 0;
  			test.cell.error = true;
  		} else {
  			test.cell.found = results.found;
  			test.cell.error = false;
  		}
  		
  		score[test.name] += test.cell.speed;
  		scores[test.name].innerHTML =  '&nbsp;' + score[test.name] + '&nbsp;';
  		
  		if (test.cell == test.row.lastChild) colourRow(test.row);
  		timer = setTimeout(testRunner, 250);
  	};
  	
  	var colourRow = function(row){
  		
  		var cells = [];
  		
  		var tds = row.getElementsByTagName('td');
  		forEach(tds, function(td){
  			cells.push(td);
  		});
  		
  		var speeds = [];
  		
  		forEach(cells, function(cell, i){
  			if (!cell.error) speeds[i] = cell.speed;
  			//error, so we exclude it from colouring good. does not affect score (it should?).
  			else speeds[i] = 99999999999999999999999;
  		});
  		
  		var min = Math.min.apply(this, speeds);
  		var max = Math.max.apply(this, speeds);
  		
  		var found = [];
  		var mismatch = false;
  		forEach(cells, function(cell, i){
  			found.push(cell.found);
  			if (!mismatch){
  				forEach(found, function(n){
  					if (!cell.error && cell.found != undefined && n && cell.found != n){
  						mismatch = true;
  						return;
  					}
  				});
  			}
  			if (cell.speed == min) cell.className += ' good';
  			else if (cell.speed == max) cell.className += ' bad';
  			else cell.className += ' normal';
  		});
  		
  		if (mismatch){
  			forEach(cells, function(cell, i){
  				if (cell.found != undefined) cell.className += ' mismatch';
  			});
  		}
  		
  	};
  	
  
  };