browser_394759.js
Go to the documentation of this file.
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is sessionstore test code.
15  *
16  * The Initial Developer of the Original Code is
17  * Simon Bünzli <zeniko@gmail.com>.
18  * Portions created by the Initial Developer are Copyright (C) 2008
19  * the Initial Developer. All Rights Reserved.
20  *
21  * Contributor(s):
22  * Paul O’Shannessy <paul@oshannessy.com>
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 
38 function test() {
41  // test setup
42  let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
43  let pb = Cc["@mozilla.org/privatebrowsing;1"].getService(Ci.nsIPrivateBrowsingService);
45 
46  function test_basic(callback) {
47 
48  let testURL = "about:config";
49  let uniqueKey = "bug 394759";
50  let uniqueValue = "unik" + Date.now();
51  let uniqueText = "pi != " + Math.random();
52 
53 
54  // make sure that the next closed window will increase getClosedWindowCount
55  let max_windows_undo = gPrefService.getIntPref("browser.sessionstore.max_windows_undo");
56  gPrefService.setIntPref("browser.sessionstore.max_windows_undo", max_windows_undo + 1);
57  let closedWindowCount = ss.getClosedWindowCount();
58 
59  let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", testURL);
60  newWin.addEventListener("load", function(aEvent) {
61  newWin.removeEventListener("load", arguments.callee, false);
62  newWin.gBrowser.addEventListener("load", function(aEvent) {
63  newWin.gBrowser.removeEventListener("load", arguments.callee, true);
64 
65  executeSoon(function() {
66  newWin.gBrowser.addTab();
67  executeSoon(function() {
68  // mark the window with some unique data to be restored later on
69  ss.setWindowValue(newWin, uniqueKey, uniqueValue);
70  let textbox = newWin.content.document.getElementById("textbox");
71  textbox.wrappedJSObject.value = uniqueText;
72 
73  newWin.close();
74 
75  is(ss.getClosedWindowCount(), closedWindowCount + 1,
76  "The closed window was added to Recently Closed Windows");
77  let data = JSON.parse(ss.getClosedWindowData())[0];
78  ok(data.title == testURL && data.toSource().indexOf(uniqueText) > -1,
79  "The closed window data was stored correctly");
80 
81  // reopen the closed window and ensure its integrity
82  let newWin2 = ss.undoCloseWindow(0);
83 
84  ok(newWin2 instanceof ChromeWindow,
85  "undoCloseWindow actually returned a window");
86  is(ss.getClosedWindowCount(), closedWindowCount,
87  "The reopened window was removed from Recently Closed Windows");
88 
89  newWin2.addEventListener("load", function(aEvent) {
90  newWin2.gBrowser.addEventListener("SSTabRestored", function(aEvent) {
91  newWin2.gBrowser.removeEventListener("SSTabRestored", arguments.callee, true);
92 
93  is(newWin2.gBrowser.tabContainer.childNodes.length, 2,
94  "The window correctly restored 2 tabs");
95  is(newWin2.gBrowser.currentURI.spec, testURL,
96  "The window correctly restored the URL");
97 
98  let textbox = newWin2.content.document.getElementById("textbox");
99  is(textbox.wrappedJSObject.value, uniqueText,
100  "The window correctly restored the form");
101  is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
102  "The window correctly restored the data associated with it");
103 
104  // clean up
105  newWin2.close();
106  if (gPrefService.prefHasUserValue("browser.sessionstore.max_windows_undo"))
107  gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
108  executeSoon(callback);
109  }, true);
110  }, false);
111  });
112  });
113  }, true);
114  }, false);
115  }
116 
117  function test_behavior (callback) {
118  // helper function that does the actual testing
119  function openWindowRec(windowsToOpen, expectedResults, recCallback) {
120  // do actual checking
121  if (!windowsToOpen.length) {
122  let closedWindowData = JSON.parse(ss.getClosedWindowData());
123  let numPopups = closedWindowData.filter(function(el, i, arr) {
124  return el.isPopup;
125  }).length;
126  let numNormal = ss.getClosedWindowCount() - numPopups;
127  // #ifdef doesn't work in browser-chrome tests, so do a simple regex on platform
128  let oResults = navigator.platform.match(/Mac/) ? expectedResults.mac
129  : expectedResults.other;
130  is(numPopups, oResults.popup,
131  "There were " + oResults.popup + " popup windows to repoen");
132  is(numNormal, oResults.normal,
133  "There were " + oResults.normal + " normal windows to repoen");
134 
135  // cleanup & return
136  executeSoon(recCallback);
137  return;
138  }
139  // hack to force window to be considered a popup (toolbar=no didn't work)
140  let winData = windowsToOpen.shift();
141  let settings = "chrome,dialog=no," +
142  (winData.isPopup ? "all=no" : "all");
143  let url = "http://window" + windowsToOpen.length + ".example.com";
144  let window = openDialog(location, "_blank", settings, url);
145  window.addEventListener("load", function(aEvent) {
146  window.gBrowser.addEventListener("load", function(aEvent) {
147  // the window _should_ have state with a tab of url, but it doesn't
148  // always happend before window.close(). addTab ensure we don't treat
149  // this window as a stateless window
150  window.gBrowser.addTab();
151  window.gBrowser.removeEventListener("load", arguments.callee, true);
152  executeSoon(function() {
153  window.close();
154  executeSoon(function() {
155  openWindowRec(windowsToOpen, expectedResults, recCallback);
156  });
157  });
158  }, true);
159  }, true);
160  }
161 
162  let windowsToOpen = [{isPopup: false},
163  {isPopup: false},
164  {isPopup: true},
165  {isPopup: true},
166  {isPopup: true}];
167  let expectedResults = {mac: {popup: 3, normal: 0},
168  other: {popup: 3, normal: 1}};
169  let windowsToOpen2 = [{isPopup: false},
170  {isPopup: false},
171  {isPopup: false},
172  {isPopup: false},
173  {isPopup: false}];
174  let expectedResults2 = {mac: {popup: 0, normal: 3},
175  other: {popup: 0, normal: 3}};
176  openWindowRec(windowsToOpen, expectedResults, function() {
177  openWindowRec(windowsToOpen2, expectedResults2, callback);
178  });
179  }
180 
181  function test_purge(callback) {
182  // utility functions
183  function countClosedTabsByTitle(aClosedTabList, aTitle)
184  aClosedTabList.filter(function(aData) aData.title == aTitle).length;
185 
186  function countOpenTabsByTitle(aOpenTabList, aTitle)
187  aOpenTabList.filter(function(aData) aData.entries.some(function(aEntry) aEntry.title == aTitle) ).length
188 
189  // backup old state
190  let oldState = ss.getBrowserState();
191  // create a new state for testing
192  const REMEMBER = Date.now(), FORGET = Math.random();
193  let testState = {
194  windows: [ { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 } ],
195  _closedWindows : [
196  // _closedWindows[0]
197  {
198  tabs: [
199  { entries: [{ url: "http://example.com/", title: REMEMBER }] },
200  { entries: [{ url: "http://mozilla.org/", title: FORGET }] }
201  ],
202  selected: 2,
203  title: "mozilla.org",
204  _closedTabs: []
205  },
206  // _closedWindows[1]
207  {
208  tabs: [
209  { entries: [{ url: "http://mozilla.org/", title: FORGET }] },
210  { entries: [{ url: "http://example.com/", title: REMEMBER }] },
211  { entries: [{ url: "http://example.com/", title: REMEMBER }] },
212  { entries: [{ url: "http://mozilla.org/", title: FORGET }] },
213  { entries: [{ url: "http://example.com/", title: REMEMBER }] }
214  ],
215  selected: 5,
216  _closedTabs: []
217  },
218  // _closedWindows[2]
219  {
220  tabs: [
221  { entries: [{ url: "http://example.com/", title: REMEMBER }] }
222  ],
223  selected: 1,
224  _closedTabs: [
225  {
226  state: {
227  entries: [
228  { url: "http://mozilla.org/", title: FORGET },
229  { url: "http://mozilla.org/again", title: "doesn't matter" }
230  ]
231  },
232  pos: 1,
233  title: FORGET
234  },
235  {
236  state: {
237  entries: [
238  { url: "http://example.com", title: REMEMBER }
239  ]
240  },
241  title: REMEMBER
242  }
243  ]
244  }
245  ]
246  };
247 
248  // set browser to test state
249  ss.setBrowserState(JSON.stringify(testState));
250 
251  // purge domain & check that we purged correctly for closed windows
252  pb.removeDataFromDomain("mozilla.org");
253 
254  let closedWindowData = JSON.parse(ss.getClosedWindowData());
255 
256  // First set of tests for _closedWindows[0] - tests basics
257  let window = closedWindowData[0];
258  is(window.tabs.length, 1, "1 tab was removed");
259  is(countOpenTabsByTitle(window.tabs, FORGET), 0,
260  "The correct tab was removed");
261  is(countOpenTabsByTitle(window.tabs, REMEMBER), 1,
262  "The correct tab was remembered");
263  is(window.selected, 1, "Selected tab has changed");
264  is(window.title, REMEMBER, "The window title was correctly updated");
265 
266  // Test more complicated case
267  window = closedWindowData[1];
268  is(window.tabs.length, 3, "2 tabs were removed");
269  is(countOpenTabsByTitle(window.tabs, FORGET), 0,
270  "The correct tabs were removed");
271  is(countOpenTabsByTitle(window.tabs, REMEMBER), 3,
272  "The correct tabs were remembered");
273  is(window.selected, 3, "Selected tab has changed");
274  is(window.title, REMEMBER, "The window title was correctly updated");
275 
276  // Tests handling of _closedTabs
277  window = closedWindowData[2];
278  is(countClosedTabsByTitle(window._closedTabs, REMEMBER), 1,
279  "The correct number of tabs were removed, and the correct ones");
280  is(countClosedTabsByTitle(window._closedTabs, FORGET), 0,
281  "All tabs to be forgotten were indeed removed");
282 
283  // restore pre-test state
284  ss.setBrowserState(oldState);
285  executeSoon(callback);
286  }
287 
288  test_basic(function() {
289  test_behavior(function() {
290  test_purge(function() {
291  finish();
292  });
293  });
294  });
295 }
const Cc
_dialogDatepicker pos
var windows
let window
var tabs
waitForExplicitFinish()
_dialogDatepicker settings
var testURL
grep callback
return!aWindow arguments!aWindow arguments[0]
var gPrefService
Definition: overlay.js:34
function url(spec)
const Ci
var JSON
function test()
observe data
Definition: FeedWriter.js:1329
_getSelectedPageStyle s i
var winData
_updateTextAndScrollDataForFrame aData