Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

function cleanup_and_finish() {
try {
cleanup_fake_appdir();
} catch (ex) {}
Services.prefs.clearUserPref("breakpad.reportURL");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
finish();
}
/*
* check_crash_list
*
* Check that the list of crashes displayed by about:crashes matches
* the list of crashes that we placed in the pending+submitted directories.
*
* This function is run in a separate JS context via SpecialPowers.spawn, so
* it has no access to other functions or variables in this file.
*/
function check_crash_list(crashes) {
const doc = content.document;
const crashIdNodes = Array.from(doc.getElementsByClassName("crash-id"));
const pageCrashIds = new Set(crashIdNodes.map(node => node.textContent));
const crashIds = new Set(crashes.map(crash => crash.id));
Assert.deepEqual(
pageCrashIds,
crashIds,
"about:crashes lists the correct crash reports."
);
}
/*
* check_submit_pending
*
* Click on a pending crash in about:crashes, wait for it to be submitted (which
* should redirect us to the crash report page). Verify that the data provided
* by our test crash report server matches the data we submitted.
* Additionally, click "back" and verify that the link now points to our new
*/
function check_submit_pending(tab, crashes) {
const browser = gBrowser.getBrowserForTab(tab);
let SubmittedCrash = null;
let CrashID = null;
let CrashURL = null;
function csp_onsuccess() {
const crashLinks = content.document.getElementsByClassName("crash-link");
// Get the last link since it is appended to the end of the list
const link = crashLinks[crashLinks.length - 1];
link.click();
}
function csp_onload() {
// loaded the crash report page
ok(true, "got submission onload");
SpecialPowers.spawn(browser, [], function () {
// grab the Crash ID here to verify later
let CrashID = content.location.search.split("=")[1];
let CrashURL = content.location.toString();
// check the JSON content vs. what we submitted
let result = JSON.parse(content.document.documentElement.textContent);
Assert.equal(
result.upload_file_minidump,
"MDMP",
"minidump file sent properly"
);
Assert.equal(
result.memory_report,
"Let's pretend this is a memory report",
"memory report sent properly"
);
Assert.equal(
+result.Throttleable,
0,
"correctly sent as non-throttleable"
);
Assert.equal(
result.SubmittedFrom,
"AboutCrashes",
"correctly flagged as sent from about:crashes"
);
// we checked these, they're set by the submission process,
// so they won't be in the "extra" data.
delete result.upload_file_minidump;
delete result.memory_report;
delete result.Throttleable;
delete result.SubmittedFrom;
return { id: CrashID, url: CrashURL, result };
}).then(({ id, url, result }) => {
// Likewise, this is discarded before it gets to the server
delete SubmittedCrash.extra.ServerURL;
CrashID = id;
CrashURL = url;
for (let x in result) {
if (x in SubmittedCrash.extra) {
is(
result[x],
SubmittedCrash.extra[x],
"submitted value for " + x + " matches expected"
);
} else {
ok(false, "property " + x + " missing from submitted data!");
}
}
for (let y in SubmittedCrash.extra) {
if (!(y in result)) {
ok(false, "property " + y + " missing from result data!");
}
}
// We can listen for pageshow like this because the tab is not remote.
BrowserTestUtils.waitForEvent(browser, "pageshow", true).then(
csp_pageshow
);
// now navigate back
browser.goBack();
});
}
function csp_fail() {
browser.removeEventListener("CrashSubmitFailed", csp_fail, true);
ok(false, "failed to submit crash report!");
cleanup_and_finish();
}
browser.addEventListener("CrashSubmitSucceeded", csp_onsuccess, true);
browser.addEventListener("CrashSubmitFailed", csp_fail, true);
BrowserTestUtils.browserLoaded(
browser,
false,
url => url !== "about:crashes"
).then(csp_onload);
function csp_pageshow() {
SpecialPowers.spawn(
browser,
[{ CrashID, CrashURL }],
function ({ CrashID, CrashURL }) {
Assert.equal(
content.location.href,
"about:crashes",
"navigated back successfully"
);
const link = content.document
.getElementById(CrashID)
.getElementsByClassName("crash-link")[0];
Assert.notEqual(link, null, "crash report link changed correctly");
if (link) {
Assert.equal(
link.href,
CrashURL,
"crash report link points to correct href"
);
}
}
).then(cleanup_and_finish);
}
// try submitting the pending report
for (const crash of crashes) {
if (crash.pending) {
SubmittedCrash = crash;
break;
}
}
SpecialPowers.spawn(browser, [SubmittedCrash.id], id => {
const submitButton = content.document
.getElementById(id)
.getElementsByClassName("submit-button")[0];
submitButton.click();
});
}
function test() {
waitForExplicitFinish();
const appD = make_fake_appdir();
const crD = appD.clone();
crD.append("Crash Reports");
const crashes = add_fake_crashes(crD, 1);
// we don't need much data here, it's not going to a real Socorro
crashes.push(
addPendingCrashreport(crD, crashes[crashes.length - 1].date + 60000, {
ServerURL:
ProductName: "Test App",
Foo: "ABC=XYZ", // test that we don't truncat eat = (bug 512853)
})
);
crashes.sort((a, b) => b.date - a.date);
// set this pref so we can link to our test server
Services.prefs.setCharPref(
"breakpad.reportURL",
);
BrowserTestUtils.openNewForegroundTab(gBrowser, "about:crashes").then(tab => {
SpecialPowers.spawn(tab.linkedBrowser, [crashes], check_crash_list).then(
() => check_submit_pending(tab, crashes)
);
});
}