/* 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; 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 ); let manifestDirectives = [ [ "content", "reftest", "chrome/reftest/content/", "contentaccessible=yes", ], ]; if (Services.appinfo.OS == "Android") { manifestDirectives.push([ "override", "chrome://global/skin/global.css", "chrome://reftest/content/fake-global.css", ]); } this.chromeHandle = aomStartup.registerChrome( manifestURI, manifestDirectives ); // 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.importESModule( "resource://reftest/PerTestCoverageUtils.sys.mjs" ); 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"); } } };