summaryrefslogtreecommitdiffstats
path: root/layout/tools/reftest/api.js
diff options
context:
space:
mode:
Diffstat (limited to 'layout/tools/reftest/api.js')
-rw-r--r--layout/tools/reftest/api.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/layout/tools/reftest/api.js b/layout/tools/reftest/api.js
new file mode 100644
index 0000000000..a0f20a77ad
--- /dev/null
+++ b/layout/tools/reftest/api.js
@@ -0,0 +1,163 @@
+/* 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");
+ }
+ }
+};