| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <script src="../../http/tests/inspector/resources/inspector-test.js"></script> | |
| <script> | |
| function typeError() { | |
| let object = {}; | |
| try { | |
| object.propertyDoesnt.exist; | |
| } catch (e) { | |
| console.trace(); | |
| return e.stack; | |
| } | |
| } | |
| function triggerTypeError() { | |
| return typeError(); | |
| } | |
| function triggerTypeErrorWithNativeCallInBetween() { | |
| return [42].map(typeError)[0]; | |
| } | |
| let _anonymousFunctionError = null; | |
| (function() { | |
| let object = {}; | |
| try { | |
| object.methodDoesntExist(); | |
| } catch (e) { | |
| _anonymousFunctionError = e.stack; | |
| } | |
| })(); | |
| function getAnonymousFunctionError() { | |
| return _anonymousFunctionError; | |
| } | |
| function* generator1() { | |
| yield* generator2(); | |
| } | |
| function* generator2() { | |
| yield typeError(); | |
| } | |
| function triggerGeneratorError() { | |
| return generator1().next().value; | |
| } | |
| function test() | |
| { | |
| function stripFilePaths(stackTrace) { | |
| for (let frame of stackTrace) { | |
| if (typeof frame.url === "string") | |
| frame.url = frame.url.replace(/^.+?LayoutTests/, ""); | |
| } | |
| return stackTrace; | |
| } | |
| function stripCallFramesAfterEval(stackTrace) { | |
| for (let i = 0; i < stackTrace.length; ++i) { | |
| let frame = stackTrace[i]; | |
| if (frame.programCode) | |
| return stackTrace.slice(0, i + 1); | |
| } | |
| return stackTrace; | |
| } | |
| function stripPayloadAfterGlobalCode(stackTrace) { | |
| for (let i = 0; i < stackTrace.length; ++i) { | |
| let frame = stackTrace[i]; | |
| if (frame.functionName === "global code") | |
| return stackTrace.slice(0, i + 1); | |
| } | |
| return stackTrace; | |
| } | |
| WI.consoleManager.addEventListener(WI.ConsoleManager.Event.MessageAdded, (event) => { | |
| InspectorTest.log("\nconsole.trace():"); | |
| let stackTrace = []; | |
| let callFramesBeforeEval = stripCallFramesAfterEval(event.data.message.stackTrace.callFrames); | |
| for (let callFrame of callFramesBeforeEval) { | |
| let lineNumber = callFrame.sourceCodeLocation ? callFrame.sourceCodeLocation.lineNumber : null; | |
| let columnNumber = callFrame.sourceCodeLocation ? callFrame.sourceCodeLocation.columnNumber : null; | |
| stackTrace.push({ | |
| lineNumber: lineNumber, | |
| columnNumber: columnNumber, | |
| functionName: callFrame.functionName, | |
| nativeCode: callFrame.nativeCode, | |
| programCode: callFrame.programCode, | |
| }); | |
| } | |
| InspectorTest.log(JSON.stringify(stackTrace, null, 4)); | |
| }); | |
| let suite = InspectorTest.createAsyncSuite("ConsoleTraceAndJavaScriptStackTrace"); | |
| function addTestCase({name, expression}) { | |
| suite.addTestCase({ | |
| name, | |
| test(resolve, reject) { | |
| InspectorTest.evaluateInPage(expression, (error, result) => { | |
| InspectorTest.assert(!error, error); | |
| InspectorTest.log("\nError object:"); | |
| let stackTrace = stripFilePaths(stripPayloadAfterGlobalCode(WI.StackTrace._parseStackTrace(result))); | |
| InspectorTest.log(JSON.stringify(stackTrace, null, 4)); | |
| resolve(); | |
| }); | |
| } | |
| }); | |
| } | |
| addTestCase({ | |
| name: "ConsoleTraceAndJavaScriptStackTrace.BasicError", | |
| expression: "triggerTypeError()", | |
| }); | |
| addTestCase({ | |
| name: "ConsoleTraceAndJavaScriptStackTrace.ErrorInNativeCall", | |
| expression: "triggerTypeErrorWithNativeCallInBetween()", | |
| }); | |
| addTestCase({ | |
| name: "ConsoleTraceAndJavaScriptStackTrace.ErrorInAnonymousFunction", | |
| expression: "getAnonymousFunctionError()", | |
| }); | |
| addTestCase({ | |
| name: "ConsoleTraceAndJavaScriptStackTrace.ErrorInGenerator", | |
| expression: "triggerGeneratorError()", | |
| }); | |
| suite.runTestCasesAndFinish(); | |
| } | |
| </script> | |
| </head> | |
| <body onload="runTest()"> | |
| <p>Tests that we can parse the stack trace format used by JavaScriptCore and the contents of Error / console.trace stack traces.</p> | |
| </body> | |
| </html> |