tor-browser

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

promise-job-incumbent.html (5000B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>Incumbent settings object for promise jobs</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 
      7 <!-- This is the entry page. -->
      8 
      9 <iframe src="resources/promise-job-incumbent-incumbent.html"></iframe>
     10 <iframe src="resources/promise-job-incumbent-resolver.html"></iframe>
     11 
     12 <script>
     13 setup({ explicit_done: true });
     14 
     15 // postMessage should pick the incumbent page as its .source value to set on the MessageEvent, even
     16 // inside promise jobs.
     17 const expectedURL = (new URL("resources/promise-job-incumbent-incumbent.html", location.href)).href;
     18 
     19 let testId = 0;
     20 
     21 window.onload = () => {
     22  const relevantWindow = frames[0].document.querySelector("#r").contentWindow;
     23  const runInResolver = frames[1].runWhatYouGiveMe;
     24 
     25  function setupTest(t) {
     26    ++testId;
     27    const thisTestId = testId;
     28 
     29    relevantWindow.addEventListener("messagereceived", t.step_func(e => {
     30      const [receivedTestId, receivedSourceURL] = e.detail;
     31 
     32      if (receivedTestId !== thisTestId) {
     33        return;
     34      }
     35 
     36      assert_equals(receivedSourceURL, expectedURL);
     37      t.done();
     38    }));
     39 
     40    return thisTestId;
     41  }
     42 
     43  async_test(t => {
     44    const thisTestId = setupTest(t);
     45 
     46    frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
     47  }, "Sanity check: this all works as expected with no promises involved");
     48 
     49  async_test(t => {
     50    const thisTestId = setupTest(t);
     51 
     52    // No t.step_func because that could change the realms
     53    Promise.resolve().then(() => {
     54      frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
     55    });
     56  }, "Fulfillment handler on fulfilled promise");
     57 
     58  async_test(t => {
     59    const thisTestId = setupTest(t);
     60 
     61    const p = Promise.resolve();
     62    frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "then", thisTestId, "*");
     63  }, "Fulfillment handler on fulfilled promise, using backup incumbent settings object stack");
     64 
     65  async_test(t => {
     66    const thisTestId = setupTest(t);
     67 
     68    // No t.step_func because that could change the realms
     69    Promise.reject().catch(() => {
     70      frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
     71    });
     72  }, "Rejection handler on rejected promise");
     73 
     74  async_test(t => {
     75    const thisTestId = setupTest(t);
     76 
     77    const p = Promise.reject();
     78    frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "catch", thisTestId, "*");
     79  }, "Rejection handler on rejected promise, using backup incumbent settings object stack");
     80 
     81  // The following tests test that we derive the incumbent settings object at promise-job time from
     82  // the incumbent realm at the time the handler was added, not at the time the resolve()/reject()
     83  // was done. See https://github.com/whatwg/html/issues/5213 for the spec side of this issue.
     84 
     85  async_test(t => {
     86    const thisTestId = setupTest(t);
     87 
     88    let resolve;
     89    const p = new Promise(r => { resolve = r; });
     90 
     91    // No t.step_func because that could change the realms
     92    p.then(() => {
     93      frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
     94    });
     95 
     96    t.step_timeout(() => {
     97      runInResolver(resolve);
     98    }, 0);
     99  }, "Fulfillment handler on pending-then-fulfilled promise");
    100 
    101  async_test(t => {
    102    const thisTestId = setupTest(t);
    103 
    104    let resolve;
    105    const p = new Promise(r => { resolve = r; });
    106 
    107    frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "then", thisTestId, "*");
    108 
    109    t.step_timeout(() => {
    110      runInResolver(resolve);
    111    }, 0);
    112  }, "Fulfillment handler on pending-then-fulfilled promise, using backup incumbent settings object stack");
    113 
    114  async_test(t => {
    115    const thisTestId = setupTest(t);
    116 
    117    let reject;
    118    const p = new Promise((_, r) => { reject = r; });
    119 
    120    // No t.step_func because that could change the realms
    121    p.catch(() => {
    122      frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
    123    });
    124 
    125    t.step_timeout(() => {
    126      runInResolver(reject);
    127    }, 0);
    128  }, "Rejection handler on pending-then-rejected promise");
    129 
    130  async_test(t => {
    131    const thisTestId = setupTest(t);
    132 
    133    let reject;
    134    const p = new Promise((_, r) => { reject = r; });
    135 
    136    frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "catch", thisTestId, "*");
    137 
    138    t.step_timeout(() => {
    139      runInResolver(reject);
    140    }, 0);
    141  }, "Rejection handler on pending-then-rejected promise, using backup incumbent settings object stack");
    142 
    143  async_test(t => {
    144    const thisTestId = setupTest(t);
    145 
    146    const thenable = {
    147      // No t.step_func because that could change the realms
    148      then(f) {
    149        frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
    150      }
    151    };
    152 
    153    Promise.resolve(thenable);
    154  }, "Thenable resolution");
    155 
    156  async_test(t => {
    157    const thisTestId = setupTest(t);
    158 
    159    frames[0].resolveThenableThatRunsWindowPostMessageVeryIndirectlyWithNoUserCode(testId, "*", []);
    160  }, "Thenable resolution, using backup incumbent settings object stack");
    161 
    162  done();
    163 };
    164 </script>