summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/test/head.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/sessionstore/test/head.js')
-rw-r--r--browser/components/sessionstore/test/head.js564
1 files changed, 0 insertions, 564 deletions
diff --git a/browser/components/sessionstore/test/head.js b/browser/components/sessionstore/test/head.js
deleted file mode 100644
index 5a8c5dbfc..000000000
--- a/browser/components/sessionstore/test/head.js
+++ /dev/null
@@ -1,564 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const TAB_STATE_NEEDS_RESTORE = 1;
-const TAB_STATE_RESTORING = 2;
-
-const ROOT = getRootDirectory(gTestPath);
-const HTTPROOT = ROOT.replace("chrome://mochitests/content/", "http://example.com/");
-const FRAME_SCRIPTS = [
- ROOT + "content.js",
- ROOT + "content-forms.js"
-];
-
-var mm = Cc["@mozilla.org/globalmessagemanager;1"]
- .getService(Ci.nsIMessageListenerManager);
-
-for (let script of FRAME_SCRIPTS) {
- mm.loadFrameScript(script, true);
-}
-
-registerCleanupFunction(() => {
- for (let script of FRAME_SCRIPTS) {
- mm.removeDelayedFrameScript(script, true);
- }
-});
-
-const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
-const {SessionStore} = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {});
-const {SessionSaver} = Cu.import("resource:///modules/sessionstore/SessionSaver.jsm", {});
-const {SessionFile} = Cu.import("resource:///modules/sessionstore/SessionFile.jsm", {});
-const {TabState} = Cu.import("resource:///modules/sessionstore/TabState.jsm", {});
-const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-
-// Some tests here assume that all restored tabs are loaded without waiting for
-// the user to bring them to the foreground. We ensure this by resetting the
-// related preference (see the "firefox.js" defaults file for details).
-Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", false);
-registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
-});
-
-// Obtain access to internals
-Services.prefs.setBoolPref("browser.sessionstore.debug", true);
-registerCleanupFunction(function () {
- Services.prefs.clearUserPref("browser.sessionstore.debug");
-});
-
-
-// This kicks off the search service used on about:home and allows the
-// session restore tests to be run standalone without triggering errors.
-Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
-
-function provideWindow(aCallback, aURL, aFeatures) {
- function callbackSoon(aWindow) {
- executeSoon(function executeCallbackSoon() {
- aCallback(aWindow);
- });
- }
-
- let win = openDialog(getBrowserURL(), "", aFeatures || "chrome,all,dialog=no", aURL || "about:blank");
- whenWindowLoaded(win, function onWindowLoaded(aWin) {
- if (!aURL) {
- info("Loaded a blank window.");
- callbackSoon(aWin);
- return;
- }
-
- aWin.gBrowser.selectedBrowser.addEventListener("load", function selectedBrowserLoadListener() {
- aWin.gBrowser.selectedBrowser.removeEventListener("load", selectedBrowserLoadListener, true);
- callbackSoon(aWin);
- }, true);
- });
-}
-
-// This assumes that tests will at least have some state/entries
-function waitForBrowserState(aState, aSetStateCallback) {
- if (typeof aState == "string") {
- aState = JSON.parse(aState);
- }
- if (typeof aState != "object") {
- throw new TypeError("Argument must be an object or a JSON representation of an object");
- }
- let windows = [window];
- let tabsRestored = 0;
- let expectedTabsRestored = 0;
- let expectedWindows = aState.windows.length;
- let windowsOpen = 1;
- let listening = false;
- let windowObserving = false;
- let restoreHiddenTabs = Services.prefs.getBoolPref(
- "browser.sessionstore.restore_hidden_tabs");
-
- aState.windows.forEach(function (winState) {
- winState.tabs.forEach(function (tabState) {
- if (restoreHiddenTabs || !tabState.hidden)
- expectedTabsRestored++;
- });
- });
-
- // There must be only hidden tabs and restoreHiddenTabs = false. We still
- // expect one of them to be restored because it gets shown automatically.
- if (!expectedTabsRestored)
- expectedTabsRestored = 1;
-
- function onSSTabRestored(aEvent) {
- if (++tabsRestored == expectedTabsRestored) {
- // Remove the event listener from each window
- windows.forEach(function(win) {
- win.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
- });
- listening = false;
- info("running " + aSetStateCallback.name);
- executeSoon(aSetStateCallback);
- }
- }
-
- // Used to add our listener to further windows so we can catch SSTabRestored
- // coming from them when creating a multi-window state.
- function windowObserver(aSubject, aTopic, aData) {
- if (aTopic == "domwindowopened") {
- let newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
- newWindow.addEventListener("load", function() {
- newWindow.removeEventListener("load", arguments.callee, false);
-
- if (++windowsOpen == expectedWindows) {
- Services.ww.unregisterNotification(windowObserver);
- windowObserving = false;
- }
-
- // Track this window so we can remove the progress listener later
- windows.push(newWindow);
- // Add the progress listener
- newWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
- }, false);
- }
- }
-
- // We only want to register the notification if we expect more than 1 window
- if (expectedWindows > 1) {
- registerCleanupFunction(function() {
- if (windowObserving) {
- Services.ww.unregisterNotification(windowObserver);
- }
- });
- windowObserving = true;
- Services.ww.registerNotification(windowObserver);
- }
-
- registerCleanupFunction(function() {
- if (listening) {
- windows.forEach(function(win) {
- win.gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
- });
- }
- });
- // Add the event listener for this window as well.
- listening = true;
- gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
-
- // Ensure setBrowserState() doesn't remove the initial tab.
- gBrowser.selectedTab = gBrowser.tabs[0];
-
- // Finally, call setBrowserState
- ss.setBrowserState(JSON.stringify(aState));
-}
-
-function promiseBrowserState(aState) {
- return new Promise(resolve => waitForBrowserState(aState, resolve));
-}
-
-function promiseTabState(tab, state) {
- if (typeof(state) != "string") {
- state = JSON.stringify(state);
- }
-
- let promise = promiseTabRestored(tab);
- ss.setTabState(tab, state);
- return promise;
-}
-
-/**
- * Wait for a content -> chrome message.
- */
-function promiseContentMessage(browser, name) {
- let mm = browser.messageManager;
-
- return new Promise(resolve => {
- function removeListener() {
- mm.removeMessageListener(name, listener);
- }
-
- function listener(msg) {
- removeListener();
- resolve(msg.data);
- }
-
- mm.addMessageListener(name, listener);
- registerCleanupFunction(removeListener);
- });
-}
-
-function waitForTopic(aTopic, aTimeout, aCallback) {
- let observing = false;
- function removeObserver() {
- if (!observing)
- return;
- Services.obs.removeObserver(observer, aTopic);
- observing = false;
- }
-
- let timeout = setTimeout(function () {
- removeObserver();
- aCallback(false);
- }, aTimeout);
-
- function observer(aSubject, aTopic, aData) {
- removeObserver();
- timeout = clearTimeout(timeout);
- executeSoon(() => aCallback(true));
- }
-
- registerCleanupFunction(function() {
- removeObserver();
- if (timeout) {
- clearTimeout(timeout);
- }
- });
-
- observing = true;
- Services.obs.addObserver(observer, aTopic, false);
-}
-
-/**
- * Wait until session restore has finished collecting its data and is
- * has written that data ("sessionstore-state-write-complete").
- *
- * @param {function} aCallback If sessionstore-state-write-complete is sent
- * within buffering interval + 100 ms, the callback is passed |true|,
- * otherwise, it is passed |false|.
- */
-function waitForSaveState(aCallback) {
- let timeout = 100 +
- Services.prefs.getIntPref("browser.sessionstore.interval");
- return waitForTopic("sessionstore-state-write-complete", timeout, aCallback);
-}
-function promiseSaveState() {
- return new Promise(resolve => {
- waitForSaveState(isSuccessful => {
- if (!isSuccessful) {
- throw new Error("timeout");
- }
-
- resolve();
- });
- });
-}
-function forceSaveState() {
- return SessionSaver.run();
-}
-
-function promiseRecoveryFileContents() {
- let promise = forceSaveState();
- return promise.then(function() {
- return OS.File.read(SessionFile.Paths.recovery, { encoding: "utf-8" });
- });
-}
-
-var promiseForEachSessionRestoreFile = Task.async(function*(cb) {
- for (let key of SessionFile.Paths.loadOrder) {
- let data = "";
- try {
- data = yield OS.File.read(SessionFile.Paths[key], { encoding: "utf-8" });
- } catch (ex) {
- // Ignore missing files
- if (!(ex instanceof OS.File.Error && ex.becauseNoSuchFile)) {
- throw ex;
- }
- }
- cb(data, key);
- }
-});
-
-function promiseBrowserLoaded(aBrowser, ignoreSubFrames = true, wantLoad = null) {
- return BrowserTestUtils.browserLoaded(aBrowser, !ignoreSubFrames, wantLoad);
-}
-
-function whenWindowLoaded(aWindow, aCallback = next) {
- aWindow.addEventListener("load", function windowLoadListener() {
- aWindow.removeEventListener("load", windowLoadListener, false);
- executeSoon(function executeWhenWindowLoaded() {
- aCallback(aWindow);
- });
- }, false);
-}
-function promiseWindowLoaded(aWindow) {
- return new Promise(resolve => whenWindowLoaded(aWindow, resolve));
-}
-
-var gUniqueCounter = 0;
-function r() {
- return Date.now() + "-" + (++gUniqueCounter);
-}
-
-function* BrowserWindowIterator() {
- let windowsEnum = Services.wm.getEnumerator("navigator:browser");
- while (windowsEnum.hasMoreElements()) {
- let currentWindow = windowsEnum.getNext();
- if (!currentWindow.closed) {
- yield currentWindow;
- }
- }
-}
-
-var gWebProgressListener = {
- _callback: null,
-
- setCallback: function (aCallback) {
- if (!this._callback) {
- window.gBrowser.addTabsProgressListener(this);
- }
- this._callback = aCallback;
- },
-
- unsetCallback: function () {
- if (this._callback) {
- this._callback = null;
- window.gBrowser.removeTabsProgressListener(this);
- }
- },
-
- onStateChange: function (aBrowser, aWebProgress, aRequest,
- aStateFlags, aStatus) {
- if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK &&
- aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
- this._callback(aBrowser);
- }
- }
-};
-
-registerCleanupFunction(function () {
- gWebProgressListener.unsetCallback();
-});
-
-var gProgressListener = {
- _callback: null,
-
- setCallback: function (callback) {
- Services.obs.addObserver(this, "sessionstore-debug-tab-restored", false);
- this._callback = callback;
- },
-
- unsetCallback: function () {
- if (this._callback) {
- this._callback = null;
- Services.obs.removeObserver(this, "sessionstore-debug-tab-restored");
- }
- },
-
- observe: function (browser, topic, data) {
- gProgressListener.onRestored(browser);
- },
-
- onRestored: function (browser) {
- if (browser.__SS_restoreState == TAB_STATE_RESTORING) {
- let args = [browser].concat(gProgressListener._countTabs());
- gProgressListener._callback.apply(gProgressListener, args);
- }
- },
-
- _countTabs: function () {
- let needsRestore = 0, isRestoring = 0, wasRestored = 0;
-
- for (let win of BrowserWindowIterator()) {
- for (let i = 0; i < win.gBrowser.tabs.length; i++) {
- let browser = win.gBrowser.tabs[i].linkedBrowser;
- if (!browser.__SS_restoreState)
- wasRestored++;
- else if (browser.__SS_restoreState == TAB_STATE_RESTORING)
- isRestoring++;
- else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
- needsRestore++;
- }
- }
- return [needsRestore, isRestoring, wasRestored];
- }
-};
-
-registerCleanupFunction(function () {
- gProgressListener.unsetCallback();
-});
-
-// Close all but our primary window.
-function promiseAllButPrimaryWindowClosed() {
- let windows = [];
- for (let win of BrowserWindowIterator()) {
- if (win != window) {
- windows.push(win);
- }
- }
-
- return Promise.all(windows.map(BrowserTestUtils.closeWindow));
-}
-
-// Forget all closed windows.
-function forgetClosedWindows() {
- while (ss.getClosedWindowCount() > 0) {
- ss.forgetClosedWindow(0);
- }
-}
-
-/**
- * When opening a new window it is not sufficient to wait for its load event.
- * We need to use whenDelayedStartupFinshed() here as the browser window's
- * delayedStartup() routine is executed one tick after the window's load event
- * has been dispatched. browser-delayed-startup-finished might be deferred even
- * further if parts of the window's initialization process take more time than
- * expected (e.g. reading a big session state from disk).
- */
-function whenNewWindowLoaded(aOptions, aCallback) {
- let features = "";
- let url = "about:blank";
-
- if (aOptions && aOptions.private || false) {
- features = ",private";
- url = "about:privatebrowsing";
- }
-
- let win = openDialog(getBrowserURL(), "", "chrome,all,dialog=no" + features, url);
- let delayedStartup = promiseDelayedStartupFinished(win);
-
- let browserLoaded = new Promise(resolve => {
- if (url == "about:blank") {
- resolve();
- return;
- }
-
- win.addEventListener("load", function onLoad() {
- win.removeEventListener("load", onLoad);
- let browser = win.gBrowser.selectedBrowser;
- promiseBrowserLoaded(browser).then(resolve);
- });
- });
-
- Promise.all([delayedStartup, browserLoaded]).then(() => aCallback(win));
-}
-function promiseNewWindowLoaded(aOptions) {
- return new Promise(resolve => whenNewWindowLoaded(aOptions, resolve));
-}
-
-/**
- * This waits for the browser-delayed-startup-finished notification of a given
- * window. It indicates that the windows has loaded completely and is ready to
- * be used for testing.
- */
-function whenDelayedStartupFinished(aWindow, aCallback) {
- Services.obs.addObserver(function observer(aSubject, aTopic) {
- if (aWindow == aSubject) {
- Services.obs.removeObserver(observer, aTopic);
- executeSoon(aCallback);
- }
- }, "browser-delayed-startup-finished", false);
-}
-function promiseDelayedStartupFinished(aWindow) {
- return new Promise(resolve => whenDelayedStartupFinished(aWindow, resolve));
-}
-
-function promiseEvent(element, eventType, isCapturing = false) {
- return new Promise(resolve => {
- element.addEventListener(eventType, function listener(event) {
- element.removeEventListener(eventType, listener, isCapturing);
- resolve(event);
- }, isCapturing);
- });
-}
-
-function promiseTabRestored(tab) {
- return promiseEvent(tab, "SSTabRestored");
-}
-
-function promiseTabRestoring(tab) {
- return promiseEvent(tab, "SSTabRestoring");
-}
-
-function sendMessage(browser, name, data = {}) {
- browser.messageManager.sendAsyncMessage(name, data);
- return promiseContentMessage(browser, name);
-}
-
-// This creates list of functions that we will map to their corresponding
-// ss-test:* messages names. Those will be sent to the frame script and
-// be used to read and modify form data.
-const FORM_HELPERS = [
- "getTextContent",
- "getInputValue", "setInputValue",
- "getInputChecked", "setInputChecked",
- "getSelectedIndex", "setSelectedIndex",
- "getMultipleSelected", "setMultipleSelected",
- "getFileNameArray", "setFileNameArray",
-];
-
-for (let name of FORM_HELPERS) {
- let msg = "ss-test:" + name;
- this[name] = (browser, data) => sendMessage(browser, msg, data);
-}
-
-// Removes the given tab immediately and returns a promise that resolves when
-// all pending status updates (messages) of the closing tab have been received.
-function promiseRemoveTab(tab) {
- return BrowserTestUtils.removeTab(tab);
-}
-
-// Write DOMSessionStorage data to the given browser.
-function modifySessionStorage(browser, data, options = {}) {
- return ContentTask.spawn(browser, [data, options], function* ([data, options]) {
- let frame = content;
- if (options && "frameIndex" in options) {
- frame = content.frames[options.frameIndex];
- }
-
- let keys = new Set(Object.keys(data));
- let storage = frame.sessionStorage;
-
- return new Promise(resolve => {
- addEventListener("MozSessionStorageChanged", function onStorageChanged(event) {
- if (event.storageArea == storage) {
- keys.delete(event.key);
- }
-
- if (keys.size == 0) {
- removeEventListener("MozSessionStorageChanged", onStorageChanged, true);
- resolve();
- }
- }, true);
-
- for (let key of keys) {
- frame.sessionStorage[key] = data[key];
- }
- });
- });
-}
-
-function pushPrefs(...aPrefs) {
- return new Promise(resolve => {
- SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve);
- });
-}
-
-function popPrefs() {
- return new Promise(resolve => {
- SpecialPowers.popPrefEnv(resolve);
- });
-}
-
-function* checkScroll(tab, expected, msg) {
- let browser = tab.linkedBrowser;
- yield TabStateFlusher.flush(browser);
-
- let scroll = JSON.parse(ss.getTabState(tab)).scroll || null;
- is(JSON.stringify(scroll), JSON.stringify(expected), msg);
-}