Dactyloidae/dom/base/test/chrome/window_groupedSHistory.xul

343 lines
17 KiB
XML

<?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>