210 lines
5.5 KiB
JavaScript
210 lines
5.5 KiB
JavaScript
var { XPCOMUtils } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
|
);
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
|
PromiseUtils: "resource://gre/modules/PromiseUtils.sys.mjs",
|
|
});
|
|
|
|
// Various tests in this directory may define gTestBrowser, to use as the
|
|
// default browser under test in some of the functions below.
|
|
/* global gTestBrowser:true */
|
|
|
|
/**
|
|
* Waits a specified number of miliseconds.
|
|
*
|
|
* Usage:
|
|
* let wait = yield waitForMs(2000);
|
|
* ok(wait, "2 seconds should now have elapsed");
|
|
*
|
|
* @param aMs the number of miliseconds to wait for
|
|
* @returns a Promise that resolves to true after the time has elapsed
|
|
*/
|
|
function waitForMs(aMs) {
|
|
return new Promise(resolve => {
|
|
setTimeout(done, aMs);
|
|
function done() {
|
|
resolve(true);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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.loadURI(tab.linkedBrowser, url);
|
|
}
|
|
|
|
return loaded;
|
|
}
|
|
|
|
function waitForCondition(condition, nextTest, errorMsg, aTries, aWait) {
|
|
let tries = 0;
|
|
let maxTries = aTries || 100; // 100 tries
|
|
let maxWait = aWait || 100; // 100 msec x 100 tries = ten seconds
|
|
let interval = setInterval(function() {
|
|
if (tries >= maxTries) {
|
|
ok(false, errorMsg);
|
|
moveOn();
|
|
}
|
|
let conditionPassed;
|
|
try {
|
|
conditionPassed = condition();
|
|
} catch (e) {
|
|
ok(false, e + "\n" + e.stack);
|
|
conditionPassed = false;
|
|
}
|
|
if (conditionPassed) {
|
|
moveOn();
|
|
}
|
|
tries++;
|
|
}, maxWait);
|
|
let moveOn = function() {
|
|
clearInterval(interval);
|
|
nextTest();
|
|
};
|
|
}
|
|
|
|
// Waits for a conditional function defined by the caller to return true.
|
|
function promiseForCondition(aConditionFn, aMessage, aTries, aWait) {
|
|
return new Promise(resolve => {
|
|
waitForCondition(
|
|
aConditionFn,
|
|
resolve,
|
|
aMessage || "Condition didn't pass.",
|
|
aTries,
|
|
aWait
|
|
);
|
|
});
|
|
}
|
|
|
|
// Returns a promise for nsIObjectLoadingContent props data.
|
|
function promiseForPluginInfo(aId, aBrowser) {
|
|
let browser = aBrowser || gTestBrowser;
|
|
return SpecialPowers.spawn(browser, [aId], async function(contentId) {
|
|
let plugin = content.document.getElementById(contentId);
|
|
if (!(plugin instanceof Ci.nsIObjectLoadingContent)) {
|
|
throw new Error("no plugin found");
|
|
}
|
|
return {
|
|
activated: plugin.activated,
|
|
hasRunningPlugin: plugin.hasRunningPlugin,
|
|
displayedType: plugin.displayedType,
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns a Promise that resolves when a notification bar
|
|
* for a browser is shown. Alternatively, for old-style callers,
|
|
* can automatically call a callback before it resolves.
|
|
*
|
|
* @param notificationID
|
|
* The ID of the notification to look for.
|
|
* @param browser
|
|
* The browser to check for the notification bar.
|
|
* @param callback (optional)
|
|
* A function to be called just before the Promise resolves.
|
|
*
|
|
* @return Promise
|
|
*/
|
|
function waitForNotificationBar(notificationID, browser, callback) {
|
|
return new Promise((resolve, reject) => {
|
|
let notification;
|
|
let notificationBox = gBrowser.getNotificationBox(browser);
|
|
waitForCondition(
|
|
() =>
|
|
(notification = notificationBox.getNotificationWithValue(
|
|
notificationID
|
|
)),
|
|
() => {
|
|
ok(
|
|
notification,
|
|
`Successfully got the ${notificationID} notification bar`
|
|
);
|
|
if (callback) {
|
|
callback(notification);
|
|
}
|
|
resolve(notification);
|
|
},
|
|
`Waited too long for the ${notificationID} notification bar`
|
|
);
|
|
});
|
|
}
|
|
|
|
function promiseForNotificationBar(notificationID, browser) {
|
|
return new Promise(resolve => {
|
|
waitForNotificationBar(notificationID, browser, resolve);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reshow a notification and call a callback when it is reshown.
|
|
* @param notification
|
|
* The notification to reshow
|
|
* @param callback
|
|
* A function to be called when the notification has been reshown
|
|
*/
|
|
function waitForNotificationShown(notification, callback) {
|
|
if (PopupNotifications.panel.state == "open") {
|
|
executeSoon(callback);
|
|
return;
|
|
}
|
|
PopupNotifications.panel.addEventListener(
|
|
"popupshown",
|
|
function(e) {
|
|
callback();
|
|
},
|
|
{ once: true }
|
|
);
|
|
notification.reshow();
|
|
}
|
|
|
|
function promiseForNotificationShown(notification) {
|
|
return new Promise(resolve => {
|
|
waitForNotificationShown(notification, resolve);
|
|
});
|
|
}
|