summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/test/browser_tab_label_during_restore.js
blob: 71089908185356b9c261a232f99d6196f8505636 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

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