Source code

Revision control

Copy as Markdown

Other Tools

<!--
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>