browser_broadcast.js (4536B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const INITIAL_VALUE = "browser_broadcast.js-initial-value-" + Date.now(); 7 8 /** 9 * This test ensures we won't lose tab data queued in the content script when 10 * closing a tab. 11 */ 12 add_task(async function flush_on_tabclose() { 13 let tab = await createTabWithStorageData(["http://example.com/"]); 14 let browser = tab.linkedBrowser; 15 16 await modifySessionStorage(browser, { test: "on-tab-close" }); 17 await TabStateFlusher.flush(browser); 18 await promiseRemoveTabAndSessionState(tab); 19 20 let [ 21 { 22 state: { storage }, 23 }, 24 ] = ss.getClosedTabDataForWindow(window); 25 is( 26 storage["http://example.com"].test, 27 "on-tab-close", 28 "sessionStorage data has been flushed on TabClose" 29 ); 30 }); 31 32 /** 33 * This test ensures we won't lose tab data queued in the content script when 34 * duplicating a tab. 35 */ 36 add_task(async function flush_on_duplicate() { 37 let tab = await createTabWithStorageData(["http://example.com/"]); 38 let browser = tab.linkedBrowser; 39 40 await modifySessionStorage(browser, { test: "on-duplicate" }); 41 let tab2 = ss.duplicateTab(window, tab); 42 await promiseTabRestored(tab2); 43 44 await promiseRemoveTabAndSessionState(tab2); 45 let [ 46 { 47 state: { storage }, 48 }, 49 ] = ss.getClosedTabDataForWindow(window); 50 is( 51 storage["http://example.com"].test, 52 "on-duplicate", 53 "sessionStorage data has been flushed when duplicating tabs" 54 ); 55 56 gBrowser.removeTab(tab); 57 }); 58 59 /** 60 * This test ensures we won't lose tab data queued in the content script when 61 * a window is closed. 62 */ 63 add_task(async function flush_on_windowclose() { 64 let win = await promiseNewWindow(); 65 let tab = await createTabWithStorageData(["http://example.com/"], win); 66 let browser = tab.linkedBrowser; 67 68 await modifySessionStorage(browser, { test: "on-window-close" }); 69 await BrowserTestUtils.closeWindow(win); 70 71 let [ 72 { 73 tabs: [, { storage }], 74 }, 75 ] = ss.getClosedWindowData(); 76 is( 77 storage["http://example.com"].test, 78 "on-window-close", 79 "sessionStorage data has been flushed when closing a window" 80 ); 81 }); 82 83 /** 84 * This test ensures that stale tab data is ignored when reusing a tab 85 * (via e.g. setTabState) and does not overwrite the new data. 86 */ 87 add_task(async function flush_on_settabstate() { 88 let tab = await createTabWithStorageData(["http://example.com/"]); 89 let browser = tab.linkedBrowser; 90 91 // Flush to make sure our tab state is up-to-date. 92 await TabStateFlusher.flush(browser); 93 94 let state = ss.getTabState(tab); 95 await modifySessionStorage(browser, { test: "on-set-tab-state" }); 96 97 // Flush all data contained in the content script but send it using 98 // asynchronous messages. 99 TabStateFlusher.flush(browser); 100 101 await promiseTabState(tab, state); 102 103 let { storage } = JSON.parse(ss.getTabState(tab)); 104 is( 105 storage["http://example.com"].test, 106 INITIAL_VALUE, 107 "sessionStorage data has not been overwritten" 108 ); 109 110 gBrowser.removeTab(tab); 111 }); 112 113 /** 114 * This test ensures that we won't lose tab data that has been sent 115 * asynchronously just before closing a tab. Flushing must re-send all data 116 * that hasn't been received by chrome, yet. 117 */ 118 add_task(async function flush_on_tabclose_racy() { 119 let tab = await createTabWithStorageData(["http://example.com/"]); 120 let browser = tab.linkedBrowser; 121 122 // Flush to make sure we start with an empty queue. 123 await TabStateFlusher.flush(browser); 124 125 await modifySessionStorage(browser, { test: "on-tab-close-racy" }); 126 127 // Flush all data contained in the content script but send it using 128 // asynchronous messages. 129 TabStateFlusher.flush(browser); 130 await promiseRemoveTabAndSessionState(tab); 131 132 let [ 133 { 134 state: { storage }, 135 }, 136 ] = ss.getClosedTabDataForWindow(window); 137 is( 138 storage["http://example.com"].test, 139 "on-tab-close-racy", 140 "sessionStorage data has been merged correctly to prevent data loss" 141 ); 142 }); 143 144 function promiseNewWindow() { 145 return new Promise(resolve => { 146 whenNewWindowLoaded({ private: false }, resolve); 147 }); 148 } 149 150 async function createTabWithStorageData(urls, win = window) { 151 let tab = BrowserTestUtils.addTab(win.gBrowser); 152 let browser = tab.linkedBrowser; 153 154 for (let url of urls) { 155 BrowserTestUtils.startLoadingURIString(browser, url); 156 await promiseBrowserLoaded(browser, true, url); 157 dump("Loaded url: " + url + "\n"); 158 await modifySessionStorage(browser, { test: INITIAL_VALUE }); 159 } 160 161 return tab; 162 }