4 ** Copyright (c) 2013 The Khronos Group Inc.
6 ** Permission is hereby granted, free of charge, to any person obtaining a
7 ** copy of this software and/or associated documentation files (the
8 ** "Materials"), to deal in the Materials without restriction, including
9 ** without limitation the rights to use, copy, modify, merge, publish,
10 ** distribute, sublicense, and/or sell copies of the Materials, and to
11 ** permit persons to whom the Materials are furnished to do so, subject to
12 ** the following conditions:
14 ** The above copyright notice and this permission notice shall be included
15 ** in all copies or substantial portions of the Materials.
17 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30 <meta charset="utf-8">
31 <!-- Prevents Chrome from offering to translate tests which generate
32 random characters for things like attribute names -->
33 <meta name="google" value="notranslate">
34 <title>WebGL Conformance Tests</title>
42 font-family: Verdana, Arial, sans-serif;
48 text-decoration: none;
52 border-bottom: 1px solid #66D;
72 border-bottom: 1px solid #CCC;
87 border-left: 1px solid #CCC;
104 margin-bottom: 1.5em;
122 border-width: 0px 0 1px 0;
123 background-color: #FFF;
124 padding: 4px 0 4px 0;
126 -webkit-transition: background-color 0.25s;
127 -moz-transition: background-color 0.25s;
128 transition: background-color 0.25s;
131 .testpage:first-child {
132 border-width: 1px 0 1px 0;
138 .testpagesuccess { background-color: #8F8; }
139 .testpagefail { background-color: #F88; }
140 .testpageskipped { background-color: #888; }
141 .testpagetimeout { background-color: #FC8; }
142 .nowebgl { font-weight: bold; color: red; }
160 <script type="text/javascript" src="resources/webgl-test-harness.js"></script>
163 var DEFAULT_CONFORMANCE_TEST_VERSION = "1.0.3 (beta)";
166 version: DEFAULT_CONFORMANCE_TEST_VERSION,
181 if (window.console && window.console.log) {
182 window.console.log(msg);
186 function create3DContext(canvas, attrs, version) {
188 canvas = document.createElement("canvas");
194 names = ["webgl2", "experimental-webgl2"]; break;
196 names = ["webgl", "experimental-webgl"]; break;
198 for (var i = 0; i < names.length; ++i) {
200 context = canvas.getContext(names[i], attrs);
210 var reportType = WebGLTestHarnessModule.TestHarness.reportType;
213 var autoScrollEnabled = true; // Whether the user prefers to auto scroll
214 var autoScroll = true; // Whether auto scroll is actually performed
216 var Page = function(reporter, folder, testIndex, url) {
217 this.reporter = reporter;
218 this.folder = folder;
221 this.totalSuccessful = 0;
222 this.totalTimeouts = 0;
223 this.totalSkipped = 0;
224 this.testIndex = testIndex;
226 this.elementId = "page" + pageCount++;
227 var li = reporter.localDoc.createElement('li');
228 li.id = this.elementId;
229 var div = reporter.localDoc.createElement('div');
230 div.classList.add('pageHeader');
231 var check = reporter.localDoc.createElement('input');
232 check.type = 'checkbox';
233 check.checked = true;
234 div.appendChild(check);
235 var button = reporter.localDoc.createElement('input');
236 button.type = 'button';
237 button.value = 'run';
238 button.onclick = function() {
240 reporter.runTest(url);
242 if (reporter.noWebGL) {
243 button.disabled = true;
245 div.appendChild(button);
246 var a = reporter.localDoc.createElement('a');
249 var node = reporter.localDoc.createTextNode(url);
252 li.setAttribute('class', 'testpage');
254 var ul = reporter.localDoc.createElement('ul');
255 var node = reporter.localDoc.createTextNode('');
257 div.appendChild(node);
258 this.totalsElem = node;
259 this.resultElem = ul;
264 Page.prototype.addResult = function(msg, success, skipped) {
266 if (success === undefined) {
267 ++this.totalTimeouts;
268 var result = "timeout";
270 } else if (success) {
274 ++this.totalSuccessful;
276 // don't report success.
279 var result = "failed";
283 var node = this.reporter.localDoc.createTextNode(result + ': ' + msg);
284 var li = this.reporter.localDoc.createElement('li');
285 li.appendChild(node);
286 li.setAttribute('class', css);
287 this.resultElem.appendChild(li);
290 Page.prototype.startPage = function() {
291 if (autoScroll && this.elem.scrollIntoView) {
292 this.elem.scrollIntoView(false);
295 this.totalSuccessful = 0;
296 this.totalTimeouts = 0;
297 // remove previous results.
298 while (this.resultElem.hasChildNodes()) {
299 this.resultElem.removeChild(this.resultElem.childNodes[0]);
301 this.totalsElem.textContent = '';
303 var shouldRun = this.check.checked && this.folder.checked();
306 this.elem.classList.remove('testpagetimeout');
307 this.elem.classList.remove('testpageskipped');
308 this.elem.classList.remove('testpagefail');
309 this.elem.classList.remove('testpagesuccess');
312 return this.check.checked && this.folder.checked();
315 Page.prototype.firstTestIndex = function() {
316 return this.testIndex;
319 Page.prototype.finishPage = function(success) {
320 if(this.totalSkipped) {
321 var msg = ' (' + this.totalSkipped + ' of ' + this.totalTests + ' skipped)';
323 var msg = ' (' + this.totalSuccessful + ' of ' + this.totalTests + ' passed)';
326 if (success === undefined) {
327 var css = 'testpagetimeout';
330 ++this.totalTimeouts;
331 } else if (this.totalSkipped) {
332 var css = 'testpageskipped';
333 } else if (this.totalSuccessful != this.totalTests) {
334 var css = 'testpagefail';
336 var css = 'testpagesuccess';
338 this.elem.classList.add(css);
339 this.totalsElem.textContent = msg;
342 Page.prototype.enableTest = function(re) {
343 if (this.url.match(re)) {
344 this.check.checked = true;
345 this.folder.enableUp_();
349 Page.prototype.disableTest = function(re) {
350 if (this.url.match(re)) {
351 this.check.checked = false;
355 var Folder = function(reporter, folder, depth, opt_name) {
356 this.reporter = reporter;
358 this.name = opt_name || "";
359 this.displayName = this.name;
360 if (folder && folder.displayName) {
361 this.displayName = folder.displayName + '/' + this.displayName;
363 this.subFolders = {};
366 this.folder = folder;
369 var doc = reporter.localDoc;
370 this.elementId = "folder" + folderCount++;
371 var li = doc.createElement('li');
372 li.id = this.elementId;
373 li.classList.add("folder");
374 var div = doc.createElement('div');
375 div.classList.add('folderHeader');
376 var check = doc.createElement('input');
377 check.type = 'checkbox';
378 check.checked = true;
379 div.appendChild(check);
380 var button = doc.createElement('input');
381 button.type = 'button';
382 button.value = 'run';
383 button.onclick = function() {
384 autoScroll = autoScrollEnabled;
387 if (reporter.noWebGL) {
388 button.disabled = true;
390 div.appendChild(button);
391 var h = doc.createElement('span');
392 h.classList.add('folderName');
393 h.appendChild(doc.createTextNode(this.displayName));
395 var ul = doc.createElement('ul');
401 this.folderHeader = div;
404 Folder.prototype.checked = function() {
405 return this.check.checked &&
406 (this.folder ? this.folder.checked() : true);
409 Folder.prototype.firstTestIndex = function() {
410 return this.items[0].firstTestIndex();
413 Folder.prototype.numChildren = function() {
415 for (var name in this.subFolders) {
416 numChildren += this.subFolders[name].numChildren();
418 return numChildren + this.pages.length;
421 Folder.prototype.run = function() {
422 var firstTestIndex = this.firstTestIndex();
423 var count = this.numChildren();
424 log("run tests: " + firstTestIndex + " to " + (firstTestIndex + count - 1))
425 testHarness.runTests({start: firstTestIndex, count: count});
428 Folder.prototype.getSubFolder = function(name) {
429 var subFolder = this.subFolders[name];
430 if (subFolder === undefined) {
431 subFolder = new Folder(this.reporter, this, this.depth + 1, name);
432 this.subFolders[name] = subFolder;
433 this.items.push(subFolder);
434 this.childUL.appendChild(subFolder.elem);
439 Folder.prototype.getOrCreateFolder = function(url) {
440 var parts = url.split('/');
442 for (var pp = 0; pp < parts.length - 1; ++pp) {
443 folder = folder.getSubFolder(parts[pp]);
448 Folder.prototype.addPage = function(page) {
449 this.pages.push(page);
450 this.items.push(page);
451 this.childUL.appendChild(page.elem);
452 this.folderHeader.classList.add('hasPages');
455 Folder.prototype.disableTest = function(re, opt_forceRecurse) {
457 if (this.name.match(re)) {
458 this.check.checked = false;
459 recurse = opt_forceRecurse;
462 for (var name in this.subFolders) {
463 this.subFolders[name].disableTest(re, opt_forceRecurse);
465 for (var ii = 0; ii < this.pages.length; ++ii) {
466 this.pages[ii].disableTest(re);
471 Folder.prototype.enableUp_ = function() {
472 this.check.checked = true;
473 var parent = this.folder;
479 Folder.prototype.enableTest = function(re) {
480 if (this.name.match(re)) {
483 for (var name in this.subFolders) {
484 this.subFolders[name].enableTest(re);
486 for (var ii = 0; ii < this.pages.length; ++ii) {
487 this.pages[ii].enableTest(re);
491 var Reporter = function(iframes) {
492 this.localDoc = document;
493 this.resultElem = document.getElementById("results");
494 this.fullResultsElem = document.getElementById("fullresults");
495 var node = this.localDoc.createTextNode('');
496 this.fullResultsElem.appendChild(node);
497 this.fullResultsNode = node;
498 this.iframes = iframes;
499 this.currentPageElem = null;
501 this.pagesByURL = {};
503 // Check to see if WebGL is supported
504 var canvas = document.createElement("canvas");
505 var ctx = create3DContext(canvas, null, 1);
508 // Check to see if WebGL2 is supported
509 this.noWebGL2 = true;
510 var canvas2 = document.createElement("canvas");
511 var ctx2 = create3DContext(canvas2, null, 2);
513 // If the WebGL2 context could be created use it instead
515 this.noWebGL2 = false;
519 this.contextInfo = {};
520 this.root = new Folder(this, null, 0, "all");
521 this.resultElem.appendChild(this.root.elem);
522 this.callbacks = { };
525 this.contextInfo["VENDOR"] = ctx.getParameter(ctx.VENDOR);
526 this.contextInfo["VERSION"] = ctx.getParameter(ctx.VERSION);
527 this.contextInfo["RENDERER"] = ctx.getParameter(ctx.RENDERER);
528 this.contextInfo["RED_BITS"] = ctx.getParameter(ctx.RED_BITS);
529 this.contextInfo["GREEN_BITS"] = ctx.getParameter(ctx.GREEN_BITS);
530 this.contextInfo["BLUE_BITS"] = ctx.getParameter(ctx.BLUE_BITS);
531 this.contextInfo["ALPHA_BITS"] = ctx.getParameter(ctx.ALPHA_BITS);
532 this.contextInfo["DEPTH_BITS"] = ctx.getParameter(ctx.DEPTH_BITS);
533 this.contextInfo["STENCIL_BITS"] = ctx.getParameter(ctx.STENCIL_BITS);
535 var ext = ctx.getExtension("WEBGL_debug_renderer_info");
537 this.contextInfo["UNMASKED_VENDOR"] = ctx.getParameter(ext.UNMASKED_VENDOR_WEBGL);
538 this.contextInfo["UNMASKED_RENDERER"] = ctx.getParameter(ext.UNMASKED_RENDERER_WEBGL);
543 Reporter.prototype.enableTest = function(name) {
544 this.root.enableTest(name);
547 Reporter.prototype.disableTest = function(name) {
548 this.root.disableTest(name);
551 Reporter.prototype.disableAllTests = function() {
552 this.root.disableTest(".*", true);
555 Reporter.prototype.addEventListener = function(type, func) {
556 if (!this.callbacks[type]) {
557 this.callbacks[type] = [];
559 this.callbacks[type].push(func);
562 Reporter.prototype.executeListenerEvents_ = function(type) {
563 var callbacks = this.callbacks[type].slice(0);
564 for (var ii = 0; ii < callbacks.length; ++ii) {
565 setTimeout(callbacks[ii], 0);
569 Reporter.prototype.runTest = function(url) {
570 var page = this.pagesByURL[url];
571 testHarness.runTests({start: page.firstTestIndex(), count: 1});
574 Reporter.prototype.getFolder = function(url) {
575 return this.root.getOrCreateFolder(url);
578 Reporter.prototype.addPage = function(url) {
579 var folder = this.getFolder(url);
580 var page = new Page(this, folder, this.totalPages, url);
581 folder.addPage(page);
583 this.pagesByURL[url] = page;
586 Reporter.prototype.startPage = function(url) {
587 var page = this.pagesByURL[url];
588 return page.startPage();
591 Reporter.prototype.addResult = function(url, msg, success, skipped) {
592 var page = this.pagesByURL[url];
593 page.addResult(msg, success, skipped);
596 Reporter.prototype.finishPage = function(url, success) {
597 var page = this.pagesByURL[url];
598 page.finishPage(success);
601 Reporter.prototype.displayFinalResults = function(msg, success) {
604 var totalSuccessful = 0;
605 var totalTimeouts = 0;
606 var totalSkipped = 0;
607 for (var url in this.pagesByURL) {
608 var page = this.pagesByURL[url];
609 totalTests += page.totalTests;
610 totalSuccessful += page.totalSuccessful;
611 totalTimeouts += page.totalTimeouts;
612 totalSkipped += page.totalSkipped;
615 if (totalTimeouts > 0) {
616 timeout = ', ' + totalTimeouts + ' timed out';
618 var msg = ' (' + totalSuccessful + ' of ' +
619 totalTests + ' passed' + timeout + ')';
620 this.fullResultsNode.textContent = msg;
622 // generate a text summary
624 tx += "WebGL Conformance Test Results\n";
625 tx += "Subset: Version " + OPTIONS.version + "\n";
627 tx += "-------------------\n\n";
628 tx += "User Agent: " + (navigator.userAgent ? navigator.userAgent : "(navigator.userAgent is null)") + "\n";
629 tx += "WebGL VENDOR: " + this.contextInfo["VENDOR"] + "\n";
630 tx += "WebGL VERSION: " + this.contextInfo["VERSION"] + "\n";
631 tx += "WebGL RENDERER: " + this.contextInfo["RENDERER"] + "\n";
632 tx += "Unmasked VENDOR: " + this.contextInfo["UNMASKED_VENDOR"] + "\n";
633 tx += "Unmasked RENDERER: " + this.contextInfo["UNMASKED_RENDERER"] + "\n";
634 tx += "WebGL R/G/B/A/Depth/Stencil bits (default config): " + this.contextInfo["RED_BITS"] + "/" + this.contextInfo["GREEN_BITS"] + "/" + this.contextInfo["BLUE_BITS"] + "/" + this.contextInfo["ALPHA_BITS"] + "/" + this.contextInfo["DEPTH_BITS"] + "/" + this.contextInfo["STENCIL_BITS"] + "\n";
636 tx += "-------------------\n\n";
637 tx += "Test Summary (" + totalTests + " total tests):\n";
638 tx += "Tests PASSED: " + totalSuccessful + "\n";
639 tx += "Tests FAILED: " + (totalTests - totalSuccessful - totalSkipped) + "\n";
640 tx += "Tests TIMED OUT: " + totalTimeouts + "\n";
641 tx += "Tests SKIPPED: " + totalSkipped + "\n";
643 tx += "-------------------\n\n";
644 if (totalSuccessful < totalTests) {
645 tx += "Failures:\n\n";
646 for (var url in this.pagesByURL) {
647 var page = this.pagesByURL[url];
648 var pageTotalFail = page.totalTests - page.totalSuccessful - page.totalSkipped;
649 if (!(page.totalTests == 0 && page.totalTimeouts == 0) &&
652 tx += url + ": " + pageTotalFail + " tests failed";
653 if (page.totalTimeouts)
654 tx += " (" + page.totalTimeouts + " timed out)";
659 tx += "All tests PASSED\n\n";
662 tx += "-------------------\n\n";
663 tx += "Complete Test Results (total / pass / fail / timeout / skipped):\n\n";
664 for (var url in this.pagesByURL) {
665 var page = this.pagesByURL[url];
666 var pageTotalFail = page.totalTests - page.totalSuccessful - page.totalSkipped;
667 if (!(page.totalTests == 0 && page.totalTimeouts == 0)) {
668 tx += url + ": " + page.totalTests + " / " +
669 page.totalSuccessful + " / " + pageTotalFail + " / " + page.totalTimeouts + " / " + page.totalSkipped + "\n";
673 tx += "-------------------\n\n";
674 tx += "Generated on: " + (new Date()).toString() + "\n";
676 var r = document.getElementById("testResultsAsText");
677 while (r.firstChild) r.removeChild(r.firstChild);
678 r.appendChild(document.createTextNode(tx));
679 document.getElementById("showTextSummary").style.visibility = "visible";
681 this.postResultsToServer(tx);
683 var e = document.getElementById("error");
685 this.postResultsToServer(msg);
689 Reporter.prototype.postTestStartToServer = function(resultText) {
690 if(OPTIONS.postResults == undefined || OPTIONS.postResults == 0) {
694 var xhr = new XMLHttpRequest();
695 xhr.open('POST', "/start", true);
699 Reporter.prototype.postResultsToServer = function(resultText) {
700 if(OPTIONS.postResults == undefined || OPTIONS.postResults == 0) {
704 var xhr = new XMLHttpRequest();
705 xhr.open('POST', "/finish", true);
706 xhr.setRequestHeader("Content-Type", "text/plain");
707 xhr.send(resultText);
710 Reporter.prototype.ready = function() {
711 var loading = document.getElementById("loading");
712 loading.style.display = "none";
714 var button = document.getElementById("runTestsButton");
715 button.disabled = false;
716 this.executeListenerEvents_("ready");
720 Reporter.prototype.reportFunc = function(type, url, msg, success, skipped) {
722 case reportType.ADD_PAGE:
723 return this.addPage(msg);
724 case reportType.READY:
726 case reportType.START_PAGE:
727 return this.startPage(url);
728 case reportType.TEST_RESULT:
729 return this.addResult(url, msg, success, skipped);
730 case reportType.FINISH_PAGE:
731 return this.finishPage(url, success);
732 case reportType.FINISHED_ALL_TESTS:
733 return this.displayFinalResults(msg, success);
740 var getURLOptions = function(obj) {
741 var s = window.location.href;
742 var q = s.indexOf("?");
743 var e = s.indexOf("#");
747 var query = s.substring(q + 1, e);
748 var pairs = query.split("&");
749 for (var ii = 0; ii < pairs.length; ++ii) {
750 var keyValue = pairs[ii].split("=");
751 var key = keyValue[0];
752 var value = decodeURIComponent(keyValue[1]);
757 getURLOptions(OPTIONS);
759 var makeVersionSelect = function(currentVersion) {
760 var versionSelect = document.getElementById("testVersion");
761 var foundCurrentVersion = false;
762 var numericCurrentVersion = currentVersion.replace(/[^\d.]/g, '');
764 for (var i in testVersions) {
765 var version = testVersions[i];
766 var numericVersion = version.replace(/[^\d.]/g, '');
767 var option = document.createElement("option");
768 option.setAttribute('value', numericVersion);
769 option.innerHTML = version;
771 if (numericVersion == numericCurrentVersion) {
772 foundCurrentVersion = true;
773 option.selected = true;
776 versionSelect.appendChild(option);
779 // If the version requested by the query string isn't in the list add it.
780 if (!foundCurrentVersion) {
781 var option = document.createElement("option");
782 option.setAttribute('value', numericCurrentVersion);
783 option.innerHTML = currentVersion + " (unknown)";
784 option.selected = true;
786 versionSelect.appendChild(option);
789 versionSelect.addEventListener('change', function(ev) {
790 window.location.href = "?version=" + versionSelect.value;
794 makeVersionSelect(OPTIONS.version);
797 var makeIFrames = function() {
798 var toparea = document.getElementById("toparea");
799 var frame = document.getElementById("frames");
800 var areaWidth = Math.max(100, toparea.clientWidth - 300);
801 var areaHeight = Math.max(100, frame.clientHeight);
803 var numCells = OPTIONS.frames;
805 var gridWidth = Math.max(1, Math.ceil(Math.sqrt(numCells)));
806 var gridHeight = gridWidth;
807 var bestAspect = 99999;
808 var bestNumEmptyCells = 99999;
809 var bestNumEmptyCellsColumns = 0;
810 var bestNumEmptyCellsAspect = 99999;
811 var minGoodAspect = 1 / 3;
812 var maxGoodAspect = 3 / 1;
814 for (var columns = 1; columns <= numCells; ++columns) {
815 var rows = Math.ceil(numCells / columns);
816 var cellWidth = areaWidth / columns;
817 var cellHeight = areaHeight / rows;
818 var cellAspect = cellWidth / cellHeight;
819 if (cellAspect >= minGoodAspect && cellAspect <= maxGoodAspect) {
820 var numEmptyCells = columns * rows - numCells;
821 // Keep the one with the least number of empty cells.
822 if (numEmptyCells < bestNumEmptyCells) {
823 bestNumEmptyCells = numEmptyCells;
824 bestNumEmptyCellsColumns = columns;
825 bestNumEmptyCellsAspect = cellAspect;
826 // If it's the same number of empty cells keep the one
827 // with the best aspect.
828 } else if (numEmptyCells == bestNumEmptyCells &&
829 Math.abs(cellAspect - 1) <
830 Math.abs(bestNumEmptyCellsAspect - 1)) {
831 bestNumEmptyCellsColumns = columns;
832 bestNumEmptyCellsAspect = cellAspect;
835 if (Math.abs(cellAspect - 1) < Math.abs(bestAspect - 1)) {
838 bestAspect = cellAspect;
842 // if we found an aspect with few empty cells use that.
843 var numEmptyCells = gridWidth * gridHeight - numCells;
844 if (bestNumEmptyCellsColumns && bestNumEmptyCells < numEmptyCells) {
845 gridWidth = bestNumEmptyCellsColumns;
846 gridHeight = Math.ceil(numCells / gridWidth);
849 var table = document.createElement("table");
850 table.style.height = areaHeight + "px";
851 var tbody = document.createElement("tbody");
853 for (var row = 0; row < gridHeight; ++row) {
854 var tr = document.createElement("tr");
855 for (var column = 0; column < gridWidth; ++column) {
856 var td = document.createElement("td");
859 var iframe = document.createElement("iframe");
860 iframe.setAttribute("scrolling", "yes");
861 iframe.style.width = "100%";
862 iframe.style.height = "100%";
863 iframes.push(iframe);
864 td.appendChild(iframe);
868 tbody.appendChild(tr);
870 table.appendChild(tbody);
871 frame.appendChild(table);
874 var iframes = makeIFrames();
876 var reporter = new Reporter(iframes);
877 var testHarness = new WebGLTestHarnessModule.TestHarness(
880 function(type, url, msg, success, skipped) {
881 return reporter.reportFunc(type, url, msg, success, skipped);
884 reporter.addEventListener("ready", function() {
885 // Set which tests to include.
886 if (OPTIONS.include) {
887 reporter.disableAllTests();
888 var includes = OPTIONS.include.split(",")
889 for (var ii = 0; ii < includes.length; ++ii) {
890 reporter.enableTest(new RegExp(includes[ii]));
893 // Remove tests based on skip=re1,re2 in URL.
895 var skips = OPTIONS.skip.split(",")
896 for (var ii = 0; ii < skips.length; ++ii) {
897 reporter.disableTest(new RegExp(skips[ii]));
900 // Auto run the tests if the run=1 in URL
901 if (OPTIONS.run != undefined && OPTIONS.run != 0) {
902 reporter.postTestStartToServer();
903 testHarness.runTests();
906 window.webglTestHarness = testHarness;
907 var button = document.getElementById("runTestsButton");
908 button.disabled = true;
909 button.onclick = function() {
910 autoScroll = autoScrollEnabled;
911 reporter.postTestStartToServer();
912 testHarness.runTests();
914 var autoScrollCheckbox = document.getElementById("autoScrollCheckbox");
915 autoScrollCheckbox.checked = autoScrollEnabled;
916 autoScrollCheckbox.onclick = function() {
917 autoScrollEnabled = autoScrollCheckbox.checked;
918 autoScroll = autoScrollEnabled;
920 var textbutton = document.getElementById("showTextSummary");
921 textbutton.onclick = function() {
923 var htmldiv = document.getElementById("testResultsHTML");
924 var textdiv = document.getElementById("testResultsText");
925 if (textdiv.style.display == "none") {
926 textdiv.style.display = "block";
927 htmldiv.style.display = "none";
928 textbutton.setAttribute("value", "display html summary");
930 textdiv.style.display = "none";
931 htmldiv.style.display = "block";
932 textbutton.setAttribute("value", "display text summary");
935 if (reporter.noWebGL) {
936 button.disabled = true;
937 var elem = document.getElementById("nowebgl");
938 elem.style.display = "";
939 reporter.postResultsToServer("Browser does not appear to support WebGL");
944 <body onload="start()">
948 <div id="testResultsHTML">
952 <div style="display: none;" id="testResultsText">
953 <pre id="testResultsAsText"></pre>
956 </div> <!-- end of container -->
961 <tr style="height: 300px;">
965 <td style="width: 300px">
967 <img src="resources/webgl-logo.png" /><br />
968 WebGL Conformance Test Runner<br/>
970 <select id="testVersion">
973 <a href="../../conformance-suites/"><i>(click here for previous versions)</i></a>
975 <input type="button" value="run tests" id="runTestsButton"/>
977 <input type="checkbox" id="autoScrollCheckbox"/>
978 <label for="autoScrollCheckbox">auto scroll</label>
980 <input type="button" style="visibility: hidden;" value="display text summary" id="showTextSummary"/>
981 <div id="nowebgl" class="nowebgl" style="display: none;">
982 This browser does not appear to support WebGL
994 <span id="fullresults">
1001 <div id="error-wrap">
1002 <pre id="error"></pre>
1008 <td id="frames"></td>
1011 </div> <!-- end of header -->