summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js')
-rw-r--r--browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js207
1 files changed, 207 insertions, 0 deletions
diff --git a/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
new file mode 100644
index 000000000..ab4743f6f
--- /dev/null
+++ b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
@@ -0,0 +1,207 @@
+Cu.import("resource://gre/modules/CrashSubmit.jsm", this);
+
+const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
+
+var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
+var gTestBrowser = null;
+var config = {};
+
+add_task(function* () {
+ // The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
+ // crash reports. This test needs them enabled. The test also needs a mock
+ // report server, and fortunately one is already set up by toolkit/
+ // crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
+ // which CrashSubmit.jsm uses as a server override.
+ let env = Components.classes["@mozilla.org/process/environment;1"]
+ .getService(Components.interfaces.nsIEnvironment);
+ let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
+ let serverUrl = env.get("MOZ_CRASHREPORTER_URL");
+ env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
+ env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
+
+ gBrowser.selectedTab = gBrowser.addTab();
+ gTestBrowser = gBrowser.selectedBrowser;
+
+ // Crash immediately
+ Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", 0);
+
+ registerCleanupFunction(Task.async(function*() {
+ Services.prefs.clearUserPref("dom.ipc.plugins.timeoutSecs");
+ env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
+ env.set("MOZ_CRASHREPORTER_URL", serverUrl);
+ env = null;
+ config = null;
+ gTestBrowser = null;
+ gBrowser.removeCurrentTab();
+ window.focus();
+ }));
+});
+
+add_task(function* () {
+ config = {
+ shouldSubmissionUIBeVisible: true,
+ comment: "",
+ urlOptIn: false
+ };
+
+ setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
+
+ let pluginCrashed = promisePluginCrashed();
+
+ yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_crashCommentAndURL.html");
+
+ // Work around for delayed PluginBindingAttached
+ yield promiseUpdatePluginBindings(gTestBrowser);
+
+ // Wait for the plugin to crash
+ yield pluginCrashed;
+
+ let crashReportStatus = TestUtils.topicObserved("crash-report-status", onSubmitStatus);
+
+ // Test that the crash submission UI is actually visible and submit the crash report.
+ yield ContentTask.spawn(gTestBrowser, config, function* (aConfig) {
+ let doc = content.document;
+ let plugin = doc.getElementById("plugin");
+ let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
+ let submitButton = doc.getAnonymousElementByAttribute(plugin, "anonid", "submitButton");
+ // Test that we don't send the URL when urlOptIn is false.
+ doc.getAnonymousElementByAttribute(plugin, "anonid", "submitURLOptIn").checked = aConfig.urlOptIn;
+ submitButton.click();
+ Assert.equal(content.getComputedStyle(pleaseSubmit).display == "block",
+ aConfig.shouldSubmissionUIBeVisible, "The crash UI should be visible");
+ });
+
+ yield crashReportStatus;
+});
+
+add_task(function* () {
+ config = {
+ shouldSubmissionUIBeVisible: true,
+ comment: "a test comment",
+ urlOptIn: true
+ };
+
+ setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
+
+ let pluginCrashed = promisePluginCrashed();
+
+ yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_crashCommentAndURL.html");
+
+ // Work around for delayed PluginBindingAttached
+ yield promiseUpdatePluginBindings(gTestBrowser);
+
+ // Wait for the plugin to crash
+ yield pluginCrashed;
+
+ let crashReportStatus = TestUtils.topicObserved("crash-report-status", onSubmitStatus);
+
+ // Test that the crash submission UI is actually visible and submit the crash report.
+ yield ContentTask.spawn(gTestBrowser, config, function* (aConfig) {
+ let doc = content.document;
+ let plugin = doc.getElementById("plugin");
+ let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
+ let submitButton = doc.getAnonymousElementByAttribute(plugin, "anonid", "submitButton");
+ // Test that we send the URL when urlOptIn is true.
+ doc.getAnonymousElementByAttribute(plugin, "anonid", "submitURLOptIn").checked = aConfig.urlOptIn;
+ doc.getAnonymousElementByAttribute(plugin, "anonid", "submitComment").value = aConfig.comment;
+ submitButton.click();
+ Assert.equal(content.getComputedStyle(pleaseSubmit).display == "block",
+ aConfig.shouldSubmissionUIBeVisible, "The crash UI should be visible");
+ });
+
+ yield crashReportStatus;
+});
+
+add_task(function* () {
+ config = {
+ shouldSubmissionUIBeVisible: false,
+ comment: "",
+ urlOptIn: true
+ };
+
+ setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
+
+ let pluginCrashed = promisePluginCrashed();
+
+ // Make sure that the plugin container is too small to display the crash submission UI
+ yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_crashCommentAndURL.html?" +
+ encodeURIComponent(JSON.stringify({width: 300, height: 300})));
+
+ // Work around for delayed PluginBindingAttached
+ yield promiseUpdatePluginBindings(gTestBrowser);
+
+ // Wait for the plugin to crash
+ yield pluginCrashed;
+
+ // Test that the crash submission UI is not visible and do not submit a crash report.
+ yield ContentTask.spawn(gTestBrowser, config, function* (aConfig) {
+ let doc = content.document;
+ let plugin = doc.getElementById("plugin");
+ let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
+ Assert.equal(!!pleaseSubmit && content.getComputedStyle(pleaseSubmit).display == "block",
+ aConfig.shouldSubmissionUIBeVisible, "Plugin crash UI should not be visible");
+ });
+});
+
+function promisePluginCrashed() {
+ return new ContentTask.spawn(gTestBrowser, {}, function* () {
+ yield new Promise((resolve) => {
+ addEventListener("PluginCrashReporterDisplayed", function onPluginCrashed() {
+ removeEventListener("PluginCrashReporterDisplayed", onPluginCrashed);
+ resolve();
+ });
+ });
+ })
+}
+
+function onSubmitStatus(aSubject, aData) {
+ // Wait for success or failed, doesn't matter which.
+ if (aData != "success" && aData != "failed")
+ return false;
+
+ let propBag = aSubject.QueryInterface(Ci.nsIPropertyBag);
+ if (aData == "success") {
+ let remoteID = getPropertyBagValue(propBag, "serverCrashID");
+ ok(!!remoteID, "serverCrashID should be set");
+
+ // Remove the submitted report file.
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(Services.crashmanager._submittedDumpsDir);
+ file.append(remoteID + ".txt");
+ ok(file.exists(), "Submitted report file should exist");
+ file.remove(false);
+ }
+
+ let extra = getPropertyBagValue(propBag, "extra");
+ ok(extra instanceof Ci.nsIPropertyBag, "Extra data should be property bag");
+
+ let val = getPropertyBagValue(extra, "PluginUserComment");
+ if (config.comment)
+ is(val, config.comment,
+ "Comment in extra data should match comment in textbox");
+ else
+ ok(val === undefined,
+ "Comment should be absent from extra data when textbox is empty");
+
+ val = getPropertyBagValue(extra, "PluginContentURL");
+ if (config.urlOptIn)
+ is(val, gBrowser.currentURI.spec,
+ "URL in extra data should match browser URL when opt-in checked");
+ else
+ ok(val === undefined,
+ "URL should be absent from extra data when opt-in not checked");
+
+ return true;
+}
+
+function getPropertyBagValue(bag, key) {
+ try {
+ var val = bag.getProperty(key);
+ }
+ catch (e) {
+ if (e.result != Cr.NS_ERROR_FAILURE) {
+ throw e;
+ }
+ }
+ return val;
+}