tor-browser

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

setup.js (10649B)


      1 /* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 "use strict";
      8 
      9 // This file expects the following files to be loaded.
     10 /* import-globals-from TestRunner.js */
     11 
     12 // From the harness:
     13 /* import-globals-from ../../chrome-harness.js */
     14 /* import-globals-from ../../chunkifyTests.js */
     15 
     16 TestRunner.logEnabled = true;
     17 TestRunner.logger = LogController;
     18 
     19 if (!("SpecialPowers" in window)) {
     20  dump("SimpleTest setup.js found SpecialPowers unavailable: reloading...\n");
     21  setTimeout(window.location.reload);
     22 }
     23 
     24 /* Helper function */
     25 function parseQueryString(encodedString, useArrays) {
     26  // strip a leading '?' from the encoded string
     27  var qstr =
     28    encodedString.length && encodedString[0] == "?"
     29      ? encodedString.substring(1)
     30      : encodedString;
     31  var pairs = qstr.replace(/\+/g, "%20").split(/(\&amp\;|\&\#38\;|\&|\&)/);
     32  var o = {};
     33  var decode;
     34  if (typeof decodeURIComponent != "undefined") {
     35    decode = decodeURIComponent;
     36  } else {
     37    decode = unescape;
     38  }
     39  if (useArrays) {
     40    for (var i = 0; i < pairs.length; i++) {
     41      var pair = pairs[i].split("=");
     42      if (pair.length !== 2) {
     43        continue;
     44      }
     45      var name = decode(pair[0]);
     46      var arr = o[name];
     47      if (!(arr instanceof Array)) {
     48        arr = [];
     49        o[name] = arr;
     50      }
     51      arr.push(decode(pair[1]));
     52    }
     53  } else {
     54    for (i = 0; i < pairs.length; i++) {
     55      pair = pairs[i].split("=");
     56      if (pair.length !== 2) {
     57        continue;
     58      }
     59      o[decode(pair[0])] = decode(pair[1]);
     60    }
     61  }
     62  return o;
     63 }
     64 
     65 /* helper function, specifically for prefs to ignore */
     66 function loadFile(url, callback) {
     67  let req = new XMLHttpRequest();
     68  req.open("GET", url);
     69  req.onload = function () {
     70    if (req.readyState == 4) {
     71      if (req.status == 200) {
     72        try {
     73          let prefs = JSON.parse(req.responseText);
     74          callback(prefs);
     75        } catch (e) {
     76          dump(
     77            "TEST-UNEXPECTED-FAIL: setup.js | error parsing " +
     78              url +
     79              " (" +
     80              e +
     81              ")\n"
     82          );
     83          throw e;
     84        }
     85      } else {
     86        dump(
     87          "TEST-UNEXPECTED-FAIL: setup.js | error loading " +
     88            url +
     89            " (HTTP " +
     90            req.status +
     91            ")\n"
     92        );
     93        callback({});
     94      }
     95    }
     96  };
     97  req.send();
     98 }
     99 
    100 // Check the query string for arguments
    101 var params = parseQueryString(location.search.substring(1), true);
    102 
    103 var config = {};
    104 if (window.readConfig) {
    105  config = readConfig();
    106 }
    107 
    108 if (config.testRoot == "chrome" || config.testRoot == "a11y") {
    109  for (var p in params) {
    110    // Compare with arrays to find boolean equivalents, since that's what
    111    // |parseQueryString| with useArrays returns.
    112    if (params[p] == [1]) {
    113      config[p] = true;
    114    } else if (params[p] == [0]) {
    115      config[p] = false;
    116    } else {
    117      config[p] = params[p];
    118    }
    119  }
    120  params = config;
    121  params.baseurl = "chrome://mochitests/content";
    122 } else if (params.xOriginTests) {
    123  params.baseurl = "http://mochi.test:8888/tests/";
    124 } else {
    125  params.baseurl = "";
    126 }
    127 
    128 if (params.testRoot == "browser") {
    129  params.testPrefix = "chrome://mochitests/content/browser/";
    130 } else if (params.testRoot == "chrome") {
    131  params.testPrefix = "chrome://mochitests/content/chrome/";
    132 } else if (params.testRoot == "a11y") {
    133  params.testPrefix = "chrome://mochitests/content/a11y/";
    134 } else if (params.xOriginTests) {
    135  params.testPrefix = "http://mochi.test:8888/tests/";
    136  params.httpsBaseUrl = "https://example.org:443/tests/";
    137 } else {
    138  params.testPrefix = "/tests/";
    139 }
    140 
    141 // set the per-test timeout if specified in the query string
    142 if (params.timeout) {
    143  TestRunner.timeout = parseInt(params.timeout) * 1000;
    144 }
    145 
    146 // log levels for console and logfile
    147 var fileLevel = params.fileLevel || null;
    148 var consoleLevel = params.consoleLevel || null;
    149 
    150 // repeat tells us how many times to repeat the tests
    151 if (params.repeat) {
    152  TestRunner.repeat = params.repeat;
    153 }
    154 
    155 if (params.runUntilFailure) {
    156  TestRunner.runUntilFailure = true;
    157 }
    158 
    159 // closeWhenDone tells us to close the browser when complete
    160 if (params.closeWhenDone) {
    161  TestRunner.onComplete = SpecialPowers.quit.bind(SpecialPowers);
    162 }
    163 
    164 if (params.failureFile) {
    165  TestRunner.setFailureFile(params.failureFile);
    166 }
    167 
    168 // Breaks execution and enters the JS debugger on a test failure
    169 if (params.debugOnFailure) {
    170  TestRunner.debugOnFailure = true;
    171 }
    172 
    173 // logFile to write our results
    174 if (params.logFile) {
    175  var mfl = new MozillaFileLogger(params.logFile);
    176  TestRunner.logger.addListener("mozLogger", fileLevel + "", mfl.logCallback);
    177 }
    178 
    179 // A temporary hack for android 4.0 where Fennec utilizes the pandaboard so much it reboots
    180 if (params.runSlower) {
    181  TestRunner.runSlower = true;
    182 }
    183 
    184 if (params.dumpOutputDirectory) {
    185  TestRunner.dumpOutputDirectory = params.dumpOutputDirectory;
    186 }
    187 
    188 if (params.dumpAboutMemoryAfterTest) {
    189  TestRunner.dumpAboutMemoryAfterTest = true;
    190 }
    191 
    192 if (params.dumpDMDAfterTest) {
    193  TestRunner.dumpDMDAfterTest = true;
    194 }
    195 
    196 // We need to check several things here because mochitest-chrome passes
    197 // `jsdebugger` and `debugger` directly, but in other tests we're reliant
    198 // on the `interactiveDebugger` flag being passed along.
    199 if (params.interactiveDebugger || params.jsdebugger || params.debugger) {
    200  TestRunner.interactiveDebugger = true;
    201 }
    202 
    203 if (params.jscovDirPrefix) {
    204  TestRunner.jscovDirPrefix = params.jscovDirPrefix;
    205 }
    206 
    207 if (params.maxTimeouts) {
    208  TestRunner.maxTimeouts = params.maxTimeouts;
    209 }
    210 
    211 if (params.cleanupCrashes) {
    212  TestRunner.cleanupCrashes = true;
    213 }
    214 
    215 if (params.xOriginTests) {
    216  TestRunner.xOriginTests = true;
    217  TestRunner.setXOriginEventHandler();
    218 }
    219 
    220 if (params.timeoutAsPass) {
    221  TestRunner.timeoutAsPass = true;
    222 }
    223 
    224 if (params.conditionedProfile) {
    225  TestRunner.conditionedProfile = {
    226    knownServiceWorkers: null,
    227  };
    228  // Asynchronously populate knownServiceWorkers above.  Because we only check
    229  // this list after awaiting a different call to registeredServiceWorkers() in
    230  // SimpleTest.js's afterCleanup, we are guaranteed that the list will be
    231  // populated before we check it.
    232  //
    233  // That said, the question is whether the list was sampled before the test
    234  // could start and add a ServiceWorker.  And the answer is mainly yes because
    235  // the request will make it to the parent process main thread before any call
    236  // to register() can get there with very high probability.  (We are dealing
    237  // with different top-level protocols so there are some theoretical
    238  // opportunities for pathological scheduling but practically speaking it is
    239  // very unlikely to happen.)
    240  SpecialPowers.registeredServiceWorkers(/* aForce */ true).then(workers => {
    241    TestRunner.conditionedProfile.knownServiceWorkers = workers;
    242  });
    243 }
    244 
    245 if (params.comparePrefs) {
    246  TestRunner.comparePrefs = true;
    247 }
    248 
    249 // Log things to the console if appropriate.
    250 TestRunner.logger.addListener(
    251  "dumpListener",
    252  consoleLevel + "",
    253  function (msg) {
    254    dump(msg.info.join(" ") + "\n");
    255  }
    256 );
    257 
    258 var gTestList = [];
    259 var RunSet = {};
    260 
    261 RunSet.runall = function () {
    262  // Filter tests to include|exclude tests based on data in params.filter.
    263  // This allows for including or excluding tests from the gTestList
    264  // TODO Only used by ipc tests, remove once those are implemented sanely
    265  if (params.testManifest) {
    266    getTestManifest(
    267      getTestManifestURL(params.testManifest),
    268      params,
    269      function (filter) {
    270        gTestList = filterTests(filter, gTestList, params.runOnly);
    271        RunSet.runtests();
    272      }
    273    );
    274  } else {
    275    RunSet.runtests();
    276  }
    277 };
    278 
    279 RunSet.runtests = function () {
    280  // Which tests we're going to run
    281  var my_tests = gTestList;
    282 
    283  if (params.startAt || params.endAt) {
    284    my_tests = skipTests(my_tests, params.startAt, params.endAt);
    285  }
    286 
    287  if (params.shuffle) {
    288    for (var i = my_tests.length - 1; i > 0; --i) {
    289      var j = Math.floor(Math.random() * i);
    290      var tmp = my_tests[j];
    291      my_tests[j] = my_tests[i];
    292      my_tests[i] = tmp;
    293    }
    294  }
    295  TestRunner.setParameterInfo(params);
    296  TestRunner.runTests(my_tests);
    297 };
    298 
    299 RunSet.reloadAndRunAll = function (e) {
    300  e.preventDefault();
    301  //window.location.hash = "";
    302  if (params.autorun) {
    303    window.location.search += "";
    304    // eslint-disable-next-line no-self-assign
    305    window.location.href = window.location.href;
    306  } else if (window.location.search) {
    307    window.location.href += "&autorun=1";
    308  } else {
    309    window.location.href += "?autorun=1";
    310  }
    311 };
    312 
    313 // UI Stuff
    314 function toggleVisible(elem) {
    315  elem.classList.toggle("invisible");
    316 }
    317 
    318 function isVisible(elem) {
    319  // you may also want to check for
    320  // getElement(elem).style.display == "none"
    321  return !elem.classList.contains("invisible");
    322 }
    323 
    324 function toggleNonTests(e) {
    325  e.preventDefault();
    326  var elems = document.getElementsByClassName("non-test");
    327  for (var i = 0; i < elems.length; i++) {
    328    toggleVisible(elems[i]);
    329  }
    330  if (!elems.length) {
    331    $("toggleNonTests").textContent = "No Non-Tests";
    332  } else if (isVisible(elems[0])) {
    333    $("toggleNonTests").textContent = "Hide Non-Tests";
    334  } else {
    335    $("toggleNonTests").textContent = "Show Non-Tests";
    336  }
    337 }
    338 
    339 // hook up our buttons
    340 function hookup() {
    341  if (params.manifestFile) {
    342    getTestManifest(
    343      getTestManifestURL(params.manifestFile),
    344      params,
    345      hookupTests
    346    );
    347  } else {
    348    hookupTests(gTestList);
    349  }
    350 }
    351 
    352 function getPrefList() {
    353  if (params.ignorePrefsFile) {
    354    loadFile(getTestManifestURL(params.ignorePrefsFile), function (prefs) {
    355      TestRunner.ignorePrefs = prefs;
    356      RunSet.runall();
    357    });
    358  } else {
    359    RunSet.runall();
    360  }
    361 }
    362 
    363 function hookupTests(testList) {
    364  if (testList.length) {
    365    gTestList = testList;
    366  } else {
    367    gTestList = [];
    368    for (var obj in testList) {
    369      gTestList.push(testList[obj]);
    370    }
    371  }
    372 
    373  document.getElementById("runtests").onclick = RunSet.reloadAndRunAll;
    374  document.getElementById("toggleNonTests").onclick = toggleNonTests;
    375  // run automatically if autorun specified
    376  if (params.autorun) {
    377    getPrefList();
    378  }
    379 }
    380 
    381 function getTestManifestURL(path) {
    382  // The test manifest url scheme should be the same protocol as the containing
    383  // window... unless it's not http(s)
    384  if (
    385    window.location.protocol == "http:" ||
    386    window.location.protocol == "https:"
    387  ) {
    388    return window.location.protocol + "//" + window.location.host + "/" + path;
    389  }
    390  return "http://mochi.test:8888/" + path;
    391 }