--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/cors1.0/MANIFEST Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,4 @@
+access-control-basic-allow.html
+access-control-basic-allow-star.html
+access-control-basic-denied.html
+access-control-basic-allow-access-control-origin-header.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/cors1.0/access-control-basic-allow-access-control-origin-header.html Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,50 @@
+<html>
+<body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+<pre id='console'></pre>
+<div id=log></div>
+
+
+<script type="text/javascript">
+function log(message)
+{
+ document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
+}
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+var accessControlBasicAllowAccessControlOriginHeader = function() {
+ var xhr = new XMLHttpRequest;
+ var path = "/webappsec/tests/cors/submitted/cors1.0";
+
+ try {
+ xhr.open("GET", "http://www1.w3c-test.org" + path + "/resources/access-control-basic-allow-access-control-origin-header.php", false);
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'open'. [" + e.message + "].");
+ assert_true(false);
+ return;
+ }
+
+ try {
+ xhr.send();
+ assert_true(true);
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'send'. [" + e.message + "].");
+ assert_true(false);
+ return;
+ }
+
+ //log(xhr.responseText);
+};
+
+test(accessControlBasicAllowAccessControlOriginHeader, "access-control-basic-allow-access-control-origin-header")
+
+
+if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/cors1.0/access-control-basic-allow-star.html Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,52 @@
+<html>
+<body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+<pre id='console'></pre>
+<div id=log></div>
+
+
+<script type="text/javascript">
+function log(message)
+{
+ document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
+}
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+
+var accessControlBasicAllowStar = function() {
+ var xhr = new XMLHttpRequest;
+ var path = "/webappsec/tests/cors/submitted/cors1.0";
+
+ try {
+ xhr.open("GET", "http://www1.w3c-test.org" + path + "/resources/access-control-basic-allow-star.php", false);
+
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'open'. [" + e.message + "].");
+ return;
+ }
+
+ try {
+ xhr.send();
+ console.log(xhr.responseText);
+ assert_equals(xhr.responseText,"PASS: Cross-domain access allowed.", "test for cross domain" );
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'send'. [" + e.message + "].");
+ assert_true(false);
+ return;
+ }
+
+ //log(xhr.responseText);
+};
+
+test(accessControlBasicAllowStar, "access-control-basic-allow-star")
+
+
+if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/cors1.0/access-control-basic-allow.html Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,51 @@
+<html>
+<body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+<pre id='console'></pre>
+<div id=log></div>
+
+<script type="text/javascript">
+function log(message)
+{
+ document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
+}
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+var accessControlBasicAllow = function() {
+ var xhr = new XMLHttpRequest;
+ var path = "/webappsec/tests/cors/submitted/cors1.0";
+
+ try {
+ xhr.open("GET", "http://www1.w3c-test.org" + path + "/resources/access-control-basic-allow.php", false);
+
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'open'. [" + e.message + "].");
+ assert_true(false);
+ return;
+ }
+
+ try {
+ xhr.send();
+ console.log(xhr.responseText);
+ assert_equals(xhr.responseText,"PASS: Cross-domain access allowed.", "test for cross domain" );
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'send'. [" + e.message + "].");
+ assert_true(false);
+ return;
+ }
+
+ //log(xhr.responseText);
+};
+
+test(accessControlBasicAllow, "access-control-basic-allow")
+
+
+if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/cors1.0/access-control-basic-denied.html Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,50 @@
+<html>
+<body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+<pre id='console'></pre>
+<div id=log></div>
+
+
+<script type="text/javascript">
+function log(message)
+{
+ document.getElementById('console').appendChild(document.createTextNode(message + "\n"));
+}
+
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+
+var accessControlBasicDenied = function() {
+ var xhr = new XMLHttpRequest;
+ var path = "/webappsec/tests/cors/submitted/cors1.0";
+
+ try {
+ xhr.open("GET", "http://www1.w3c-test.org" + path + "/resources/access-control-basic-denied.php", false);
+ } catch(e) {
+ log("FAIL: Exception thrown. Cross-domain access is not allowed in 'open'. [" + e.message + "].");
+ assert_true(false);
+ return;
+ }
+
+ try {
+ xhr.send();
+ assert_true(false);
+ } catch(e) {
+ assert_true(true);
+ //log("PASS: Exception thrown. Cross-domain access was denied in 'send'. [" + e.message + "].");
+ return;
+ }
+
+ log(xhr.responseText);
+};
+
+test(accessControlBasicDenied, "access-control-basic-denied")
+
+if (window.layoutTestController)
+ layoutTestController.notifyDone();
+</script>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/webkit/resources/access-control-basic-allow-star.php Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,7 @@
+<?php
+
+header("Content-Type: text/plain");
+header("Access-Control-Allow-Origin: *");
+
+echo "PASS: Cross-domain access allowed.";
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/cors/submitted/webkit/resources/access-control-basic-allow.php Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,10 @@
+<?php
+
+header("Content-Type: text/plain");
+header("Access-Control-Allow-Credentials: true");
+header("Access-Control-Allow-Origin:" . $_SERVER['HTTP_ORIGIN']);
+
+echo "PASS: Cross-domain access allowed.";
+
+?>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/checkManifests.py Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,46 @@
+# Copyright (C) 2011-2012 Ms2ger
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os, sys
+import parseManifest
+
+def getDirsAndFiles(root):
+ files = ["MANIFEST"]
+ dirs, autotests, reftests, othertests, supportfiles = parseManifest.parseManifestFile(root + "/MANIFEST")
+ files.extend(autotests)
+ for r in reftests:
+ files.extend([r[1], r[2]])
+ files.extend(othertests)
+ files.extend(supportfiles)
+ return set(dirs), set(files)
+
+def checkDir(path):
+ for root, dirs, files in os.walk(path):
+ print "Checking " + root
+ mdirs, mfiles = getDirsAndFiles(root)
+ for real in dirs:
+ if not real in mdirs:
+ raise Exception(real + " not listed.")
+ for real in files:
+ if not real in mfiles:
+ raise Exception(real + " not listed.")
+
+if __name__ == "__main__":
+ checkDir(sys.argv[1])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/index.html Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html lang=en>
+<meta charset=UTF-8>
+<title>Web tests</title>
+<link rel=stylesheet href=runner.css>
+<script src=runner.js></script>
+<p><button value=/webappsec/tests/cors/submitted/cors1.0/>Run CORS 1.0 tests</button>
+<button value=/webappsec/tests/cors/submitted/opera/js/>Run CORS Opera tests</button>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/manifests.txt Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,10 @@
+This code relies on the existence of MANIFEST files to list the tests within
+a directory. These files consist of LF-separated lines, each of which falls
+in one of categories:
+
+* Directory: "dir foo"
+* Support files: "support foo.html"
+* Reftests: "foo.html == foo-ref.html == foo-ref2.html != foo-notref.html"
+* Automated tests (testharness.js): "foo.html"
+* Manual tests: "manual foo.html"
+* HTML parser data files: "parser foo.dat"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/parseManifest.py Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,64 @@
+# Copyright (C) 2011-2012 Ms2ger
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+def parseManifest(fd):
+ def parseReftestLine(chunks):
+ assert len(chunks) % 2 == 0
+ reftests = []
+ for i in range(2, len(chunks), 2):
+ if not chunks[i] in ["==", "!="]:
+ raise Exception("Misformatted reftest line " + line)
+ reftests.append([chunks[i], chunks[1], chunks[i + 1]])
+ return reftests
+
+ dirs = []
+ autotests = []
+ reftests = []
+ othertests = []
+ supportfiles = []
+ for fullline in fd:
+ line = fullline.strip()
+ if not line:
+ continue
+
+ chunks = line.split(" ")
+
+ if chunks[0] == "MANIFEST":
+ raise Exception("MANIFEST listed on line " + line)
+
+ if chunks[0] == "dir" or (chunks[0] == "support" and chunks[1] == "dir"):
+ dirs.append(chunks[1]);
+ elif chunks[0] == "ref":
+ if len(chunks) % 2:
+ raise Exception("Missing chunk in line " + line)
+ reftests.extend(parseReftestLine(chunks))
+ elif chunks[0] == "support":
+ supportfiles.append(chunks[1])
+ elif chunks[0] in ["manual", "parser"]:
+ othertests.append(chunks[1])
+ else: # automated
+ autotests.append(chunks[0])
+ return dirs, autotests, reftests, othertests, supportfiles
+
+def parseManifestFile(path):
+ fp = open(path)
+ dirs, autotests, reftests, othertests, supportfiles = parseManifest(fp)
+ fp.close()
+ return dirs, autotests, reftests, othertests, supportfiles
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/reftest.html Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,91 @@
+<!doctype html>
+<title>Reftest harness</title>
+<style>
+iframe { width: 95%; height: 20em; }
+#test { border-color: blue; }
+#ref { border-color: green; }
+</style>
+<h1>Reftests</h1>
+<script>
+"use strict";
+function report(aResult, aMessage) {
+ pass &= aResult
+ var res = { status: +!aResult,
+ nodes: aResult ? [] : [document.createTextNode(aMessage)] }
+ results.push(res)
+ parent.result_callback(res)
+}
+function nextTest() {
+ if (!tests.length) {
+ parent.completion_callback(results, { status: +!pass })
+ return;
+ }
+ var test = tests.shift()
+ msgs.textContent = "These pages should " +
+ (test[0] === "==" ? "match" : "not match") +
+ "."
+ iframetest.src = path + test[1]
+ iframeref.src = path + test[2]
+}
+var pass = true
+var results = []
+var t = JSON.parse(decodeURIComponent(location.search.substring(1))), path = t[0], tests = t[1]
+var msgs = document.body.appendChild(document.createElement("p"))
+var p = document.body.appendChild(document.createElement("p"));
+p.textContent = "Look at the "
+var tButton = document.createElement("button")
+tButton.textContent = "Test"
+tButton.disabled = true
+tButton.onclick = function() {
+ tButton.disabled = true
+ rButton.disabled = false
+ iframetest.style.display = "inline"
+ iframeref.style.display = "none"
+}
+p.appendChild(tButton);
+p.appendChild(document.createTextNode(" "));
+var rButton = document.createElement("button")
+rButton.textContent = "Reference"
+rButton.onclick = function() {
+ rButton.disabled = true
+ tButton.disabled = false
+ iframetest.style.display = "none"
+ iframeref.style.display = "inline"
+}
+p.appendChild(rButton);
+
+var iframetest = document.body.appendChild(document.createElement("p"))
+ .appendChild(document.createElement("iframe"))
+iframetest.id = "test"
+iframetest.style.display = "inline"
+var iframeref = document.body.lastChild
+ .appendChild(document.createElement("iframe"))
+iframeref.id = "ref"
+iframeref.style.display = "none"
+
+p = document.body.appendChild(document.createElement("p"));
+p.textContent = "This test has: "
+var button = document.createElement("button")
+button.textContent = "Passed"
+button.onclick = function() {
+ report(true, "Tester clicked \"Pass\"");
+ nextTest()
+}
+p.appendChild(button);
+p.appendChild(document.createTextNode(" "));
+button = document.createElement("button")
+button.textContent = "Failed"
+button.onclick = function() {
+ report(false, "Tester clicked \"Fail\"");
+ nextTest()
+}
+p.appendChild(button);
+p.appendChild(document.createTextNode(" "));
+button = document.createElement("button")
+button.textContent = "Skip"
+button.onclick = function() {
+ nextTest()
+}
+p.appendChild(button);
+nextTest()
+</script>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/runner.css Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,81 @@
+@charset "UTF-8";
+html { margin: 0 8px; }
+body { margin: 0; }
+html.done { border: 2px solid limegreen; margin: 3px; padding: 3px; }
+
+html:not(.done) { height: 100%; }
+html:not(.done) body { height: 100%; }
+
+header { display: block; font-weight: bold; }
+html.done header { font-size: 1.5em; margin: 0 0 .66em; }
+html.done header p { height: 5em; margin: 0; }
+
+html:not(.done) header { border: thin solid; height: 1.5em;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box; }
+html:not(.done) header p { height: 100%; width: 15em; margin: 0; float: right; }
+
+header meter { display: block; height: 100%; width: 100%; }
+header dl, header dt, header dd { margin: 0; padding: 0; }
+header dt, header dd { display: inline; }
+header dt:after { content: ": "; }
+html.done header dd:after { content: "\a"; white-space: pre-line; }
+html:not(.done) header dd:after { content: "; "; }
+html:not(.done) header dd:last-child:after { content: "."; }
+html:not(.done) header dl { line-height: 1.5; }
+
+html:not(.done) #wrapper { height: 100%; margin-top: -1.5em; padding-top: 1.5em;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box; }
+
+html:not(.done) #results { width: 15em; height: 100%; float:left;
+ overflow-x: hidden; overflow-y: scroll; }
+
+section { display: block; border: thin solid black; padding: 0.5em 0; }
+section h1 { margin: 0; font-size: 1em; }
+html.done section h1 { text-align: center; }
+section ol { padding: 0; margin: 0; list-style-position: inside; }
+html.done section ol { -moz-column-count: 3; -webkit-column-count: 3; column-count: 3; }
+section li { padding: 0.1em 0.5em; }
+section li.pass:nth-child(odd) { background: #E5FFE5; }
+section li.pass:nth-child(even) { background: #DEF8DE; }
+section li.fail:nth-child(odd) { background: #FFE5E5; }
+section li.fail:nth-child(even) { background: #F8DEDE; }
+section p { margin: 0; }
+html:not(.done) section { border-top: none; }
+html.done section + section { border-top: none; }
+
+html:not(.done) #iframewrapper { margin: 0 0 0 15em; padding: 2px 2px 3px; height: 100%;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box; }
+html:not(.done) iframe { width: 100%; height: 100%; border-width: 2px; margin: -2px; }
+
+html:not(.done) body.manual #iframewrapper { height: 90%; }
+html:not(.done) body.manual #manualUI { display: block; margin: 0 0 0 15em;
+ height: 10%; }
+#manualUI { display: none; }
+
+body > p { text-align: center; }
+body > p > textarea { width: 90%; height: 20em; }
+
+meter::-webkit-meter-horizontal-bar {
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%,
+ from(#F77),
+ color-stop(0.2, #FCC),
+ color-stop(0.45, #D44),
+ color-stop(0.55, #D44),
+ to(#F77));
+}
+meter::-webkit-meter-horizontal-optimum-value,
+meter::-webkit-meter-horizontal-suboptimal-value,
+meter::-webkit-meter-horizontal-even-less-good-value {
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%,
+ from(#AD7),
+ color-stop(0.2, #CEA),
+ color-stop(0.45, #7A3),
+ color-stop(0.55, #7A3),
+ to(#AD7));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/testRunner/runner.js Thu May 03 15:19:42 2012 -0700
@@ -0,0 +1,530 @@
+"use strict";
+var runner;
+
+function Runner(aPath) {
+ this.mStartTime = (new Date()).getTime();
+ this.mPath = aPath;
+ this.mTimeouts = 0;
+ this.mToBeProcessed = 1;
+ this.mPasses = 0;
+ this.mFails = 0;
+ this.mIframe = document.createElement("iframe");
+ this.mMeter = null;
+ this.mScoreNode = null
+ this.mPassNode = null
+ this.mFailNode = null
+ this.mWrapper = null;
+ this.mSectionWrapper = null;
+ this.mSection = null;
+ this.mOl = null;
+ this.mTests = [];
+ this.mTestCount = -1;
+ this.mSkipManual = false;
+};
+Runner.prototype = {
+ "sTimeout": 10000, //ms
+
+ "sOrigTitle": document.title,
+
+ "sSupportsMeter": "value" in document.createElement("meter"),
+
+ "currentTest": function Runner_currentTest() {
+ return this.mTests[this.mTestCount];
+ },
+
+ "start": function Runner_start() {
+ var options = parseOptions();
+ this.mSkipManual = "skipmanual" in options && options["skipmanual"] === "1";
+
+ document.title = this.sOrigTitle;
+ document.documentElement.className = "";
+
+ clearBody();
+
+ var header = document.body.appendChild(document.createElement("header"));
+ this.mMeter = header.appendChild(document.createElement("p"))
+ .appendChild(document.createElement("meter"));
+
+ if (!this.sSupportsMeter) {
+ this.mMeter.parentNode.style.background = "red";
+ this.mMeter.style.background = "limegreen";
+ this.mMeter.style.width = "67%";
+ }
+
+ var dl = header.appendChild(document.createElement("dl"));
+ dl.appendChild(document.createElement("dt"))
+ .appendChild(document.createTextNode("Score"));
+ this.mScoreNode = dl.appendChild(document.createElement("dd"))
+ .appendChild(document.createTextNode("0%"));
+ dl.appendChild(document.createElement("dt"))
+ .appendChild(document.createTextNode("Pass"));
+ this.mPassNode = dl.appendChild(document.createElement("dd"))
+ .appendChild(document.createTextNode("0"));
+ dl.appendChild(document.createElement("dt"))
+ .appendChild(document.createTextNode("Fail"));
+ this.mFailNode = dl.appendChild(document.createElement("dd"))
+ .appendChild(document.createTextNode("0"));
+
+ this.mWrapper =
+ document.body.appendChild(document.createElement("div"));
+ this.mWrapper.id = "wrapper";
+
+ this.mSectionWrapper =
+ this.mWrapper.appendChild(document.createElement("div"));
+ this.mSectionWrapper.id = "results";
+
+ var p = this.mWrapper.appendChild(document.createElement("p"));
+ p.id = "iframewrapper";
+ p.appendChild(this.mIframe);
+
+ if (!this.mSkipManual) {
+ p = this.mWrapper.appendChild(document.createElement("p"));
+ p.id = "manualUI";
+ p.textContent = "This test has: "
+
+ var button = document.createElement("button")
+ button.textContent = "Passed"
+ button.onclick = function() {
+ report(true, "Tester clicked \"Pass\"");
+ runner.currentTest().passes = 1;
+ runner.finishTest();
+ }
+ p.appendChild(button);
+ p.appendChild(document.createTextNode(" "));
+ button = document.createElement("button")
+ button.textContent = "Failed"
+ button.onclick = function() {
+ report(false, "Tester clicked \"Fail\"");
+ runner.currentTest().fails = 1;
+ runner.finishTest();
+ }
+ p.appendChild(button);
+ p.appendChild(document.createTextNode(" "));
+ button = document.createElement("button")
+ button.textContent = "Skip"
+ button.onclick = function() {
+ runner.finishTest();
+ }
+ p.appendChild(button);
+ }
+
+ var xhr = new XMLHttpRequest(), self = this;
+ xhr.onreadystatechange = function onrsc() {
+ if (this.readyState !== 4 || !(this.status === 200 || this.status === 0))
+ return;
+ self.process(this.responseText, "");
+ };
+ xhr.open("GET", this.mPath + "MANIFEST");
+ xhr.send(null);//Fx 3
+ },
+
+ "process": function Runner_process(aManifest, aPath) {
+ --this.mToBeProcessed;
+ var dirs = this.parseManifest(aManifest.split("\n"), aPath);
+ for (var k = 0, kl = dirs.length; k < kl; ++k) {
+ var dir = dirs[k] + "/";
+ ++this.mToBeProcessed;
+ var xhr = new XMLHttpRequest(), self = this;
+ xhr.dataDir = dir;
+ xhr.onreadystatechange = function() {
+ if (this.readyState !== 4 || !(this.status === 200 || this.status === 0))
+ return;
+
+ self.process(this.responseText, this.dataDir);
+ };
+ xhr.open("GET", this.mPath + dir + "MANIFEST");
+ xhr.send(null);//Fx 3
+ }
+
+ if (!this.mToBeProcessed) {
+ this.runNextTest()
+ }
+ },
+
+ "parseManifest": function Runner_parseManifest(aLines, aPath) {
+ var dirs = [];
+ for (var i = 0, il = aLines.length; i < il; ++i) {
+ if (!aLines[i]) {
+ continue;
+ }
+
+ var chunks = aLines[i].split(" ");
+
+ switch (chunks[0]) {
+ case "support":
+ case "list":
+ break;
+
+ case "dir":
+ if (chunks[1]) {
+ dirs.push(aPath + chunks[1]);
+ }
+ break;
+
+ case "manual":
+ if (chunks[1]) {
+ this.mTests.push({ url: aPath + chunks[1], passes: 0, fails: 0, type: "manual" });
+ }
+ break;
+
+ case "ref":
+ if (chunks.length % 2) {
+ break;
+ }
+ var reftests = [];
+ for (var j = 2, jl = chunks.length; j < jl; j += 2) {
+ reftests.push([chunks[j], aPath + chunks[1], aPath + chunks[j + 1]]);
+ }
+ this.mTests.push({ type: "reftest", url: aPath + chunks[1], passes: 0, fails: 0, tests: reftests })
+ break;
+
+ default:
+ if (chunks.length > 1) {
+ break;
+ }
+ this.mTests.push({ url: aPath + chunks[0], passes: 0, fails: 0, type: "automated" });
+ }
+ }
+ return dirs;
+ },
+
+ /* ***** Running the test suite ***** */
+ "_report": function Runner__report(aPass, aMessageNodes) {
+ var li = document.createElement("li");
+ li.className = aPass ? "pass" : "fail";
+ li.appendChild(document.createTextNode(aPass ? "Pass" : "Fail: "));
+ for (var i = 0, il = aMessageNodes.length; i < il; ++i) {
+ li.appendChild(aMessageNodes[i]);
+ }
+ this.mOl.appendChild(li);
+ },
+
+ "fail": function Runner_fail(aMsg) {
+ ++this.mFails;
+ this._report(false, [document.createTextNode(aMsg)]);
+ },
+
+ "timedOut": function Runner_timedOut() {
+ this.fail("Timed out.");
+ ++this.mTimeouts;
+ clearTimeout(this.currentTest().timeout);
+ this.runNextTest();
+ },
+
+ "updateResults": function Runner_updateResults() {
+ if (!this.mPasses && !this.mFails)
+ return;
+ var score = this.mPasses / (this.mPasses + this.mFails);
+ var scorestr = (100 * score).toFixed(2) + "%";
+ if (this.sSupportsMeter)
+ this.mMeter.value = score;
+ else
+ this.mMeter.style.width = scorestr;
+ this.mScoreNode.data = scorestr;
+ this.mPassNode.data = this.mPasses;
+ this.mFailNode.data = this.mFails;
+
+ var metadata = this.mIframe && this.mIframe.contentWindow &&
+ this.mIframe.contentWindow.Test && this.mIframe.contentWindow.Test.meta;
+ if (!metadata)
+ return;
+
+ var p = this.mSection.appendChild(document.createElement("p"));
+
+ this.appendList("Created by", metadata.authors, p);
+ this.appendList("Reviewed by", metadata.reviewers, p);
+ this.appendList("Help:", metadata.helps, p);
+
+ if (metadata.assert) {
+ p.appendChild(document.createTextNode("Asserting that " + metadata.assert +
+ "."));
+ }
+ },
+
+ "createLink": function Runner_createLink(aLink) {
+ var a = document.createElement("a");
+ a.href = aLink.href;
+ a.appendChild(document.createTextNode(aLink.text));
+ return a;
+ },
+
+ "appendList": function Runner_appendList(aLabel, aList, aEl) {
+ if (!aList.length)
+ return;
+
+ aEl.appendChild(document.createTextNode(aLabel + " "));
+ for (var i = 0, il = aList.length; i < il; ++i) {
+ if (i)
+ aEl.appendChild(document.createTextNode(", "));
+ aEl.appendChild(this.createLink(aList[i]));
+ }
+ aEl.appendChild(document.createTextNode(". "));
+ },
+
+ "addTitle": function Runner_addTitle() {
+ this.mSection = document.createElement("section");
+ this.mSectionWrapper.appendChild(this.mSection);
+
+ var a = document.createElement("a");
+ a.appendChild(document.createTextNode(this.currentTest().url));
+ a.href = this.mPath + this.currentTest().url;
+
+ var h1 = document.createElement("h1");
+ h1.appendChild(a);
+ this.mSection.appendChild(h1);
+
+ this.mOl = this.mSection.appendChild(document.createElement("ol"));
+ },
+
+ "hideManualUI": function() {
+ document.body.className = ""
+ },
+
+ "showManualUI": function() {
+ document.body.className = "manual"
+ },
+
+ "runNextTest": function Runner_runNextTest() {
+ ++this.mTestCount;
+ if (!this.currentTest()) {
+ this.finish();
+ return;
+ }
+
+ this.addTitle();
+
+ switch (this.currentTest().type) {
+ case "automated":
+ if (!this.mSkipManual) {
+ this.hideManualUI()
+ }
+ this.currentTest().timeout =
+ setTimeout(function() { runner.timedOut() }, this.sTimeout);
+ this.mIframe.src = this.mPath + this.currentTest().url;
+ break;
+
+ case "reftest":
+ if (!this.mSkipManual) {
+ this.hideManualUI()
+ }
+ this.mIframe.src = "reftest.html?" +
+ JSON.stringify([this.mPath, this.currentTest().tests]);
+ break;
+
+ case "manual":
+ if (!this.mSkipManual) {
+ this.showManualUI()
+ this.mIframe.src = this.mPath + this.currentTest().url;
+ } else {
+ this.finishTest();
+ }
+ break;
+
+ default:
+ throw "Unrecognized test type";
+ }
+ },
+
+ "finishTest": function Report_finishTest() {
+ this.mPasses += this.currentTest().passes;
+ this.mFails += this.currentTest().fails;
+ this.updateResults();
+ clearTimeout(this.currentTest().timeout);
+ this.runNextTest();
+ },
+
+ /* ***** Finishing up ***** */
+ "getXMLReport": function Runner_getXMLReport() {
+ var container = document.createElement("div");
+ var tests = container
+ .appendChild(document.createElementNS(null, "testresults"))
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "browser"))
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "ua"))
+ .appendChild(document.createTextNode(navigator.userAgent))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "browsername"))
+ .appendChild(document.createTextNode("REPLACE WITH BROWSERNAME BEFORE PUSHING TO HG"))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "dateran"))
+ .appendChild(document.createTextNode(Date()))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n "))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "tests"));
+
+ for (var i = 0, il = this.mTests.length; i < il; ++i) {
+ if (this.mTests[i].passes || this.mTests[i].fails) {
+ tests.appendChild(document.createTextNode("\n "));
+ tests
+ .appendChild(document.createElementNS(null, "test"))
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "uri"))
+ .appendChild(document.createTextNode(this.mTests[i].url))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n "))
+ .parentNode
+ .appendChild(document.createElementNS(null, "result"))
+ .appendChild(document.createTextNode(
+ !this.mTests[i].fails ? "Pass" : "Fail"))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n "));
+ }
+ }
+ container
+ .firstChild
+ .lastChild
+ .appendChild(document.createTextNode("\n "))
+ .parentNode.parentNode
+ .appendChild(document.createTextNode("\n"));
+ return container.innerHTML;
+ },
+
+ "finish": function Runner_finish() {
+ this.mWrapper.removeChild(this.mIframe.parentNode);
+ this.updateResults();
+ var time = (((new Date()).getTime() - this.mStartTime) / 1000).toFixed(0);
+ document.body.appendChild(document.createElement("p"))
+ .appendChild(document.createTextNode("Application ran for "
+ + time + " seconds."));
+ document.body.appendChild(document.createElement("p"))
+ .appendChild(document.createTextNode(this.mTimeouts + " timeouts."));
+ var button = document.body.appendChild(document.createElement("p"))
+ .appendChild(document.createElement("button"));
+ button.appendChild(document.createTextNode("Run again"));
+ button.value = this.mPath;
+ button.onclick = startRunning;
+ this.mMeter.onclick = function(e) {
+ if (e.altKey) {
+ document.open();
+ document.write("<pre>");
+ document.writeln(" <dt>" + navigator.userAgent);
+ document.writeln(" <dd>Pass " + this.mPasses);
+ document.writeln(" <dd>Fail " + this.mFails);
+ document.writeln(" <dd>Score "
+ + (100 * this.mPasses / (this.mPasses + this.mFails)).toFixed(2) + "%");
+ document.write("</pre>");
+ document.close();
+ }
+ };
+ document.body.appendChild(document.createElement("p"))
+ .appendChild(document.createElement("textarea"))
+ .appendChild(document.createTextNode(this.getXMLReport()));
+ document.title = "Done \u2013 " + document.title;
+ document.documentElement.className = "done";
+ }
+};
+
+
+/* ***** Preparation ***** */
+function parseOptions() {
+ var optionstrings = location.search.substring(1).split("&");
+ var options = {};
+ for (var i = 0, il = optionstrings.length; i < il; ++i) {
+ var opt = optionstrings[i];
+ options[opt.substring(0, opt.indexOf("="))] =
+ opt.substring(opt.indexOf("=") + 1);
+ }
+ return options;
+}
+
+function setup() {
+ var options = parseOptions();
+ if (options["autorun"] === "1") {
+ runner = new Runner(options["path"] || "../html5/");
+ runner.start();
+ return;
+ }
+
+ if (options["path"]) {
+ clearBody();
+ var button = document.body.appendChild(document.createElement("p"))
+ .appendChild(document.createElement("button"));
+ button.appendChild(document.createTextNode("Run tests"));
+ button.value = options["path"];
+ button.onclick = startRunning;
+ return;
+ }
+
+ var buttons = document.getElementsByTagName("button");
+ for (var i = 0, il = buttons.length; i < il; ++i) {
+ buttons[i].onclick = startRunning;
+ }
+}
+
+function startRunning() {
+ runner = new Runner(this.value);
+ runner.start();
+}
+
+
+function report(aPass, aMessage) {
+ var nodes = [];
+ if (!aPass)
+ nodes.push(document.createTextNode(aMessage));
+ runner._report(aPass, nodes);
+}
+
+function result_callback(aTest) {
+ if (runner.currentTest().type === "manual" && aTest.status === aTest.TIMEOUT) {
+ return;
+ }
+ var nodes = [];
+ if (aTest.message) {
+ if (typeof aTest.message === "string") {
+ nodes = [document.createTextNode(aTest.message)];
+ } else {
+ var rendered = runner.mIframe.contentWindow.template.render(aTest.message);
+ if (rendered.length) {
+ nodes = nodes.concat(rendered);
+ } else {
+ nodes.push(rendered);
+ }
+ }
+ } else if (aTest.nodes) {
+ nodes = aTest.nodes;
+ }
+ runner._report(!aTest.status, nodes);
+ !aTest.status ? runner.currentTest().passes++ : runner.currentTest().fails++;
+}
+
+function separate() {
+}
+
+
+function finishTest() {
+ runner.currentTest().passes = runner.mIframe.contentWindow.Test.results.passes;
+ runner.currentTest().fails = runner.mIframe.contentWindow.Test.results.fails;
+ runner.finishTest();
+}
+
+function completion_callback(aTests, aStatus) {
+ if (runner.currentTest().type === "manual") {
+ for (var i = 0, il = aTests.length; i < il; ++i) {
+ var test = aTests[i];
+ if (test.status == test.TIMEOUT) {
+ return;
+ }
+ }
+ }
+ runner.finishTest();
+}
+
+function clearBody() {
+ var i = document.body.childNodes.length;
+ while (i--) {
+ document.body.removeChild(document.body.childNodes[i]);
+ }
+}
+
+window.onload = setup;