<!doctype html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>polyfill-service test director</title>

	<style>
		* { box-sizing: border-box; }
		html, body { width: 100%; height: 100%; padding:0; margin: 0; overflow: hidden; }
		#runner { width: 100%; height: 100%; z-index:1; overflow: auto; border: none; display: block;}
		#log { width: 100%; height:30%; z-index: 2; font-size: 14px; font-family: monospace; border: 0; background: white; background: rgba(255,255,255,0.8); padding: 3px 10px; overflow-y: auto; }
		#log p { margin: 0.2em 0; }
		.pass { color: #6b6;}
		.fail { color: white; background: red; display: inline-block; padding: 1px 4px; }
	</style>

	<script>
		var runner, timer;
		var globalresults = {
			passed: 0,
			failed: 0,
			total: 0,
			duration: 0,
			tests: [],
			failingSuites: {},
			testedSuites: [],
			uaString: 'unknown'
		};
		var queue = "{{#features}}{{{feature}}},{{/features}}".split(',').slice(0,-1);
		var runnerCompletedCount = 0;
		var runnerTotalCount = queue.length;
		var windowQueryString = "?mode={{{mode}}}";
		var timeout = 30000;
		var timeoutMaxRetries = 2;
		var timeoutRetryCount = 0;

		window.onload = function() {
			runner = document.getElementById('runner');
			if (queue.length) {
				executeTest();
			} else {
				log('No features to test');
			}
		};

		function executeTest() {
			var feature = queue.pop();
			var url = '/test/tests' + windowQueryString + '&feature=' + feature;
			log('['+(runnerCompletedCount+1)+'/'+runnerTotalCount+'] Testing <a target="runner" href="'+url+'">'+feature+'</a>...');
			runner.src = url;
			timer = setTimeout(function() {
				receiveTestResults([feature]);
			}, timeout);
		}

        function postResult(featureName, result) {
            if (window.top !== this && parent && 'receiveTestResult' in parent) {
                parent.receiveTestResult(featureName, result, '{{{mode}}}');
            } else if (window.top !== this && parent && 'postMessage' in parent && 'JSON' in window) {
                parent.postMessage(JSON.stringify({featureName:featureName, result:result, mode:'{{{mode}}}'}), '*');
            }
        }

		function receiveTestResults(featureList, results) {
			var resultsummary = [], featureName;
			clearTimeout(timer);

			if (!results) {
				resultsummary.push('<span class="fail">Timeout waiting for results</span>');
				if (timeoutRetryCount < timeoutMaxRetries) {
					timeoutRetryCount++;
					resultsummary.push('Scheduling retry ('+timeoutRetryCount+'/'+timeoutMaxRetries+')');
					queue = queue.concat(featureList);
				} else {
					globalresults.failed++;
					globalresults.total++;
					for (var i=0,s=featureList.length; i<s; i++) {
						globalresults.failingSuites[featureList[i]+' (timeout after '+timeout+'ms, '+timeoutMaxRetries+' retries)'] = true;
                        postResult(featureList[i], 'timeout');
					}
					resultsummary.push('No more retries left');
				}
			} else {
				if (results.passed) globalresults.passed += results.passed;
				if (results.failed) globalresults.failed += results.failed;
				if (results.total) globalresults.total += results.total;
				if (results.duration) globalresults.duration += results.duration;
				if (results.tests) globalresults.tests = globalresults.tests.concat(results.tests);
				if (results.testedSuites) globalresults.testedSuites = globalresults.testedSuites.concat(results.testedSuites);
				if (results.uaString) globalresults.uaString = results.uaString;
				if (results.failingSuites) {
					for (var f in results.failingSuites) {
						if (results.failingSuites.hasOwnProperty(f)) {
							globalresults.failingSuites[f] = results.failingSuites[f];
						}
					}
				}
				if (results.testedSuites) {
                    for (var t in results.testedSuites) {
                    	featureName = results.testedSuites[t];
						postResult(featureName, (results.failingSuites && featureName in results.failingSuites) ? 'fail' : 'pass');
					}
                }
				timeoutRetryCount = 0;

				if (results.passed) resultsummary.push('<span class="pass">'+results.passed+' pass</span>');
				if (results.failed) resultsummary.push('<span class="fail">'+results.failed+' fail</span>');
				if (!resultsummary.length) resultsummary.push('No tests to run');
			}

			log(resultsummary.join(', ') + ' ('+featureList.join(', ')+')');
			runnerCompletedCount = runnerTotalCount - queue.length;

			if (!queue.length) {

				globalresults.state = 'complete';
				globalresults.runnerCount = runnerTotalCount;
				window.global_test_results = window.global_test_progress = globalresults;

				resultsummary = [];
				if (globalresults.passed) resultsummary.push('<span class="pass">'+globalresults.passed+' pass</span>');
				if (globalresults.failed) resultsummary.push('<span class="fail">'+globalresults.failed+' fail</span>');
				if (!resultsummary.length) resultsummary.push('No tests to run');
				log('<strong>All tests complete, result data populated into global_test_results.  Total: '+resultsummary.join(', ')+'.</strong>');
			} else {
				window.global_test_progress = { state: 'running', runnerCompletedCount: runnerCompletedCount, runnerCount: runnerTotalCount, failed: globalresults.failed, passed: globalresults.passed };
				executeTest();
			}
		}

		function log(str) {
			var t = new Date();
			var el = document.getElementById('log');
			var p = document.createElement('p');
			p.innerHTML = ((t.getHours()<10)?'0':'') + t.getHours() + ":" + ((t.getMinutes()<10)?'0':'') + t.getMinutes() + ":" + ((t.getSeconds()<10)?'0':'') + t.getSeconds() + ' ' + str;
			el.appendChild(p);
			el.scrollTop = 99999999;
		}
	</script>
</head>
<body>
	<iframe name='runner' id='runner' frameborder='0'></iframe>
	<div id='log'></div>
</body>
</html>
