browser_tab_label_during_restore.js (6499B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Test that we don't do unnecessary tab label changes while restoring a tab. 8 */ 9 10 add_task(async function () { 11 await SpecialPowers.pushPrefEnv({ 12 set: [ 13 ["browser.sessionstore.restore_on_demand", true], 14 ["browser.sessionstore.restore_tabs_lazily", true], 15 ], 16 }); 17 18 const BACKUP_STATE = SessionStore.getBrowserState(); 19 const REMOTE_URL = "http://www.example.com/"; 20 const ABOUT_ROBOTS_URI = "about:robots"; 21 const ABOUT_ROBOTS_TITLE = "Gort! Klaatu barada nikto!"; 22 const NO_TITLE_URL = "data:text/plain,foo"; 23 const EMPTY_TAB_TITLE = gBrowser.tabContainer.emptyTabTitle; 24 25 function observeLabelChanges(tab, expectedLabels) { 26 let seenLabels = [tab.label]; 27 function TabAttrModifiedListener(event) { 28 if (event.detail.changed.some(attr => attr == "label")) { 29 seenLabels.push(tab.label); 30 } 31 } 32 tab.addEventListener("TabAttrModified", TabAttrModifiedListener); 33 return async () => { 34 await BrowserTestUtils.waitForCondition( 35 () => seenLabels.length == expectedLabels.length, 36 "saw " + seenLabels.length + " TabAttrModified events" 37 ); 38 tab.removeEventListener("TabAttrModified", TabAttrModifiedListener); 39 is( 40 JSON.stringify(seenLabels), 41 JSON.stringify(expectedLabels || []), 42 "observed tab label changes" 43 ); 44 }; 45 } 46 47 info("setting test browser state"); 48 let browserLoadedPromise = BrowserTestUtils.firstBrowserLoaded(window, false); 49 await promiseBrowserState({ 50 windows: [ 51 { 52 tabs: [ 53 { entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] }, 54 { entries: [{ url: ABOUT_ROBOTS_URI, triggeringPrincipal_base64 }] }, 55 { entries: [{ url: REMOTE_URL, triggeringPrincipal_base64 }] }, 56 { entries: [{ url: NO_TITLE_URL, triggeringPrincipal_base64 }] }, 57 { entries: [{ url: "about:blank", triggeringPrincipal_base64 }] }, 58 ], 59 }, 60 ], 61 }); 62 let [tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs; 63 is(gBrowser.selectedTab, tab1, "first tab is selected"); 64 65 await browserLoadedPromise; 66 const REMOTE_TITLE = tab1.linkedBrowser.contentTitle; 67 is( 68 tab1.linkedBrowser.currentURI.spec, 69 REMOTE_URL, 70 "correct URL loaded in first tab" 71 ); 72 is(typeof REMOTE_TITLE, "string", "content title is a string"); 73 isnot(REMOTE_TITLE.length, 0, "content title isn't empty"); 74 isnot(REMOTE_TITLE, REMOTE_URL, "content title is different from the URL"); 75 is(tab1.label, REMOTE_TITLE, "first tab displays content title"); 76 ok( 77 document.title.startsWith(REMOTE_TITLE), 78 "title bar displays content title" 79 ); 80 ok(tab2.hasAttribute("pending"), "second tab is pending"); 81 ok(tab3.hasAttribute("pending"), "third tab is pending"); 82 ok(tab4.hasAttribute("pending"), "fourth tab is pending"); 83 is(tab5.label, EMPTY_TAB_TITLE, "fifth tab dislpays empty tab title"); 84 85 info("selecting the second tab"); 86 // The fix for bug 1364127 caused about: pages' initial tab titles to show 87 // their about: URIs until their actual page titles are known, e.g. 88 // "about:addons" -> "Add-ons Manager". This is bug 1371896. Previously, 89 // about: pages' initial tab titles were blank until the page title was known. 90 let finishObservingLabelChanges = observeLabelChanges(tab2, [ 91 ABOUT_ROBOTS_URI, 92 ABOUT_ROBOTS_TITLE, 93 ]); 94 browserLoadedPromise = BrowserTestUtils.browserLoaded( 95 tab2.linkedBrowser, 96 false, 97 ABOUT_ROBOTS_URI 98 ); 99 gBrowser.selectedTab = tab2; 100 await browserLoadedPromise; 101 ok(!tab2.hasAttribute("pending"), "second tab isn't pending anymore"); 102 await finishObservingLabelChanges(); 103 ok( 104 document.title.startsWith(ABOUT_ROBOTS_TITLE), 105 "title bar displays content title" 106 ); 107 108 info("selecting the third tab"); 109 finishObservingLabelChanges = observeLabelChanges(tab3, [ 110 "example.com/", 111 REMOTE_TITLE, 112 ]); 113 browserLoadedPromise = BrowserTestUtils.browserLoaded( 114 tab3.linkedBrowser, 115 false, 116 REMOTE_URL 117 ); 118 gBrowser.selectedTab = tab3; 119 await browserLoadedPromise; 120 ok(!tab3.hasAttribute("pending"), "third tab isn't pending anymore"); 121 await finishObservingLabelChanges(); 122 ok( 123 document.title.startsWith(REMOTE_TITLE), 124 "title bar displays content title" 125 ); 126 127 info("selecting the fourth tab"); 128 finishObservingLabelChanges = observeLabelChanges(tab4, [NO_TITLE_URL]); 129 browserLoadedPromise = BrowserTestUtils.browserLoaded( 130 tab4.linkedBrowser, 131 false, 132 NO_TITLE_URL 133 ); 134 gBrowser.selectedTab = tab4; 135 await browserLoadedPromise; 136 ok(!tab4.hasAttribute("pending"), "fourth tab isn't pending anymore"); 137 await finishObservingLabelChanges(); 138 is( 139 document.title, 140 document.getElementById("bundle_brand").getString("brandFullName"), 141 "title bar doesn't display content title since page doesn't have one" 142 ); 143 144 info("restoring the modified browser state"); 145 gBrowser.selectedTab = tab3; 146 await TabStateFlusher.flushWindow(window); 147 await promiseBrowserState(SessionStore.getBrowserState()); 148 [tab1, tab2, tab3, tab4, tab5] = gBrowser.tabs; 149 is(tab3, gBrowser.selectedTab, "third tab is selected after restoring"); 150 ok( 151 document.title.startsWith(REMOTE_TITLE), 152 "title bar displays content title" 153 ); 154 ok(tab1.hasAttribute("pending"), "first tab is pending after restoring"); 155 ok(tab2.hasAttribute("pending"), "second tab is pending after restoring"); 156 is(tab2.label, ABOUT_ROBOTS_TITLE, "second tab displays content title"); 157 ok(!tab3.hasAttribute("pending"), "third tab is not pending after restoring"); 158 is( 159 tab3.label, 160 REMOTE_TITLE, 161 "third tab displays content title in pending state" 162 ); 163 ok(tab4.hasAttribute("pending"), "fourth tab is pending after restoring"); 164 is(tab4.label, NO_TITLE_URL, "fourth tab displays URL"); 165 is(tab5.label, EMPTY_TAB_TITLE, "fifth tab still displays empty tab title"); 166 167 info("selecting the first tab"); 168 finishObservingLabelChanges = observeLabelChanges(tab1, [REMOTE_TITLE]); 169 let tabContentRestored = TestUtils.topicObserved( 170 "sessionstore-debug-tab-restored" 171 ); 172 gBrowser.selectedTab = tab1; 173 ok( 174 document.title.startsWith(REMOTE_TITLE), 175 "title bar displays content title" 176 ); 177 await tabContentRestored; 178 ok(!tab1.hasAttribute("pending"), "first tab isn't pending anymore"); 179 await finishObservingLabelChanges(); 180 181 await promiseBrowserState(BACKUP_STATE); 182 });