michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: function test() { michael@0: /** Test (B) for Bug 248970 **/ michael@0: waitForExplicitFinish(); michael@0: michael@0: let windowsToClose = []; michael@0: let file = Services.dirsvc.get("TmpD", Ci.nsIFile); michael@0: let filePath = file.path; michael@0: let fieldList = { michael@0: "//input[@name='input']": Date.now().toString(), michael@0: "//input[@name='spaced 1']": Math.random().toString(), michael@0: "//input[3]": "three", michael@0: "//input[@type='checkbox']": true, michael@0: "//input[@name='uncheck']": false, michael@0: "//input[@type='radio'][1]": false, michael@0: "//input[@type='radio'][2]": true, michael@0: "//input[@type='radio'][3]": false, michael@0: "//select": 2, michael@0: "//select[@multiple]": [1, 3], michael@0: "//textarea[1]": "", michael@0: "//textarea[2]": "Some text... " + Math.random(), michael@0: "//textarea[3]": "Some more text\n" + new Date(), michael@0: "//input[@type='file']": filePath michael@0: }; michael@0: michael@0: registerCleanupFunction(function() { michael@0: windowsToClose.forEach(function(win) { michael@0: win.close(); michael@0: }); michael@0: }); michael@0: michael@0: function test(aLambda) { michael@0: try { michael@0: return aLambda() || true; michael@0: } catch(ex) { } michael@0: return false; michael@0: } michael@0: michael@0: function getElementByXPath(aTab, aQuery) { michael@0: let doc = aTab.linkedBrowser.contentDocument; michael@0: let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE; michael@0: return doc.evaluate(aQuery, doc, null, xptype, null).singleNodeValue; michael@0: } michael@0: michael@0: function setFormValue(aTab, aQuery, aValue) { michael@0: let node = getElementByXPath(aTab, aQuery); michael@0: if (typeof aValue == "string") michael@0: node.value = aValue; michael@0: else if (typeof aValue == "boolean") michael@0: node.checked = aValue; michael@0: else if (typeof aValue == "number") michael@0: node.selectedIndex = aValue; michael@0: else michael@0: Array.forEach(node.options, function(aOpt, aIx) michael@0: (aOpt.selected = aValue.indexOf(aIx) > -1)); michael@0: } michael@0: michael@0: function compareFormValue(aTab, aQuery, aValue) { michael@0: let node = getElementByXPath(aTab, aQuery); michael@0: if (!node) michael@0: return false; michael@0: if (node instanceof Ci.nsIDOMHTMLInputElement) michael@0: return aValue == (node.type == "checkbox" || node.type == "radio" ? michael@0: node.checked : node.value); michael@0: if (node instanceof Ci.nsIDOMHTMLTextAreaElement) michael@0: return aValue == node.value; michael@0: if (!node.multiple) michael@0: return aValue == node.selectedIndex; michael@0: return Array.every(node.options, function(aOpt, aIx) michael@0: (aValue.indexOf(aIx) > -1) == aOpt.selected); michael@0: } michael@0: michael@0: ////////////////////////////////////////////////////////////////// michael@0: // Test (B) : Session data restoration between windows // michael@0: ////////////////////////////////////////////////////////////////// michael@0: michael@0: let rootDir = getRootDirectory(gTestPath); michael@0: const testURL = rootDir + "browser_248970_b_sample.html"; michael@0: const testURL2 = "http://mochi.test:8888/browser/" + michael@0: "browser/components/sessionstore/test/browser_248970_b_sample.html"; michael@0: michael@0: whenNewWindowLoaded({ private: false }, function(aWin) { michael@0: windowsToClose.push(aWin); michael@0: michael@0: // get closed tab count michael@0: let count = ss.getClosedTabCount(aWin); michael@0: let max_tabs_undo = michael@0: Services.prefs.getIntPref("browser.sessionstore.max_tabs_undo"); michael@0: ok(0 <= count && count <= max_tabs_undo, michael@0: "getClosedTabCount should return zero or at most max_tabs_undo"); michael@0: michael@0: // setup a state for tab (A) so we can check later that is restored michael@0: let key = "key"; michael@0: let value = "Value " + Math.random(); michael@0: let state = { entries: [{ url: testURL }], extData: { key: value } }; michael@0: michael@0: // public session, add new tab: (A) michael@0: let tab_A = aWin.gBrowser.addTab(testURL); michael@0: ss.setTabState(tab_A, JSON.stringify(state)); michael@0: whenBrowserLoaded(tab_A.linkedBrowser, function() { michael@0: // make sure that the next closed tab will increase getClosedTabCount michael@0: Services.prefs.setIntPref( michael@0: "browser.sessionstore.max_tabs_undo", max_tabs_undo + 1) michael@0: michael@0: // populate tab_A with form data michael@0: for (let i in fieldList) michael@0: setFormValue(tab_A, i, fieldList[i]); michael@0: michael@0: // public session, close tab: (A) michael@0: aWin.gBrowser.removeTab(tab_A); michael@0: michael@0: // verify that closedTabCount increased michael@0: ok(ss.getClosedTabCount(aWin) > count, michael@0: "getClosedTabCount has increased after closing a tab"); michael@0: michael@0: // verify tab: (A), in undo list michael@0: let tab_A_restored = test(function() ss.undoCloseTab(aWin, 0)); michael@0: ok(tab_A_restored, "a tab is in undo list"); michael@0: whenTabRestored(tab_A_restored, function() { michael@0: is(testURL, tab_A_restored.linkedBrowser.currentURI.spec, michael@0: "it's the same tab that we expect"); michael@0: aWin.gBrowser.removeTab(tab_A_restored); michael@0: michael@0: whenNewWindowLoaded({ private: true }, function(aWin) { michael@0: windowsToClose.push(aWin); michael@0: michael@0: // setup a state for tab (B) so we can check that its duplicated michael@0: // properly michael@0: let key1 = "key1"; michael@0: let value1 = "Value " + Math.random(); michael@0: let state1 = { michael@0: entries: [{ url: testURL2 }], extData: { key1: value1 } michael@0: }; michael@0: michael@0: let tab_B = aWin.gBrowser.addTab(testURL2); michael@0: ss.setTabState(tab_B, JSON.stringify(state1)); michael@0: whenTabRestored(tab_B, function() { michael@0: // populate tab: (B) with different form data michael@0: for (let item in fieldList) michael@0: setFormValue(tab_B, item, fieldList[item]); michael@0: michael@0: // duplicate tab: (B) michael@0: let tab_C = aWin.gBrowser.duplicateTab(tab_B); michael@0: whenTabRestored(tab_C, function() { michael@0: // verify the correctness of the duplicated tab michael@0: is(ss.getTabValue(tab_C, key1), value1, michael@0: "tab successfully duplicated - correct state"); michael@0: michael@0: for (let item in fieldList) michael@0: ok(compareFormValue(tab_C, item, fieldList[item]), michael@0: "The value for \"" + item + "\" was correctly duplicated"); michael@0: michael@0: // private browsing session, close tab: (C) and (B) michael@0: aWin.gBrowser.removeTab(tab_C); michael@0: aWin.gBrowser.removeTab(tab_B); michael@0: michael@0: finish(); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }