Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); 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", false); } function findChromeWindowByURI(aURI) { let windows = Services.wm.getEnumerator(null); while (windows.hasMoreElements()) { let win = windows.getNext(); if (win.location.href == aURI) return win; } return null; } function waitForCondition(condition, nextTest, errorMsg) { var tries = 0; var interval = setInterval(function() { if (tries >= 30) { 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 getTestPlugin(aName) { var pluginName = aName || "Test Plug-in"; var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); var tags = ph.getPluginTags(); // Find the test plugin for (var i = 0; i < tags.length; i++) { if (tags[i].name == pluginName) return tags[i]; } ok(false, "Unable to find plugin"); return null; } // call this to set the test plugin(s) initially expected enabled state. // it will automatically be reset to it's previous value after the test // ends function setTestPluginEnabledState(newEnabledState, pluginName) { var plugin = getTestPlugin(pluginName); var oldEnabledState = plugin.enabledState; plugin.enabledState = newEnabledState; SimpleTest.registerCleanupFunction(function() { getTestPlugin(pluginName).enabledState = oldEnabledState; }); } // after a test is done using the plugin doorhanger, we should just clear // any permissions that may have crept in function clearAllPluginPermissions() { let perms = Services.perms.enumerator; while (perms.hasMoreElements()) { let perm = perms.getNext(); if (perm.type.startsWith('plugin')) { Services.perms.remove(perm.host, perm.type); } } } function updateBlocklist(aCallback) { var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"] .getService(Ci.nsITimerCallback); var observer = function() { Services.obs.removeObserver(observer, "blocklist-updated"); SimpleTest.executeSoon(aCallback); }; Services.obs.addObserver(observer, "blocklist-updated", false); blocklistNotifier.notify(null); } var _originalTestBlocklistURL = null; function setAndUpdateBlocklist(aURL, aCallback) { if (!_originalTestBlocklistURL) _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url"); Services.prefs.setCharPref("extensions.blocklist.url", aURL); updateBlocklist(aCallback); } function resetBlocklist() { Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL); } function waitForNotificationPopup(notificationID, browser, callback) { let notification; waitForCondition( () => (notification = PopupNotifications.getNotification(notificationID, browser)), () => { ok(notification, `Successfully got the ${notificationID} notification popup`); callback(notification); }, `Waited too long for the ${notificationID} notification popup` ); } /** * 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` ); }); } /** * 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 onShown(e) { PopupNotifications.panel.removeEventListener("popupshown", onShown); callback(); }, false); notification.reshow(); } /** * Due to layout being async, "PluginBindAttached" may trigger later. * This returns a Promise that resolves once we've forced a layout * flush, which triggers the PluginBindAttached event to fire. * * @param browser * The browser to force plugin bindings in. * * @return Promise */ function forcePluginBindingAttached(browser) { return new Promise((resolve, reject) => { let doc = browser.contentDocument; let elems = doc.getElementsByTagName('embed'); if (elems.length < 1) { elems = doc.getElementsByTagName('object'); } elems[0].clientTop; executeSoon(resolve); }); } /** * Loads a page in a browser, and returns a Promise that * resolves once the "load" event has been fired for that * browser. * * @param browser * The browser to load the page in. * @param uri * The URI to load. * * @return Promise */ function loadPage(browser, uri) { return new Promise((resolve, reject) => { browser.addEventListener("load", function onLoad(event) { browser.removeEventListener("load", onLoad, true); resolve(); }, true); browser.loadURI(uri); }); }