browser_webconsole_promise_rejected_object.js (3448B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 // Test that rejected promise are reported to the console. 5 6 "use strict"; 7 8 const TEST_URI = `data:text/html;charset=utf-8,<!DOCTYPE html> 9 <script> 10 function createRejectedPromise(reason) { 11 new Promise(function promiseCb(_, reject) { 12 setTimeout(function setTimeoutCb(){ 13 reject(reason); 14 }, 0); 15 }); 16 } 17 18 var err = new Error("carrot"); 19 err.name = "VeggieError"; 20 21 const reasons = [ 22 "potato", 23 "", 24 0, 25 false, 26 null, 27 undefined, 28 {fav: "eggplant"}, 29 ["cherry", "strawberry"], 30 new Error("spinach"), 31 err, 32 ]; 33 34 reasons.forEach(function forEachCb(reason) { 35 createRejectedPromise(reason); 36 }); 37 </script>`; 38 39 add_task(async function () { 40 await pushPref("javascript.options.asyncstack_capture_debuggee_only", false); 41 const hud = await openNewTabAndConsole(TEST_URI); 42 43 const expectedErrors = [ 44 "Uncaught (in promise) potato", 45 "Uncaught (in promise) <empty string>", 46 "Uncaught (in promise) 0", 47 "Uncaught (in promise) false", 48 "Uncaught (in promise) null", 49 "Uncaught (in promise) undefined", 50 `Uncaught (in promise) Object { fav: "eggplant" }`, 51 `Uncaught (in promise) Array [ "cherry", "strawberry" ]`, 52 `Uncaught (in promise) Error: spinach`, 53 `Uncaught (in promise) VeggieError: carrot`, 54 ]; 55 56 for (const expectedError of expectedErrors) { 57 const message = await waitFor( 58 () => findErrorMessage(hud, expectedError), 59 `Couldn't find «${expectedError}» message` 60 ); 61 ok(message, `Found «${expectedError}» message`); 62 63 message.querySelector(".collapse-button").click(); 64 const framesEl = await waitFor(() => { 65 const frames = message.querySelectorAll( 66 `.message-body-wrapper > .stacktrace .frame, 67 .message-body-wrapper > .stacktrace .location-async-cause` 68 ); 69 return frames.length ? frames : null; 70 }, "Couldn't find stacktrace"); 71 72 const frames = [...framesEl] 73 .map(frameEl => { 74 const el = frameEl.querySelector(".title") || frameEl; 75 return el.textContent.trim(); 76 }) 77 .flat(); 78 79 is( 80 frames.join("\n"), 81 [ 82 "setTimeoutCb", 83 "(Async: setTimeout handler)", 84 "promiseCb", 85 "createRejectedPromise", 86 "forEachCb", 87 "forEach", 88 "<anonymous>", 89 ].join("\n"), 90 "Error message has expected frames" 91 ); 92 } 93 ok(true, "All expected messages were found"); 94 95 info("Check that object in errors can be expanded"); 96 const rejectedObjectMessage = findErrorMessage( 97 hud, 98 `Uncaught (in promise) Object { fav: "eggplant" }` 99 ); 100 const oi = rejectedObjectMessage.querySelector(".tree"); 101 ok(true, "The object was rendered in an ObjectInspector"); 102 103 info("Expanding the object"); 104 await expandObjectInspectorNode(oi.querySelector(".tree-node")); 105 106 // The object inspector now looks like: 107 // Object { fav: "eggplant" } 108 // | fav: "eggplant" 109 // | <prototype>: Object { ... } 110 111 const oiNodes = oi.querySelectorAll(".node"); 112 is(oiNodes.length, 3, "There is the expected number of nodes in the tree"); 113 114 ok(oiNodes[0].textContent.includes(`Object { fav: "eggplant" }`)); 115 ok(oiNodes[1].textContent.includes(`fav: "eggplant"`)); 116 ok(oiNodes[2].textContent.includes(`<prototype>: Object { \u2026 }`)); 117 });