Bug 1465806 - Wait for addon manager and session restore full initialization before starting DAMP tests. r=jdescottes
MozReview-Commit-ID: 1xszgL781BU
--- a/testing/talos/talos/tests/devtools/addon/content/damp.js
+++ b/testing/talos/talos/tests/devtools/addon/content/damp.js
@@ -1,10 +1,11 @@
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", {});
+const { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
XPCOMUtils.defineLazyGetter(this, "require", function() {
let { require } =
ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
return require;
});
XPCOMUtils.defineLazyGetter(this, "gDevTools", function() {
@@ -158,16 +159,31 @@ Damp.prototype = {
async addTab(url) {
let tab = this._win.gBrowser.selectedTab = this._win.gBrowser.addTab(url);
let browser = tab.linkedBrowser;
await awaitBrowserLoaded(browser);
return tab;
},
+ async waitForPendingPaints(window) {
+ let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ window.performance.mark("pending paints.start");
+ while (utils.isMozAfterPaintPending) {
+ await new Promise(done => {
+ window.addEventListener("MozAfterPaint", function listener() {
+ window.performance.mark("pending paint");
+ done();
+ }, { once: true });
+ });
+ }
+ window.performance.measure("pending paints", "pending paints.start");
+ },
+
closeCurrentTab() {
this._win.BrowserCloseTabOrWindow();
return this._win.gBrowser.selectedTab;
},
reloadPage(onReload) {
return new Promise(resolve => {
let browser = gBrowser.selectedBrowser;
@@ -195,19 +211,16 @@ Damp.prototype = {
await this.garbageCollect();
let duration = Math.round(performance.now() - this._startTime);
dump(`${this._currentTest} took ${duration}ms.\n`);
this._runNextTest();
},
- // Everything below here are common pieces needed for the test runner to function,
- // just copy and pasted from Tart with /s/TART/DAMP
-
_win: undefined,
_dampTab: undefined,
_results: [],
_config: {subtests: [], repeat: 1, rest: 100},
_nextTestIndex: 0,
_tests: [],
_onSequenceComplete: 0,
@@ -345,16 +358,50 @@ Damp.prototype = {
this._doneInternal();
},
exception(e) {
this.error(e);
dump(e.stack + "\n");
},
+ // Waits for any pending operations that may execute on Firefox startup and that
+ // can still be pending when we start running DAMP tests.
+ async waitBeforeRunningTests() {
+ // Addons may still be being loaded, so wait for them to be fully set up.
+ if (!AddonManager.isReady) {
+ let onAddonManagerReady = new Promise(resolve => {
+ let listener = {
+ onStartup() {
+ AddonManager.removeManagerListener(listener);
+ resolve();
+ },
+ onShutdown() {},
+ };
+ AddonManager.addManagerListener(listener);
+ });
+ await onAddonManagerReady;
+ }
+
+ // SessionRestore triggers some saving sequence on idle,
+ // so wait for that to be processed before starting tests.
+ // https://searchfox.org/mozilla-central/rev/83a923ef7a3b95a516f240a6810c20664b1e0ac9/browser/components/sessionstore/content/content-sessionStore.js#828-830
+ // https://searchfox.org/mozilla-central/rev/83a923ef7a3b95a516f240a6810c20664b1e0ac9/browser/components/sessionstore/content/content-sessionStore.js#858
+ await new Promise(resolve => {
+ setTimeout(resolve, 1500);
+ });
+ await new Promise(resolve => {
+ requestIdleCallback(resolve, { timeout: 15000 });
+ });
+
+ // Free memory before running the first test, otherwise we may have a GC
+ // related to Firefox startup or DAMP setup during the first test.
+ await this.garbageCollect();
+ },
+
startTest(doneCallback, config) {
try {
dump("Initialize the head file with a reference to this DAMP instance\n");
let head = require("chrome://damp/content/tests/head.js");
head.initialize(this);
this._onTestComplete = function(results) {
TalosParentProfiler.pause("DAMP - end");
@@ -389,19 +436,17 @@ Damp.prototype = {
// Construct the sequence array while filtering tests
let sequenceArray = [];
for (let test of tests) {
for (let r = 0; r < config.repeat; r++) {
sequenceArray.push(test.path);
}
}
- // Free memory before running the first test, otherwise we may have a GC
- // related to Firefox startup or DAMP setup during the first test.
- this.garbageCollect().then(() => {
+ this.waitBeforeRunningTests().then(() => {
this._doSequence(sequenceArray, this._doneInternal);
}).catch(e => {
this.exception(e);
});
} catch (e) {
this.exception(e);
}
}
--- a/testing/talos/talos/tests/devtools/addon/content/tests/head.js
+++ b/testing/talos/talos/tests/devtools/addon/content/tests/head.js
@@ -3,18 +3,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* This helper contains the public API that can be used by DAMP tests.
*/
-// eslint-disable-next-line mozilla/no-define-cc-etc
-const { Ci } = require("chrome");
const Services = require("Services");
const { gDevTools } = require("devtools/client/framework/devtools");
const { TargetFactory } = require("devtools/client/framework/target");
const webserver = Services.prefs.getCharPref("addon.test.damp.webserver");
const PAGES_BASE_URL = webserver + "/tests/devtools/addon/content/pages/";
@@ -72,29 +70,17 @@ exports.getToolbox = function() {
* Wait for any pending paint.
* The tool may have touched the DOM elements at the very end of the current test.
* We should ensure waiting for the reflow related to these changes.
*/
async function waitForPendingPaints(toolbox) {
let panel = toolbox.getCurrentPanel();
// All panels have its own way of exposing their window object...
let window = panel.panelWin || panel._frameWindow || panel.panelWindow;
-
- let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
- window.performance.mark("pending paints.start");
- while (utils.isMozAfterPaintPending) {
- await new Promise(done => {
- window.addEventListener("MozAfterPaint", function listener() {
- window.performance.mark("pending paint");
- done();
- }, { once: true });
- });
- }
- window.performance.measure("pending paints", "pending paints.start");
+ return damp.waitForPendingPaints(window);
}
const openToolbox = async function(tool = "webconsole", onLoad) {
let tab = getActiveTab();
let target = TargetFactory.forTab(tab);
let onToolboxCreated = gDevTools.once("toolbox-created");
let showPromise = gDevTools.showToolbox(target, tool);
let toolbox = await onToolboxCreated;