diff options
Diffstat (limited to '')
-rw-r--r-- | layout/tools/reftest/api.js | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/layout/tools/reftest/api.js b/layout/tools/reftest/api.js new file mode 100644 index 0000000000..bfb04e7b3f --- /dev/null +++ b/layout/tools/reftest/api.js @@ -0,0 +1,155 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const Cm = Components.manager; + +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); +var OnRefTestLoad, OnRefTestUnload; + +XPCOMUtils.defineLazyServiceGetter( + this, + "resProto", + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler" +); + +XPCOMUtils.defineLazyServiceGetter( + this, + "aomStartup", + "@mozilla.org/addons/addon-manager-startup;1", + "amIAddonManagerStartup" +); + +function processTerminated() { + return new Promise(resolve => { + Services.obs.addObserver(function observe(subject, topic) { + if (topic == "ipc:content-shutdown") { + Services.obs.removeObserver(observe, topic); + resolve(); + } + }, "ipc:content-shutdown"); + }); +} + +function startAndroid(win) { + // Add setTimeout here because windows.innerWidth/Height are not set yet. + win.setTimeout(function() { + OnRefTestLoad(win); + }, 0); +} + +function GetMainWindow() { + let win = Services.wm.getMostRecentWindow("navigator:browser"); + if (!win) { + // There is no navigator:browser in the geckoview TestRunnerActivity; + // try navigator.geckoview instead. + win = Services.wm.getMostRecentWindow("navigator:geckoview"); + } + return win; +} + +this.reftest = class extends ExtensionAPI { + onStartup() { + let uri = Services.io.newURI( + "chrome/reftest/res/", + null, + this.extension.rootURI + ); + resProto.setSubstitutionWithFlags( + "reftest", + uri, + resProto.ALLOW_CONTENT_ACCESS + ); + + const manifestURI = Services.io.newURI( + "manifest.json", + null, + this.extension.rootURI + ); + this.chromeHandle = aomStartup.registerChrome(manifestURI, [ + [ + "content", + "reftest", + "chrome/reftest/content/", + "contentaccessible=yes", + ], + ]); + + // Starting tests is handled quite differently on android and desktop. + // On Android, OnRefTestLoad() takes over the main browser window so + // we just need to call it as soon as the browser window is available. + // On desktop, a separate window (dummy) is created and explicitly given + // focus (see bug 859339 for details), then tests are launched in a new + // top-level window. + let win = GetMainWindow(); + if (Services.appinfo.OS == "Android") { + ({ OnRefTestLoad, OnRefTestUnload } = ChromeUtils.import( + "resource://reftest/reftest.jsm" + )); + if (win) { + startAndroid(win); + } else { + // The window type parameter is only available once the window's document + // element has been created. The main window has already been created + // however and it is in an in-between state which means that you can't + // find it by its type nor will domwindowcreated be fired. + // So we listen to either initial-document-element-inserted which + // indicates when it's okay to search for the main window by type again. + Services.obs.addObserver(function observer(aSubject, aTopic, aData) { + Services.obs.removeObserver(observer, aTopic); + startAndroid(GetMainWindow()); + }, "initial-document-element-inserted"); + } + return; + } + + Services.io.manageOfflineStatus = false; + Services.io.offline = false; + + let dummy = Services.ww.openWindow( + null, + "about:blank", + "dummy", + "chrome,dialog=no,left=800,height=200,width=200,all", + null + ); + dummy.onload = async function() { + // Close pre-existing window + win.close(); + + const { PerTestCoverageUtils } = ChromeUtils.import( + "resource://reftest/PerTestCoverageUtils.jsm" + ); + if (PerTestCoverageUtils.enabled) { + // In PerTestCoverage mode, wait for the process belonging to the window we just closed + // to be terminated, to avoid its shutdown interfering when we reset the counters. + await processTerminated(); + } + + dummy.focus(); + Services.ww.openWindow( + null, + "chrome://reftest/content/reftest.xhtml", + "_blank", + "chrome,dialog=no,all", + {} + ); + }; + } + + onShutdown() { + resProto.setSubstitution("reftest", null); + + this.chromeHandle.destruct(); + this.chromeHandle = null; + + if (Services.appinfo.OS == "Android") { + OnRefTestUnload(); + Cu.unload("resource://reftest/reftest.jsm"); + } + } +}; |