browser_shown.js (7537B)
1 "use strict"; 2 3 const PAGE = 4 "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page."; 5 const COMMENTS = "Here's my test comment!"; 6 7 // Avoid timeouts, as in bug 1325530 8 requestLongerTimeout(2); 9 10 add_setup(async function () { 11 await setupLocalCrashReportServer(); 12 }); 13 14 /** 15 * This function returns a Promise that resolves once the following 16 * actions have taken place: 17 * 18 * 1) A new tab is opened up at PAGE 19 * 2) The tab is crashed 20 * 3) The about:tabcrashed page's fields are set in accordance with 21 * fieldValues 22 * 4) The tab is restored 23 * 5) A crash report is received from the testing server 24 * 6) Any tab crash prefs that were overwritten are reset 25 * 26 * @param fieldValues 27 * An Object describing how to set the about:tabcrashed 28 * fields. The following properties are accepted: 29 * 30 * comments (String) 31 * The comments to put in the comment textarea 32 * includeURL (bool) 33 * The checked value of the "Include URL" checkbox 34 * 35 * If any of these fields are missing, the defaults from 36 * the user preferences are used. 37 * @param expectedExtra 38 * An Object describing the expected values that the submitted 39 * crash report's extra data should contain. 40 * @returns Promise 41 */ 42 function crashTabTestHelper(fieldValues, expectedExtra, shouldFail = false) { 43 return BrowserTestUtils.withNewTab( 44 { 45 gBrowser, 46 url: PAGE, 47 }, 48 async function (browser) { 49 let prefs = TabCrashHandler.prefs; 50 let originalSendReport = prefs.getBoolPref("sendReport"); 51 let originalIncludeURL = prefs.getBoolPref("includeURL"); 52 53 let tab = gBrowser.getTabForBrowser(browser); 54 await BrowserTestUtils.crashFrame(browser); 55 let doc = browser.contentDocument; 56 57 // Since about:tabcrashed will run in the parent process, we can safely 58 // manipulate its DOM nodes directly 59 let comments = doc.getElementById("comments"); 60 let includeURL = doc.getElementById("includeURL"); 61 62 if (fieldValues.hasOwnProperty("comments")) { 63 comments.value = fieldValues.comments; 64 } 65 66 if (fieldValues.hasOwnProperty("includeURL")) { 67 includeURL.checked = fieldValues.includeURL; 68 } 69 70 let crashReport = shouldFail 71 ? promiseCrashReportFail() 72 : promiseCrashReport(expectedExtra); 73 let restoreTab = browser.contentDocument.getElementById("restoreTab"); 74 restoreTab.click(); 75 await BrowserTestUtils.waitForEvent(tab, "SSTabRestored"); 76 await crashReport; 77 78 // Submitting the crash report may have set some prefs regarding how to 79 // send tab crash reports. Let's reset them for the next test. 80 prefs.setBoolPref("sendReport", originalSendReport); 81 prefs.setBoolPref("includeURL", originalIncludeURL); 82 } 83 ); 84 } 85 86 /** 87 * Tests what we send with the crash report by default. By default, we do not 88 * send any comments or the URL of the crashing page. 89 */ 90 add_task(async function test_default() { 91 let submissionBefore = Glean.crashSubmission.success.testGetValue(); 92 await crashTabTestHelper( 93 {}, 94 { 95 SubmittedFrom: "CrashedTab", 96 Throttleable: "1", 97 Comments: null, 98 URL: "", 99 } 100 ); 101 Assert.equal( 102 submissionBefore + 1, 103 Glean.crashSubmission.success.testGetValue() 104 ); 105 }); 106 107 /** 108 * Test just sending a comment. 109 */ 110 add_task(async function test_just_a_comment() { 111 let submissionBefore = Glean.crashSubmission.success.testGetValue(); 112 await crashTabTestHelper( 113 { 114 SubmittedFrom: "CrashedTab", 115 Throttleable: "1", 116 comments: COMMENTS, 117 }, 118 { 119 Comments: COMMENTS, 120 URL: "", 121 } 122 ); 123 Assert.equal( 124 submissionBefore + 1, 125 Glean.crashSubmission.success.testGetValue() 126 ); 127 }); 128 129 /** 130 * Test that we will send the URL of the page if includeURL is checked. 131 */ 132 add_task(async function test_send_URL() { 133 let submissionBefore = Glean.crashSubmission.success.testGetValue(); 134 await crashTabTestHelper( 135 { 136 SubmittedFrom: "CrashedTab", 137 Throttleable: "1", 138 includeURL: true, 139 }, 140 { 141 Comments: null, 142 URL: PAGE, 143 } 144 ); 145 Assert.equal( 146 submissionBefore + 1, 147 Glean.crashSubmission.success.testGetValue() 148 ); 149 }); 150 151 /** 152 * Test that we can send comments and the URL 153 */ 154 add_task(async function test_send_all() { 155 let successBefore = Glean.crashSubmission.success.testGetValue(); 156 let failureBefore = Glean.crashSubmission.failure.testGetValue(); 157 await crashTabTestHelper( 158 { 159 SubmittedFrom: "CrashedTab", 160 Throttleable: "1", 161 includeURL: true, 162 comments: COMMENTS, 163 }, 164 { 165 Comments: COMMENTS, 166 URL: PAGE, 167 } 168 ); 169 Assert.equal(successBefore + 1, Glean.crashSubmission.success.testGetValue()); 170 Assert.equal(failureBefore, Glean.crashSubmission.failure.testGetValue()); 171 }); 172 173 add_task(async function test_send_error() { 174 let successBefore = Glean.crashSubmission.success.testGetValue(); 175 let failureBefore = Glean.crashSubmission.failure.testGetValue(); 176 const eventsBefore = Glean.crashSubmission.failureEvent.testGetValue() ?? []; 177 178 Assert.equal( 179 null, 180 Glean.crashSubmission.collectorErrors.unknown_error.testGetValue() 181 ); 182 let invalidAnnotation = 183 Glean.crashSubmission.collectorErrors.malformed_invalid_annotation_value_400.testGetValue(); 184 185 await crashTabTestHelper( 186 { 187 SubmittedFrom: "CrashedTab", 188 Throttleable: "0", 189 comments: "fail-me://400:malformed_invalid_annotation_value", 190 }, 191 { 192 Comments: "fail-me://400:malformed_invalid_annotation_value", 193 }, 194 /* shouldFail */ true 195 ); 196 Assert.equal(successBefore, Glean.crashSubmission.success.testGetValue()); 197 Assert.equal(failureBefore + 1, Glean.crashSubmission.failure.testGetValue()); 198 199 Assert.equal( 200 null, 201 Glean.crashSubmission.collectorErrors.unknown_error.testGetValue() 202 ); 203 Assert.equal( 204 invalidAnnotation + 1, 205 Glean.crashSubmission.collectorErrors.malformed_invalid_annotation_value_400.testGetValue() 206 ); 207 208 const events = Glean.crashSubmission.failureEvent.testGetValue(); 209 Assert.equal(eventsBefore.length + 1, events.length); 210 Assert.equal( 211 "received bad response: 400 Discarded=malformed_invalid_annotation_value", 212 events[events.length - 1].extra.reason 213 ); 214 Assert.greater(events[events.length - 1].extra.id.length, 0, "id not set"); 215 }); 216 217 add_task(async function test_send_error_server() { 218 let successBefore = Glean.crashSubmission.success.testGetValue(); 219 let failureBefore = Glean.crashSubmission.failure.testGetValue(); 220 let unknownError503 = 221 Glean.crashSubmission.collectorErrors.unknown_error_503.testGetValue(); 222 const eventsBefore = Glean.crashSubmission.failureEvent.testGetValue() ?? []; 223 224 await crashTabTestHelper( 225 { 226 SubmittedFrom: "CrashedTab", 227 Throttleable: "0", 228 comments: "fail-me://503:should_get_unkown_error", 229 }, 230 { 231 Comments: "fail-me://503:should_get_unkown_error", 232 }, 233 /* shouldFail */ true 234 ); 235 Assert.equal(successBefore, Glean.crashSubmission.success.testGetValue()); 236 Assert.equal(failureBefore + 1, Glean.crashSubmission.failure.testGetValue()); 237 238 Assert.equal( 239 unknownError503 + 1, 240 Glean.crashSubmission.collectorErrors.unknown_error_503.testGetValue() 241 ); 242 243 const events = Glean.crashSubmission.failureEvent.testGetValue(); 244 Assert.equal(eventsBefore.length + 1, events.length); 245 Assert.equal( 246 "received bad response: 503 Discarded=unknown_error", 247 events[events.length - 1].extra.reason 248 ); 249 });