Bug 1344715 - adds test to check that we are not saving session while restoring,r=mikedeboer
The tests start restoring a state, and then attempt a session save immediately
after. We assert that no file was written by this save.
There are 2 tests in this commit. They measure the same thing, but follow
different approaches as documented in the file.
MozReview-Commit-ID: 3eojPAD43zn
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -239,8 +239,9 @@ run-if = e10s && crashreporter
skip-if = debug
[browser_docshell_uuid_consistency.js]
[browser_grouped_session_store.js]
skip-if = !e10s # GroupedSHistory is e10s-only
[browser_closed_objects_changed_notifications_tabs.js]
[browser_closed_objects_changed_notifications_windows.js]
[browser_duplicate_history.js]
+[browser_save_while_restoring.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_save_while_restoring.js
@@ -0,0 +1,111 @@
+"use strict";
+
+/**
+ * Ensure that session is not saved (written) while restoring session.
+ * There are two tests measuring the same thing, in different ways.
+ */
+
+var gOriginalState = JSON.parse(SessionStore.getBrowserState());
+
+// Restore this arbitrary `gStateToLoad` to our browser.
+var gStateToLoad = { windows: [
+ {
+ tabs: [
+ { entries: [{ url: "http://example.org#0", triggeringPrincipal_base64 }] },
+ { entries: [{ url: "http://example.com#1", triggeringPrincipal_base64 }] },
+ { entries: [{ url: "http://example.com#2", triggeringPrincipal_base64 }] },
+ ],
+ selected: 0
+ },
+ {
+ tabs: [
+ { entries: [{ url: "http://example.com#3", triggeringPrincipal_base64 }] },
+ { entries: [{ url: "http://example.com#4", triggeringPrincipal_base64 }] },
+ { entries: [{ url: "http://example.com#5", triggeringPrincipal_base64 }] },
+ { entries: [{ url: "http://example.com#6", triggeringPrincipal_base64 }] }
+ ],
+ selected: 1
+ }
+] };
+
+async function cleanupWindows() {
+ let windowsEnum = Services.wm.getEnumerator("navigator:browser");
+ while (windowsEnum.hasMoreElements()) {
+ let currWin = windowsEnum.getNext();
+ if (currWin !== window) {
+ await BrowserTestUtils.closeWindow(currWin);
+ }
+ }
+}
+
+/**
+ * Testing Method:
+ * Set a really small interval to get lots of saves.
+ * Add observer to watch for session saving.
+ * Trigger a session restore.
+ * After restore is completed, remove observer and see if it was ever called.
+ * After restoring the old session to the browser, see if we saved it a nonzero.
+ * number of times.
+ */
+add_task(async function() {
+ gPrefService.setIntPref("browser.sessionstore.interval", 1);
+ registerCleanupFunction(() => {
+ gPrefService.clearUserPref("browser.sessionstore.interval");
+ });
+
+ let stateSavedWhileRestoring = false;
+ let wroteStateObserver = () => {
+ stateSavedWhileRestoring = true;
+ };
+
+ Services.obs.addObserver(wroteStateObserver,
+ "sessionstore-state-write-complete", false);
+
+ // While observing for any saves, restore `gStateToLoad`.
+ await promiseBrowserState(gStateToLoad);
+
+ Assert.ok(!stateSavedWhileRestoring,
+ "Expected that state would not be written while restoring.");
+
+ await cleanupWindows();
+ await promiseBrowserState(gOriginalState);
+
+ Assert.ok(!stateSavedWhileRestoring, "Expected a state save by now.");
+
+ Services.obs.removeObserver(wroteStateObserver,
+ "sessionstore-state-write-complete");
+});
+
+/**
+ * Testing Method:
+ * Set a really large timeout so that session saving doesn't happen on its own.
+ * Trigger a session restore async.
+ * Trigger a session save (keep track of successful write - in case it writes, fail).
+ * Wait on session restore completion.
+ */
+add_task(async function() {
+ // Any saves must be forced on our part.
+ gPrefService.setIntPref("browser.sessionstore.interval", 100000);
+ registerCleanupFunction(() => {
+ gPrefService.clearUserPref("browser.sessionstore.interval");
+ });
+
+ let stateSavedWhileRestoring = false;
+
+ // Start a restore, and immediately after restoring, check if we've saved state.
+ let promiseRestore = promiseBrowserState(gStateToLoad);
+
+ // Force a state save after starting restore.
+ promiseSaveState().then(() => {
+ stateSavedWhileRestoring = true;
+ }).catch(err => {
+ // Ignore, this is what we want to happen.
+ });
+
+ await promiseRestore;
+ Assert.ok(!stateSavedWhileRestoring,
+ "Expected that state would not be written while restoring.");
+
+ await cleanupWindows();
+ await promiseBrowserState(gOriginalState);
+});