1305 lines
38 KiB
HTML
1305 lines
38 KiB
HTML
<!--
|
|
Copyright (c) 2019 The Khronos Group Inc.
|
|
Use of this source code is governed by an MIT-style license that can be
|
|
found in the LICENSE.txt file.
|
|
-->
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<!-- Prevents Chrome from offering to translate tests which generate
|
|
random characters for things like attribute names -->
|
|
<meta name="google" value="notranslate">
|
|
<meta name="viewport" content="width=device-width">
|
|
<title>WebGL Conformance Tests</title>
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
border: 0;
|
|
margin: 0;
|
|
padding: 0;
|
|
height: 100%;
|
|
max-height:100%;
|
|
font-family: Verdana, Arial, sans-serif;
|
|
font-size: 0.8em;
|
|
}
|
|
|
|
input[type=button], select {
|
|
padding: 2px 6px 2px 6px;
|
|
margin: 0;
|
|
border: 1px solid #888;
|
|
border-radius: 2px;
|
|
background: #f4f4f4;
|
|
}
|
|
|
|
a {
|
|
color: #88F;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:hover {
|
|
border-bottom: 1px solid #66D;
|
|
}
|
|
|
|
label {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
#testlist {
|
|
position:fixed;
|
|
top:180px;
|
|
left:0;
|
|
right: calc(10% + 50px);
|
|
bottom:0px;
|
|
overflow:auto;
|
|
min-height: 200px;
|
|
}
|
|
|
|
@media screen and (max-width: 500px) {
|
|
#testlist {
|
|
font-size: 80%;
|
|
}
|
|
}
|
|
|
|
#header {
|
|
position:absolute;
|
|
top:0;
|
|
left:0;
|
|
width:100%;
|
|
height: 160px;
|
|
overflow: scroll;
|
|
border-bottom: 1px solid #CCC;
|
|
}
|
|
|
|
#info {
|
|
margin: 0 auto;
|
|
max-width: 280px;
|
|
}
|
|
#logo {
|
|
width: 68px;
|
|
height: 40px;
|
|
}
|
|
|
|
#iframe-container {
|
|
color: white;
|
|
display: block;
|
|
position: fixed;
|
|
width: 90%;
|
|
height: calc(100% - 170px);
|
|
bottom: 0px;
|
|
left: calc(90% - 50px);
|
|
transition: left 0.15s;
|
|
}
|
|
#iframe-container.iframe-shown {
|
|
left: 10%;
|
|
}
|
|
#iframe-toggle {
|
|
display: inline-block;
|
|
vertical-align: middle;
|
|
width: 20px;
|
|
height: 100%;
|
|
padding: 0;
|
|
-webkit-appearance: none;
|
|
}
|
|
#test-iframe {
|
|
display: inline-block;
|
|
vertical-align: middle;
|
|
background: white;
|
|
width: calc(100% - 20px);
|
|
height: 100%;
|
|
border: 1px solid black;
|
|
}
|
|
|
|
.folder {
|
|
margin-bottom: 1.5em;
|
|
}
|
|
|
|
.folderHeader {
|
|
white-space: nowrap;
|
|
position: sticky;
|
|
top: 0;
|
|
}
|
|
.folderHeaderInner {
|
|
background: white;
|
|
/* to hide checkboxes from parent headers */
|
|
position: relative;
|
|
left: -2em;
|
|
padding-left: 2em;
|
|
}
|
|
|
|
.folderName {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.folderMessage {
|
|
margin-left: 1em;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.pageHeader {
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.testpage {
|
|
border-style: solid;
|
|
border-color: #CCC;
|
|
border-width: 0px 0 1px 0;
|
|
background-color: #FFF;
|
|
padding: 4px 0 4px 0;
|
|
|
|
-webkit-transition: background-color 0.25s;
|
|
-moz-transition: background-color 0.25s;
|
|
transition: background-color 0.25s;
|
|
}
|
|
|
|
.testpage:first-child {
|
|
border-width: 1px 0 1px 0;
|
|
}
|
|
|
|
.timeout { }
|
|
.success { }
|
|
.fail { }
|
|
.testpagesuccess { background-color: #8F8; }
|
|
.testpagefail { background-color: #F88; }
|
|
.testpageskipped { background-color: #888; }
|
|
.testpagetimeout { background-color: #FC8; }
|
|
.nowebgl { font-weight: bold; color: red; }
|
|
#error-wrap {
|
|
float: left;
|
|
position: relative;
|
|
left: 50%;
|
|
}
|
|
#error {
|
|
color: red;
|
|
float: left;
|
|
position: relative;
|
|
left: -50%;
|
|
text-align: left;
|
|
}
|
|
ul {
|
|
list-style: none;
|
|
padding-left: 1em;
|
|
}
|
|
</style>
|
|
<script type="application/javascript" src="js/webgl-test-harness.js"></script>
|
|
<script>
|
|
"use strict";
|
|
|
|
window.onbeforeunload = function() {
|
|
// Prompt user before reloading
|
|
return false;
|
|
}
|
|
|
|
var DEFAULT_CONFORMANCE_TEST_VERSION = "2.0.1 (beta)";
|
|
|
|
var OPTIONS = {
|
|
version: DEFAULT_CONFORMANCE_TEST_VERSION,
|
|
frames: 1,
|
|
allowSkip: 0,
|
|
root: null,
|
|
quiet: 0
|
|
};
|
|
|
|
var testVersions = [
|
|
"1.0.4 (beta)",
|
|
"2.0.1 (beta)"
|
|
];
|
|
|
|
function start() {
|
|
|
|
function log(msg) {
|
|
if (window.console && window.console.log) {
|
|
window.console.log(msg);
|
|
}
|
|
}
|
|
|
|
function createStylesheet() {
|
|
var style = document.createElement("style");
|
|
style.appendChild(document.createTextNode(""));
|
|
document.head.appendChild(style);
|
|
return style.sheet;
|
|
}
|
|
|
|
function create3DContext(canvas, attrs, version) {
|
|
if (!canvas) {
|
|
canvas = document.createElement("canvas");
|
|
}
|
|
var context = null;
|
|
var names;
|
|
switch (version) {
|
|
case 2:
|
|
names = ["webgl2"]; break;
|
|
default:
|
|
names = ["webgl", "experimental-webgl"]; break;
|
|
}
|
|
for (var i = 0; i < names.length; ++i) {
|
|
try {
|
|
context = canvas.getContext(names[i], attrs);
|
|
} catch (e) {
|
|
}
|
|
if (context) {
|
|
break;
|
|
}
|
|
}
|
|
return context;
|
|
}
|
|
|
|
var reportType = WebGLTestHarnessModule.TestHarness.reportType;
|
|
var pageCount = 0;
|
|
var folderCount = 0;
|
|
var autoScrollEnabled = true; // Whether the user prefers to auto scroll
|
|
var autoScroll = true; // Whether auto scroll is actually performed
|
|
let quickTestMode = true;
|
|
|
|
var Page = function(reporter, folder, testIndex, url) {
|
|
this.reporter = reporter;
|
|
this.folder = folder;
|
|
this.url = url;
|
|
this.totalTests = 0;
|
|
this.totalSuccessful = 0;
|
|
this.totalTimeouts = 0;
|
|
this.totalSkipped = 0;
|
|
this.totalFailed = 0;
|
|
this.testIndex = testIndex;
|
|
this.startTime = new Date();
|
|
this.totalTime = 0;
|
|
var that = this;
|
|
|
|
this.elementId = "page" + pageCount++;
|
|
var li = reporter.localDoc.createElement('li');
|
|
li.id = this.elementId;
|
|
var div = reporter.localDoc.createElement('div');
|
|
div.classList.add('pageHeader');
|
|
var check = reporter.localDoc.createElement('input');
|
|
check.type = 'checkbox';
|
|
check.checked = true;
|
|
check.onclick = function() {
|
|
if (this.checked) {
|
|
that.folder.enableUp_();
|
|
}
|
|
else {
|
|
that.folder.disableUp_();
|
|
}
|
|
};
|
|
div.appendChild(check);
|
|
var button = reporter.localDoc.createElement('input');
|
|
button.type = 'button';
|
|
button.id = this.elementId + "-button";
|
|
button.value = 'run';
|
|
button.onclick = function() {
|
|
autoScroll = false;
|
|
reporter.runTest(url);
|
|
};
|
|
if (reporter.noSelectedWebGLVersion) {
|
|
button.disabled = true;
|
|
}
|
|
div.appendChild(button);
|
|
var a = reporter.localDoc.createElement('a');
|
|
a.href = WebGLTestHarnessModule.getURLWithOptions(url, {
|
|
webglVersion: reporter.selectedWebGLVersion,
|
|
quiet: OPTIONS.quiet,
|
|
quick: quickTestMode ? 1 : 0,
|
|
});
|
|
a.target = "_blank";
|
|
const folderName = that.folder.displayName;
|
|
console.assert(folderName.startsWith("all/"));
|
|
console.assert(url.startsWith(folderName.substring(4) + "/"));
|
|
const urlWithoutFolder = url.substring(folderName.length - 4 + 1);
|
|
var node = reporter.localDoc.createTextNode(urlWithoutFolder);
|
|
a.appendChild(node);
|
|
div.appendChild(a);
|
|
li.setAttribute('class', 'testpage');
|
|
li.appendChild(div);
|
|
var ul = reporter.localDoc.createElement('ul');
|
|
var node = reporter.localDoc.createTextNode('');
|
|
li.appendChild(ul);
|
|
div.appendChild(node);
|
|
this.totalsElem = node;
|
|
this.resultElem = ul;
|
|
this.elem = li;
|
|
this.check = check;
|
|
};
|
|
|
|
Page.prototype.checked = function() {
|
|
return this.check.checked;
|
|
}
|
|
|
|
Page.prototype.addResult = function(msg, success, skipped) {
|
|
++this.totalTests;
|
|
if (success === undefined) {
|
|
++this.totalTimeouts;
|
|
var result = "timeout";
|
|
var css = "timeout";
|
|
} else if (success) {
|
|
++this.totalSuccessful;
|
|
// don't report success.
|
|
return;
|
|
} else {
|
|
++this.totalFailed;
|
|
if (skipped) {
|
|
// Skipped tests are counted as both skips and failures (because we
|
|
// don't want to accidentally accept a conformance submission with
|
|
// skipped tests).
|
|
++this.totalSkipped;
|
|
}
|
|
var result = "failed";
|
|
var css = "fail";
|
|
}
|
|
|
|
var node = this.reporter.localDoc.createTextNode(result + ': ' + msg);
|
|
var li = this.reporter.localDoc.createElement('li');
|
|
li.appendChild(node);
|
|
li.setAttribute('class', css);
|
|
this.resultElem.appendChild(li);
|
|
};
|
|
|
|
Page.prototype.startPage = function() {
|
|
if (autoScroll && this.elem.scrollIntoView) {
|
|
this.elem.scrollIntoView(false);
|
|
}
|
|
this.totalTests = 0;
|
|
this.totalSuccessful = 0;
|
|
this.totalSkipped = 0;
|
|
this.totalFailed = 0;
|
|
this.totalTimeouts = 0;
|
|
this.totalTime = 0;
|
|
// remove previous results.
|
|
while (this.resultElem.hasChildNodes()) {
|
|
this.resultElem.removeChild(this.resultElem.childNodes[0]);
|
|
}
|
|
this.totalsElem.textContent = '';
|
|
|
|
var shouldRun = this.check.checked && this.folder.checked();
|
|
|
|
if (shouldRun) {
|
|
this.elem.classList.remove('testpagetimeout');
|
|
this.elem.classList.remove('testpageskipped');
|
|
this.elem.classList.remove('testpagefail');
|
|
this.elem.classList.remove('testpagesuccess');
|
|
this.startTime = Date.now();
|
|
}
|
|
|
|
return this.check.checked && this.folder.checked();
|
|
};
|
|
|
|
Page.prototype.firstTestIndex = function() {
|
|
return this.testIndex;
|
|
};
|
|
|
|
Page.prototype.finishPage = function(success) {
|
|
var shouldRun = this.check.checked && this.folder.checked();
|
|
if (shouldRun) {
|
|
this.totalTime = Date.now() - this.startTime;
|
|
} else {
|
|
this.totalTime = 0;
|
|
}
|
|
|
|
var passedMsg = ' (Passed: ' + this.totalSuccessful + '/' + this.totalTests;
|
|
var skippedMsg = '';
|
|
if (this.totalSkipped > 0) {
|
|
skippedMsg = ' Skipped: ' + this.totalSkipped + '/' + this.totalTests;
|
|
}
|
|
var failedMsg = '';
|
|
if (this.totalFailed > 0) {
|
|
failedMsg = ' Failed: ' + this.totalFailed + '/' + this.totalTests;
|
|
}
|
|
var timeoutMsg = '';
|
|
if (this.totalTimeouts > 0) {
|
|
timeoutMsg = ' Timeout: ' + this.totalTimeouts + '/' + this.totalTests;
|
|
}
|
|
var msg = passedMsg + skippedMsg + failedMsg + timeoutMsg + ' in ' + this.totalTime.toFixed(1) + ' ms)';
|
|
|
|
if (success === undefined) {
|
|
var css = 'testpagetimeout';
|
|
msg = '(*timeout*)';
|
|
++this.totalTests;
|
|
++this.totalTimeouts;
|
|
} else if (this.totalSkipped) {
|
|
var css = 'testpageskipped';
|
|
} else if (this.totalSuccessful != this.totalTests) {
|
|
var css = 'testpagefail';
|
|
} else {
|
|
var css = 'testpagesuccess';
|
|
}
|
|
this.elem.classList.add(css);
|
|
this.totalsElem.textContent = msg;
|
|
this.folder.pageFinished(this, success);
|
|
};
|
|
|
|
Page.prototype.enableTest = function(re) {
|
|
if (this.url.match(re)) {
|
|
this.check.checked = true;
|
|
this.folder.enableUp_();
|
|
}
|
|
};
|
|
|
|
Page.prototype.disableTest = function(re) {
|
|
if (this.url.match(re)) {
|
|
this.check.checked = false;
|
|
}
|
|
};
|
|
|
|
Page.prototype.toJSON = function() {
|
|
return {
|
|
'subtests': this.totalTests,
|
|
'successful': this.totalSuccessful,
|
|
'skipped': this.totalSkipped,
|
|
'failed': this.totalFailed,
|
|
'timedOut': this.totalTimeouts,
|
|
'totalTime': this.totalTime,
|
|
};
|
|
};
|
|
|
|
|
|
var Folder = function(reporter, folder, depth, opt_name) {
|
|
this.reporter = reporter;
|
|
this.depth = depth;
|
|
this.name = opt_name || "";
|
|
this.displayName = this.name;
|
|
if (folder && folder.displayName) {
|
|
this.displayName = folder.displayName + '/' + this.displayName;
|
|
}
|
|
this.subFolders = {};
|
|
this.pages = [];
|
|
this.items = [];
|
|
this.folder = folder;
|
|
this.cachedTotalTime = 0;
|
|
this.cachedTotalSuccessful = 0;
|
|
this.cachedTotalSkipped = 0;
|
|
this.cachedTotalTimeouts = 0;
|
|
this.cachedTotalTests = 0;
|
|
var that = this;
|
|
|
|
var doc = reporter.localDoc;
|
|
this.elementId = "folder" + folderCount++;
|
|
var li = doc.createElement('li');
|
|
li.id = this.elementId;
|
|
li.classList.add("folder");
|
|
var folderHeader = doc.createElement('div');
|
|
folderHeader.classList.add('folderHeader');
|
|
var folderHeaderInner = doc.createElement('div');
|
|
folderHeaderInner.classList.add('folderHeaderInner');
|
|
folderHeader.appendChild(folderHeaderInner);
|
|
var check = doc.createElement('input');
|
|
check.type = 'checkbox';
|
|
check.checked = true;
|
|
check.onclick = function() {
|
|
if (this.checked) {
|
|
that.enableTest(".*");
|
|
}
|
|
else {
|
|
that.disableTest(".*", true);
|
|
}
|
|
};
|
|
folderHeaderInner.appendChild(check);
|
|
var button = doc.createElement('input');
|
|
button.type = 'button';
|
|
button.value = 'run';
|
|
button.onclick = function() {
|
|
autoScroll = autoScrollEnabled;
|
|
that.run();
|
|
};
|
|
if (reporter.noSelectedWebGLVersion) {
|
|
button.disabled = true;
|
|
}
|
|
folderHeaderInner.appendChild(button);
|
|
var h = doc.createElement('span');
|
|
h.classList.add('folderName');
|
|
h.appendChild(doc.createTextNode(this.displayName));
|
|
folderHeaderInner.appendChild(h);
|
|
var m = doc.createElement('span');
|
|
m.classList.add('folderMessage');
|
|
this.msgNode = doc.createTextNode('');
|
|
m.appendChild(this.msgNode);
|
|
folderHeaderInner.appendChild(m);
|
|
var ul = doc.createElement('ul');
|
|
li.appendChild(folderHeader);
|
|
li.appendChild(ul);
|
|
this.childUL = ul;
|
|
this.elem = li;
|
|
this.check = check;
|
|
this.folderHeader = folderHeader;
|
|
};
|
|
|
|
Folder.prototype.checked = function() {
|
|
return this.check.checked &&
|
|
(this.folder ? this.folder.checked() : true);
|
|
};
|
|
|
|
Folder.prototype.firstTestIndex = function() {
|
|
return this.items[0].firstTestIndex();
|
|
};
|
|
|
|
Folder.prototype.numChildren = function() {
|
|
var numChildren = 0;
|
|
for (var name in this.subFolders) {
|
|
numChildren += this.subFolders[name].numChildren();
|
|
}
|
|
return numChildren + this.pages.length;
|
|
};
|
|
|
|
Folder.prototype.totalTime = function() {
|
|
// Check to see if the cached total time needs to be recomputed
|
|
if (this.cachedTotalTime == -1) {
|
|
this.cachedTotalTime = 0;
|
|
for (var name in this.subFolders) {
|
|
this.cachedTotalTime += this.subFolders[name].totalTime();
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.cachedTotalTime += this.pages[ii].totalTime;
|
|
}
|
|
}
|
|
return this.cachedTotalTime;
|
|
};
|
|
|
|
Folder.prototype.totalSuccessful = function() {
|
|
if (this.cachedTotalSuccessful == -1) {
|
|
this.cachedTotalSuccessful = 0;
|
|
for (var name in this.subFolders) {
|
|
this.cachedTotalSuccessful += this.subFolders[name].totalSuccessful();
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.cachedTotalSuccessful += this.pages[ii].totalSuccessful;
|
|
}
|
|
}
|
|
return this.cachedTotalSuccessful;
|
|
};
|
|
|
|
Folder.prototype.totalSkipped = function() {
|
|
if (this.cachedTotalSkipped == -1) {
|
|
this.cachedTotalSkipped = 0;
|
|
for (var name in this.subFolders) {
|
|
this.cachedTotalSkipped += this.subFolders[name].totalSkipped();
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.cachedTotalSkipped += this.pages[ii].totalSkipped;
|
|
}
|
|
}
|
|
return this.cachedTotalSkipped;
|
|
};
|
|
|
|
Folder.prototype.totalFailed = function() {
|
|
if (this.cachedTotalFailed == -1) {
|
|
this.cachedTotalFailed = 0;
|
|
for (var name in this.subFolders) {
|
|
this.cachedTotalFailed += this.subFolders[name].totalFailed();
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.cachedTotalFailed += this.pages[ii].totalFailed;
|
|
}
|
|
}
|
|
return this.cachedTotalFailed;
|
|
};
|
|
|
|
Folder.prototype.totalTimeouts = function() {
|
|
if (this.cachedTotalTimeouts == -1) {
|
|
this.cachedTotalTimeouts = 0;
|
|
for (var name in this.subFolders) {
|
|
this.cachedTotalTimeouts += this.subFolders[name].totalTimeouts();
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.cachedTotalTimeouts += this.pages[ii].totalTimeouts;
|
|
}
|
|
}
|
|
return this.cachedTotalTimeouts;
|
|
};
|
|
|
|
Folder.prototype.totalTests = function() {
|
|
if (this.cachedTotalTests == -1) {
|
|
this.cachedTotalTests = 0;
|
|
for (var name in this.subFolders) {
|
|
this.cachedTotalTests += this.subFolders[name].totalTests();
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.cachedTotalTests += this.pages[ii].totalTests;
|
|
}
|
|
}
|
|
return this.cachedTotalTests;
|
|
};
|
|
|
|
Folder.prototype.run = function() {
|
|
this.msgNode.textContent = '';
|
|
var firstTestIndex = this.firstTestIndex();
|
|
var count = this.numChildren();
|
|
log("run tests: " + firstTestIndex + " to " + (firstTestIndex + count - 1))
|
|
testHarness.runTests({start: firstTestIndex, count: count});
|
|
};
|
|
|
|
Folder.prototype.pageFinished = function(page, success) {
|
|
this.cachedTotalTime = -1;
|
|
this.cachedTotalSuccessful = -1;
|
|
this.cachedTotalSkipped = -1;
|
|
this.cachedTotalFailed = -1;
|
|
this.cachedTotalTimeouts = -1;
|
|
this.cachedTotalTests = -1;
|
|
var passedMsg = ' (Passed: ' + this.totalSuccessful() + '/' + this.totalTests();
|
|
var skippedMsg = '';
|
|
if (this.totalSkipped() > 0) {
|
|
skippedMsg = ' Skipped: ' + this.totalSkipped() + '/' + this.totalTests();
|
|
}
|
|
var failedMsg = '';
|
|
if (this.totalFailed() > 0) {
|
|
failedMsg = ' Failed: ' + this.totalFailed() + '/' + this.totalTests();
|
|
}
|
|
var timeoutMsg = '';
|
|
if (this.totalTimeouts() > 0) {
|
|
timeoutMsg = ' Timeout: ' + this.totalTimeouts() + '/' + this.totalTests();
|
|
}
|
|
this.msgNode.textContent = passedMsg + skippedMsg + failedMsg + timeoutMsg + ' in ' + (this.totalTime() / 1000).toFixed(2) + ' seconds)';
|
|
if (this.folder) {
|
|
this.folder.pageFinished(page, success);
|
|
}
|
|
};
|
|
|
|
Folder.prototype.getSubFolder = function(name) {
|
|
var subFolder = this.subFolders[name];
|
|
if (subFolder === undefined) {
|
|
subFolder = new Folder(this.reporter, this, this.depth + 1, name);
|
|
this.subFolders[name] = subFolder;
|
|
this.items.push(subFolder);
|
|
this.childUL.appendChild(subFolder.elem);
|
|
}
|
|
return subFolder;
|
|
};
|
|
|
|
Folder.prototype.getOrCreateFolder = function(url) {
|
|
var parts = url.split('/');
|
|
var folder = this;
|
|
for (var pp = 0; pp < parts.length - 1; ++pp) {
|
|
folder = folder.getSubFolder(parts[pp]);
|
|
}
|
|
return folder;
|
|
};
|
|
|
|
Folder.prototype.addPage = function(page) {
|
|
this.pages.push(page);
|
|
this.items.push(page);
|
|
this.childUL.appendChild(page.elem);
|
|
this.folderHeader.classList.add('hasPages');
|
|
};
|
|
|
|
Folder.prototype.disableTest = function(re, opt_forceRecurse) {
|
|
var recurse = true;
|
|
if (this.name.match(re)) {
|
|
this.check.checked = false;
|
|
recurse = opt_forceRecurse;
|
|
}
|
|
if (recurse) {
|
|
for (var name in this.subFolders) {
|
|
this.subFolders[name].disableTest(re, opt_forceRecurse);
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.pages[ii].disableTest(re);
|
|
}
|
|
}
|
|
};
|
|
|
|
Folder.prototype.enableUp_ = function() {
|
|
this.check.checked = true;
|
|
var parent = this.folder;
|
|
if (parent) {
|
|
parent.enableUp_();
|
|
}
|
|
}
|
|
|
|
Folder.prototype.disableUp_ = function() {
|
|
var checked = false;
|
|
for (var name in this.subFolders) {
|
|
checked = this.subFolders[name].checked();
|
|
if (checked) {
|
|
break;
|
|
}
|
|
}
|
|
for (var ii = 0; ii < this.pages.length && checked == false; ++ii) {
|
|
checked = this.pages[ii].checked();
|
|
}
|
|
this.check.checked = checked;
|
|
var parent = this.folder;
|
|
if (parent) {
|
|
parent.disableUp_();
|
|
}
|
|
}
|
|
|
|
Folder.prototype.enableTest = function(re) {
|
|
if (this.name.match(re)) {
|
|
this.enableUp_();
|
|
}
|
|
for (var name in this.subFolders) {
|
|
this.subFolders[name].enableTest(re);
|
|
}
|
|
for (var ii = 0; ii < this.pages.length; ++ii) {
|
|
this.pages[ii].enableTest(re);
|
|
}
|
|
};
|
|
|
|
var Reporter = function(iframes) {
|
|
this.localDoc = document;
|
|
this.resultElem = document.getElementById("results");
|
|
this.fullResultsElem = document.getElementById("fullresults");
|
|
var node = this.localDoc.createTextNode('');
|
|
this.fullResultsElem.appendChild(node);
|
|
this.fullResultsNode = node;
|
|
this.iframes = iframes;
|
|
this.currentPageElem = null;
|
|
this.totalPages = 0;
|
|
this.pagesByURL = {};
|
|
|
|
// Check to see if WebGL is supported
|
|
var canvas = document.createElement("canvas");
|
|
var ctx = create3DContext(canvas, null, 1);
|
|
|
|
// Check to see if WebGL2 is supported
|
|
var canvas2 = document.createElement("canvas");
|
|
var ctx2 = create3DContext(canvas2, null, 2);
|
|
|
|
this.noSelectedWebGLVersion = false;
|
|
this.selectedWebGLVersion = WebGLTestHarnessModule.getMajorVersion(OPTIONS.version);
|
|
if (this.selectedWebGLVersion == 2 && !ctx2) {
|
|
this.noSelectedWebGLVersion = true;
|
|
} else if (this.selectedWebGLVersion == 1 && !ctx) {
|
|
this.noSelectedWebGLVersion = true;
|
|
}
|
|
|
|
// If the WebGL2 context could be created use it to get context info
|
|
if (ctx2) {
|
|
ctx = ctx2;
|
|
}
|
|
|
|
this.noWebGL = !ctx;
|
|
|
|
this.contextInfo = {};
|
|
this.root = new Folder(this, null, 0, "all");
|
|
this.resultElem.appendChild(this.root.elem);
|
|
this.callbacks = { };
|
|
this.startTime = new Date();
|
|
|
|
if (ctx) {
|
|
this.contextInfo["VENDOR"] = ctx.getParameter(ctx.VENDOR);
|
|
this.contextInfo["VERSION"] = ctx.getParameter(ctx.VERSION);
|
|
this.contextInfo["RENDERER"] = ctx.getParameter(ctx.RENDERER);
|
|
this.contextInfo["RED_BITS"] = ctx.getParameter(ctx.RED_BITS);
|
|
this.contextInfo["GREEN_BITS"] = ctx.getParameter(ctx.GREEN_BITS);
|
|
this.contextInfo["BLUE_BITS"] = ctx.getParameter(ctx.BLUE_BITS);
|
|
this.contextInfo["ALPHA_BITS"] = ctx.getParameter(ctx.ALPHA_BITS);
|
|
this.contextInfo["DEPTH_BITS"] = ctx.getParameter(ctx.DEPTH_BITS);
|
|
this.contextInfo["STENCIL_BITS"] = ctx.getParameter(ctx.STENCIL_BITS);
|
|
|
|
var ext = ctx.getExtension("WEBGL_debug_renderer_info");
|
|
if (ext) {
|
|
this.contextInfo["UNMASKED_VENDOR"] = ctx.getParameter(ext.UNMASKED_VENDOR_WEBGL);
|
|
this.contextInfo["UNMASKED_RENDERER"] = ctx.getParameter(ext.UNMASKED_RENDERER_WEBGL);
|
|
}
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.enableTest = function(name) {
|
|
this.root.enableTest(name);
|
|
};
|
|
|
|
Reporter.prototype.disableTest = function(name) {
|
|
this.root.disableTest(name);
|
|
};
|
|
|
|
Reporter.prototype.disableAllTests = function() {
|
|
this.root.disableTest(".*", true);
|
|
};
|
|
|
|
Reporter.prototype.addEventListener = function(type, func) {
|
|
if (!this.callbacks[type]) {
|
|
this.callbacks[type] = [];
|
|
}
|
|
this.callbacks[type].push(func);
|
|
};
|
|
|
|
Reporter.prototype.executeListenerEvents_ = function(type) {
|
|
var callbacks = this.callbacks[type].slice(0);
|
|
for (var ii = 0; ii < callbacks.length; ++ii) {
|
|
setTimeout(callbacks[ii], 0);
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.runTest = function(url) {
|
|
var page = this.pagesByURL[url];
|
|
testHarness.runTests({start: page.firstTestIndex(), count: 1});
|
|
};
|
|
|
|
Reporter.prototype.getFolder = function(url) {
|
|
return this.root.getOrCreateFolder(url);
|
|
};
|
|
|
|
Reporter.prototype.addPage = function(url) {
|
|
var folder = this.getFolder(url);
|
|
var page = new Page(this, folder, this.totalPages, url);
|
|
folder.addPage(page);
|
|
++this.totalPages;
|
|
this.pagesByURL[url] = page;
|
|
};
|
|
|
|
Reporter.prototype.startPage = function(url) {
|
|
var page = this.pagesByURL[url];
|
|
return page.startPage();
|
|
};
|
|
|
|
Reporter.prototype.addResult = function(url, msg, success, skipped) {
|
|
var page = this.pagesByURL[url];
|
|
page.addResult(msg, success, skipped);
|
|
};
|
|
|
|
Reporter.prototype.finishPage = function(url, success) {
|
|
var page = this.pagesByURL[url];
|
|
page.finishPage(success);
|
|
if (OPTIONS.dumpShaders == 1) {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', "/finishIndividualTest", true);
|
|
xhr.send(null);
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.displayFinalResults = function(msg, success) {
|
|
if (success) {
|
|
var totalTests = 0;
|
|
var testsSucceeded = 0;
|
|
var testsFailed = 0;
|
|
var testsSkipped = 0;
|
|
var testsTimedOut = 0;
|
|
|
|
var subtestsHit = 0;
|
|
var subtestsSucceeded = 0;
|
|
var subtestsTimedOut = 0;
|
|
var subtestsSkipped = 0;
|
|
var subtestsFailed = 0;
|
|
|
|
var totalTime = Date.now() - this.startTime;
|
|
|
|
for (var url in this.pagesByURL) {
|
|
var page = this.pagesByURL[url];
|
|
totalTests += 1;
|
|
if (page.totalSkipped) {
|
|
testsSkipped += 1;
|
|
}
|
|
if (page.totalFailed) {
|
|
testsFailed += 1;
|
|
} else if (page.totalTimeouts) {
|
|
testsTimedOut += 1;
|
|
} else if (page.totalSuccessful) {
|
|
if (page.totalSuccessful != page.totalTests)
|
|
throw successes_not_equal_total;
|
|
testsSucceeded += 1;
|
|
}
|
|
|
|
subtestsHit += page.totalTests;
|
|
subtestsSucceeded += page.totalSuccessful;
|
|
subtestsTimedOut += page.totalTimeouts;
|
|
subtestsSkipped += page.totalSkipped;
|
|
subtestsFailed += page.totalFailed;
|
|
}
|
|
|
|
function ratio_str(x, y, name) {
|
|
return x + '/' + y + ' ' + name + ' (' + (x / y * 100).toFixed(2) + '%)';
|
|
}
|
|
var testsSucceededRatio = ratio_str(testsSucceeded, totalTests, 'tests');
|
|
var passedMsg = 'Passed ' + testsSucceededRatio + ', ' +
|
|
ratio_str(subtestsSucceeded, subtestsHit, 'subtests');
|
|
var skippedMsg = '';
|
|
if (testsSkipped > 0) {
|
|
skippedMsg = ' Skipped ' + ratio_str(testsSkipped, totalTests, 'tests');
|
|
}
|
|
var failedMsg = '';
|
|
if (testsFailed > 0) {
|
|
failedMsg = ' Failed ' + ratio_str(testsFailed, totalTests, 'tests') + ', ' +
|
|
ratio_str(subtestsFailed, subtestsHit, 'subtests');
|
|
}
|
|
var timeoutMsg = '';
|
|
if (testsTimedOut > 0) {
|
|
timeoutMsg = ' Timeout ' + ratio_str(testsTimedOut, totalTests, 'tests');
|
|
}
|
|
var msg = passedMsg + skippedMsg + failedMsg + timeoutMsg;
|
|
this.fullResultsNode.textContent = msg;
|
|
|
|
// generate a text summary
|
|
var tx = "";
|
|
tx += "WebGL Conformance Test Results\n";
|
|
tx += "Version " + OPTIONS.version + "\n";
|
|
tx += "Generated on: " + (new Date()).toString() + "\n";
|
|
tx += "\n";
|
|
tx += "-------------------\n\n";
|
|
tx += "User Agent: " + (navigator.userAgent ? navigator.userAgent : "(navigator.userAgent is null)") + "\n";
|
|
tx += "WebGL VENDOR: " + this.contextInfo["VENDOR"] + "\n";
|
|
tx += "WebGL VERSION: " + this.contextInfo["VERSION"] + "\n";
|
|
tx += "WebGL RENDERER: " + this.contextInfo["RENDERER"] + "\n";
|
|
tx += "Unmasked VENDOR: " + this.contextInfo["UNMASKED_VENDOR"] + "\n";
|
|
tx += "Unmasked RENDERER: " + this.contextInfo["UNMASKED_RENDERER"] + "\n";
|
|
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";
|
|
tx += "\n-------------------\n\n";
|
|
|
|
var result;
|
|
if (totalTests && testsSucceeded == totalTests) {
|
|
result = 'PASS';
|
|
} else {
|
|
result = 'FAIL';
|
|
}
|
|
tx += "Test Summary: " + result + " (" + totalTests + " tests):\n";
|
|
tx += subtestsHit + " subtests ran in " + (totalTime / 1000.0).toFixed(2) + " seconds\n";
|
|
function record(what, tests, subtests) {
|
|
tx += what + ": " + tests + " tests, " + subtests + " subtests\n";
|
|
}
|
|
record('PASSED', testsSucceeded, subtestsSucceeded);
|
|
record('NOT PASSED', totalTests - testsSucceeded, subtestsHit - subtestsSucceeded);
|
|
|
|
record('FAILED', testsFailed, subtestsFailed);
|
|
record('TIMED OUT', testsTimedOut, subtestsTimedOut);
|
|
record('SKIPPED', testsSkipped, subtestsSkipped);
|
|
|
|
tx += "\n-------------------\n\n";
|
|
|
|
const failureLines = [];
|
|
const timeoutLines = [];
|
|
const resultLines = [];
|
|
|
|
for (var url in this.pagesByURL) {
|
|
var page = this.pagesByURL[url];
|
|
resultLines.push(' "' + url + '":' + JSON.stringify(page.toJSON()));
|
|
|
|
if (page.totalFailed) {
|
|
failureLines.push(' "' + url + '",');
|
|
}
|
|
if (page.totalTimeouts) {
|
|
timeoutLines.push(' "' + url + '",');
|
|
}
|
|
}
|
|
|
|
const lines = [].concat(
|
|
[
|
|
'{',
|
|
' "failures": [',
|
|
],
|
|
failureLines,
|
|
[
|
|
' ],',
|
|
' "timeouts": [',
|
|
],
|
|
timeoutLines,
|
|
[
|
|
' ],',
|
|
' "results": {',
|
|
],
|
|
resultLines,
|
|
[
|
|
' },',
|
|
'}',
|
|
]
|
|
);
|
|
|
|
tx += lines.join('\n');
|
|
|
|
var r = document.getElementById("testResultsAsText");
|
|
while (r.firstChild) r.removeChild(r.firstChild);
|
|
r.appendChild(document.createTextNode(tx));
|
|
document.getElementById("showTextSummary").disabled = false;
|
|
document.getElementById("dlTextSummary").disabled = false;
|
|
|
|
this.postResultsToServer(tx);
|
|
} else {
|
|
var e = document.getElementById("error");
|
|
e.innerHTML = msg;
|
|
this.postResultsToServer(msg);
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.postTestStartToServer = function(resultText) {
|
|
this.startTime = Date.now();
|
|
if(OPTIONS.postResults == undefined || OPTIONS.postResults == 0) {
|
|
return;
|
|
}
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', "/start", true);
|
|
xhr.send(null);
|
|
};
|
|
|
|
Reporter.prototype.postResultsToServer = function(resultText) {
|
|
if(OPTIONS.postResults == undefined || OPTIONS.postResults == 0) {
|
|
return;
|
|
}
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', "/finish", true);
|
|
xhr.setRequestHeader("Content-Type", "text/plain");
|
|
xhr.send(resultText);
|
|
};
|
|
|
|
Reporter.prototype.ready = function() {
|
|
var loading = document.getElementById("loading");
|
|
loading.style.display = "none";
|
|
if (!this.noSelectedWebGLVersion) {
|
|
var button = document.getElementById("runTestsButton");
|
|
button.disabled = false;
|
|
this.executeListenerEvents_("ready");
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.reportFunc = function(type, url, msg, success, skipped) {
|
|
switch (type) {
|
|
case reportType.ADD_PAGE:
|
|
return this.addPage(msg);
|
|
case reportType.READY:
|
|
return this.ready();
|
|
case reportType.START_PAGE:
|
|
return this.startPage(url);
|
|
case reportType.TEST_RESULT:
|
|
return this.addResult(url, msg, success, skipped);
|
|
case reportType.FINISH_PAGE:
|
|
return this.finishPage(url, success);
|
|
case reportType.FINISHED_ALL_TESTS:
|
|
return this.displayFinalResults(msg, success);
|
|
default:
|
|
throw 'unhandled';
|
|
break;
|
|
};
|
|
};
|
|
|
|
var getURLOptions = function(obj) {
|
|
var s = window.location.href;
|
|
var q = s.indexOf("?");
|
|
var e = s.indexOf("#");
|
|
if (e < 0) {
|
|
e = s.length;
|
|
}
|
|
var query = s.substring(q + 1, e);
|
|
var pairs = query.split("&");
|
|
for (var ii = 0; ii < pairs.length; ++ii) {
|
|
var keyValue = pairs[ii].split("=");
|
|
var key = keyValue[0];
|
|
var value = decodeURIComponent(keyValue[1]);
|
|
obj[key] = value;
|
|
}
|
|
};
|
|
|
|
getURLOptions(OPTIONS);
|
|
|
|
var makeVersionSelect = function(currentVersion) {
|
|
var versionSelect = document.getElementById("testVersion");
|
|
var foundCurrentVersion = false;
|
|
var numericCurrentVersion = currentVersion.replace(/[^\d.]/g, '');
|
|
|
|
for (var i in testVersions) {
|
|
var version = testVersions[i];
|
|
var numericVersion = version.replace(/[^\d.]/g, '');
|
|
var option = document.createElement("option");
|
|
option.setAttribute('value', numericVersion);
|
|
option.innerHTML = version;
|
|
|
|
if (numericVersion == numericCurrentVersion) {
|
|
foundCurrentVersion = true;
|
|
option.selected = true;
|
|
}
|
|
|
|
versionSelect.appendChild(option);
|
|
}
|
|
|
|
// If the version requested by the query string isn't in the list add it.
|
|
if (!foundCurrentVersion) {
|
|
var option = document.createElement("option");
|
|
option.setAttribute('value', numericCurrentVersion);
|
|
option.innerHTML = currentVersion + " (unknown)";
|
|
option.selected = true;
|
|
|
|
versionSelect.appendChild(option);
|
|
}
|
|
|
|
versionSelect.addEventListener('change', function(ev) {
|
|
window.location.href = "?version=" + versionSelect.value;
|
|
}, false);
|
|
}
|
|
|
|
makeVersionSelect(OPTIONS.version);
|
|
|
|
// Make iframes
|
|
var iframes = [document.getElementById("test-iframe")];
|
|
|
|
var testPath = "00_test_list.txt";
|
|
if (OPTIONS.root) {
|
|
testPath = OPTIONS.root + "/" + testPath;
|
|
}
|
|
|
|
var reporter = new Reporter(iframes);
|
|
var testHarness = new WebGLTestHarnessModule.TestHarness(
|
|
iframes,
|
|
testPath,
|
|
function(type, url, msg, success, skipped) {
|
|
return reporter.reportFunc(type, url, msg, success, skipped);
|
|
},
|
|
OPTIONS);
|
|
reporter.addEventListener("ready", function() {
|
|
// Set which tests to include.
|
|
if (OPTIONS.include) {
|
|
reporter.disableAllTests();
|
|
var includes = OPTIONS.include.split(",")
|
|
for (var ii = 0; ii < includes.length; ++ii) {
|
|
reporter.enableTest(new RegExp(includes[ii]));
|
|
}
|
|
}
|
|
// Remove tests based on skip=re1,re2 in URL.
|
|
if (OPTIONS.skip) {
|
|
var skips = OPTIONS.skip.split(",")
|
|
for (var ii = 0; ii < skips.length; ++ii) {
|
|
reporter.disableTest(new RegExp(skips[ii]));
|
|
}
|
|
}
|
|
// Auto run the tests if the run=1 in URL
|
|
if (OPTIONS.run != undefined && OPTIONS.run != 0) {
|
|
reporter.postTestStartToServer();
|
|
testHarness.runTests();
|
|
}
|
|
});
|
|
window.webglTestHarness = testHarness;
|
|
var button = document.getElementById("runTestsButton");
|
|
button.disabled = true;
|
|
button.onclick = function() {
|
|
autoScroll = autoScrollEnabled;
|
|
reporter.postTestStartToServer();
|
|
testHarness.runTests();
|
|
};
|
|
var autoScrollCheckbox = document.getElementById("autoScrollCheckbox");
|
|
autoScrollCheckbox.checked = autoScrollEnabled;
|
|
autoScrollCheckbox.onclick = function() {
|
|
autoScrollEnabled = autoScrollCheckbox.checked;
|
|
autoScroll = autoScrollEnabled;
|
|
};
|
|
|
|
var hidePassedSheet = createStylesheet();
|
|
var hidePassedCheckbox = document.getElementById("hidePassedCheckbox");
|
|
hidePassedCheckbox.checked = false;
|
|
hidePassedCheckbox.onclick = function() {
|
|
var hidePassedTests = hidePassedCheckbox.checked;
|
|
if (hidePassedTests) {
|
|
hidePassedSheet.insertRule(".testpagesuccess { display: none; }", 0);
|
|
} else {
|
|
hidePassedSheet.deleteRule(0);
|
|
}
|
|
};
|
|
|
|
var quickTestModeCheckbox = document.getElementById("quickTestModeCheckbox");
|
|
quickTestModeCheckbox.checked = quickTestMode;
|
|
quickTestModeCheckbox.onclick = function() {
|
|
quickTestMode = quickTestModeCheckbox.checked;
|
|
};
|
|
|
|
var textbutton = document.getElementById("showTextSummary");
|
|
textbutton.onclick = function() {
|
|
log("click");
|
|
var htmldiv = document.getElementById("testResultsHTML");
|
|
var textdiv = document.getElementById("testResultsText");
|
|
if (textdiv.style.display == "none") {
|
|
textdiv.style.display = "block";
|
|
htmldiv.style.display = "none";
|
|
textbutton.setAttribute("value", "display html summary");
|
|
} else {
|
|
textdiv.style.display = "none";
|
|
htmldiv.style.display = "block";
|
|
textbutton.setAttribute("value", "display text summary");
|
|
}
|
|
};
|
|
|
|
function download(filename, text) {
|
|
var element = document.createElement("a");
|
|
element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
|
|
element.setAttribute("download", filename);
|
|
element.style.display = "none";
|
|
document.body.appendChild(element);
|
|
element.click();
|
|
document.body.removeChild(element);
|
|
}
|
|
var dltextbutton = document.getElementById("dlTextSummary");
|
|
dltextbutton.onclick = function() {
|
|
var textdiv = document.getElementById("testResultsText");
|
|
download("webgl-conformance-" + OPTIONS.version + ".txt", textdiv.innerText.trim());
|
|
};
|
|
|
|
if (reporter.noSelectedWebGLVersion) {
|
|
button.disabled = true;
|
|
}
|
|
if (reporter.noWebGL) {
|
|
var elem = document.getElementById("nowebgl");
|
|
elem.style.display = "";
|
|
reporter.postResultsToServer("Browser does not appear to support WebGL");
|
|
} else if (reporter.noSelectedWebGLVersion) {
|
|
var elem = document.getElementById("noselectedwebgl");
|
|
elem.style.display = "";
|
|
reporter.postResultsToServer("Browser does not appear to support the selected version of WebGL");
|
|
}
|
|
|
|
const iframeContainer = document.getElementById("iframe-container");
|
|
const iframeToggle = document.getElementById("iframe-toggle");
|
|
iframeToggle.value = iframeToggle.getAttribute("data-value-hidden");
|
|
iframeToggle.onclick = function() {
|
|
const expanded = iframeToggle.myExpanded = !iframeToggle.myExpanded;
|
|
if (expanded) {
|
|
iframeContainer.classList.add("iframe-shown");
|
|
iframeToggle.value = iframeToggle.getAttribute("data-value-shown");
|
|
} else {
|
|
iframeContainer.classList.remove("iframe-shown");
|
|
iframeToggle.value = iframeToggle.getAttribute("data-value-hidden");
|
|
}
|
|
};
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="start()">
|
|
|
|
<div id="testlist">
|
|
<div id="testResultsHTML">
|
|
<ul id="results">
|
|
</ul>
|
|
</div>
|
|
<div style="display: none;" id="testResultsText">
|
|
<pre id="testResultsAsText"></pre>
|
|
</div>
|
|
</div> <!-- end of container -->
|
|
|
|
<div id="iframe-container">
|
|
<input type="button" data-value-hidden="◄" data-value-shown="►" id="iframe-toggle" aria-hidden="true"
|
|
><iframe id="test-iframe"></iframe>
|
|
</div>
|
|
|
|
<div id="header">
|
|
<div id="info">
|
|
<div style="text-align:center">
|
|
<img src="resources/webgl-logo.png" alt="WebGL" id="logo"/>
|
|
<br/>
|
|
Conformance Test Runner
|
|
</div>
|
|
Version
|
|
<select id="testVersion">
|
|
</select>
|
|
<a href="../../conformance-suites/">(older versions?)</a>
|
|
<br/>
|
|
<input type="button" value="run tests" id="runTestsButton"/>
|
|
<label for="autoScrollCheckbox"><input type="checkbox" id="autoScrollCheckbox"/>auto scroll</label>
|
|
<label for="hidePassedCheckbox"><input type="checkbox" id="hidePassedCheckbox"/>hide passed</label>
|
|
<label for="quickTestModeCheckbox"><input type="checkbox" id="quickTestModeCheckbox"/>quick test mode</label>
|
|
<br/>
|
|
<input type="button" disabled value="show text summary" id="showTextSummary"/>
|
|
<input type="button" disabled value="download text" id="dlTextSummary"/>
|
|
<div id="nowebgl" class="nowebgl" style="display: none;">
|
|
This browser does not appear to support WebGL
|
|
</div>
|
|
<div id="noselectedwebgl" class="nowebgl" style="display: none;">
|
|
This browser does not appear to support the selected version of WebGL
|
|
</div>
|
|
<div id="loading">
|
|
Loading Tests...
|
|
</div>
|
|
<div id="fullresults">
|
|
</div>
|
|
</div>
|
|
<div id="error-wrap">
|
|
<pre id="error"></pre>
|
|
</div>
|
|
</div> <!-- end of header -->
|
|
|
|
</body>
|
|
</html>
|