browser/components/sessionstore/test/browser_formdata.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/components/sessionstore/test/browser_formdata.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,231 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +"use strict";
     1.8 +
     1.9 +/**
    1.10 + * This test ensures that form data collection respects the privacy level as
    1.11 + * set by the user.
    1.12 + */
    1.13 +add_task(function test_formdata() {
    1.14 +  const URL = "http://mochi.test:8888/browser/browser/components/" +
    1.15 +              "sessionstore/test/browser_formdata_sample.html";
    1.16 +
    1.17 +  const OUTER_VALUE = "browser_formdata_" + Math.random();
    1.18 +  const INNER_VALUE = "browser_formdata_" + Math.random();
    1.19 +
    1.20 +  // Creates a tab, loads a page with some form fields,
    1.21 +  // modifies their values and closes the tab.
    1.22 +  function createAndRemoveTab() {
    1.23 +    return Task.spawn(function () {
    1.24 +      // Create a new tab.
    1.25 +      let tab = gBrowser.addTab(URL);
    1.26 +      let browser = tab.linkedBrowser;
    1.27 +      yield promiseBrowserLoaded(browser);
    1.28 +
    1.29 +      // Modify form data.
    1.30 +      yield setInputValue(browser, {id: "txt", value: OUTER_VALUE});
    1.31 +      yield setInputValue(browser, {id: "txt", value: INNER_VALUE, frame: 0});
    1.32 +
    1.33 +      // Remove the tab.
    1.34 +      gBrowser.removeTab(tab);
    1.35 +    });
    1.36 +  }
    1.37 +
    1.38 +  yield createAndRemoveTab();
    1.39 +  let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
    1.40 +  is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
    1.41 +  is(formdata.children[0].id.txt, INNER_VALUE, "inner value is correct");
    1.42 +
    1.43 +  // Disable saving data for encrypted sites.
    1.44 +  Services.prefs.setIntPref("browser.sessionstore.privacy_level", 1);
    1.45 +
    1.46 +  yield createAndRemoveTab();
    1.47 +  let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
    1.48 +  is(formdata.id.txt, OUTER_VALUE, "outer value is correct");
    1.49 +  ok(!formdata.children, "inner value was *not* stored");
    1.50 +
    1.51 +  // Disable saving data for any site.
    1.52 +  Services.prefs.setIntPref("browser.sessionstore.privacy_level", 2);
    1.53 +
    1.54 +  yield createAndRemoveTab();
    1.55 +  let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
    1.56 +  ok(!formdata, "form data has *not* been stored");
    1.57 +
    1.58 +  // Restore the default privacy level.
    1.59 +  Services.prefs.clearUserPref("browser.sessionstore.privacy_level");
    1.60 +});
    1.61 +
    1.62 +/**
    1.63 + * This test ensures that we maintain backwards compatibility with the form
    1.64 + * data format used pre Fx 29.
    1.65 + */
    1.66 +add_task(function test_old_format() {
    1.67 +  const URL = "data:text/html;charset=utf-8,<input%20id=input>";
    1.68 +  const VALUE = "value-" + Math.random();
    1.69 +
    1.70 +  // Create a tab with an iframe containing an input field.
    1.71 +  let tab = gBrowser.addTab(URL);
    1.72 +  let browser = tab.linkedBrowser;
    1.73 +  yield promiseBrowserLoaded(browser);
    1.74 +
    1.75 +  // Check that the form value is restored.
    1.76 +  let state = {entries: [{url: URL, formdata: {id: {input: VALUE}}}]};
    1.77 +  ss.setTabState(tab, JSON.stringify(state));
    1.78 +  yield promiseTabRestored(tab);
    1.79 +  is((yield getInputValue(browser, "input")), VALUE, "form data restored");
    1.80 +
    1.81 +  // Cleanup.
    1.82 +  gBrowser.removeTab(tab);
    1.83 +});
    1.84 +
    1.85 +/**
    1.86 + * This test ensures that we maintain backwards compatibility with the form
    1.87 + * data form used pre Fx 29, esp. the .innerHTML property for editable docs.
    1.88 + */
    1.89 +add_task(function test_old_format_inner_html() {
    1.90 +  const URL = "data:text/html;charset=utf-8,<h1>mozilla</h1>" +
    1.91 +              "<script>document.designMode='on'</script>";
    1.92 +  const VALUE = "<h1>value-" + Math.random() + "</h1>";
    1.93 +
    1.94 +  // Create a tab with an iframe containing an input field.
    1.95 +  let tab = gBrowser.addTab(URL);
    1.96 +  let browser = tab.linkedBrowser;
    1.97 +  yield promiseBrowserLoaded(browser);
    1.98 +
    1.99 +  // Restore the tab state.
   1.100 +  let state = {entries: [{url: URL, innerHTML: VALUE}]};
   1.101 +  ss.setTabState(tab, JSON.stringify(state));
   1.102 +  yield promiseTabRestored(tab);
   1.103 +
   1.104 +  // Check that the innerHTML value was restored.
   1.105 +  let html = yield getInnerHTML(browser);
   1.106 +  is(html, VALUE, "editable document has been restored correctly");
   1.107 +
   1.108 +  // Cleanup.
   1.109 +  gBrowser.removeTab(tab);
   1.110 +});
   1.111 +
   1.112 +/**
   1.113 + * This test ensures that a malicious website can't trick us into restoring
   1.114 + * form data into a wrong website and that we always check the stored URL
   1.115 + * before doing so.
   1.116 + */
   1.117 +add_task(function test_url_check() {
   1.118 +  const URL = "data:text/html;charset=utf-8,<input%20id=input>";
   1.119 +  const VALUE = "value-" + Math.random();
   1.120 +
   1.121 +  // Create a tab with an iframe containing an input field.
   1.122 +  let tab = gBrowser.addTab(URL);
   1.123 +  let browser = tab.linkedBrowser;
   1.124 +  yield promiseBrowserLoaded(browser);
   1.125 +
   1.126 +  // Restore a tab state with a given form data url.
   1.127 +  function restoreStateWithURL(url) {
   1.128 +    let state = {entries: [{url: URL}], formdata: {id: {input: VALUE}}};
   1.129 +
   1.130 +    if (url) {
   1.131 +      state.formdata.url = url;
   1.132 +    }
   1.133 +
   1.134 +    ss.setTabState(tab, JSON.stringify(state));
   1.135 +    return promiseTabRestored(tab).then(() => getInputValue(browser, "input"));
   1.136 +  }
   1.137 +
   1.138 +  // Check that the form value is restored with the correct URL.
   1.139 +  is((yield restoreStateWithURL(URL)), VALUE, "form data restored");
   1.140 +
   1.141 +  // Check that the form value is *not* restored with the wrong URL.
   1.142 +  is((yield restoreStateWithURL(URL + "?")), "", "form data not restored");
   1.143 +  is((yield restoreStateWithURL()), "", "form data not restored");
   1.144 +
   1.145 +  // Cleanup.
   1.146 +  gBrowser.removeTab(tab);
   1.147 +});
   1.148 +
   1.149 +/**
   1.150 + * This test ensures that collecting form data works as expected when having
   1.151 + * nested frame sets.
   1.152 + */
   1.153 +add_task(function test_nested() {
   1.154 +  const URL = "data:text/html;charset=utf-8," +
   1.155 +              "<iframe src='data:text/html;charset=utf-8," +
   1.156 +              "<input autofocus=true>'/>";
   1.157 +
   1.158 +  const FORM_DATA = {
   1.159 +    children: [{
   1.160 +      xpath: {"/xhtml:html/xhtml:body/xhtml:input": "M"},
   1.161 +      url: "data:text/html;charset=utf-8,<input%20autofocus=true>"
   1.162 +    }]
   1.163 +  };
   1.164 +
   1.165 +  // Create a tab with an iframe containing an input field.
   1.166 +  let tab = gBrowser.selectedTab = gBrowser.addTab(URL);
   1.167 +  let browser = tab.linkedBrowser;
   1.168 +  yield promiseBrowserLoaded(browser);
   1.169 +
   1.170 +  // Modify the input field's value.
   1.171 +  yield sendMessage(browser, "ss-test:sendKeyEvent", {key: "m", frame: 0});
   1.172 +
   1.173 +  // Remove the tab and check that we stored form data correctly.
   1.174 +  gBrowser.removeTab(tab);
   1.175 +  let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
   1.176 +  is(JSON.stringify(formdata), JSON.stringify(FORM_DATA),
   1.177 +    "formdata for iframe stored correctly");
   1.178 +
   1.179 +  // Restore the closed tab.
   1.180 +  let tab = ss.undoCloseTab(window, 0);
   1.181 +  let browser = tab.linkedBrowser;
   1.182 +  yield promiseTabRestored(tab);
   1.183 +
   1.184 +  // Check that the input field has the right value.
   1.185 +  SyncHandlers.get(browser).flush();
   1.186 +  let {formdata} = JSON.parse(ss.getTabState(tab));
   1.187 +  is(JSON.stringify(formdata), JSON.stringify(FORM_DATA),
   1.188 +    "formdata for iframe restored correctly");
   1.189 +
   1.190 +  // Cleanup.
   1.191 +  gBrowser.removeTab(tab);
   1.192 +});
   1.193 +
   1.194 +/**
   1.195 + * This test ensures that collecting form data for documents with
   1.196 + * designMode=on works as expected.
   1.197 + */
   1.198 +add_task(function test_design_mode() {
   1.199 +  const URL = "data:text/html;charset=utf-8,<h1>mozilla</h1>" +
   1.200 +              "<script>document.designMode='on'</script>";
   1.201 +
   1.202 +  // Load a tab with an editable document.
   1.203 +  let tab = gBrowser.selectedTab = gBrowser.addTab(URL);
   1.204 +  let browser = tab.linkedBrowser;
   1.205 +  yield promiseBrowserLoaded(browser);
   1.206 +
   1.207 +  // Modify the document content.
   1.208 +  yield sendMessage(browser, "ss-test:sendKeyEvent", {key: "m"});
   1.209 +
   1.210 +  // Duplicate the modified tab.
   1.211 +  let tab2 = gBrowser.duplicateTab(tab);
   1.212 +  yield promiseTabRestored(tab2);
   1.213 +
   1.214 +  // Check that the innerHTML value was restored.
   1.215 +  let html = yield getInnerHTML(browser);
   1.216 +  let expected = "<h1>Mmozilla</h1><script>document.designMode='on'</script>";
   1.217 +  is(html, expected, "editable document has been restored correctly");
   1.218 +
   1.219 +  // Cleanup.
   1.220 +  gBrowser.removeTab(tab2);
   1.221 +  gBrowser.removeTab(tab);
   1.222 +});
   1.223 +
   1.224 +function getInputValue(browser, id) {
   1.225 +  return sendMessage(browser, "ss-test:getInputValue", {id: id});
   1.226 +}
   1.227 +
   1.228 +function setInputValue(browser, data) {
   1.229 +  return sendMessage(browser, "ss-test:setInputValue", data);
   1.230 +}
   1.231 +
   1.232 +function getInnerHTML(browser) {
   1.233 +  return sendMessage(browser, "ss-test:getInnerHTML", {selector: "body"});
   1.234 +}

mercurial