tor-browser

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

structured-cloning-error-stack-optional.sub.window.js (2637B)


      1 // META: script=/common/utils.js
      2 
      3 // .stack properties on errors are unspecified, but are present in most
      4 // browsers, most of the time. https://github.com/tc39/proposal-error-stacks/ tracks standardizing them.
      5 // Tests will pass automatically if the .stack property isn't present.
      6 
      7 stackTests(() => {
      8  return new Error('some message');
      9 }, 'page-created Error');
     10 
     11 stackTests(() => {
     12  return new DOMException('InvalidStateError', 'some message');
     13 }, 'page-created DOMException');
     14 
     15 stackTests(() => {
     16  try {
     17    Object.defineProperty();
     18  } catch (e) {
     19    return e;
     20  }
     21 }, 'JS-engine-created TypeError');
     22 
     23 stackTests(() => {
     24  try {
     25    HTMLParagraphElement.prototype.align;
     26  } catch (e) {
     27    return e;
     28  }
     29 }, 'web API-created TypeError');
     30 
     31 stackTests(() => {
     32  try {
     33    document.createElement('');
     34  } catch (e) {
     35    return e;
     36  }
     37 }, 'web API-created DOMException');
     38 
     39 function stackTests(errorFactory, description) {
     40  test(t => {
     41    const error = errorFactory();
     42    const originalStack = error.stack;
     43 
     44    if (!originalStack) {
     45      return;
     46    }
     47 
     48    const clonedError = structuredClone(error);
     49    assert_equals(clonedError.stack, originalStack);
     50  }, description + ' (structuredClone())');
     51 
     52  async_test(t => {
     53    const error = errorFactory();
     54    const originalStack = error.stack;
     55 
     56    if (!originalStack) {
     57      t.done();
     58      return;
     59    }
     60 
     61    const worker = new Worker('resources/echo-worker.js');
     62    worker.onmessage = t.step_func_done(e => {
     63      assert_equals(e.data.stack, originalStack);
     64    });
     65 
     66    worker.postMessage(error);
     67  }, description + ' (worker)');
     68 
     69  let iframeTest = (t, url) => {
     70    const thisTestId = token();
     71 
     72    const error = errorFactory();
     73    const originalStack = error.stack;
     74 
     75    if (!originalStack) {
     76      t.done();
     77      return;
     78    }
     79 
     80    const iframe = document.createElement('iframe');
     81    window.addEventListener('message', t.step_func(e => {
     82      if (e.data.testId === thisTestId) {
     83        assert_equals(e.data.error.stack, originalStack);
     84        t.done();
     85      }
     86    }));
     87 
     88    iframe.onload = t.step_func(() => {
     89      iframe.contentWindow.postMessage({ error, testId: thisTestId }, "*");
     90    });
     91 
     92    iframe.src = url;
     93    document.body.append(iframe);
     94  }
     95 
     96  async_test(t => {
     97    const crossSiteURL = new URL('resources/echo-iframe.html', location.href);
     98    crossSiteURL.hostname = '{{hosts[alt][www1]}}';
     99    iframeTest(t, crossSiteURL);
    100  }, description + ' (cross-site iframe)');
    101 
    102  async_test(t => {
    103    const sameOriginURL = new URL('resources/echo-iframe.html', location.href);
    104    iframeTest(t, sameOriginURL);
    105  }, description + ' (same-origin iframe)')
    106 }