Source code

Revision control

Copy as Markdown

Other Tools

ChromeUtils.defineESModuleGetters(this, {
PlacesUtils: "resource://gre/modules/PlacesUtils.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.startLoadingURIString(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 => {
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 () {
callback();
},
{ once: true }
);
notification.reshow();
}
function promiseForNotificationShown(notification) {
return new Promise(resolve => {
waitForNotificationShown(notification, resolve);
});
}