tor-browser

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

browser_radio_position.js (10121B)


      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 /* import-globals-from ../../mochitest/role.js */
      8 /* import-globals-from ../../mochitest/states.js */
      9 loadScripts(
     10  { name: "role.js", dir: MOCHITESTS_DIR },
     11  { name: "states.js", dir: MOCHITESTS_DIR }
     12 );
     13 
     14 function getChildRoles(parent) {
     15  return parent
     16    .getAttributeValue("AXChildren")
     17    .map(c => c.getAttributeValue("AXRole"));
     18 }
     19 
     20 function getLinkedTitles(element) {
     21  return element.getAttributeValue("AXLinkedUIElements").map(linkedElem => {
     22    let labelElem = linkedElem.getAttributeValue("AXTitleUIElement");
     23    let labelText = labelElem
     24      ? labelElem
     25          .getAttributeValue("AXChildren")
     26          .map(c => c.getAttributeValue("AXValue"))
     27          .join("")
     28      : null;
     29    return labelText ? labelText : linkedElem.getAttributeValue("AXTitle");
     30  });
     31 }
     32 
     33 /**
     34 * Test radio group
     35 */
     36 addAccessibleTask(
     37  `<div role="radiogroup" id="radioGroup">
     38    <div role="radio"
     39         id="radioGroupItem1">
     40       Regular crust
     41    </div>
     42    <div role="radio"
     43         id="radioGroupItem2">
     44       Deep dish
     45    </div>
     46    <div role="radio"
     47         id="radioGroupItem3">
     48       Thin crust
     49    </div>
     50  </div>`,
     51  async (browser, accDoc) => {
     52    let item1 = getNativeInterface(accDoc, "radioGroupItem1");
     53    let item2 = getNativeInterface(accDoc, "radioGroupItem2");
     54    let item3 = getNativeInterface(accDoc, "radioGroupItem3");
     55    let titleList = ["Regular crust", "Deep dish", "Thin crust"];
     56 
     57    Assert.deepEqual(
     58      titleList,
     59      [item1, item2, item3].map(c => c.getAttributeValue("AXTitle")),
     60      "Title list matches"
     61    );
     62 
     63    let linkedElems = item1.getAttributeValue("AXLinkedUIElements");
     64    is(linkedElems.length, 3, "Item 1 has three linked UI elems");
     65    Assert.deepEqual(
     66      getLinkedTitles(item1),
     67      titleList,
     68      "Item one has correctly ordered linked elements"
     69    );
     70 
     71    linkedElems = item2.getAttributeValue("AXLinkedUIElements");
     72    is(linkedElems.length, 3, "Item 2 has three linked UI elems");
     73    Assert.deepEqual(
     74      getLinkedTitles(item2),
     75      titleList,
     76      "Item two has correctly ordered linked elements"
     77    );
     78 
     79    linkedElems = item3.getAttributeValue("AXLinkedUIElements");
     80    is(linkedElems.length, 3, "Item 3 has three linked UI elems");
     81    Assert.deepEqual(
     82      getLinkedTitles(item3),
     83      titleList,
     84      "Item three has correctly ordered linked elements"
     85    );
     86  }
     87 );
     88 
     89 /**
     90 * Test dynamic add to a radio group
     91 */
     92 addAccessibleTask(
     93  `<div role="radiogroup" id="radioGroup">
     94    <div role="radio"
     95         id="radioGroupItem1">
     96       Option One
     97    </div>
     98  </div>`,
     99  async (browser, accDoc) => {
    100    let item1 = getNativeInterface(accDoc, "radioGroupItem1");
    101    let linkedElems = item1.getAttributeValue("AXLinkedUIElements");
    102 
    103    is(linkedElems.length, 1, "Item 1 has one linked UI elem");
    104    is(
    105      linkedElems[0].getAttributeValue("AXTitle"),
    106      item1.getAttributeValue("AXTitle"),
    107      "Item 1 is first element"
    108    );
    109 
    110    let reorder = waitForEvent(EVENT_REORDER, "radioGroup");
    111    await SpecialPowers.spawn(browser, [], () => {
    112      let d = content.document.createElement("div");
    113      d.setAttribute("role", "radio");
    114      content.document.getElementById("radioGroup").appendChild(d);
    115    });
    116    await reorder;
    117 
    118    let radioGroup = getNativeInterface(accDoc, "radioGroup");
    119    let groupMembers = radioGroup.getAttributeValue("AXChildren");
    120    is(groupMembers.length, 2, "Radio group has two members");
    121    let item2 = groupMembers[1];
    122    item1 = getNativeInterface(accDoc, "radioGroupItem1");
    123    let titleList = ["Option One", ""];
    124 
    125    Assert.deepEqual(
    126      titleList,
    127      [item1, item2].map(c => c.getAttributeValue("AXTitle")),
    128      "Title list matches"
    129    );
    130 
    131    linkedElems = item1.getAttributeValue("AXLinkedUIElements");
    132    is(linkedElems.length, 2, "Item 1 has two linked UI elems");
    133    Assert.deepEqual(
    134      getLinkedTitles(item1),
    135      titleList,
    136      "Item one has correctly ordered linked elements"
    137    );
    138 
    139    linkedElems = item2.getAttributeValue("AXLinkedUIElements");
    140    is(linkedElems.length, 2, "Item 2 has two linked UI elems");
    141    Assert.deepEqual(
    142      getLinkedTitles(item2),
    143      titleList,
    144      "Item two has correctly ordered linked elements"
    145    );
    146  }
    147 );
    148 
    149 /**
    150 * Test input[type=radio] for single group
    151 */
    152 addAccessibleTask(
    153  `<input type="radio" id="cat" name="animal"><label for="cat">Cat</label>
    154   <input type="radio" id="dog" name="animal"><label for="dog">Dog</label>
    155   <input type="radio" id="catdog" name="animal"><label for="catdog">CatDog</label>`,
    156  async (browser, accDoc) => {
    157    let cat = getNativeInterface(accDoc, "cat");
    158    let dog = getNativeInterface(accDoc, "dog");
    159    let catdog = getNativeInterface(accDoc, "catdog");
    160    let titleList = ["Cat", "Dog", "CatDog"];
    161 
    162    let linkedElems = cat.getAttributeValue("AXLinkedUIElements");
    163    is(linkedElems.length, 3, "Cat has three linked UI elems");
    164    Assert.deepEqual(
    165      getLinkedTitles(cat),
    166      titleList,
    167      "Cat has correctly ordered linked elements"
    168    );
    169 
    170    linkedElems = dog.getAttributeValue("AXLinkedUIElements");
    171    is(linkedElems.length, 3, "Dog has three linked UI elems");
    172    Assert.deepEqual(
    173      getLinkedTitles(dog),
    174      titleList,
    175      "Dog has correctly ordered linked elements"
    176    );
    177 
    178    linkedElems = catdog.getAttributeValue("AXLinkedUIElements");
    179    is(linkedElems.length, 3, "Catdog has three linked UI elems");
    180    Assert.deepEqual(
    181      getLinkedTitles(catdog),
    182      titleList,
    183      "catdog has correctly ordered linked elements"
    184    );
    185  }
    186 );
    187 
    188 /**
    189 * Test input[type=radio] for different groups
    190 */
    191 addAccessibleTask(
    192  `<input type="radio" id="cat" name="one"><label for="cat">Cat</label>
    193   <input type="radio" id="dog" name="two"><label for="dog">Dog</label>
    194   <input type="radio" id="catdog"><label for="catdog">CatDog</label>`,
    195  async (browser, accDoc) => {
    196    let cat = getNativeInterface(accDoc, "cat");
    197    let dog = getNativeInterface(accDoc, "dog");
    198    let catdog = getNativeInterface(accDoc, "catdog");
    199 
    200    let linkedElems = cat.getAttributeValue("AXLinkedUIElements");
    201    is(linkedElems.length, 1, "Cat has one linked UI elem");
    202    is(
    203      linkedElems[0].getAttributeValue("AXTitle"),
    204      cat.getAttributeValue("AXTitle"),
    205      "Cat is only element"
    206    );
    207 
    208    linkedElems = dog.getAttributeValue("AXLinkedUIElements");
    209    is(linkedElems.length, 1, "Dog has one linked UI elem");
    210    is(
    211      linkedElems[0].getAttributeValue("AXTitle"),
    212      dog.getAttributeValue("AXTitle"),
    213      "Dog is only element"
    214    );
    215 
    216    linkedElems = catdog.getAttributeValue("AXLinkedUIElements");
    217    is(linkedElems.length, 0, "Catdog has no linked UI elem");
    218  }
    219 );
    220 
    221 /**
    222 * Test input[type=radio] for single group across DOM
    223 */
    224 addAccessibleTask(
    225  `<input type="radio" id="cat" name="animal"><label for="cat">Cat</label>
    226   <div>
    227    <span>
    228      <input type="radio" id="dog" name="animal"><label for="dog">Dog</label>
    229    </span>
    230   </div>
    231   <div>
    232   <input type="radio" id="catdog" name="animal"><label for="catdog">CatDog</label>
    233   </div>`,
    234  async (browser, accDoc) => {
    235    let cat = getNativeInterface(accDoc, "cat");
    236    let dog = getNativeInterface(accDoc, "dog");
    237    let catdog = getNativeInterface(accDoc, "catdog");
    238    let titleList = ["Cat", "Dog", "CatDog"];
    239 
    240    let linkedElems = cat.getAttributeValue("AXLinkedUIElements");
    241    is(linkedElems.length, 3, "Cat has three linked UI elems");
    242    Assert.deepEqual(
    243      getLinkedTitles(cat),
    244      titleList,
    245      "cat has correctly ordered linked elements"
    246    );
    247 
    248    linkedElems = dog.getAttributeValue("AXLinkedUIElements");
    249    is(linkedElems.length, 3, "Dog has three linked UI elems");
    250    Assert.deepEqual(
    251      getLinkedTitles(dog),
    252      titleList,
    253      "dog has correctly ordered linked elements"
    254    );
    255 
    256    linkedElems = catdog.getAttributeValue("AXLinkedUIElements");
    257    is(linkedElems.length, 3, "Catdog has three linked UI elems");
    258    Assert.deepEqual(
    259      getLinkedTitles(catdog),
    260      titleList,
    261      "catdog has correctly ordered linked elements"
    262    );
    263  }
    264 );
    265 
    266 /**
    267 * Test dynamic add of input[type=radio] in a single group
    268 */
    269 addAccessibleTask(
    270  `<div id="container"><input type="radio" id="cat" name="animal"></div>`,
    271  async (browser, accDoc) => {
    272    let cat = getNativeInterface(accDoc, "cat");
    273    let container = getNativeInterface(accDoc, "container");
    274 
    275    let containerChildren = container.getAttributeValue("AXChildren");
    276    is(containerChildren.length, 1, "container has one button");
    277    is(
    278      containerChildren[0].getAttributeValue("AXRole"),
    279      "AXRadioButton",
    280      "Container child is radio button"
    281    );
    282 
    283    let linkedElems = cat.getAttributeValue("AXLinkedUIElements");
    284    is(linkedElems.length, 1, "Cat has 1 linked UI elem");
    285    is(
    286      linkedElems[0].getAttributeValue("AXTitle"),
    287      cat.getAttributeValue("AXTitle"),
    288      "Cat is first element"
    289    );
    290    let reorder = waitForEvent(EVENT_REORDER, "container");
    291    await SpecialPowers.spawn(browser, [], () => {
    292      let input = content.document.createElement("input");
    293      input.setAttribute("type", "radio");
    294      input.setAttribute("name", "animal");
    295      content.document.getElementById("container").appendChild(input);
    296    });
    297    await reorder;
    298 
    299    container = getNativeInterface(accDoc, "container");
    300    containerChildren = container.getAttributeValue("AXChildren");
    301 
    302    is(containerChildren.length, 2, "container has two children");
    303 
    304    Assert.deepEqual(
    305      getChildRoles(container),
    306      ["AXRadioButton", "AXRadioButton"],
    307      "Both children are radio buttons"
    308    );
    309 
    310    linkedElems = containerChildren[0].getAttributeValue("AXLinkedUIElements");
    311    is(linkedElems.length, 2, "Cat has 2 linked elements");
    312 
    313    linkedElems = containerChildren[1].getAttributeValue("AXLinkedUIElements");
    314    is(linkedElems.length, 2, "New button has 2 linked elements");
    315  }
    316 );