tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 });