summaryrefslogtreecommitdiffstats
path: root/dom/base/test/chrome/window_groupedSHistory.xul
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/test/chrome/window_groupedSHistory.xul')
-rw-r--r--dom/base/test/chrome/window_groupedSHistory.xul343
1 files changed, 343 insertions, 0 deletions
diff --git a/dom/base/test/chrome/window_groupedSHistory.xul b/dom/base/test/chrome/window_groupedSHistory.xul
new file mode 100644
index 000000000..aafa991ba
--- /dev/null
+++ b/dom/base/test/chrome/window_groupedSHistory.xul
@@ -0,0 +1,343 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1276553
+-->
+<window title="Mozilla Bug 1276553"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="run();">
+
+ <!-- test code goes here -->
+ <script type="application/javascript">
+ <![CDATA[
+
+ const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
+ Cu.import("resource://testing-common/TestUtils.jsm");
+ Cu.import("resource://testing-common/ContentTask.jsm");
+ Cu.import("resource://testing-common/BrowserTestUtils.jsm");
+ Cu.import("resource://gre/modules/Task.jsm");
+ ContentTask.setTestScope(window.opener.wrappedJSObject);
+
+ let imports = ['SimpleTest', 'SpecialPowers', 'ok', 'is', 'info'];
+ for (let name of imports) {
+ window[name] = window.opener.wrappedJSObject[name];
+ }
+
+ /** Test for Bug 1276553 **/
+ function run() {
+ new Promise(resolve => SpecialPowers.pushPrefEnv(
+ {'set' : [[ 'browser.groupedhistory.enabled', true ]]}, resolve))
+ .then(() => test(false))
+ .then(() => test(true))
+ .then(() => {
+ window.close();
+ SimpleTest.finish();
+ });
+ }
+
+ function test(remote) {
+ let act, bg1, bg2;
+ return Promise.resolve()
+
+ // create first browser with 1 entry (which will always be the active one)
+ .then(() => info('TEST-INFO | test create active browser, remote=' + remote))
+ .then(() => createBrowser('pen', remote))
+ .then(b => act = b)
+ .then(() => verifyBrowser(act, 'pen' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ false /* canGoBack */,
+ false /* canGoForward */,
+ false /* partial */ ))
+
+ // create background browser 1 with 1 entry
+ .then(() => info('TEST-INFO | test create background browser 1, remote=' + remote))
+ .then(() => createBrowser('pineapple', remote))
+ .then(b => bg1 = b)
+ .then(() => verifyBrowser(bg1, 'pineapple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ false /* canGoBack */,
+ false /* canGoForward */,
+ false /* partial */ ))
+
+ // create background browser 2 with 2 entries
+ .then(() => info('TEST-INFO | test create background browser 2, remote=' + remote))
+ .then(() => createBrowser('apple', remote))
+ .then(b => bg2 = b)
+ .then(() => verifyBrowser(bg2, 'apple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ false /* canGoBack */,
+ false /* canGoForward */,
+ false /* partial */ ))
+ .then(() => loadURI(bg2, getDummyHtml('pencil')))
+ .then(() => verifyBrowser(bg2, 'pencil' /* title */,
+ 1 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ false /* canGoForward */,
+ false /* partial */ ))
+
+ // merge to 2 entries pen-pineapple
+ .then(() => info('TEST-INFO | test merge history, remote=' + remote))
+ .then(() => mergeHistory(act, bg1))
+ .then(() => verifyBrowser(act, 'pineapple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ true /* canGoBack */,
+ false /* canGoForward */,
+ true /* partial */,
+ 1 /* offset */,
+ 2 /* globalLength */ ))
+
+ // merge to 4 entries pen-pineapple-apple-pencil
+ .then(() => mergeHistory(act, bg2))
+ .then(() => verifyBrowser(act, 'pencil' /* title */,
+ 1 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ false /* canGoForward */,
+ true /* partial */,
+ 2 /* offset */,
+ 4 /* globalLength */ ))
+
+ // test go back
+ .then(() => info('TEST-INFO | test history go back, remote=' + remote))
+ .then(() => wrapHistoryNavFn(act, act.goBack.bind(act)))
+ .then(() => verifyBrowser(act, 'apple' /* title */,
+ 0 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 2 /* offset */,
+ 4 /* globalLength */ ))
+ // XXX The 2nd pageshow comes from reload as current index of the active
+ // partial history remains the same
+ .then(() => wrapHistoryNavFn(act, act.goBack.bind(act), true))
+ .then(() => verifyBrowser(act, 'pineapple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 1 /* offset */,
+ 4 /* globalLength */ ))
+ .then(() => wrapHistoryNavFn(act, act.goBack.bind(act), true))
+ .then(() => verifyBrowser(act, 'pen' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ false /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 0 /* offset */,
+ 4 /* globalLength */ ))
+
+ // test go forward
+ .then(() => info('TEST-INFO | test history go forward, remote=' + remote))
+ .then(() => wrapHistoryNavFn(act, act.goForward.bind(act), true))
+ .then(() => verifyBrowser(act, 'pineapple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 1 /* offset */,
+ 4 /* globalLength */ ))
+ .then(() => wrapHistoryNavFn(act, act.goForward.bind(act), true))
+ .then(() => verifyBrowser(act, 'apple' /* title */,
+ 0 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 2 /* offset */,
+ 4 /* globalLength */ ))
+ .then(() => wrapHistoryNavFn(act, act.goForward.bind(act)))
+ .then(() => verifyBrowser(act, 'pencil' /* title */,
+ 1 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ false /* canGoForward */,
+ true /* partial */,
+ 2 /* offset */,
+ 4 /* globalLength */ ))
+
+ // test goto index
+ .then(() => info('TEST-INFO | test history goto index, remote=' + remote))
+ .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 0), true))
+ .then(() => verifyBrowser(act, 'pen' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ false /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 0 /* offset */,
+ 4 /* globalLength */ ))
+ // expect 2 pageshow since we're also changing mIndex of the partial history
+ .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 2), true, 2))
+ .then(() => verifyBrowser(act, 'apple' /* title */,
+ 0 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 2 /* offset */,
+ 4 /* globalLength */ ))
+ .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 1), true))
+ .then(() => verifyBrowser(act, 'pineapple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 1 /* offset */,
+ 4 /* globalLength */ ))
+ // expect 2 pageshow since we're also changing mIndex of the partial history
+ .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 3), true, 2))
+ .then(() => verifyBrowser(act, 'pencil' /* title */,
+ 1 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ false /* canGoForward */,
+ true /* partial */,
+ 2 /* offset */,
+ 4 /* globalLength */ ))
+
+ // test history change to 3 entries pen-pineapple-banana
+ .then(() => info('TEST-INFO | test history change, remote=' + remote))
+ .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 1), true))
+ .then(() => verifyBrowser(act, 'pineapple' /* title */,
+ 0 /* index */,
+ 1 /* length */,
+ true /* canGoBack */,
+ true /* canGoForward */,
+ true /* partial */,
+ 1 /* offset */,
+ 4 /* globalLength */ ))
+ .then(() => loadURI(act, getDummyHtml('banana')))
+ .then(() => verifyBrowser(act, 'banana' /* title */,
+ 1 /* index */,
+ 2 /* length */,
+ true /* canGoBack */,
+ false /* canGoForward */,
+ true /* partial */,
+ 1 /* offset */,
+ 3 /* globalLength */ ))
+ }
+
+ function getDummyHtml(title) {
+ return 'data:text/html;charset=UTF-8,' +
+ '<html><head><title>' + title + '</title></head></html>'
+ }
+
+ function createBrowser(title, remote) {
+ let browser = document.createElement('browser');
+ browser.setAttribute('type', 'content');
+ browser.setAttribute('remote', remote);
+ browser.setAttribute('src', getDummyHtml(title));
+ document.getElementById('stack').appendChild(browser);
+ return BrowserTestUtils.browserLoaded(browser)
+ .then(() => {
+ browser.messageManager.loadFrameScript('data:,' +
+ 'addEventListener("pageshow", () => sendAsyncMessage("test:pageshow", null), false);' +
+ 'addEventListener("pagehide", () => sendAsyncMessage("test:pagehide", null), false);',
+ true);
+ })
+ .then(() => {
+ // a trick to ensure webProgress object is created for e10s case
+ ok(browser.webProgress, 'check browser.webProgress exists');
+ return browser;
+ });
+ }
+
+ function loadURI(browser, uri) {
+ let promise = BrowserTestUtils.browserLoaded(browser, false, uri);
+ browser.loadURI(uri);
+ return promise;
+ }
+
+ function mergeHistory(b1, b2) {
+ let promises = [];
+ let pagehide1, pagehide2;
+
+ // For swapping there should be a pagehide followed by a pageshow.
+ promises.push(BrowserTestUtils.waitForMessage(b1.messageManager, 'test:pagehide', msg => pagehide1 = true));
+ promises.push(BrowserTestUtils.waitForMessage(b2.messageManager, 'test:pagehide', msg => pagehide2 = true));
+ promises.push(BrowserTestUtils.waitForMessage(b1.messageManager, 'test:pageshow', msg => pagehide1));
+ promises.push(BrowserTestUtils.waitForMessage(b2.messageManager, 'test:pageshow', msg => pagehide2));
+
+ // For swapping remote browsers, we'll also receive Content:LocationChange
+ if (b1.isRemoteBrowser) {
+ promises.push(BrowserTestUtils.waitForMessage(b1.messageManager, 'Content:LocationChange'));
+ }
+
+ promises.push(Promise.resolve().then(() => {
+ let f1 = b1.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+ let f2 = b2.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+ f1.appendPartialSessionHistoryAndSwap(f2);
+ }));
+
+ return Promise.all(promises);
+ }
+
+ function wrapHistoryNavFn(browser, navFn, expectSwap = false, expectPageshowCount = 1) {
+ let promises = [];
+ let pagehide = false;
+ let pageshowCount = 0;
+
+ if (expectSwap) {
+ // For swapping there should be a pagehide followed by a pageshow.
+ promises.push(BrowserTestUtils.waitForMessage(browser.messageManager,
+ 'test:pagehide', msg => pagehide = true));
+
+ // For swapping remote browsers, we'll also receive Content:LocationChange
+ if (browser.isRemoteBrowser) {
+ promises.push(BrowserTestUtils.waitForMessage(browser.messageManager,
+ 'Content:LocationChange'));
+ }
+ }
+ promises.push(BrowserTestUtils.waitForMessage(browser.messageManager,
+ 'test:pageshow', msg => {
+ // Only count events after pagehide for swapping case.
+ if (!expectSwap || pagehide) {
+ return !--expectPageshowCount;
+ }
+ return false;
+ }));
+ promises.push(Task.spawn(navFn));
+
+ return Promise.all(promises);
+ }
+
+ function verifyBrowser(browser, title, index, length, canGoBack, canGoForward,
+ partial, offset = 0, globalLength = length) {
+ is(browser.canGoBack, canGoBack, 'check browser.canGoBack');
+ is(browser.canGoForward, canGoForward, 'check browser.canGoForward');
+ if (partial) {
+ let frameLoader = browser.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
+ is(frameLoader.groupedSessionHistory.count, globalLength, 'check groupedSHistory.count');
+ }
+
+ return ContentTask.spawn(browser,
+ { title, index, length, canGoBack, canGoForward, partial, offset, globalLength },
+ ({ title, index, length, canGoBack, canGoForward, partial, offset, globalLength }) => {
+ let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
+ let shistory = webNav.sessionHistory;
+ is(content.document.title, title, 'check title');
+ is(webNav.canGoBack, canGoBack, 'check webNav.canGoBack');
+ is(webNav.canGoForward, canGoForward, 'check webNav.canGoForward');
+ is(shistory.index, index, 'check shistory.index');
+ is(shistory.count, length, 'check shistory.count');
+ is(shistory.isPartial, partial, 'check shistory.isPartial');
+ is(shistory.globalIndexOffset, offset, 'check shistory.globalIndexOffset');
+ is(shistory.globalCount, globalLength, 'check shistory.globalCount');
+ });
+ }
+
+ ]]>
+ </script>
+ <stack id="stack" flex="1" />
+</window>