summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/pageActions/head.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/pageActions/head.js')
-rw-r--r--browser/base/content/test/pageActions/head.js163
1 files changed, 163 insertions, 0 deletions
diff --git a/browser/base/content/test/pageActions/head.js b/browser/base/content/test/pageActions/head.js
new file mode 100644
index 0000000000..15801c490e
--- /dev/null
+++ b/browser/base/content/test/pageActions/head.js
@@ -0,0 +1,163 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ EnterprisePolicyTesting:
+ "resource://testing-common/EnterprisePolicyTesting.sys.mjs",
+ ExtensionCommon: "resource://gre/modules/ExtensionCommon.sys.mjs",
+ PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
+ TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs",
+ sinon: "resource://testing-common/Sinon.sys.mjs",
+});
+
+async function promisePageActionPanelOpen(win = window, eventDict = {}) {
+ await BrowserTestUtils.waitForCondition(() => {
+ // Wait for the main page action button to become visible. It's hidden for
+ // some URIs, so depending on when this is called, it may not yet be quite
+ // visible. It's up to the caller to make sure it will be visible.
+ info("Waiting for main page action button to have non-0 size");
+ let bounds = win.windowUtils.getBoundsWithoutFlushing(
+ win.BrowserPageActions.mainButtonNode
+ );
+ return bounds.width > 0 && bounds.height > 0;
+ });
+
+ // Wait for the panel to become open, by clicking the button if necessary.
+ info("Waiting for main page action panel to be open");
+ if (win.BrowserPageActions.panelNode.state == "open") {
+ return;
+ }
+ let shownPromise = promisePageActionPanelShown(win);
+ EventUtils.synthesizeMouseAtCenter(
+ win.BrowserPageActions.mainButtonNode,
+ eventDict,
+ win
+ );
+ await shownPromise;
+ info("Wait for items in the panel to become visible.");
+ await promisePageActionViewChildrenVisible(
+ win.BrowserPageActions.mainViewNode,
+ win
+ );
+}
+
+function promisePageActionPanelShown(win = window) {
+ return promisePanelShown(win.BrowserPageActions.panelNode, win);
+}
+
+function promisePageActionPanelHidden(win = window) {
+ return promisePanelHidden(win.BrowserPageActions.panelNode, win);
+}
+
+function promisePanelShown(panelIDOrNode, win = window) {
+ return promisePanelEvent(panelIDOrNode, "popupshown", win);
+}
+
+function promisePanelHidden(panelIDOrNode, win = window) {
+ return promisePanelEvent(panelIDOrNode, "popuphidden", win);
+}
+
+function promisePanelEvent(panelIDOrNode, eventType, win = window) {
+ return new Promise(resolve => {
+ let panel = panelIDOrNode;
+ if (typeof panel == "string") {
+ panel = win.document.getElementById(panelIDOrNode);
+ if (!panel) {
+ throw new Error(`Panel with ID "${panelIDOrNode}" does not exist.`);
+ }
+ }
+ if (
+ (eventType == "popupshown" && panel.state == "open") ||
+ (eventType == "popuphidden" && panel.state == "closed")
+ ) {
+ executeSoon(() => resolve(panel));
+ return;
+ }
+ panel.addEventListener(
+ eventType,
+ () => {
+ executeSoon(() => resolve(panel));
+ },
+ { once: true }
+ );
+ });
+}
+
+async function promisePageActionViewChildrenVisible(
+ panelViewNode,
+ win = window
+) {
+ info(
+ "promisePageActionViewChildrenVisible waiting for a child node to be visible"
+ );
+ await new Promise(win.requestAnimationFrame);
+ let dwu = win.windowUtils;
+ return TestUtils.waitForCondition(() => {
+ let bodyNode = panelViewNode.firstElementChild;
+ for (let childNode of bodyNode.children) {
+ let bounds = dwu.getBoundsWithoutFlushing(childNode);
+ if (bounds.width > 0 && bounds.height > 0) {
+ return true;
+ }
+ }
+ return false;
+ });
+}
+
+function promiseAddonUninstalled(addonId) {
+ return new Promise(resolve => {
+ let listener = {};
+ listener.onUninstalled = addon => {
+ if (addon.id == addonId) {
+ AddonManager.removeAddonListener(listener);
+ resolve();
+ }
+ };
+ AddonManager.addAddonListener(listener);
+ });
+}
+
+async function promiseAnimationFrame(win = window) {
+ await new Promise(resolve => win.requestAnimationFrame(resolve));
+ await win.promiseDocumentFlushed(() => {});
+}
+
+async function promisePopupNotShown(id, win = window) {
+ let deferred = PromiseUtils.defer();
+ function listener(e) {
+ deferred.reject("Unexpected popupshown");
+ }
+ let panel = win.document.getElementById(id);
+ panel.addEventListener("popupshown", listener);
+ try {
+ await Promise.race([
+ deferred.promise,
+ new Promise(resolve => {
+ /* eslint-disable mozilla/no-arbitrary-setTimeout */
+ win.setTimeout(resolve, 300);
+ }),
+ ]);
+ } finally {
+ panel.removeEventListener("popupshown", listener);
+ }
+}
+
+// TODO (Bug 1700780): Why is this necessary? Without this trick the test
+// fails intermittently on Ubuntu.
+function promiseStableResize(expectedWidth, win = window) {
+ let deferred = PromiseUtils.defer();
+ let id;
+ function listener() {
+ win.clearTimeout(id);
+ info(`Got resize event: ${win.innerWidth} x ${win.innerHeight}`);
+ if (win.innerWidth <= expectedWidth) {
+ id = win.setTimeout(() => {
+ win.removeEventListener("resize", listener);
+ deferred.resolve();
+ }, 100);
+ }
+ }
+ win.addEventListener("resize", listener);
+ win.resizeTo(expectedWidth, win.outerHeight);
+ return deferred.promise;
+}