tor-browser

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

test_SpecialPowersSandbox.js (5398B)


      1 "use strict";
      2 
      3 /* eslint-disable @microsoft/sdl/no-insecure-url */
      4 
      5 const { XPCShellContentUtils } = ChromeUtils.importESModule(
      6  "resource://testing-common/XPCShellContentUtils.sys.mjs"
      7 );
      8 
      9 XPCShellContentUtils.init(this);
     10 
     11 const HTML = String.raw`<!DOCTYPE html>
     12 <html lang="en">
     13 <head>
     14  <meta charset="UTF-8">
     15  <title></title>
     16 </head>
     17 <body>
     18  <span id="span">Hello there.</span>
     19 </body>
     20 </html>`;
     21 
     22 const server = XPCShellContentUtils.createHttpServer({
     23  hosts: ["example.com", "example.org"],
     24 });
     25 
     26 server.registerPathHandler("/", (request, response) => {
     27  response.setHeader("Content-Type", "text/html");
     28  response.write(HTML);
     29 });
     30 /**
     31 * Tests that the shared sandbox functionality for cross-process script
     32 * execution works as expected. In particular, ensures that Assert methods
     33 * report the correct diagnostics in the caller scope.
     34 */
     35 
     36 let scope = this;
     37 
     38 async function interceptDiagnostics(func) {
     39  let originalRecord = scope.do_report_result;
     40  try {
     41    let diags = [];
     42 
     43    scope.do_report_result = (passed, msg, stack) => {
     44      diags.push({ passed, msg, stack });
     45    };
     46 
     47    await func();
     48 
     49    return diags;
     50  } finally {
     51    scope.do_report_result = originalRecord;
     52  }
     53 }
     54 
     55 add_task(async function () {
     56  const frameSrc = "http://example.com/";
     57  const subframeSrc = "http://example.org/";
     58 
     59  let page = await XPCShellContentUtils.loadContentPage(frameSrc, {
     60    remote: true,
     61    remoteSubframes: true,
     62  });
     63 
     64  let { SpecialPowers, browsingContext } = page;
     65 
     66  let expected = [
     67    [false, "Thing - 1 == 2"],
     68    [true, "Hmm - 1 == 1"],
     69    [true, "Yay. - true == true"],
     70    [false, "Boo!. - false == true"],
     71    [false, "Missing expected exception Rej_bad"],
     72    [true, "Rej_ok"],
     73  ];
     74 
     75  // Test that a representative variety of assertions work as expected, and
     76  // trigger the expected calls to the harness's reporting function.
     77  //
     78  // Note: Assert.sys.mjs has its own tests, and defers all of its reporting to a
     79  // single reporting function, so we don't need to test it comprehensively. We
     80  // just need to make sure that the general functionality works as expected.
     81  let tests = {
     82    "SpecialPowers.spawn": () => {
     83      return SpecialPowers.spawn(browsingContext, [], async () => {
     84        Assert.equal(1, 2, "Thing");
     85        Assert.equal(1, 1, "Hmm");
     86        Assert.ok(true, "Yay.");
     87        Assert.ok(false, "Boo!.");
     88        await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
     89        await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
     90      });
     91    },
     92    "SpecialPowers.spawn-subframe": () => {
     93      return SpecialPowers.spawn(browsingContext, [subframeSrc], async src => {
     94        let subFrame = this.content.document.createElement("iframe");
     95        subFrame.src = src;
     96        this.content.document.body.appendChild(subFrame);
     97 
     98        await new Promise(resolve => {
     99          subFrame.addEventListener("load", resolve, { once: true });
    100        });
    101 
    102        await SpecialPowers.spawn(subFrame, [], async () => {
    103          Assert.equal(1, 2, "Thing");
    104          Assert.equal(1, 1, "Hmm");
    105          Assert.ok(true, "Yay.");
    106          Assert.ok(false, "Boo!.");
    107          await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
    108          await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
    109        });
    110      });
    111    },
    112    "SpecialPowers.spawnChrome": () => {
    113      return SpecialPowers.spawnChrome([], async () => {
    114        Assert.equal(1, 2, "Thing");
    115        Assert.equal(1, 1, "Hmm");
    116        Assert.ok(true, "Yay.");
    117        Assert.ok(false, "Boo!.");
    118        await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
    119        await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
    120      });
    121    },
    122    "SpecialPowers.loadChromeScript": async () => {
    123      let script = SpecialPowers.loadChromeScript(() => {
    124        /* eslint-env mozilla/chrome-script */
    125        const resultPromise = (async () => {
    126          Assert.equal(1, 2, "Thing");
    127          Assert.equal(1, 1, "Hmm");
    128          Assert.ok(true, "Yay.");
    129          Assert.ok(false, "Boo!.");
    130          await Assert.rejects(Promise.resolve(), /./, "Rej_bad");
    131          await Assert.rejects(Promise.reject(new Error("k")), /k/, "Rej_ok");
    132        })();
    133        this.addMessageListener("ping", () => resultPromise);
    134      });
    135 
    136      await script.sendQuery("ping");
    137      script.destroy();
    138    },
    139  };
    140 
    141  for (let [name, func] of Object.entries(tests)) {
    142    info(`Starting task: ${name}`);
    143 
    144    let diags = await interceptDiagnostics(func);
    145 
    146    let results = diags.map(diag => [diag.passed, diag.msg]);
    147 
    148    deepEqual(results, expected, "Got expected assertions");
    149    for (let { msg, stack } of diags) {
    150      ok(stack, `Got stack for: ${msg}`);
    151      // Unlike the html version of this test, this one does not include a "/"
    152      // in front of the file name, because somehow Android only includes the
    153      // file name, and not the fuller path.
    154      let expectedFilenamePart = "test_SpecialPowersSandbox.js:";
    155      if (name === "SpecialPowers.loadChromeScript") {
    156        // Unfortunately, the original file name is not included;
    157        // the function name or a dummy value is used instead.
    158        expectedFilenamePart = "loadChromeScript anonymous function>:";
    159      }
    160      if (!stack.includes(expectedFilenamePart)) {
    161        ok(false, `Stack does not contain ${expectedFilenamePart}: ${stack}`);
    162      }
    163    }
    164  }
    165 });