Files
palemoon27/mobile/android/base/tests/testSessionFormData.js
T

217 lines
6.6 KiB
JavaScript

// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
function ok(passed, text) {
do_report_result(passed, text, Components.stack.caller, false);
}
function is(lhs, rhs, text) {
do_report_result(lhs === rhs, text, Components.stack.caller, false);
}
// Make the timer global so it doesn't get GC'd
let gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
function sleep(wait) {
return new Promise((resolve, reject) => {
do_print("sleep start");
gTimer.initWithCallback({
notify: function () {
do_print("sleep end");
resolve();
},
}, wait, gTimer.TYPE_ONE_SHOT);
});
}
function promiseBrowserLoaded(browser, eventType="load") {
return new Promise((resolve, reject) => {
do_print("Wait browser event: " + eventType);
function handle(event) {
if (event.target != browser.contentDocument) {
do_print("Skipping spurious '" + eventType + "' event" + " for " + event.target.location.href);
return;
}
browser.removeEventListener(eventType, handle, true);
do_print("Browser event received: " + eventType);
resolve(event);
}
browser.addEventListener(eventType, handle, true);
});
}
function queryElement(contentWindow, data) {
let frame = contentWindow;
if (data.hasOwnProperty("frame")) {
frame = contentWindow.frames[data.frame];
}
let doc = frame.document;
if (data.hasOwnProperty("id")) {
return doc.getElementById(data.id);
}
if (data.hasOwnProperty("selector")) {
return doc.querySelector(data.selector);
}
if (data.hasOwnProperty("xpath")) {
let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
return doc.evaluate(data.xpath, doc, null, xptype, null).singleNodeValue;
}
throw new Error("couldn't query element");
}
function dispatchUIEvent(input, type) {
let event = input.ownerDocument.createEvent("UIEvents");
event.initUIEvent(type, true, true, input.ownerDocument.defaultView, 0);
input.dispatchEvent(event);
}
function setInputValue(browser, data) {
let input = queryElement(browser.contentWindow, data);
input.value = data.value;
dispatchUIEvent(input, "input");
}
function getInputValue(browser, data) {
let input = queryElement(browser.contentWindow, data);
return input.value;
}
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
let gChromeWin;
let gBrowserApp;
// Wait 2 seconds for the async Java/JS messsaging dance to settle down. We don't have
// enough pre/post events, messages or notifications to handle this without a delay.
const CLOSE_TAB_WAIT = 2000;
add_test(function setup_browser() {
gChromeWin = Services.wm.getMostRecentWindow("navigator:browser");
gBrowserApp = gChromeWin.BrowserApp;
Services.tm.mainThread.dispatch(run_next_test, Ci.nsIThread.DISPATCH_NORMAL);
});
/**
* This test ensures that form data collection respects the privacy level as
* set by the user.
*/
add_task(function test_formdata() {
const URL = "http://example.org/tests/robocop/session_formdata_sample.html";
const OUTER_VALUE = "browser_formdata_" + Math.random();
const INNER_VALUE = "browser_formdata_" + Math.random();
// Creates a tab, loads a page with some form fields,
// modifies their values and closes the tab.
function createAndRemoveTab() {
return Task.spawn(function () {
// Create a new tab.
let tab = gBrowserApp.addTab(URL);
let browser = tab.browser;
yield promiseBrowserLoaded(browser);
// Modify form data.
setInputValue(browser, {id: "txt", value: OUTER_VALUE});
setInputValue(browser, {id: "txt", value: INNER_VALUE, frame: 0});
// Remove the tab.
gBrowserApp.closeTab(tab);
yield sleep(CLOSE_TAB_WAIT);
});
}
yield createAndRemoveTab();
let state = ss.getClosedTabs(gChromeWin);
let [{formdata}] = state;
is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
is(formdata.children[0].id.txt, INNER_VALUE, "inner value is correct");
// Disable saving data for encrypted sites.
Services.prefs.setIntPref("browser.sessionstore.privacy_level", 1);
yield createAndRemoveTab();
state = ss.getClosedTabs(gChromeWin);
[{formdata}] = state;
is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
ok(!formdata.children, "inner value was *not* stored");
// Disable saving data for any site.
Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2);
yield createAndRemoveTab();
state = ss.getClosedTabs(gChromeWin);
[{formdata}] = state;
ok(!formdata, "form data has *not* been stored");
// Restore the default privacy level.
Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
});
/**
* This test ensures that form data collection restores correctly.
*/
add_task(function test_formdata() {
const URL = "http://example.org/tests/robocop/session_formdata_sample.html";
const OUTER_VALUE = "browser_formdata_" + Math.random();
const INNER_VALUE = "browser_formdata_" + Math.random();
// Creates a tab, loads a page with some form fields,
// modifies their values and closes the tab.
function createAndRemoveTab() {
return Task.spawn(function () {
// Create a new tab.
let tab = gBrowserApp.addTab(URL);
let browser = tab.browser;
yield promiseBrowserLoaded(browser);
// Modify form data.
setInputValue(browser, {id: "txt", value: OUTER_VALUE});
setInputValue(browser, {id: "txt", value: INNER_VALUE, frame: 0});
// Remove the tab.
gBrowserApp.closeTab(tab);
yield sleep(CLOSE_TAB_WAIT);
});
}
yield createAndRemoveTab();
let state = ss.getClosedTabs(gChromeWin);
let [{formdata}] = state;
is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
is(formdata.children[0].id.txt, INNER_VALUE, "inner value is correct");
// Restore the closed tab.
let closedTabData = ss.getClosedTabs(gChromeWin)[0];
let browser = ss.undoCloseTab(gChromeWin, closedTabData);
yield promiseBrowserLoaded(browser);
// Check the form data.
is(getInputValue(browser, {id: "txt"}), OUTER_VALUE, "outer value restored correctly");
is(getInputValue(browser, {id: "txt", frame: 0}), INNER_VALUE, "inner value restored correctly");
// Remove the tab.
gBrowserApp.closeTab(gBrowserApp.getTabForBrowser(browser));
});
run_next_test();