tor-browser

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

browser_submission_flush.js (3775B)


      1 "use strict";
      2 // Form submissions triggered by the Javascript 'submit' event listener are
      3 // deferred until the event listener finishes. However, changes to specific
      4 // attributes ("action" and "target" attributes) need to cause an immediate
      5 // flush of any pending submission to prevent the form submission from using the
      6 // wrong action or target. This test ensures that such flushes happen properly.
      7 
      8 const kTestPage =
      9  "https://example.org/browser/dom/html/test/submission_flush.html";
     10 // This is the page pointed to by the form action in the test HTML page.
     11 const kPostActionPage =
     12  "https://example.org/browser/dom/html/test/post_action_page.html";
     13 
     14 const kFormId = "test_form";
     15 const kFrameId = "test_frame";
     16 const kSubmitButtonId = "submit_button";
     17 
     18 // Take in a variety of actions (in the form of setting and unsetting form
     19 // attributes). Then submit the form in the submit event listener to cause a
     20 // deferred form submission. Then perform the test actions and ensure that the
     21 // form used the correct attribute values rather than the changed ones.
     22 async function runTest(aTestActions) {
     23  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, kTestPage);
     24  registerCleanupFunction(() => BrowserTestUtils.removeTab(tab));
     25 
     26  /* eslint-disable no-shadow */
     27  let frame_url = await SpecialPowers.spawn(
     28    gBrowser.selectedBrowser,
     29    [{ kFormId, kFrameId, kSubmitButtonId, aTestActions }],
     30    async function ({ kFormId, kFrameId, kSubmitButtonId, aTestActions }) {
     31      let form = content.document.getElementById(kFormId);
     32 
     33      form.addEventListener(
     34        "submit",
     35        event => {
     36          // Need to trigger the deferred submission by submitting in the submit
     37          // event handler. To prevent the form from being submitted twice, the
     38          // <form> tag contains the attribute |onsubmit="return false;"| to cancel
     39          // the original submission.
     40          form.submit();
     41 
     42          if (aTestActions.setattr) {
     43            for (let { attr, value } of aTestActions.setattr) {
     44              form.setAttribute(attr, value);
     45            }
     46          }
     47          if (aTestActions.unsetattr) {
     48            for (let attr of aTestActions.unsetattr) {
     49              form.removeAttribute(attr);
     50            }
     51          }
     52        },
     53        { capture: true, once: true }
     54      );
     55 
     56      // Trigger the above event listener
     57      content.document.getElementById(kSubmitButtonId).click();
     58 
     59      // Test that the form was submitted to the correct target (the frame) with
     60      // the correct action (kPostActionPage).
     61      let frame = content.document.getElementById(kFrameId);
     62      await new Promise(resolve => {
     63        frame.addEventListener("load", resolve, { once: true });
     64      });
     65      return frame.contentWindow.location.href;
     66    }
     67  );
     68  /* eslint-enable no-shadow */
     69  is(
     70    frame_url,
     71    kPostActionPage,
     72    "Form should have submitted with correct target and action"
     73  );
     74 }
     75 
     76 add_task(async function () {
     77  info("Changing action should flush pending submissions");
     78  await runTest({ setattr: [{ attr: "action", value: "about:blank" }] });
     79 });
     80 
     81 add_task(async function () {
     82  info("Changing target should flush pending submissions");
     83  await runTest({ setattr: [{ attr: "target", value: "_blank" }] });
     84 });
     85 
     86 add_task(async function () {
     87  info("Unsetting action should flush pending submissions");
     88  await runTest({ unsetattr: ["action"] });
     89 });
     90 
     91 // On failure, this test will time out rather than failing an assert. When the
     92 // target attribute is not set, the form will submit the active page, navigating
     93 // it away and preventing the wait for iframe load from ever finishing.
     94 add_task(async function () {
     95  info("Unsetting target should flush pending submissions");
     96  await runTest({ unsetattr: ["target"] });
     97 });