Bug 703176 - Ensure all browser chrome mochitests do fail when uncaught JS exceptions occur. (v1.1) r=jmaher

This commit is contained in:
Cameron McCormack 2011-12-02 23:25:03 +11:00
parent 5d8345a336
commit 53cc0ba3ac
27 changed files with 89 additions and 25 deletions

View File

@ -1,6 +1,7 @@
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
var frame = document.getElementById("customizeToolbarSheetIFrame");
frame.addEventListener("load", testCustomizeFrameLoadedPre, true);

View File

@ -99,4 +99,5 @@ function test() {
});
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
}

View File

@ -45,6 +45,7 @@ function test() {
let cm = Cc["@mozilla.org/cookiemanager;1"].
getService(Ci.nsICookieManager);
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
const TEST_URL = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/title.sjs";

View File

@ -18,6 +18,7 @@
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
let crashState = { windows: [{ tabs: [{ entries: [{ url: "about:mozilla" }] }]}]};

View File

@ -44,6 +44,7 @@ function observeOneRestore(callback) {
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
// There should be one tab when we start the test
let [origTab] = gBrowser.visibleTabs;

View File

@ -52,6 +52,7 @@ function cleanup() {
function test() {
/** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
// Set the pref to true so we know exactly how many tabs should be restoring at
// any given time. This guarantees that a finishing load won't start another.

View File

@ -5,6 +5,7 @@
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
let doc;
let objectNode;

View File

@ -127,6 +127,7 @@ function finishInspectorTests()
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -111,6 +111,7 @@ function inspectorRuleTrap()
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
tab1 = gBrowser.addTab();
gBrowser.selectedTab = tab1;

View File

@ -4,6 +4,7 @@
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
let doc;
let nodes;

View File

@ -218,6 +218,7 @@ function finishInspectorTests()
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -213,6 +213,7 @@ function finishUp() {
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -137,6 +137,7 @@ function ruleViewOpened2()
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
tab1 = gBrowser.addTab();
gBrowser.selectedTab = tab1;

View File

@ -263,6 +263,7 @@ function inspectorTabUnload1(evt)
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
tab1 = gBrowser.addTab();
gBrowser.selectedTab = tab1;

View File

@ -105,6 +105,7 @@ function finishUp() {
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -14,6 +14,7 @@ Cu.import("resource:///modules/devtools/CssHtmlTree.jsm");
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
addTab(TEST_URI);
browser.addEventListener("load", tabLoaded, true);
}

View File

@ -79,6 +79,7 @@ function finishUp()
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);

View File

@ -187,6 +187,7 @@ function nextTest() {
}
function test() {
ignoreAllUncaughtExceptions();
nextTest();
}

View File

@ -210,6 +210,10 @@ Tester.prototype = {
}
};
if (this.SimpleTest.isExpectingUncaughtException()) {
this.currentTest.addResult(new testResult(false, "expectUncaughtException was called but no uncaught exception was detected!", "", false));
}
// Clear document.popupNode. The test could have set it to a custom value
// for its own purposes, nulling it out it will go back to the default
// behavior of returning the last opened popup.
@ -250,6 +254,8 @@ Tester.prototype = {
execTest: function Tester_execTest() {
this.dumper.dump("TEST-START | " + this.currentTest.path + "\n");
this.SimpleTest.reset();
// Load the tests into a testscope
this.currentTest.scope = new testScope(this, this.currentTest);
@ -259,7 +265,7 @@ Tester.prototype = {
this.currentTest.scope.gTestPath = this.currentTest.path;
// Override SimpleTest methods with ours.
["ok", "is", "isnot", "todo", "todo_is", "todo_isnot"].forEach(function(m) {
["ok", "is", "isnot", "todo", "todo_is", "todo_isnot", "info"].forEach(function(m) {
this.SimpleTest[m] = this[m];
}, this.currentTest.scope);
@ -296,7 +302,13 @@ Tester.prototype = {
this.currentTest.scope.test();
}
} catch (ex) {
this.currentTest.addResult(new testResult(false, "Exception thrown", ex, false));
var isExpected = !!this.SimpleTest.isExpectingUncaughtException();
if (!this.SimpleTest.isIgnoringAllUncaughtExceptions()) {
this.currentTest.addResult(new testResult(isExpected, "Exception thrown", ex, false));
this.SimpleTest.expectUncaughtException(false);
} else {
this.currentTest.addResult(new testMessage("Exception thrown: " + ex));
}
this.currentTest.scope.finish();
}
@ -379,12 +391,11 @@ function testMessage(aName) {
// cannot conflict with global variables used in tests.
function testScope(aTester, aTest) {
this.__tester = aTester;
this.__browserTest = aTest;
var self = this;
this.ok = function test_ok(condition, name, diag, stack) {
self.__browserTest.addResult(new testResult(condition, name, diag, false,
stack ? stack : Components.stack.caller));
aTest.addResult(new testResult(condition, name, diag, false,
stack ? stack : Components.stack.caller));
};
this.is = function test_is(a, b, name) {
self.ok(a == b, name, "Got " + a + ", expected " + b, false,
@ -395,8 +406,8 @@ function testScope(aTester, aTest) {
Components.stack.caller);
};
this.todo = function test_todo(condition, name, diag, stack) {
self.__browserTest.addResult(new testResult(!condition, name, diag, true,
stack ? stack : Components.stack.caller));
aTest.addResult(new testResult(!condition, name, diag, true,
stack ? stack : Components.stack.caller));
};
this.todo_is = function test_todo_is(a, b, name) {
self.todo(a == b, name, "Got " + a + ", expected " + b,
@ -407,7 +418,7 @@ function testScope(aTester, aTest) {
Components.stack.caller);
};
this.info = function test_info(name) {
self.__browserTest.addResult(new testMessage(name));
aTest.addResult(new testMessage(name));
};
this.executeSoon = function test_executeSoon(func) {
@ -438,7 +449,13 @@ function testScope(aTester, aTest) {
// StopIteration means test is finished.
self.finish();
} catch (ex) {
aTest.addResult(new testResult(false, "Exception thrown", ex, false));
var isExpected = !!self.SimpleTest.isExpectingUncaughtException();
if (!self.SimpleTest.isIgnoringAllUncaughtExceptions()) {
aTest.addResult(new testResult(isExpected, "Exception thrown", ex, false));
self.SimpleTest.expectUncaughtException(false);
} else {
aTest.addResult(new testMessage("Exception thrown: " + ex));
}
self.finish();
}
};
@ -467,19 +484,16 @@ function testScope(aTester, aTest) {
self.SimpleTest.copyToProfile(filename);
};
this.expectUncaughtException = function test_expectUncaughtException() {
self.SimpleTest.expectUncaughtException();
this.expectUncaughtException = function test_expectUncaughtException(aExpecting) {
self.SimpleTest.expectUncaughtException(aExpecting);
};
this.ignoreAllUncaughtExceptions = function test_ignoreAllUncaughtExceptions() {
self.SimpleTest.ignoreAllUncaughtExceptions();
this.ignoreAllUncaughtExceptions = function test_ignoreAllUncaughtExceptions(aIgnoring) {
self.SimpleTest.ignoreAllUncaughtExceptions(aIgnoring);
};
this.finish = function test_finish() {
self.__done = true;
if (self.SimpleTest._expectingUncaughtException) {
self.ok(false, "expectUncaughtException was called but no uncaught exception was detected!");
}
if (self.__waitTimer) {
self.executeSoon(function() {
if (self.__done && self.__waitTimer) {

View File

@ -693,8 +693,16 @@ SimpleTest.expectChildProcessCrash = function () {
* Indicates to the test framework that the next uncaught exception during
* the test is expected, and should not cause a test failure.
*/
SimpleTest.expectUncaughtException = function () {
SimpleTest._expectingUncaughtException = true;
SimpleTest.expectUncaughtException = function (aExpecting) {
SimpleTest._expectingUncaughtException = aExpecting === void 0 || !!aExpecting;
};
/**
* Returns whether the test has indicated that it expects an uncaught exception
* to occur.
*/
SimpleTest.isExpectingUncaughtException = function () {
return SimpleTest._expectingUncaughtException;
};
/**
@ -702,8 +710,26 @@ SimpleTest.expectUncaughtException = function () {
* during the test are known problems that should be fixed in the future,
* but which should not cause the test to fail currently.
*/
SimpleTest.ignoreAllUncaughtExceptions = function () {
SimpleTest._ignoringAllUncaughtExceptions = true;
SimpleTest.ignoreAllUncaughtExceptions = function (aIgnoring) {
SimpleTest._ignoringAllUncaughtExceptions = aIgnoring === void 0 || !!aIgnoring;
};
/**
* Returns whether the test has indicated that all uncaught exceptions should be
* ignored.
*/
SimpleTest.isIgnoringAllUncaughtExceptions = function () {
return SimpleTest._ignoringAllUncaughtExceptions;
};
/**
* Resets any state this SimpleTest object has. This is important for
* browser chrome mochitests, which reuse the same SimpleTest object
* across a run.
*/
SimpleTest.reset = function () {
SimpleTest._ignoringAllUncaughtExceptions = false;
SimpleTest._expectingUncaughtException = false;
};
if (isPrimaryTestWindow) {
@ -924,22 +950,21 @@ var info = SimpleTest.info;
var gOldOnError = window.onerror;
window.onerror = function simpletestOnerror(errorMsg, url, lineNumber) {
var funcIdentifier = "[SimpleTest/SimpleTest.js, window.onerror]";
// Log the message.
// XXX Chrome mochitests sometimes trigger this window.onerror handler,
// but there are a number of uncaught JS exceptions from those tests.
// For now, for tests that self identify as having unintentional uncaught
// exceptions, just dump it so that the error is visible but doesn't cause
// a test failure. See bug 652494.
var message = "An error occurred: " + errorMsg + " at " + url + ":" + lineNumber;
var href = SpecialPowers.getPrivilegedProps(window, 'location.href');
var isExpected = !!SimpleTest._expectingUncaughtException;
var message = "an " + (isExpected ? "" : "un") + "expected uncaught JS exception reported through window.onerror";
var error = errorMsg + " at " + url + ":" + lineNumber;
if (!SimpleTest._ignoringAllUncaughtExceptions) {
SimpleTest.ok(isExpected, funcIdentifier, message);
SimpleTest.ok(isExpected, message, error);
SimpleTest._expectingUncaughtException = false;
} else {
SimpleTest.todo(false, funcIdentifier, message);
SimpleTest.todo(false, message + ": " + error);
}
// There is no Components.stack.caller to log. (See bug 511888.)

View File

@ -88,6 +88,7 @@ var Watcher = {
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
Services.wm.addListener(Watcher);

View File

@ -3,6 +3,7 @@
// exception
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
var triggers = encodeURIComponent(JSON.stringify(TESTROOT + "unsigned.xpi"));
gBrowser.selectedTab = gBrowser.addTab();

View File

@ -3,6 +3,7 @@
// exception
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
var triggers = encodeURIComponent(JSON.stringify({
"Unsigned XPI": {

View File

@ -5,6 +5,7 @@
// ----------------------------------------------------------------------------
// Tests that cancelling multiple installs doesn't fail
function test() {
ignoreAllUncaughtExceptions();
Harness.installConfirmCallback = confirm_install;
Harness.installEndedCallback = install_ended;
Harness.installsCompletedCallback = finish_test;

View File

@ -1,6 +1,7 @@
// ----------------------------------------------------------------------------
// Test whether an InstallTrigger.install call fails when xpinstall is disabled
function test() {
ignoreAllUncaughtExceptions();
Harness.installDisabledCallback = install_disabled;
Harness.installBlockedCallback = allow_blocked;
Harness.installConfirmCallback = confirm_install;

View File

@ -3,6 +3,7 @@
// web content
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
.getService(Components.interfaces.nsIChromeRegistry);

View File

@ -2,6 +2,7 @@
// Tests installing an unsigned add-on through a navigation. Should not be
// blocked since the referer is whitelisted.
function test() {
ignoreAllUncaughtExceptions();
Harness.installConfirmCallback = confirm_install;
Harness.installsCompletedCallback = finish_test;
Harness.setup();