test_page_errors.html (6733B)
1 <!DOCTYPE HTML> 2 <html lang="en"> 3 <head> 4 <meta charset="utf8"> 5 <title>Test for page errors</title> 6 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 7 <script type="text/javascript" src="common.js"></script> 8 <!-- Any copyright is dedicated to the Public Domain. 9 - http://creativecommons.org/publicdomain/zero/1.0/ --> 10 </head> 11 <body> 12 <p>Test for page errors</p> 13 14 <script class="testbody" type="text/javascript"> 15 "use strict"; 16 17 const { MESSAGE_CATEGORY } = require("devtools/shared/constants"); 18 SimpleTest.waitForExplicitFinish(); 19 20 const previousEnabled = window.docShell.cssErrorReportingEnabled; 21 window.docShell.cssErrorReportingEnabled = true; 22 23 SimpleTest.registerCleanupFunction(() => { 24 window.docShell.cssErrorReportingEnabled = previousEnabled; 25 }); 26 27 let expectedPageErrors = []; 28 29 const NO_UNCAUGHT_EXCEPTION = Symbol(); 30 31 function doPageErrors() { 32 expectedPageErrors = { 33 "document.body.style.color = 'fooColor';": { 34 errorMessage: /fooColor/, 35 sourceName: /test_page_errors/, 36 category: MESSAGE_CATEGORY.CSS_PARSER, 37 timeStamp: FRACTIONAL_NUMBER_REGEX, 38 error: false, 39 warning: true, 40 }, 41 "document.doTheImpossible();": { 42 errorMessage: /doTheImpossible/, 43 errorMessageName: undefined, 44 sourceName: /test_page_errors/, 45 category: "chrome javascript", 46 timeStamp: FRACTIONAL_NUMBER_REGEX, 47 error: true, 48 warning: false, 49 }, 50 "(42).toString(0);": { 51 errorMessage: /radix/, 52 errorMessageName: "JSMSG_BAD_RADIX", 53 sourceName: /test_page_errors/, 54 category: "chrome javascript", 55 timeStamp: FRACTIONAL_NUMBER_REGEX, 56 error: true, 57 warning: false, 58 }, 59 "'use strict'; (Object.freeze({name: 'Elsa', score: 157})).score = 0;": { 60 errorMessage: /read.only/, 61 errorMessageName: "JSMSG_READ_ONLY", 62 sourceName: /test_page_errors/, 63 category: "chrome javascript", 64 timeStamp: FRACTIONAL_NUMBER_REGEX, 65 error: true, 66 warning: false, 67 }, 68 "([]).length = -1": { 69 errorMessage: /array length/, 70 errorMessageName: "JSMSG_BAD_ARRAY_LENGTH", 71 sourceName: /test_page_errors/, 72 category: "chrome javascript", 73 timeStamp: FRACTIONAL_NUMBER_REGEX, 74 error: true, 75 warning: false, 76 }, 77 "'abc'.repeat(-1);": { 78 errorMessage: /repeat count.*non-negative/, 79 errorMessageName: "JSMSG_NEGATIVE_REPETITION_COUNT", 80 sourceName: /test_page_errors/, 81 category: "chrome javascript", 82 timeStamp: FRACTIONAL_NUMBER_REGEX, 83 error: true, 84 warning: false, 85 }, 86 "'a'.repeat(2e28);": { 87 errorMessage: /repeat count.*less than infinity/, 88 errorMessageName: "JSMSG_RESULTING_STRING_TOO_LARGE", 89 sourceName: /test_page_errors/, 90 category: "chrome javascript", 91 timeStamp: FRACTIONAL_NUMBER_REGEX, 92 error: true, 93 warning: false, 94 }, 95 "77.1234.toExponential(-1);": { 96 errorMessage: /out of range/, 97 errorMessageName: "JSMSG_PRECISION_RANGE", 98 sourceName: /test_page_errors/, 99 category: "chrome javascript", 100 timeStamp: FRACTIONAL_NUMBER_REGEX, 101 error: true, 102 warning: false, 103 }, 104 "function a() { return; 1 + 1; }": { 105 errorMessage: /unreachable code/, 106 errorMessageName: "JSMSG_STMT_AFTER_RETURN", 107 sourceName: /test_page_errors/, 108 category: "chrome javascript", 109 timeStamp: FRACTIONAL_NUMBER_REGEX, 110 error: false, 111 warning: true, 112 }, 113 "let a, a;": { 114 errorMessage: /redeclaration of/, 115 errorMessageName: "JSMSG_REDECLARED_VAR", 116 sourceName: /test_page_errors/, 117 category: "chrome javascript", 118 timeStamp: FRACTIONAL_NUMBER_REGEX, 119 error: true, 120 warning: false, 121 notes: [ 122 { 123 messageBody: /Previously declared at line/, 124 frame: { 125 source: /test_page_errors/, 126 } 127 } 128 ] 129 }, 130 [`let error = new TypeError("abc"); 131 error.name = "MyError"; 132 error.message = "here"; 133 throw error`]: { 134 errorMessage: /MyError: here/, 135 errorMessageName: "", 136 sourceName: /test_page_errors/, 137 category: "chrome javascript", 138 timeStamp: FRACTIONAL_NUMBER_REGEX, 139 error: true, 140 warning: false, 141 }, 142 "DOMTokenList.prototype.contains.call([])": { 143 errorMessage: /does not implement interface/, 144 errorMessageName: "MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE", 145 sourceName: /test_page_errors/, 146 category: "chrome javascript", 147 timeStamp: FRACTIONAL_NUMBER_REGEX, 148 error: true, 149 warning: false, 150 }, 151 [`let error2 = new TypeError("abc"); 152 error2.name = "MyPromiseError"; 153 error2.message = "here2"; 154 Promise.reject(error2)`]: { 155 errorMessage: /MyPromiseError: here2/, 156 errorMessageName: "", 157 sourceName: /test_page_errors/, 158 category: "chrome javascript", 159 timeStamp: FRACTIONAL_NUMBER_REGEX, 160 error: true, 161 warning: false, 162 // Promise.reject doesn't produce an uncaught exception 163 // even though |exception: true|. 164 [NO_UNCAUGHT_EXCEPTION]: true 165 } 166 }; 167 168 let container = document.createElement("script"); 169 for (const stmt of Object.keys(expectedPageErrors)) { 170 if (expectedPageErrors[stmt].error && 171 !expectedPageErrors[stmt][NO_UNCAUGHT_EXCEPTION]) { 172 SimpleTest.expectUncaughtException(); 173 } 174 info("starting stmt: " + stmt); 175 container = document.createElement("script"); 176 document.body.appendChild(container); 177 container.textContent = stmt; 178 document.body.removeChild(container); 179 info("ending stmt: " + stmt); 180 } 181 } 182 183 async function startTest() { 184 removeEventListener("load", startTest); 185 186 const {state} = await attachConsole(["PageError"]); 187 onAttach(state); 188 } 189 190 function onAttach(state) { 191 onPageError = onPageError.bind(null, state); 192 state.webConsoleFront.on("pageError", onPageError); 193 doPageErrors(); 194 } 195 196 const pageErrors = []; 197 198 function onPageError(state, packet) { 199 if (!packet.pageError.sourceName.includes("test_page_errors")) { 200 info("Ignoring error from unknown source: " + packet.pageError.sourceName); 201 return; 202 } 203 204 pageErrors.push(packet.pageError); 205 if (pageErrors.length != Object.keys(expectedPageErrors).length) { 206 return; 207 } 208 209 state.webConsoleFront.off("pageError", onPageError); 210 211 Object.values(expectedPageErrors).forEach(function(message, index) { 212 info("checking received page error #" + index); 213 checkObject(pageErrors[index], Object.values(expectedPageErrors)[index]); 214 }); 215 216 closeDebugger(state, function() { 217 SimpleTest.finish(); 218 }); 219 } 220 221 addEventListener("load", startTest); 222 </script> 223 </body> 224 </html>