michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: const URL = ROOT + "browser_formdata_xpath_sample.html"; michael@0: michael@0: /** michael@0: * Bug 346337 - Generic form data restoration tests. michael@0: */ michael@0: add_task(function setup() { michael@0: // make sure we don't save form data at all (except for tab duplication) michael@0: Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2); michael@0: michael@0: registerCleanupFunction(() => { michael@0: Services.prefs.clearUserPref("browser.sessionstore.privacy_level"); michael@0: }); michael@0: }); michael@0: michael@0: const FILE1 = createFilePath("346337_test1.file"); michael@0: const FILE2 = createFilePath("346337_test2.file"); michael@0: michael@0: const FIELDS = { 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'][1]": [FILE1], michael@0: "//input[@type='file'][2]": [FILE1, FILE2] michael@0: }; michael@0: michael@0: add_task(function test_form_data_restoration() { michael@0: // Load page with some input fields. michael@0: let tab = gBrowser.addTab(URL); michael@0: let browser = tab.linkedBrowser; michael@0: yield promiseBrowserLoaded(browser); michael@0: michael@0: // Fill in some values. michael@0: for (let xpath of Object.keys(FIELDS)) { michael@0: yield setFormValue(browser, xpath); michael@0: } michael@0: michael@0: // Duplicate the tab. michael@0: let tab2 = gBrowser.duplicateTab(tab); michael@0: let browser2 = tab2.linkedBrowser; michael@0: yield promiseTabRestored(tab2); michael@0: michael@0: // Check that all form values have been duplicated. michael@0: for (let xpath of Object.keys(FIELDS)) { michael@0: let expected = JSON.stringify(FIELDS[xpath]); michael@0: let actual = JSON.stringify(yield getFormValue(browser2, xpath)); michael@0: is(actual, expected, "The value for \"" + xpath + "\" was correctly restored"); michael@0: } michael@0: michael@0: // Remove all tabs. michael@0: gBrowser.removeTab(tab2); michael@0: gBrowser.removeTab(tab); michael@0: michael@0: // Restore one of the tabs again. michael@0: tab = ss.undoCloseTab(window, 0); michael@0: browser = tab.linkedBrowser; michael@0: yield promiseTabRestored(tab); michael@0: michael@0: // Check that none of the form values have been restored due to the privacy michael@0: // level settings. michael@0: for (let xpath of Object.keys(FIELDS)) { michael@0: let expected = FIELDS[xpath]; michael@0: if (expected) { michael@0: let actual = yield getFormValue(browser, xpath, expected); michael@0: isnot(actual, expected, "The value for \"" + xpath + "\" was correctly discarded"); michael@0: } michael@0: } michael@0: michael@0: // Cleanup. michael@0: gBrowser.removeTab(tab); michael@0: }); michael@0: michael@0: function createFilePath(leaf) { michael@0: let file = Services.dirsvc.get("TmpD", Ci.nsIFile); michael@0: file.append(leaf); michael@0: return file.path; michael@0: } michael@0: michael@0: function isArrayOfNumbers(value) { michael@0: return Array.isArray(value) && value.every(n => typeof(n) === "number"); michael@0: } michael@0: michael@0: function isArrayOfStrings(value) { michael@0: return Array.isArray(value) && value.every(n => typeof(n) === "string"); michael@0: } michael@0: michael@0: function getFormValue(browser, xpath) { michael@0: let value = FIELDS[xpath]; michael@0: michael@0: if (typeof value == "string") { michael@0: return getInputValue(browser, {xpath: xpath}); michael@0: } michael@0: michael@0: if (typeof value == "boolean") { michael@0: return getInputChecked(browser, {xpath: xpath}); michael@0: } michael@0: michael@0: if (typeof value == "number") { michael@0: return getSelectedIndex(browser, {xpath: xpath}); michael@0: } michael@0: michael@0: if (isArrayOfNumbers(value)) { michael@0: return getMultipleSelected(browser, {xpath: xpath}); michael@0: } michael@0: michael@0: if (isArrayOfStrings(value)) { michael@0: return getFileNameArray(browser, {xpath: xpath}); michael@0: } michael@0: michael@0: throw new Error("unknown input type"); michael@0: } michael@0: michael@0: function setFormValue(browser, xpath) { michael@0: let value = FIELDS[xpath]; michael@0: michael@0: if (typeof value == "string") { michael@0: return setInputValue(browser, {xpath: xpath, value: value}); michael@0: } michael@0: michael@0: if (typeof value == "boolean") { michael@0: return setInputChecked(browser, {xpath: xpath, checked: value}); michael@0: } michael@0: michael@0: if (typeof value == "number") { michael@0: return setSelectedIndex(browser, {xpath: xpath, index: value}); michael@0: } michael@0: michael@0: if (isArrayOfNumbers(value)) { michael@0: return setMultipleSelected(browser, {xpath: xpath, indices: value}); michael@0: } michael@0: michael@0: if (isArrayOfStrings(value)) { michael@0: return setFileNameArray(browser, {xpath: xpath, names: value}); michael@0: } michael@0: michael@0: throw new Error("unknown input type"); michael@0: }