browser_bug422543.js (7837B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 const ACTOR = "Bug422543"; 5 6 let getActor = browser => { 7 return browser.browsingContext.currentWindowGlobal.getActor(ACTOR); 8 }; 9 10 add_setup(async function () { 11 await SpecialPowers.pushPrefEnv({ 12 set: [["test.wait300msAfterTabSwitch", true]], 13 }); 14 }); 15 16 add_task(async function runTests() { 17 if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { 18 await setupAsync(); 19 let browser = gBrowser.selectedBrowser; 20 // Now that we're set up, initialize our frame script. 21 await checkListenersAsync("initial", "listeners initialized"); 22 23 // Check if all history listeners are always notified. 24 info("# part 1"); 25 await whenPageShown(browser, () => 26 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 27 BrowserTestUtils.startLoadingURIString(browser, "http://www.example.com/") 28 ); 29 await checkListenersAsync("newentry", "shistory has a new entry"); 30 ok(browser.canGoBackIgnoringUserInteraction, "we can go back"); 31 32 await whenPageShown(browser, () => browser.goBack()); 33 await checkListenersAsync("gotoindex", "back to the first shentry"); 34 ok(browser.canGoForward, "we can go forward"); 35 36 await whenPageShown(browser, () => browser.goForward()); 37 await checkListenersAsync("gotoindex", "forward to the second shentry"); 38 39 await whenPageShown(browser, () => browser.reload()); 40 await checkListenersAsync("reload", "current shentry reloaded"); 41 42 await whenPageShown(browser, () => browser.gotoIndex(0)); 43 await checkListenersAsync("gotoindex", "back to the first index"); 44 45 // Check nsISHistory.notifyOnHistoryReload 46 info("# part 2"); 47 ok(await notifyReloadAsync(), "reloading has not been canceled"); 48 await checkListenersAsync("reload", "saw the reload notification"); 49 50 // Let the first listener cancel the reload action. 51 info("# part 3"); 52 await resetListenersAsync(); 53 await setListenerRetvalAsync(0, false); 54 ok(!(await notifyReloadAsync()), "reloading has been canceled"); 55 await checkListenersAsync("reload", "saw the reload notification"); 56 57 // Let both listeners cancel the reload action. 58 info("# part 4"); 59 await resetListenersAsync(); 60 await setListenerRetvalAsync(1, false); 61 ok(!(await notifyReloadAsync()), "reloading has been canceled"); 62 await checkListenersAsync("reload", "saw the reload notification"); 63 64 // Let the second listener cancel the reload action. 65 info("# part 5"); 66 await resetListenersAsync(); 67 await setListenerRetvalAsync(0, true); 68 ok(!(await notifyReloadAsync()), "reloading has been canceled"); 69 await checkListenersAsync("reload", "saw the reload notification"); 70 71 function sendQuery(message, arg = {}) { 72 return getActor(gBrowser.selectedBrowser).sendQuery(message, arg); 73 } 74 75 function checkListenersAsync(aLast, aMessage) { 76 return sendQuery("getListenerStatus").then(listenerStatuses => { 77 is(listenerStatuses[0], aLast, aMessage); 78 is(listenerStatuses[1], aLast, aMessage); 79 }); 80 } 81 82 function resetListenersAsync() { 83 return sendQuery("resetListeners"); 84 } 85 86 function notifyReloadAsync() { 87 return sendQuery("notifyReload").then(({ rval }) => { 88 return rval; 89 }); 90 } 91 92 function setListenerRetvalAsync(num, val) { 93 return sendQuery("setRetval", { num, val }); 94 } 95 96 async function setupAsync() { 97 let tab = await BrowserTestUtils.openNewForegroundTab( 98 gBrowser, 99 "http://mochi.test:8888" 100 ); 101 102 let base = getRootDirectory(gTestPath).slice(0, -1); 103 ChromeUtils.registerWindowActor(ACTOR, { 104 child: { 105 esModuleURI: `${base}/Bug422543Child.sys.mjs`, 106 }, 107 }); 108 109 registerCleanupFunction(async () => { 110 await sendQuery("cleanup"); 111 gBrowser.removeTab(tab); 112 113 ChromeUtils.unregisterWindowActor(ACTOR); 114 }); 115 116 await sendQuery("init"); 117 } 118 return; 119 } 120 121 await setup(); 122 let browser = gBrowser.selectedBrowser; 123 // Now that we're set up, initialize our frame script. 124 checkListeners("initial", "listeners initialized"); 125 126 // Check if all history listeners are always notified. 127 info("# part 1"); 128 await whenPageShown(browser, () => 129 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 130 BrowserTestUtils.startLoadingURIString(browser, "http://www.example.com/") 131 ); 132 checkListeners("newentry", "shistory has a new entry"); 133 ok(browser.canGoBackIgnoringUserInteraction, "we can go back"); 134 135 await whenPageShown(browser, () => browser.goBack()); 136 checkListeners("gotoindex", "back to the first shentry"); 137 ok(browser.canGoForward, "we can go forward"); 138 139 await whenPageShown(browser, () => browser.goForward()); 140 checkListeners("gotoindex", "forward to the second shentry"); 141 142 await whenPageShown(browser, () => browser.reload()); 143 checkListeners("reload", "current shentry reloaded"); 144 145 await whenPageShown(browser, () => browser.gotoIndex(0)); 146 checkListeners("gotoindex", "back to the first index"); 147 148 // Check nsISHistory.notifyOnHistoryReload 149 info("# part 2"); 150 ok(notifyReload(browser), "reloading has not been canceled"); 151 checkListeners("reload", "saw the reload notification"); 152 153 // Let the first listener cancel the reload action. 154 info("# part 3"); 155 resetListeners(); 156 setListenerRetval(0, false); 157 ok(!notifyReload(browser), "reloading has been canceled"); 158 checkListeners("reload", "saw the reload notification"); 159 160 // Let both listeners cancel the reload action. 161 info("# part 4"); 162 resetListeners(); 163 setListenerRetval(1, false); 164 ok(!notifyReload(browser), "reloading has been canceled"); 165 checkListeners("reload", "saw the reload notification"); 166 167 // Let the second listener cancel the reload action. 168 info("# part 5"); 169 resetListeners(); 170 setListenerRetval(0, true); 171 ok(!notifyReload(browser), "reloading has been canceled"); 172 checkListeners("reload", "saw the reload notification"); 173 }); 174 175 class SHistoryListener { 176 constructor() { 177 this.retval = true; 178 this.last = "initial"; 179 } 180 181 OnHistoryNewEntry() { 182 this.last = "newentry"; 183 } 184 185 OnHistoryGotoIndex() { 186 this.last = "gotoindex"; 187 } 188 189 OnHistoryPurge() { 190 this.last = "purge"; 191 } 192 193 OnHistoryReload() { 194 this.last = "reload"; 195 return this.retval; 196 } 197 198 OnHistoryReplaceEntry() {} 199 } 200 SHistoryListener.prototype.QueryInterface = ChromeUtils.generateQI([ 201 "nsISHistoryListener", 202 "nsISupportsWeakReference", 203 ]); 204 205 let listeners = [new SHistoryListener(), new SHistoryListener()]; 206 207 function checkListeners(aLast, aMessage) { 208 is(listeners[0].last, aLast, aMessage); 209 is(listeners[1].last, aLast, aMessage); 210 } 211 212 function resetListeners() { 213 for (let listener of listeners) { 214 listener.last = "initial"; 215 } 216 } 217 218 function notifyReload(browser) { 219 return browser.browsingContext.sessionHistory.notifyOnHistoryReload(); 220 } 221 222 function setListenerRetval(num, val) { 223 listeners[num].retval = val; 224 } 225 226 async function setup() { 227 let tab = await BrowserTestUtils.openNewForegroundTab( 228 gBrowser, 229 "http://mochi.test:8888" 230 ); 231 232 let browser = tab.linkedBrowser; 233 registerCleanupFunction(async function () { 234 for (let listener of listeners) { 235 browser.browsingContext.sessionHistory.removeSHistoryListener(listener); 236 } 237 gBrowser.removeTab(tab); 238 }); 239 for (let listener of listeners) { 240 browser.browsingContext.sessionHistory.addSHistoryListener(listener); 241 } 242 } 243 244 function whenPageShown(aBrowser, aNavigation) { 245 let promise = new Promise(resolve => { 246 let unregister = BrowserTestUtils.addContentEventListener( 247 aBrowser, 248 "pageshow", 249 () => { 250 unregister(); 251 resolve(); 252 }, 253 { capture: true } 254 ); 255 }); 256 257 aNavigation(); 258 return promise; 259 }