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