head.js (4525B)
1 ChromeUtils.defineESModuleGetters(this, { 2 PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs", 3 }); 4 5 // Various tests in this directory may define gTestBrowser, to use as the 6 // default browser under test in some of the functions below. 7 /* global gTestBrowser:true */ 8 9 /** 10 * Waits a specified number of miliseconds. 11 * 12 * Usage: 13 * let wait = yield waitForMs(2000); 14 * ok(wait, "2 seconds should now have elapsed"); 15 * 16 * @param aMs the number of miliseconds to wait for 17 * @returns a Promise that resolves to true after the time has elapsed 18 */ 19 function waitForMs(aMs) { 20 return new Promise(resolve => { 21 setTimeout(done, aMs); 22 function done() { 23 resolve(true); 24 } 25 }); 26 } 27 28 function waitForCondition(condition, nextTest, errorMsg, aTries, aWait) { 29 let tries = 0; 30 let maxTries = aTries || 100; // 100 tries 31 let maxWait = aWait || 100; // 100 msec x 100 tries = ten seconds 32 let interval = setInterval(function () { 33 if (tries >= maxTries) { 34 ok(false, errorMsg); 35 moveOn(); 36 } 37 let conditionPassed; 38 try { 39 conditionPassed = condition(); 40 } catch (e) { 41 ok(false, e + "\n" + e.stack); 42 conditionPassed = false; 43 } 44 if (conditionPassed) { 45 moveOn(); 46 } 47 tries++; 48 }, maxWait); 49 let moveOn = function () { 50 clearInterval(interval); 51 nextTest(); 52 }; 53 } 54 55 // Waits for a conditional function defined by the caller to return true. 56 function promiseForCondition(aConditionFn, aMessage, aTries, aWait) { 57 return new Promise(resolve => { 58 waitForCondition( 59 aConditionFn, 60 resolve, 61 aMessage || "Condition didn't pass.", 62 aTries, 63 aWait 64 ); 65 }); 66 } 67 68 // Returns a promise for nsIObjectLoadingContent props data. 69 function promiseForPluginInfo(aId, aBrowser) { 70 let browser = aBrowser || gTestBrowser; 71 return SpecialPowers.spawn(browser, [aId], async function (contentId) { 72 let plugin = content.document.getElementById(contentId); 73 if (!(plugin instanceof Ci.nsIObjectLoadingContent)) { 74 throw new Error("no plugin found"); 75 } 76 return { 77 activated: plugin.activated, 78 hasRunningPlugin: plugin.hasRunningPlugin, 79 displayedType: plugin.displayedType, 80 }; 81 }); 82 } 83 84 /** 85 * Allows setting focus on a window, and waiting for that window to achieve 86 * focus. 87 * 88 * @param aWindow 89 * The window to focus and wait for. 90 * 91 * @returns {Promise<void>} 92 * Resolved when the window is focused. 93 */ 94 function promiseWaitForFocus(aWindow) { 95 return new Promise(resolve => { 96 waitForFocus(resolve, aWindow); 97 }); 98 } 99 100 /** 101 * Returns a Promise that resolves when a notification bar 102 * for a browser is shown. Alternatively, for old-style callers, 103 * can automatically call a callback before it resolves. 104 * 105 * @param notificationID 106 * The ID of the notification to look for. 107 * @param browser 108 * The browser to check for the notification bar. 109 * @param callback (optional) 110 * A function to be called just before the Promise resolves. 111 * 112 * @return Promise 113 */ 114 function waitForNotificationBar(notificationID, browser, callback) { 115 return new Promise(resolve => { 116 let notification; 117 let notificationBox = gBrowser.getNotificationBox(browser); 118 waitForCondition( 119 () => 120 (notification = 121 notificationBox.getNotificationWithValue(notificationID)), 122 () => { 123 ok( 124 notification, 125 `Successfully got the ${notificationID} notification bar` 126 ); 127 if (callback) { 128 callback(notification); 129 } 130 resolve(notification); 131 }, 132 `Waited too long for the ${notificationID} notification bar` 133 ); 134 }); 135 } 136 137 function promiseForNotificationBar(notificationID, browser) { 138 return new Promise(resolve => { 139 waitForNotificationBar(notificationID, browser, resolve); 140 }); 141 } 142 143 /** 144 * Reshow a notification and call a callback when it is reshown. 145 * 146 * @param notification 147 * The notification to reshow 148 * @param callback 149 * A function to be called when the notification has been reshown 150 */ 151 function waitForNotificationShown(notification, callback) { 152 if (PopupNotifications.panel.state == "open") { 153 executeSoon(callback); 154 return; 155 } 156 PopupNotifications.panel.addEventListener( 157 "popupshown", 158 function () { 159 callback(); 160 }, 161 { once: true } 162 ); 163 notification.reshow(); 164 } 165 166 function promiseForNotificationShown(notification) { 167 return new Promise(resolve => { 168 waitForNotificationShown(notification, resolve); 169 }); 170 }