parser_web_testrunner.js (4575B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /** 7 * Runs html5lib-formatted test cases in the browser. Requires SimpleTest. 8 * 9 * Define an array named parserDatFiles before loading this script, 10 * and it will load each of those dat files into an array, then run 11 * the test parser on each and run the tests by assigning the input 12 * data to an iframe's url. 13 * 14 * Your test document should have an element with id "display" and 15 * an iframe with id "testframe". 16 */ 17 18 /* import-globals-from ./parser_datreader.js */ 19 /* import-globals-from ./html5_tree_construction_exceptions.js */ 20 /* globals parserDatFiles */ 21 22 var functionsToRunAsync = []; 23 24 window.addEventListener( 25 "message", 26 function (event) { 27 if (event.source == window && event.data == "async-run") { 28 event.stopPropagation(); 29 var fn = functionsToRunAsync.shift(); 30 fn(); 31 } 32 }, 33 true 34 ); 35 36 function asyncRun(fn) { 37 functionsToRunAsync.push(fn); 38 window.postMessage("async-run", "*"); 39 } 40 41 function writeErrorSummary(input, expected, got, isTodo) { 42 if (isTodo) { 43 $("display").appendChild(createEl("h2", null, "Unexpected Success:")); 44 } else { 45 $("display").appendChild(createEl("h2", null, "Unexpected Failure:")); 46 } 47 $("display").appendChild(createEl("br")); 48 $("display").appendChild(createEl("span", null, "Matched: ")); 49 $("display").appendChild(document.createTextNode("" + (expected == got))); 50 var pre = createEl("pre"); 51 pre.appendChild(document.createTextNode("Input: \n" + input, "\n-\n")); 52 pre.appendChild(document.createTextNode("Expected:\n" + expected, "\n-\n")); 53 pre.appendChild(document.createTextNode("Output:\n" + got + "\n-\n")); 54 $("display").appendChild(pre); 55 $("display").appendChild(createEl("hr")); 56 } 57 58 /** 59 * Control will bounce back and forth between nextTest() and the 60 * event handler returned by makeTestChecker() or the callback returned by 61 * makeFragmentTestChecker() until the 'testcases' iterator is spent. 62 */ 63 function makeTestChecker(input, expected) { 64 return function (e) { 65 var domAsString = docToTestOutput(e.target.contentDocument); 66 if (html5Exceptions[input]) { 67 todo_is(domAsString, expected, "HTML5 expected success."); 68 if (domAsString == expected) { 69 writeErrorSummary(input, expected, domAsString, true); 70 } 71 } else { 72 is(domAsString, expected, "HTML5 expected success."); 73 if (domAsString != expected) { 74 writeErrorSummary(input, expected, domAsString, false); 75 } 76 } 77 nextTest(e.target); 78 }; 79 } 80 81 function makeFragmentTestChecker(input, expected, errors, fragment, testframe) { 82 return function () { 83 var context; 84 if (fragment.startsWith("svg ")) { 85 context = document.createElementNS( 86 "http://www.w3.org/2000/svg", 87 fragment.substring(4) 88 ); 89 } else if (fragment.startsWith("math ")) { 90 context = document.createElementNS( 91 "http://www.w3.org/1998/Math/MathML", 92 fragment.substring(5) 93 ); 94 } else { 95 context = document.createElementNS( 96 "http://www.w3.org/1999/xhtml", 97 fragment 98 ); 99 } 100 context.innerHTML = input; 101 var domAsString = fragmentToTestOutput(context); 102 is(domAsString, expected, "HTML5 expected success. " + new Date()); 103 if (domAsString != expected) { 104 writeErrorSummary(input, expected, domAsString, false); 105 } 106 nextTest(testframe); 107 }; 108 } 109 110 var testcases; 111 function nextTest(testframe) { 112 var { done, value } = testcases.next(); 113 if (done) { 114 SimpleTest.finish(); 115 return; 116 } 117 var [input, output, errors, fragment] = value; 118 if (fragment) { 119 asyncRun( 120 makeFragmentTestChecker(input, output, errors, fragment, testframe) 121 ); 122 } else { 123 testframe.onload = makeTestChecker(input, output, errors); 124 testframe.srcdoc = input; 125 } 126 } 127 128 var testFileContents = []; 129 function loadNextTestFile() { 130 var datFile = parserDatFiles.shift(); 131 if (datFile) { 132 var xhr = new XMLHttpRequest(); 133 xhr.onreadystatechange = function () { 134 if (this.readyState == 4) { 135 testFileContents.push(this.responseText); 136 loadNextTestFile(); 137 } 138 }; 139 xhr.open("GET", "html5lib_tree_construction/" + datFile); 140 xhr.send(); 141 } else { 142 testcases = test_parser(testFileContents); 143 nextTest($("testframe")); 144 } 145 } 146 147 addLoadEvent(loadNextTestFile); 148 SimpleTest.waitForExplicitFinish();