summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/test/browser_broadcast.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/sessionstore/test/browser_broadcast.js')
-rw-r--r--browser/components/sessionstore/test/browser_broadcast.js162
1 files changed, 162 insertions, 0 deletions
diff --git a/browser/components/sessionstore/test/browser_broadcast.js b/browser/components/sessionstore/test/browser_broadcast.js
new file mode 100644
index 0000000000..02f3bc59e7
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_broadcast.js
@@ -0,0 +1,162 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const INITIAL_VALUE = "browser_broadcast.js-initial-value-" + Date.now();
+
+/**
+ * This test ensures we won't lose tab data queued in the content script when
+ * closing a tab.
+ */
+add_task(async function flush_on_tabclose() {
+ let tab = await createTabWithStorageData(["http://example.com/"]);
+ let browser = tab.linkedBrowser;
+
+ await modifySessionStorage(browser, { test: "on-tab-close" });
+ await TabStateFlusher.flush(browser);
+ await promiseRemoveTabAndSessionState(tab);
+
+ let [
+ {
+ state: { storage },
+ },
+ ] = ss.getClosedTabDataForWindow(window);
+ is(
+ storage["http://example.com"].test,
+ "on-tab-close",
+ "sessionStorage data has been flushed on TabClose"
+ );
+});
+
+/**
+ * This test ensures we won't lose tab data queued in the content script when
+ * duplicating a tab.
+ */
+add_task(async function flush_on_duplicate() {
+ let tab = await createTabWithStorageData(["http://example.com/"]);
+ let browser = tab.linkedBrowser;
+
+ await modifySessionStorage(browser, { test: "on-duplicate" });
+ let tab2 = ss.duplicateTab(window, tab);
+ await promiseTabRestored(tab2);
+
+ await promiseRemoveTabAndSessionState(tab2);
+ let [
+ {
+ state: { storage },
+ },
+ ] = ss.getClosedTabDataForWindow(window);
+ is(
+ storage["http://example.com"].test,
+ "on-duplicate",
+ "sessionStorage data has been flushed when duplicating tabs"
+ );
+
+ gBrowser.removeTab(tab);
+});
+
+/**
+ * This test ensures we won't lose tab data queued in the content script when
+ * a window is closed.
+ */
+add_task(async function flush_on_windowclose() {
+ let win = await promiseNewWindow();
+ let tab = await createTabWithStorageData(["http://example.com/"], win);
+ let browser = tab.linkedBrowser;
+
+ await modifySessionStorage(browser, { test: "on-window-close" });
+ await BrowserTestUtils.closeWindow(win);
+
+ let [
+ {
+ tabs: [, { storage }],
+ },
+ ] = ss.getClosedWindowData();
+ is(
+ storage["http://example.com"].test,
+ "on-window-close",
+ "sessionStorage data has been flushed when closing a window"
+ );
+});
+
+/**
+ * This test ensures that stale tab data is ignored when reusing a tab
+ * (via e.g. setTabState) and does not overwrite the new data.
+ */
+add_task(async function flush_on_settabstate() {
+ let tab = await createTabWithStorageData(["http://example.com/"]);
+ let browser = tab.linkedBrowser;
+
+ // Flush to make sure our tab state is up-to-date.
+ await TabStateFlusher.flush(browser);
+
+ let state = ss.getTabState(tab);
+ await modifySessionStorage(browser, { test: "on-set-tab-state" });
+
+ // Flush all data contained in the content script but send it using
+ // asynchronous messages.
+ TabStateFlusher.flush(browser);
+
+ await promiseTabState(tab, state);
+
+ let { storage } = JSON.parse(ss.getTabState(tab));
+ is(
+ storage["http://example.com"].test,
+ INITIAL_VALUE,
+ "sessionStorage data has not been overwritten"
+ );
+
+ gBrowser.removeTab(tab);
+});
+
+/**
+ * This test ensures that we won't lose tab data that has been sent
+ * asynchronously just before closing a tab. Flushing must re-send all data
+ * that hasn't been received by chrome, yet.
+ */
+add_task(async function flush_on_tabclose_racy() {
+ let tab = await createTabWithStorageData(["http://example.com/"]);
+ let browser = tab.linkedBrowser;
+
+ // Flush to make sure we start with an empty queue.
+ await TabStateFlusher.flush(browser);
+
+ await modifySessionStorage(browser, { test: "on-tab-close-racy" });
+
+ // Flush all data contained in the content script but send it using
+ // asynchronous messages.
+ TabStateFlusher.flush(browser);
+ await promiseRemoveTabAndSessionState(tab);
+
+ let [
+ {
+ state: { storage },
+ },
+ ] = ss.getClosedTabDataForWindow(window);
+ is(
+ storage["http://example.com"].test,
+ "on-tab-close-racy",
+ "sessionStorage data has been merged correctly to prevent data loss"
+ );
+});
+
+function promiseNewWindow() {
+ return new Promise(resolve => {
+ whenNewWindowLoaded({ private: false }, resolve);
+ });
+}
+
+async function createTabWithStorageData(urls, win = window) {
+ let tab = BrowserTestUtils.addTab(win.gBrowser);
+ let browser = tab.linkedBrowser;
+
+ for (let url of urls) {
+ BrowserTestUtils.loadURIString(browser, url);
+ await promiseBrowserLoaded(browser, true, url);
+ dump("Loaded url: " + url + "\n");
+ await modifySessionStorage(browser, { test: INITIAL_VALUE });
+ }
+
+ return tab;
+}