Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
/**
* Test that we don't do unnecessary tab label changes while restoring a tab.
*/
add_task(async function () {
await SpecialPowers.pushPrefEnv({
set: [
["browser.sessionstore.restore_on_demand", true],
["browser.sessionstore.restore_tabs_lazily", true],
],
});
const BACKUP_STATE = SessionStore.getBrowserState();
const REMOTE_URL = "http://www.example.com/";
const ABOUT_ROBOTS_URI = "about:robots";
const ABOUT_ROBOTS_TITLE = "Gort! Klaatu barada nikto!";
const NO_TITLE_URL = "data:text/plain,foo";
const EMPTY_TAB_TITLE = gBrowser.tabContainer.emptyTabTitle;
function observeLabelChanges(tab, expectedLabels) {
let seenLabels = [tab.label];
function TabAttrModifiedListener(event) {
if (event.detail.changed.some(attr => attr == "label")) {
seenLabels.push(tab.label);
}
}
tab.addEventListener("TabAttrModified", TabAttrModifiedListener);
return async () => {
await BrowserTestUtils.waitForCondition(
() => seenLabels.length == expectedLabels.length,
"saw " + seenLabels.length + " TabAttrModified events"
);
tab.removeEventListener("TabAttrModified", TabAttrModifiedListener);
is(
JSON.stringify(seenLabels),
JSON.stringify(expectedLabels || []),
"observed tab label changes"
);
};
}
info("setting test browser state");
let browserLoadedPromise = BrowserTestUtils.firstBrowserLoaded(window, false);
await promiseBrowserState({
windows: [
{
tabs: [
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
{ entries: [{ url: ABOUT_ROBOTS_URI, triggeringPrincipal_base64 }] },
{ entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] },
{ entries: [{ url: NO_TITLE_URL, triggeringPrincipal_base64 }] },
{ entries: [{ url: "about:blank", triggeringPrincipal_base64 }] },
],
},
],
});
let [tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs;
is(gBrowser.selectedTab, tab1, "first tab is selected");
await browserLoadedPromise;
const REMOTE_TITLE = tab1.linkedBrowser.contentTitle;
is(
tab1.linkedBrowser.currentURI.spec,
REMOTE_URL,
"correct URL loaded in first tab"
);
is(typeof REMOTE_TITLE, "string", "content title is a string");
isnot(REMOTE_TITLE.length, 0, "content title isn't empty");
isnot(REMOTE_TITLE, REMOTE_URL, "content title is different from the URL");
is(tab1.label, REMOTE_TITLE, "first tab displays content title");
ok(
document.title.startsWith(REMOTE_TITLE),
"title bar displays content title"
);
ok(tab2.hasAttribute("pending"), "second tab is pending");
ok(tab3.hasAttribute("pending"), "third tab is pending");
ok(tab4.hasAttribute("pending"), "fourth tab is pending");
is(tab5.label, EMPTY_TAB_TITLE, "fifth tab dislpays empty tab title");
info("selecting the second tab");
// The fix for bug 1364127 caused about: pages' initial tab titles to show
// their about: URIs until their actual page titles are known, e.g.
// "about:addons" -> "Add-ons Manager". This is bug 1371896. Previously,
// about: pages' initial tab titles were blank until the page title was known.
let finishObservingLabelChanges = observeLabelChanges(tab2, [
ABOUT_ROBOTS_URI,
ABOUT_ROBOTS_TITLE,
]);
browserLoadedPromise = BrowserTestUtils.browserLoaded(
tab2.linkedBrowser,
false,
ABOUT_ROBOTS_URI
);
gBrowser.selectedTab = tab2;
await browserLoadedPromise;
ok(!tab2.hasAttribute("pending"), "second tab isn't pending anymore");
await finishObservingLabelChanges();
ok(
document.title.startsWith(ABOUT_ROBOTS_TITLE),
"title bar displays content title"
);
info("selecting the third tab");
finishObservingLabelChanges = observeLabelChanges(tab3, [
"example.com/",
REMOTE_TITLE,
]);
browserLoadedPromise = BrowserTestUtils.browserLoaded(
tab3.linkedBrowser,
false,
REMOTE_URL
);
gBrowser.selectedTab = tab3;
await browserLoadedPromise;
ok(!tab3.hasAttribute("pending"), "third tab isn't pending anymore");
await finishObservingLabelChanges();
ok(
document.title.startsWith(REMOTE_TITLE),
"title bar displays content title"
);
info("selecting the fourth tab");
finishObservingLabelChanges = observeLabelChanges(tab4, [NO_TITLE_URL]);
browserLoadedPromise = BrowserTestUtils.browserLoaded(
tab4.linkedBrowser,
false,
NO_TITLE_URL
);
gBrowser.selectedTab = tab4;
await browserLoadedPromise;
ok(!tab4.hasAttribute("pending"), "fourth tab isn't pending anymore");
await finishObservingLabelChanges();
is(
document.title,
document.getElementById("bundle_brand").getString("brandFullName"),
"title bar doesn't display content title since page doesn't have one"
);
info("restoring the modified browser state");
gBrowser.selectedTab = tab3;
await TabStateFlusher.flushWindow(window);
await promiseBrowserState(SessionStore.getBrowserState());
[tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs;
is(tab3, gBrowser.selectedTab, "third tab is selected after restoring");
ok(
document.title.startsWith(REMOTE_TITLE),
"title bar displays content title"
);
ok(tab1.hasAttribute("pending"), "first tab is pending after restoring");
ok(tab2.hasAttribute("pending"), "second tab is pending after restoring");
is(tab2.label, ABOUT_ROBOTS_TITLE, "second tab displays content title");
ok(!tab3.hasAttribute("pending"), "third tab is not pending after restoring");
is(
tab3.label,
REMOTE_TITLE,
"third tab displays content title in pending state"
);
ok(tab4.hasAttribute("pending"), "fourth tab is pending after restoring");
is(tab4.label, NO_TITLE_URL, "fourth tab displays URL");
is(tab5.label, EMPTY_TAB_TITLE, "fifth tab still displays empty tab title");
info("selecting the first tab");
finishObservingLabelChanges = observeLabelChanges(tab1, [REMOTE_TITLE]);
let tabContentRestored = TestUtils.topicObserved(
"sessionstore-debug-tab-restored"
);
gBrowser.selectedTab = tab1;
ok(
document.title.startsWith(REMOTE_TITLE),
"title bar displays content title"
);
await tabContentRestored;
ok(!tab1.hasAttribute("pending"), "first tab isn't pending anymore");
await finishObservingLabelChanges();
await promiseBrowserState(BACKUP_STATE);
});