tor-browser

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

head.js (4992B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 /* exported gIsUiaEnabled, addUiaTask, definePyVar, assignPyVarToUiaWithId, setUpWaitForUiaEvent, setUpWaitForUiaPropEvent, waitForUiaEvent, testPatternAbsent, testPythonRaises, isUiaElementArray */
      8 
      9 // Load the shared-head file first.
     10 Services.scriptloader.loadSubScript(
     11  "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js",
     12  this
     13 );
     14 
     15 // Loading and common.js from accessible/tests/mochitest/ for all tests, as
     16 // well as promisified-events.js and layout.js.
     17 loadScripts(
     18  { name: "common.js", dir: MOCHITESTS_DIR },
     19  { name: "promisified-events.js", dir: MOCHITESTS_DIR },
     20  { name: "layout.js", dir: MOCHITESTS_DIR }
     21 );
     22 
     23 let gIsUiaEnabled = false;
     24 
     25 /**
     26 * This is like addAccessibleTask, but takes two additional boolean options:
     27 * - uiaEnabled: Whether to run a variation of this test with Gecko UIA enabled.
     28 * - uiaDisabled: Whether to run a variation of this test with UIA disabled. In
     29 *   this case, UIA will rely entirely on the IA2 -> UIA proxy.
     30 * If both are set, the test will be run twice with different configurations.
     31 * You can determine which variant is currently running using the gIsUiaEnabled
     32 * variable. This is useful for conditional tests; e.g. if Gecko UIA supports
     33 * something that the IA2 -> UIA proxy doesn't support.
     34 */
     35 function addUiaTask(doc, task, options = {}) {
     36  const { uiaEnabled = true, uiaDisabled = true } = options;
     37 
     38  function addTask(shouldEnable) {
     39    async function uiaTask(browser, docAcc, topDocAcc) {
     40      await SpecialPowers.pushPrefEnv({
     41        // 1 means enable unconditionally. 2 means enable only if NVDA or JAWS
     42        // isn't detected. The user could be running a screen reader while
     43        // running the tests, so use 1 to enable unconditionally lest the tests
     44        // fail.
     45        set: [["accessibility.uia.enable", shouldEnable ? 1 : 0]],
     46      });
     47      gIsUiaEnabled = shouldEnable;
     48      info(shouldEnable ? "Gecko UIA enabled" : "Gecko UIA disabled");
     49      await task(browser, docAcc, topDocAcc);
     50    }
     51    // Propagate the name of the task function to our wrapper function so it shows
     52    // up in test run output. Suffix with the test type. For example:
     53    // 0:39.16 INFO Entering test bound testProtected_uiaEnabled_remoteIframe
     54    // The "name" property of functions is not writable, but we can override that
     55    // using Object.defineProperty.
     56    let name = task.name;
     57    if (name) {
     58      name += shouldEnable ? "_uiaEnabled" : "_uiaDisabled";
     59    }
     60    Object.defineProperty(uiaTask, "name", { value: name });
     61    addAccessibleTask(doc, uiaTask, options);
     62  }
     63 
     64  if (uiaEnabled) {
     65    addTask(true);
     66  }
     67  if (uiaDisabled) {
     68    addTask(false);
     69  }
     70 }
     71 
     72 /**
     73 * Define a global Python variable and assign it to a given Python expression.
     74 */
     75 function definePyVar(varName, expression) {
     76  return runPython(`
     77    global ${varName}
     78    ${varName} = ${expression}
     79  `);
     80 }
     81 
     82 /**
     83 * Get the UIA element with the given id and assign it to a global Python
     84 * variable using the id as the variable name.
     85 */
     86 function assignPyVarToUiaWithId(id) {
     87  return definePyVar(id, `findUiaByDomId(doc, "${id}")`);
     88 }
     89 
     90 /**
     91 * Set up to wait for a UIA event. You must await this before performing the
     92 * action which fires the event.
     93 */
     94 function setUpWaitForUiaEvent(eventName, id) {
     95  return definePyVar(
     96    "onEvent",
     97    `WaitForUiaEvent(eventId=UIA_${eventName}EventId, match="${id}")`
     98  );
     99 }
    100 
    101 /**
    102 * Set up to wait for a UIA property change event. You must await this before
    103 * performing the action which fires the event.
    104 */
    105 function setUpWaitForUiaPropEvent(propName, id) {
    106  return definePyVar(
    107    "onEvent",
    108    `WaitForUiaEvent(property=UIA_${propName}PropertyId, match="${id}")`
    109  );
    110 }
    111 
    112 /**
    113 * Wait for the event requested in setUpWaitForUia*Event.
    114 */
    115 function waitForUiaEvent() {
    116  return runPython(`
    117    onEvent.wait()
    118  `);
    119 }
    120 
    121 /**
    122 * Verify that a UIA element does *not* support the given control pattern.
    123 */
    124 async function testPatternAbsent(id, patternName) {
    125  const hasPattern = await runPython(`
    126    el = findUiaByDomId(doc, "${id}")
    127    return bool(getUiaPattern(el, "${patternName}"))
    128  `);
    129  ok(!hasPattern, `${id} doesn't have ${patternName} pattern`);
    130 }
    131 
    132 /**
    133 * Verify that a Python expression raises an exception.
    134 */
    135 async function testPythonRaises(expression, message) {
    136  let failed = false;
    137  try {
    138    await runPython(expression);
    139  } catch {
    140    failed = true;
    141  }
    142  ok(failed, message);
    143 }
    144 
    145 /**
    146 * Verify that an array of UIA elements contains (only) elements with the given
    147 * DOM ids.
    148 */
    149 async function isUiaElementArray(pyExpr, ids, message) {
    150  const result = await runPython(`
    151    uias = (${pyExpr})
    152    return [uias.GetElement(i).CurrentAutomationId for i in range(uias.Length)]
    153  `);
    154  SimpleTest.isDeeply(result, ids, message);
    155 }