tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_formdata_face.js (4873B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * This test ensures that collecting form data for form-associated custom
      8 * elements works as expected.
      9 */
     10 add_task(async function test_face_restore() {
     11  const URL = `data:text/html;charset=utf-8,<!DOCTYPE html>
     12    <h1>mozilla</h1>
     13    <script>
     14      restoredStates = {};
     15      customElements.define("c-e", class extends HTMLElement {
     16        static formAssociated = true;
     17        constructor() {
     18          super();
     19          this.internals = this.attachInternals();
     20        }
     21        formStateRestoreCallback(state, reason) {
     22          if (reason == "restore") {
     23            restoredStates[this.id] = state;
     24          }
     25        }
     26      });
     27    </script>
     28    <form>
     29      <c-e id="test1"></c-e>
     30      <c-e id="test2"></c-e>
     31      <c-e id="test3"></c-e>
     32      <c-e id="test4"></c-e>
     33      <c-e id="test5"></c-e>
     34      <c-e id="test6"></c-e>
     35    </form>`;
     36 
     37  // Load a tab with a FACE.
     38  let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, URL));
     39  let browser = tab.linkedBrowser;
     40  await promiseBrowserLoaded(browser);
     41 
     42  // Set the FACE state and value.
     43  await SpecialPowers.spawn(browser, ["c-e"], selector => {
     44    function formDataWith(...entries) {
     45      const formData = new content.FormData();
     46      for (let [key, value] of entries) {
     47        formData.append(key, value);
     48      }
     49      return formData;
     50    }
     51    const states = [
     52      "test state",
     53      new content.File(["state"], "state.txt"),
     54      formDataWith(["1", "state"], ["2", new content.Blob(["state_blob"])]),
     55      null,
     56      undefined,
     57      null,
     58    ];
     59    const values = [
     60      "test value",
     61      new content.File(["value"], "value.txt"),
     62      formDataWith(["1", "value"], ["2", new content.Blob(["value_blob"])]),
     63      "null state",
     64      "both value and state",
     65      null,
     66    ];
     67 
     68    [...content.document.querySelectorAll(selector)].forEach((node, i) => {
     69      node.internals.setFormValue(values[i], states[i]);
     70    });
     71  });
     72 
     73  // Close and restore the tab.
     74  await promiseRemoveTabAndSessionState(tab);
     75 
     76  {
     77    let [
     78      {
     79        state: { formdata },
     80      },
     81    ] = ss.getClosedTabDataForWindow(window);
     82 
     83    is(formdata.id.test1.value, "test value", "String value should be stored");
     84    is(formdata.id.test1.state, "test state", "String state should be stored");
     85 
     86    let storedFile = formdata.id.test2.value;
     87    is(storedFile.name, "value.txt", "File value name should be stored");
     88    is(await storedFile.text(), "value", "File value text should be stored");
     89    storedFile = formdata.id.test2.state;
     90    is(storedFile.name, "state.txt", "File state name should be stored");
     91    is(await storedFile.text(), "state", "File state text should be stored");
     92 
     93    let storedFormData = formdata.id.test3.value;
     94    is(
     95      storedFormData.get("1"),
     96      "value",
     97      "FormData value string should be stored"
     98    );
     99    is(
    100      await storedFormData.get("2").text(),
    101      "value_blob",
    102      "Form value blob should be stored"
    103    );
    104    storedFormData = formdata.id.test3.state;
    105    is(
    106      storedFormData.get("1"),
    107      "state",
    108      "FormData state string should be stored"
    109    );
    110    is(
    111      await storedFormData.get("2").text(),
    112      "state_blob",
    113      "Form state blob should be stored"
    114    );
    115 
    116    is(formdata.id.test4.state, null, "Null state stored");
    117    is(formdata.id.test4.value, "null state", "Value with null state stored");
    118 
    119    is(
    120      formdata.id.test5.value,
    121      "both value and state",
    122      "Undefined state should be set to value"
    123    );
    124    is(
    125      formdata.id.test5.state,
    126      "both value and state",
    127      "Undefined state should be set to value"
    128    );
    129 
    130    ok(
    131      !("test6" in formdata.id),
    132      "Completely null values should not be stored"
    133    );
    134  }
    135 
    136  tab = ss.undoCloseTab(window, 0);
    137  browser = tab.linkedBrowser;
    138  await promiseTabRestored(tab);
    139 
    140  // Check that the FACE state was restored.
    141  await SpecialPowers.spawn(browser, ["restoredStates"], async prop => {
    142    let restoredStates = content.wrappedJSObject[prop];
    143    is(restoredStates.test1, "test state", "String should be stored");
    144 
    145    let storedFile = restoredStates.test2;
    146    is(storedFile.name, "state.txt", "File name should be stored");
    147    is(await storedFile.text(), "state", "File text should be stored");
    148 
    149    const storedFormData = restoredStates.test3;
    150    is(storedFormData.get("1"), "state", "Form data string should be stored");
    151    is(
    152      await storedFormData.get("2").text(),
    153      "state_blob",
    154      "Form data blob should be stored"
    155    );
    156 
    157    ok(!("test4" in restoredStates), "Null values don't get restored");
    158 
    159    is(
    160      restoredStates.test5,
    161      "both value and state",
    162      "Undefined state should be set to value"
    163    );
    164  });
    165 
    166  // Cleanup.
    167  gBrowser.removeTab(tab);
    168 });