diff options
Diffstat (limited to 'browser/base/content/test/pageActions/head.js')
-rw-r--r-- | browser/base/content/test/pageActions/head.js | 163 |
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; +} |