319 lines
8.5 KiB
JavaScript
319 lines
8.5 KiB
JavaScript
ChromeUtils.defineESModuleGetters(this, {
|
|
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
|
|
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
|
|
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
|
TabCrashHandler: "resource:///modules/ContentCrashHandlers.sys.mjs",
|
|
});
|
|
|
|
/**
|
|
* Wait for a <notification> to be closed then call the specified callback.
|
|
*/
|
|
function waitForNotificationClose(notification, cb) {
|
|
let observer = new MutationObserver(function onMutatations(mutations) {
|
|
for (let mutation of mutations) {
|
|
for (let i = 0; i < mutation.removedNodes.length; i++) {
|
|
let node = mutation.removedNodes.item(i);
|
|
if (node != notification) {
|
|
continue;
|
|
}
|
|
observer.disconnect();
|
|
cb();
|
|
}
|
|
}
|
|
});
|
|
observer.observe(notification.control.stack, { childList: true });
|
|
}
|
|
|
|
function closeAllNotifications() {
|
|
if (!gNotificationBox.currentNotification) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
return new Promise(resolve => {
|
|
for (let notification of gNotificationBox.allNotifications) {
|
|
waitForNotificationClose(notification, function () {
|
|
if (gNotificationBox.allNotifications.length === 0) {
|
|
resolve();
|
|
}
|
|
});
|
|
notification.close();
|
|
}
|
|
});
|
|
}
|
|
|
|
function whenDelayedStartupFinished(aWindow, aCallback) {
|
|
Services.obs.addObserver(function observer(aSubject, aTopic) {
|
|
if (aWindow == aSubject) {
|
|
Services.obs.removeObserver(observer, aTopic);
|
|
executeSoon(aCallback);
|
|
}
|
|
}, "browser-delayed-startup-finished");
|
|
}
|
|
|
|
function openToolbarCustomizationUI(aCallback, aBrowserWin) {
|
|
if (!aBrowserWin) {
|
|
aBrowserWin = window;
|
|
}
|
|
|
|
aBrowserWin.gCustomizeMode.enter();
|
|
|
|
aBrowserWin.gNavToolbox.addEventListener(
|
|
"customizationready",
|
|
function () {
|
|
executeSoon(function () {
|
|
aCallback(aBrowserWin);
|
|
});
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
|
|
function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
|
|
aBrowserWin.gNavToolbox.addEventListener(
|
|
"aftercustomization",
|
|
function () {
|
|
executeSoon(aCallback);
|
|
},
|
|
{ once: true }
|
|
);
|
|
|
|
aBrowserWin.gCustomizeMode.exit();
|
|
}
|
|
|
|
function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
|
|
retryTimes = typeof retryTimes !== "undefined" ? retryTimes : 30;
|
|
var tries = 0;
|
|
var interval = setInterval(function () {
|
|
if (tries >= retryTimes) {
|
|
ok(false, errorMsg);
|
|
moveOn();
|
|
}
|
|
var conditionPassed;
|
|
try {
|
|
conditionPassed = condition();
|
|
} catch (e) {
|
|
ok(false, e + "\n" + e.stack);
|
|
conditionPassed = false;
|
|
}
|
|
if (conditionPassed) {
|
|
moveOn();
|
|
}
|
|
tries++;
|
|
}, 100);
|
|
var moveOn = function () {
|
|
clearInterval(interval);
|
|
nextTest();
|
|
};
|
|
}
|
|
|
|
function promiseWaitForCondition(aConditionFn) {
|
|
return new Promise(resolve => {
|
|
waitForCondition(aConditionFn, resolve, "Condition didn't pass.");
|
|
});
|
|
}
|
|
|
|
function promiseWaitForEvent(
|
|
object,
|
|
eventName,
|
|
capturing = false,
|
|
chrome = false
|
|
) {
|
|
return new Promise(resolve => {
|
|
function listener(event) {
|
|
info("Saw " + eventName);
|
|
object.removeEventListener(eventName, listener, capturing, chrome);
|
|
resolve(event);
|
|
}
|
|
|
|
info("Waiting for " + eventName);
|
|
object.addEventListener(eventName, listener, capturing, chrome);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Allows setting focus on a window, and waiting for that window to achieve
|
|
* focus.
|
|
*
|
|
* @param aWindow
|
|
* The window to focus and wait for.
|
|
*
|
|
* @return {Promise}
|
|
* @resolves When the window is focused.
|
|
* @rejects Never.
|
|
*/
|
|
function promiseWaitForFocus(aWindow) {
|
|
return new Promise(resolve => {
|
|
waitForFocus(resolve, aWindow);
|
|
});
|
|
}
|
|
|
|
function pushPrefs(...aPrefs) {
|
|
return SpecialPowers.pushPrefEnv({ set: aPrefs });
|
|
}
|
|
|
|
function popPrefs() {
|
|
return SpecialPowers.popPrefEnv();
|
|
}
|
|
|
|
function promiseWindowClosed(win) {
|
|
let promise = BrowserTestUtils.domWindowClosed(win);
|
|
win.close();
|
|
return promise;
|
|
}
|
|
|
|
async function whenNewTabLoaded(aWindow, aCallback) {
|
|
aWindow.BrowserCommands.openTab();
|
|
|
|
let expectedURL = AboutNewTab.newTabURL;
|
|
let browser = aWindow.gBrowser.selectedBrowser;
|
|
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, expectedURL);
|
|
let alreadyLoaded = await SpecialPowers.spawn(browser, [expectedURL], url => {
|
|
let doc = content.document;
|
|
return doc && doc.readyState === "complete" && doc.location.href == url;
|
|
});
|
|
if (!alreadyLoaded) {
|
|
await loadPromise;
|
|
}
|
|
aCallback();
|
|
}
|
|
|
|
function whenTabLoaded(aTab, aCallback) {
|
|
promiseTabLoadEvent(aTab).then(aCallback);
|
|
}
|
|
|
|
function promiseTabLoaded(aTab) {
|
|
return new Promise(resolve => {
|
|
whenTabLoaded(aTab, resolve);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Waits for a load (or custom) event to finish in a given tab. If provided
|
|
* load an uri into the tab.
|
|
*
|
|
* @param tab
|
|
* The tab to load into.
|
|
* @param [optional] url
|
|
* The url to load, or the current url.
|
|
* @return {Promise} resolved when the event is handled.
|
|
* @resolves to the received event
|
|
* @rejects if a valid load event is not received within a meaningful interval
|
|
*/
|
|
function promiseTabLoadEvent(tab, url) {
|
|
info("Wait tab event: load");
|
|
|
|
function handle(loadedUrl) {
|
|
if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
|
|
info(`Skipping spurious load event for ${loadedUrl}`);
|
|
return false;
|
|
}
|
|
|
|
info("Tab event received: load");
|
|
return true;
|
|
}
|
|
|
|
let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
|
|
|
|
if (url) {
|
|
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url);
|
|
}
|
|
|
|
return loaded;
|
|
}
|
|
|
|
function is_hidden(element) {
|
|
var style = element.ownerGlobal.getComputedStyle(element);
|
|
if (style.display == "none") {
|
|
return true;
|
|
}
|
|
if (style.visibility != "visible") {
|
|
return true;
|
|
}
|
|
if (XULPopupElement.isInstance(element)) {
|
|
return ["hiding", "closed"].includes(element.state);
|
|
}
|
|
|
|
// Hiding a parent element will hide all its children
|
|
if (element.parentNode != element.ownerDocument) {
|
|
return is_hidden(element.parentNode);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function is_element_visible(element, msg) {
|
|
isnot(element, null, "Element should not be null, when checking visibility");
|
|
ok(BrowserTestUtils.isVisible(element), msg || "Element should be visible");
|
|
}
|
|
|
|
function is_element_hidden(element, msg) {
|
|
isnot(element, null, "Element should not be null, when checking visibility");
|
|
ok(is_hidden(element), msg || "Element should be hidden");
|
|
}
|
|
|
|
function promisePopupShown(popup) {
|
|
return BrowserTestUtils.waitForPopupEvent(popup, "shown");
|
|
}
|
|
|
|
function promisePopupHidden(popup) {
|
|
return BrowserTestUtils.waitForPopupEvent(popup, "hidden");
|
|
}
|
|
|
|
function promiseNotificationShown(notification) {
|
|
let win = notification.browser.ownerGlobal;
|
|
if (win.PopupNotifications.panel.state == "open") {
|
|
return Promise.resolve();
|
|
}
|
|
let panelPromise = promisePopupShown(win.PopupNotifications.panel);
|
|
notification.reshow();
|
|
return panelPromise;
|
|
}
|
|
|
|
/**
|
|
* Resolves when a bookmark with the given uri is added.
|
|
*/
|
|
function promiseOnBookmarkItemAdded(aExpectedURI) {
|
|
return new Promise((resolve, reject) => {
|
|
let listener = events => {
|
|
is(events.length, 1, "Should only receive one event.");
|
|
info("Added a bookmark to " + events[0].url);
|
|
PlacesUtils.observers.removeListener(["bookmark-added"], listener);
|
|
if (events[0].url == aExpectedURI.spec) {
|
|
resolve();
|
|
} else {
|
|
reject(new Error("Added an unexpected bookmark"));
|
|
}
|
|
};
|
|
info("Waiting for a bookmark to be added");
|
|
PlacesUtils.observers.addListener(["bookmark-added"], listener);
|
|
});
|
|
}
|
|
|
|
async function loadBadCertPage(url, feltPrivacy = false) {
|
|
let loaded = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser);
|
|
BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url);
|
|
await loaded;
|
|
|
|
await SpecialPowers.spawn(
|
|
gBrowser.selectedBrowser,
|
|
[feltPrivacy],
|
|
async isFeltPrivacy => {
|
|
if (isFeltPrivacy) {
|
|
let netErrorCard =
|
|
content.document.querySelector("net-error-card").wrappedJSObject;
|
|
await netErrorCard.getUpdateComplete();
|
|
netErrorCard.advancedButton.click();
|
|
await ContentTaskUtils.waitForCondition(() => {
|
|
return (
|
|
netErrorCard.exceptionButton &&
|
|
!netErrorCard.exceptionButton.disabled
|
|
);
|
|
}, "Waiting for exception button");
|
|
netErrorCard.exceptionButton.click();
|
|
} else {
|
|
content.document.getElementById("exceptionDialogButton").click();
|
|
}
|
|
}
|
|
);
|
|
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
|
}
|