tor-browser

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

browser_live_regions.js (6636B)


      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 /**
      8 * Test live region creation and removal.
      9 */
     10 addAccessibleTask(
     11  `
     12  <div id="polite" aria-relevant="removals">Polite region</div>
     13  <div id="assertive" aria-live="assertive">Assertive region</div>
     14  `,
     15  async (browser, accDoc) => {
     16    let politeRegion = getNativeInterface(accDoc, "polite");
     17    ok(
     18      !politeRegion.attributeNames.includes("AXARIALive"),
     19      "region is not live"
     20    );
     21 
     22    let liveRegionAdded = waitForMacEvent("AXLiveRegionCreated", "polite");
     23    await SpecialPowers.spawn(browser, [], () => {
     24      content.document
     25        .getElementById("polite")
     26        .setAttribute("aria-atomic", "true");
     27      content.document
     28        .getElementById("polite")
     29        .setAttribute("aria-live", "polite");
     30    });
     31    await liveRegionAdded;
     32    is(
     33      politeRegion.getAttributeValue("AXARIALive"),
     34      "polite",
     35      "region is now live"
     36    );
     37    ok(politeRegion.getAttributeValue("AXARIAAtomic"), "region is atomic");
     38    is(
     39      politeRegion.getAttributeValue("AXARIARelevant"),
     40      "removals",
     41      "region has defined aria-relevant"
     42    );
     43 
     44    let assertiveRegion = getNativeInterface(accDoc, "assertive");
     45    is(
     46      assertiveRegion.getAttributeValue("AXARIALive"),
     47      "assertive",
     48      "region is assertive"
     49    );
     50    ok(
     51      !assertiveRegion.getAttributeValue("AXARIAAtomic"),
     52      "region is not atomic"
     53    );
     54    is(
     55      assertiveRegion.getAttributeValue("AXARIARelevant"),
     56      "additions text",
     57      "region has default aria-relevant"
     58    );
     59 
     60    let liveRegionRemoved = waitForEvent(
     61      EVENT_LIVE_REGION_REMOVED,
     62      "assertive"
     63    );
     64    await SpecialPowers.spawn(browser, [], () => {
     65      content.document.getElementById("assertive").removeAttribute("aria-live");
     66    });
     67    await liveRegionRemoved;
     68    ok(!assertiveRegion.getAttributeValue("AXARIALive"), "region is not live");
     69 
     70    liveRegionAdded = waitForMacEvent("AXLiveRegionCreated", "new-region");
     71    await SpecialPowers.spawn(browser, [], () => {
     72      let newRegionElm = content.document.createElement("div");
     73      newRegionElm.id = "new-region";
     74      newRegionElm.setAttribute("aria-live", "assertive");
     75      content.document.body.appendChild(newRegionElm);
     76    });
     77    await liveRegionAdded;
     78 
     79    let newRegion = getNativeInterface(accDoc, "new-region");
     80    is(
     81      newRegion.getAttributeValue("AXARIALive"),
     82      "assertive",
     83      "region is assertive"
     84    );
     85 
     86    let loadComplete = Promise.all([
     87      waitForMacEvent("AXLoadComplete"),
     88      waitForMacEvent("AXLiveRegionCreated", "region-1"),
     89      waitForMacEvent("AXLiveRegionCreated", "region-2"),
     90      waitForMacEvent("AXLiveRegionCreated", "status"),
     91      waitForMacEvent("AXLiveRegionCreated", "output"),
     92    ]);
     93 
     94    await SpecialPowers.spawn(browser, [], () => {
     95      content.location = `data:text/html;charset=utf-8,
     96        <div id="region-1" aria-live="polite"></div>
     97        <div id="region-2" aria-live="assertive"></div>
     98        <div id="region-3" aria-live="off"></div>
     99        <div id="alert" role="alert"></div>
    100        <div id="status" role="status"></div>
    101        <output id="output"></output>`;
    102    });
    103    let webArea = (await loadComplete)[0];
    104 
    105    is(webArea.getAttributeValue("AXRole"), "AXWebArea", "web area yeah");
    106    const searchPred = {
    107      AXSearchKey: "AXLiveRegionSearchKey",
    108      AXResultsLimit: -1,
    109      AXDirection: "AXDirectionNext",
    110    };
    111    const liveRegions = webArea.getParameterizedAttributeValue(
    112      "AXUIElementsForSearchPredicate",
    113      NSDictionary(searchPred)
    114    );
    115    Assert.deepEqual(
    116      liveRegions.map(r => r.getAttributeValue("AXDOMIdentifier")),
    117      ["region-1", "region-2", "alert", "status", "output"],
    118      "SearchPredicate returned all live regions"
    119    );
    120  }
    121 );
    122 
    123 /**
    124 * Test live region changes
    125 */
    126 addAccessibleTask(
    127  `
    128  <div id="live" aria-live="polite">
    129  The time is <span id="time">4:55pm</span>
    130  <p id="p" style="display: none">Georgia on my mind</p>
    131  <button id="button" aria-label="Start"></button>
    132  </div>
    133  `,
    134  async browser => {
    135    let liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
    136    await SpecialPowers.spawn(browser, [], () => {
    137      content.document.getElementById("time").textContent = "4:56pm";
    138    });
    139    await liveRegionChanged;
    140    ok(true, "changed textContent");
    141 
    142    liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
    143    await SpecialPowers.spawn(browser, [], () => {
    144      content.document.getElementById("p").style.display = "block";
    145    });
    146    await liveRegionChanged;
    147    ok(true, "changed display style to block");
    148 
    149    liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
    150    await SpecialPowers.spawn(browser, [], () => {
    151      content.document.getElementById("p").style.display = "none";
    152    });
    153    await liveRegionChanged;
    154    ok(true, "changed display style to none");
    155 
    156    liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
    157    await SpecialPowers.spawn(browser, [], () => {
    158      content.document
    159        .getElementById("button")
    160        .setAttribute("aria-label", "Stop");
    161    });
    162    await liveRegionChanged;
    163    ok(true, "changed aria-label");
    164 
    165    liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
    166    await SpecialPowers.spawn(browser, [], () => {
    167      content.document.getElementById("live").firstChild.data = "The hour is ";
    168    });
    169    await liveRegionChanged;
    170    ok(true, "changed text leaf contents");
    171 
    172    liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
    173    await SpecialPowers.spawn(browser, [], () => {
    174      content.document.getElementById("live").firstChild.data = "";
    175    });
    176    await liveRegionChanged;
    177    ok(true, "delete text leaf contents");
    178  }
    179 );
    180 
    181 /**
    182 * Test live region announcements caused by clicking a button that modifies a region.
    183 */
    184 addAccessibleTask(
    185  `
    186  <div id="status-container" aria-live="polite" aria-label="">
    187  </div>
    188 
    189  <button id="clickme" onClick="(function(){document.getElementById('status-container').setAttribute('aria-label', 'hello world');})()">
    190    Add something!
    191  </button>
    192  `,
    193  async (browser, accDoc) => {
    194    let liveRegionChanged = waitForMacEvent(
    195      "AXLiveRegionChanged",
    196      "status-container"
    197    );
    198    const button = getNativeInterface(accDoc, "clickme");
    199    button.performAction("AXPress");
    200    await liveRegionChanged;
    201    ok(true, "aria-label was changed, and event was fired");
    202  }
    203 );