diff options
Diffstat (limited to 'browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js')
-rw-r--r-- | browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js | 207 |
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; +} |