Bug 1437295 - Ensure cleanup functions registered in a subtest are invoked when unloading the subtest. r?botond
If we are registering a cleanup function inside a subtest (as we will do
in the next patch) then we need to make sure it gets cleaned up before
the subtest is unloaded. Otherwise the cleanup will be attempted when
the top-level test page is unloaded, at which point the subtest is long
gone, and that results in an error.
MozReview-Commit-ID: 828XddkOUlP
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -192,16 +192,20 @@ function waitForApzFlushedRepaints(aCall
function runSubtestsSeriallyInFreshWindows(aSubtests) {
return new Promise(function(resolve, reject) {
var testIndex = -1;
var w = null;
function advanceSubtestExecution() {
var test = aSubtests[testIndex];
if (w) {
+ // Run any cleanup functions registered in the subtest
+ if (w.ApzCleanup) { // guard against the subtest not loading apz_test_utils.js
+ w.ApzCleanup.execute();
+ }
if (typeof test.dp_suppression != 'undefined') {
// We modified the suppression when starting the test, so now undo that.
SpecialPowers.getDOMWindowUtils(window).respectDisplayPortSuppression(!test.dp_suppression);
}
if (test.prefs) {
// We pushed some prefs for this test, pop them, and re-invoke
// advanceSubtestExecution() after that's been processed
SpecialPowers.popPrefEnv(function() {
@@ -229,16 +233,17 @@ function runSubtestsSeriallyInFreshWindo
// to avoid that we can force the displayport to be unsuppressed for the
// entire test which is more deterministic.
SpecialPowers.getDOMWindowUtils(window).respectDisplayPortSuppression(test.dp_suppression);
}
function spawnTest(aFile) {
w = window.open('', "_blank");
w.subtestDone = advanceSubtestExecution;
+ w.isApzSubtest = true;
w.SimpleTest = SimpleTest;
w.is = function(a, b, msg) { return is(a, b, aFile + " | " + msg); };
w.ok = function(cond, name, diag) { return ok(cond, aFile + " | " + name, diag); };
if (test.onload) {
w.addEventListener('load', function(e) { test.onload(w); }, { once: true });
}
var subtestUrl = location.href.substring(0, location.href.lastIndexOf('/') + 1) + aFile;
function urlResolves(url) {
@@ -364,17 +369,17 @@ function getSnapshot(rect) {
ctx.drawWindow(topWin, rect.x, rect.y, rect.w, rect.h, 'rgb(255,255,255)', ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_CARET);
return canvas.toDataURL();
});
}
if (typeof getSnapshot.chromeHelper == 'undefined') {
// This is the first time getSnapshot is being called; do initialization
getSnapshot.chromeHelper = SpecialPowers.loadChromeScript(parentProcessSnapshot);
- SimpleTest.registerCleanupFunction(function() { getSnapshot.chromeHelper.destroy() });
+ ApzCleanup.register(function() { getSnapshot.chromeHelper.destroy() });
}
return getSnapshot.chromeHelper.sendSyncMessage('snapshot', JSON.stringify(rect)).toString();
}
// Takes the document's query string and parses it, assuming the query string
// is composed of key-value pairs where the value is in JSON format. The object
// returned contains the various values indexed by their respective keys. In
@@ -551,8 +556,32 @@ function hitTestScrollbar(params) {
};
var {hitInfo, scrollId} = hitTest(horizontalScrollbarPoint);
is(hitInfo, expectedHitInfo,
scrollframeMsg + " - horizontal scrollbar hit info");
is(scrollId, params.expectedScrollId,
scrollframeMsg + " - horizontal scrollbar scrollid");
}
}
+
+var ApzCleanup = {
+ _cleanups: [],
+
+ register: function(func) {
+ if (this._cleanups.length == 0) {
+ if (!window.isApzSubtest) {
+ SimpleTest.registerCleanupFunction(this.execute.bind(this));
+ } // else ApzCleanup.execute is called from runSubtestsSeriallyInFreshWindows
+ }
+ this._cleanups.push(func);
+ },
+
+ execute: function() {
+ while (this._cleanups.length > 0) {
+ var func = this._cleanups.pop();
+ try {
+ func();
+ } catch (ex) {
+ SimpleTest.ok(false, "Subtest cleanup function [" + func.toString() + "] threw exception [" + ex + "] on page [" + location.href + "]");
+ }
+ }
+ }
+};
--- a/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html
+++ b/gfx/layers/apz/test/mochitest/helper_touch_action_regions.html
@@ -71,17 +71,17 @@ function chromeTouchEventCounter(operati
delete topWin.eventCounts;
return true;
});
}
if (typeof chromeTouchEventCounter.chromeHelper == 'undefined') {
// This is the first time chromeTouchEventCounter is being called; do initialization
chromeTouchEventCounter.chromeHelper = SpecialPowers.loadChromeScript(chromeProcessCounter);
- SimpleTest.registerCleanupFunction(function() { chromeTouchEventCounter.chromeHelper.destroy() });
+ ApzCleanup.register(function() { chromeTouchEventCounter.chromeHelper.destroy() });
}
return chromeTouchEventCounter.chromeHelper.sendSyncMessage(operation, "");
}
// Simple wrapper that waits until the chrome process has seen |count| instances
// of the |eventType| event. Returns true on success, and false if 10 seconds
// go by without the condition being satisfied.