|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 function test() { |
|
6 /** Test (B) for Bug 248970 **/ |
|
7 waitForExplicitFinish(); |
|
8 |
|
9 let windowsToClose = []; |
|
10 let file = Services.dirsvc.get("TmpD", Ci.nsIFile); |
|
11 let filePath = file.path; |
|
12 let fieldList = { |
|
13 "//input[@name='input']": Date.now().toString(), |
|
14 "//input[@name='spaced 1']": Math.random().toString(), |
|
15 "//input[3]": "three", |
|
16 "//input[@type='checkbox']": true, |
|
17 "//input[@name='uncheck']": false, |
|
18 "//input[@type='radio'][1]": false, |
|
19 "//input[@type='radio'][2]": true, |
|
20 "//input[@type='radio'][3]": false, |
|
21 "//select": 2, |
|
22 "//select[@multiple]": [1, 3], |
|
23 "//textarea[1]": "", |
|
24 "//textarea[2]": "Some text... " + Math.random(), |
|
25 "//textarea[3]": "Some more text\n" + new Date(), |
|
26 "//input[@type='file']": filePath |
|
27 }; |
|
28 |
|
29 registerCleanupFunction(function() { |
|
30 windowsToClose.forEach(function(win) { |
|
31 win.close(); |
|
32 }); |
|
33 }); |
|
34 |
|
35 function test(aLambda) { |
|
36 try { |
|
37 return aLambda() || true; |
|
38 } catch(ex) { } |
|
39 return false; |
|
40 } |
|
41 |
|
42 function getElementByXPath(aTab, aQuery) { |
|
43 let doc = aTab.linkedBrowser.contentDocument; |
|
44 let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE; |
|
45 return doc.evaluate(aQuery, doc, null, xptype, null).singleNodeValue; |
|
46 } |
|
47 |
|
48 function setFormValue(aTab, aQuery, aValue) { |
|
49 let node = getElementByXPath(aTab, aQuery); |
|
50 if (typeof aValue == "string") |
|
51 node.value = aValue; |
|
52 else if (typeof aValue == "boolean") |
|
53 node.checked = aValue; |
|
54 else if (typeof aValue == "number") |
|
55 node.selectedIndex = aValue; |
|
56 else |
|
57 Array.forEach(node.options, function(aOpt, aIx) |
|
58 (aOpt.selected = aValue.indexOf(aIx) > -1)); |
|
59 } |
|
60 |
|
61 function compareFormValue(aTab, aQuery, aValue) { |
|
62 let node = getElementByXPath(aTab, aQuery); |
|
63 if (!node) |
|
64 return false; |
|
65 if (node instanceof Ci.nsIDOMHTMLInputElement) |
|
66 return aValue == (node.type == "checkbox" || node.type == "radio" ? |
|
67 node.checked : node.value); |
|
68 if (node instanceof Ci.nsIDOMHTMLTextAreaElement) |
|
69 return aValue == node.value; |
|
70 if (!node.multiple) |
|
71 return aValue == node.selectedIndex; |
|
72 return Array.every(node.options, function(aOpt, aIx) |
|
73 (aValue.indexOf(aIx) > -1) == aOpt.selected); |
|
74 } |
|
75 |
|
76 ////////////////////////////////////////////////////////////////// |
|
77 // Test (B) : Session data restoration between windows // |
|
78 ////////////////////////////////////////////////////////////////// |
|
79 |
|
80 let rootDir = getRootDirectory(gTestPath); |
|
81 const testURL = rootDir + "browser_248970_b_sample.html"; |
|
82 const testURL2 = "http://mochi.test:8888/browser/" + |
|
83 "browser/components/sessionstore/test/browser_248970_b_sample.html"; |
|
84 |
|
85 whenNewWindowLoaded({ private: false }, function(aWin) { |
|
86 windowsToClose.push(aWin); |
|
87 |
|
88 // get closed tab count |
|
89 let count = ss.getClosedTabCount(aWin); |
|
90 let max_tabs_undo = |
|
91 Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo"); |
|
92 ok(0 <= count && count <= max_tabs_undo, |
|
93 "getClosedTabCount should return zero or at most max_tabs_undo"); |
|
94 |
|
95 // setup a state for tab (A) so we can check later that is restored |
|
96 let key = "key"; |
|
97 let value = "Value " + Math.random(); |
|
98 let state = { entries: [{ url: testURL }], extData: { key: value } }; |
|
99 |
|
100 // public session, add new tab: (A) |
|
101 let tab_A = aWin.gBrowser.addTab(testURL); |
|
102 ss.setTabState(tab_A, JSON.stringify(state)); |
|
103 whenBrowserLoaded(tab_A.linkedBrowser, function() { |
|
104 // make sure that the next closed tab will increase getClosedTabCount |
|
105 Services.prefs.setIntPref( |
|
106 "browser.sessionstore.max_tabs_undo", max_tabs_undo + 1) |
|
107 |
|
108 // populate tab_A with form data |
|
109 for (let i in fieldList) |
|
110 setFormValue(tab_A, i, fieldList[i]); |
|
111 |
|
112 // public session, close tab: (A) |
|
113 aWin.gBrowser.removeTab(tab_A); |
|
114 |
|
115 // verify that closedTabCount increased |
|
116 ok(ss.getClosedTabCount(aWin) > count, |
|
117 "getClosedTabCount has increased after closing a tab"); |
|
118 |
|
119 // verify tab: (A), in undo list |
|
120 let tab_A_restored = test(function() ss.undoCloseTab(aWin, 0)); |
|
121 ok(tab_A_restored, "a tab is in undo list"); |
|
122 whenTabRestored(tab_A_restored, function() { |
|
123 is(testURL, tab_A_restored.linkedBrowser.currentURI.spec, |
|
124 "it's the same tab that we expect"); |
|
125 aWin.gBrowser.removeTab(tab_A_restored); |
|
126 |
|
127 whenNewWindowLoaded({ private: true }, function(aWin) { |
|
128 windowsToClose.push(aWin); |
|
129 |
|
130 // setup a state for tab (B) so we can check that its duplicated |
|
131 // properly |
|
132 let key1 = "key1"; |
|
133 let value1 = "Value " + Math.random(); |
|
134 let state1 = { |
|
135 entries: [{ url: testURL2 }], extData: { key1: value1 } |
|
136 }; |
|
137 |
|
138 let tab_B = aWin.gBrowser.addTab(testURL2); |
|
139 ss.setTabState(tab_B, JSON.stringify(state1)); |
|
140 whenTabRestored(tab_B, function() { |
|
141 // populate tab: (B) with different form data |
|
142 for (let item in fieldList) |
|
143 setFormValue(tab_B, item, fieldList[item]); |
|
144 |
|
145 // duplicate tab: (B) |
|
146 let tab_C = aWin.gBrowser.duplicateTab(tab_B); |
|
147 whenTabRestored(tab_C, function() { |
|
148 // verify the correctness of the duplicated tab |
|
149 is(ss.getTabValue(tab_C, key1), value1, |
|
150 "tab successfully duplicated - correct state"); |
|
151 |
|
152 for (let item in fieldList) |
|
153 ok(compareFormValue(tab_C, item, fieldList[item]), |
|
154 "The value for \"" + item + "\" was correctly duplicated"); |
|
155 |
|
156 // private browsing session, close tab: (C) and (B) |
|
157 aWin.gBrowser.removeTab(tab_C); |
|
158 aWin.gBrowser.removeTab(tab_B); |
|
159 |
|
160 finish(); |
|
161 }); |
|
162 }); |
|
163 }); |
|
164 }); |
|
165 }); |
|
166 }); |
|
167 } |