tor-browser

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

browser_treeWidget_basic.js (9842B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 // Tests that the tree widget api works fine
      5 "use strict";
      6 
      7 const TEST_URI =
      8  "data:text/html;charset=utf-8,<head>" +
      9  "<link rel='stylesheet' type='text/css' href='chrome://devtools/skin/widg" +
     10  "ets.css'></head><body><div></div><span></span></body>";
     11 const {
     12  TreeWidget,
     13 } = require("resource://devtools/client/shared/widgets/TreeWidget.js");
     14 
     15 add_task(async function () {
     16  await SpecialPowers.pushPrefEnv({
     17    set: [["security.allow_unsafe_parent_loads", true]],
     18  });
     19  await addTab("about:blank");
     20  const { host, doc } = await createHost("bottom", TEST_URI);
     21 
     22  const tree = new TreeWidget(doc.querySelector("div"), {
     23    defaultType: "store",
     24  });
     25 
     26  populateTree(tree, doc);
     27  testTreeItemInsertedCorrectly(tree, doc);
     28  testAPI(tree, doc);
     29  populateUnsortedTree(tree, doc);
     30  testUnsortedTreeItemInsertedCorrectly(tree, doc);
     31 
     32  tree.destroy();
     33  host.destroy();
     34  gBrowser.removeCurrentTab();
     35 });
     36 
     37 function populateTree(tree) {
     38  tree.add([
     39    {
     40      id: "level1",
     41      label: "Level 1",
     42    },
     43    {
     44      id: "level2-1",
     45      label: "Level 2",
     46    },
     47    {
     48      id: "level3-1",
     49      label: "Level 3 - Child 1",
     50      type: "dir",
     51    },
     52  ]);
     53  tree.add([
     54    "level1",
     55    "level2-1",
     56    {
     57      id: "level3-2",
     58      label: "Level 3 - Child 2",
     59    },
     60  ]);
     61  tree.add([
     62    "level1",
     63    "level2-1",
     64    {
     65      id: "level3-3",
     66      label: "Level 3 - Child 3",
     67    },
     68  ]);
     69  tree.add([
     70    "level1",
     71    {
     72      id: "level2-2",
     73      label: "Level 2.1",
     74    },
     75    {
     76      id: "level3-1",
     77      label: "Level 3.1",
     78    },
     79  ]);
     80  tree.add([
     81    {
     82      id: "level1",
     83      label: "Level 1",
     84    },
     85    {
     86      id: "level2",
     87      label: "Level 2",
     88    },
     89    {
     90      id: "level3",
     91      label: "Level 3",
     92      type: "js",
     93    },
     94  ]);
     95  tree.add(["level1.1", "level2", { id: "level3", type: "url" }]);
     96 }
     97 
     98 /**
     99 * Test if the nodes are inserted correctly in the tree.
    100 */
    101 function testTreeItemInsertedCorrectly(tree, doc) {
    102  is(
    103    tree.root.children.children.length,
    104    2,
    105    "Number of top level elements match"
    106  );
    107  is(
    108    tree.root.children.firstChild.lastChild.children.length,
    109    3,
    110    "Number of first second level elements match"
    111  );
    112  is(
    113    tree.root.children.lastChild.lastChild.children.length,
    114    1,
    115    "Number of second second level elements match"
    116  );
    117 
    118  ok(tree.root.items.has("level1"), "Level1 top level element exists");
    119  is(
    120    tree.root.children.firstChild.dataset.id,
    121    JSON.stringify(["level1"]),
    122    "Data id of first top level element matches"
    123  );
    124  is(
    125    tree.root.children.firstChild.firstChild.textContent,
    126    "Level 1",
    127    "Text content of first top level element matches"
    128  );
    129 
    130  ok(tree.root.items.has("level1.1"), "Level1.1 top level element exists");
    131  is(
    132    tree.root.children.firstChild.nextSibling.dataset.id,
    133    JSON.stringify(["level1.1"]),
    134    "Data id of second top level element matches"
    135  );
    136  is(
    137    tree.root.children.firstChild.nextSibling.firstChild.textContent,
    138    "level1.1",
    139    "Text content of second top level element matches"
    140  );
    141 
    142  // Adding a new non text item in the tree.
    143  const node = doc.createElement("div");
    144  node.textContent = "Foo Bar";
    145  node.className = "foo bar";
    146  tree.add([
    147    {
    148      id: "level1.2",
    149      node,
    150      attachment: {
    151        foo: "bar",
    152      },
    153    },
    154  ]);
    155 
    156  is(
    157    tree.root.children.children.length,
    158    3,
    159    "Number of top level elements match after update"
    160  );
    161  ok(tree.root.items.has("level1.2"), "New level node got added");
    162  ok(
    163    tree.attachments.has(JSON.stringify(["level1.2"])),
    164    "Attachment is present for newly added node"
    165  );
    166  // The item should be added before level1 and level 1.1 as lexical sorting
    167  is(
    168    tree.root.children.firstChild.dataset.id,
    169    JSON.stringify(["level1.2"]),
    170    "Data id of last top level element matches"
    171  );
    172  is(
    173    tree.root.children.firstChild.firstChild.firstChild,
    174    node,
    175    "Newly added node is inserted at the right location"
    176  );
    177 }
    178 
    179 /**
    180 * Populate the unsorted tree.
    181 */
    182 function populateUnsortedTree(tree) {
    183  tree.sorted = false;
    184 
    185  tree.add([{ id: "g-1", label: "g-1" }]);
    186  tree.add(["g-1", { id: "d-2", label: "d-2.1" }]);
    187  tree.add(["g-1", { id: "b-2", label: "b-2.2" }]);
    188  tree.add(["g-1", { id: "a-2", label: "a-2.3" }]);
    189 }
    190 
    191 /**
    192 * Test if the nodes are inserted correctly in the unsorted tree.
    193 */
    194 function testUnsortedTreeItemInsertedCorrectly(tree) {
    195  ok(tree.root.items.has("g-1"), "g-1 top level element exists");
    196 
    197  is(
    198    tree.root.children.firstChild.lastChild.children.length,
    199    3,
    200    "Number of children for g-1 matches"
    201  );
    202  is(
    203    tree.root.children.firstChild.dataset.id,
    204    JSON.stringify(["g-1"]),
    205    "Data id of g-1 matches"
    206  );
    207  is(
    208    tree.root.children.firstChild.firstChild.textContent,
    209    "g-1",
    210    "Text content of g-1 matches"
    211  );
    212  is(
    213    tree.root.children.firstChild.lastChild.firstChild.dataset.id,
    214    JSON.stringify(["g-1", "d-2"]),
    215    "Data id of d-2 matches"
    216  );
    217  is(
    218    tree.root.children.firstChild.lastChild.firstChild.textContent,
    219    "d-2.1",
    220    "Text content of d-2 matches"
    221  );
    222  is(
    223    tree.root.children.firstChild.lastChild.firstChild.nextSibling.textContent,
    224    "b-2.2",
    225    "Text content of b-2 matches"
    226  );
    227  is(
    228    tree.root.children.firstChild.lastChild.lastChild.textContent,
    229    "a-2.3",
    230    "Text content of a-2 matches"
    231  );
    232 }
    233 
    234 /**
    235 * Tests if the API exposed by TreeWidget works properly
    236 */
    237 function testAPI(tree, doc) {
    238  info("Testing TreeWidget API");
    239  // Check if selectItem and selectedItem setter works as expected
    240  // Nothing should be selected beforehand
    241  ok(!doc.querySelector(".theme-selected"), "Nothing is selected");
    242  tree.selectItem(["level1"]);
    243  const node = doc.querySelector(".theme-selected");
    244  ok(!!node, "Something got selected");
    245  is(
    246    node.parentNode.dataset.id,
    247    JSON.stringify(["level1"]),
    248    "Correct node selected"
    249  );
    250 
    251  tree.selectItem(["level1", "level2"]);
    252  const node2 = doc.querySelector(".theme-selected");
    253  ok(!!node2, "Something is still selected");
    254  isnot(node, node2, "Newly selected node is different from previous");
    255  is(
    256    node2.parentNode.dataset.id,
    257    JSON.stringify(["level1", "level2"]),
    258    "Correct node selected"
    259  );
    260 
    261  // test if selectedItem getter works
    262  is(tree.selectedItem.length, 2, "Correct length of selected item");
    263  is(tree.selectedItem[0], "level1", "Correct selected item");
    264  is(tree.selectedItem[1], "level2", "Correct selected item");
    265 
    266  // test if isSelected works
    267  ok(tree.isSelected(["level1", "level2"]), "isSelected works");
    268 
    269  tree.selectedItem = ["level1"];
    270  const node3 = doc.querySelector(".theme-selected");
    271  ok(!!node3, "Something is still selected");
    272  isnot(node2, node3, "Newly selected node is different from previous");
    273  is(node3, node, "First and third selected nodes should be same");
    274  is(
    275    node3.parentNode.dataset.id,
    276    JSON.stringify(["level1"]),
    277    "Correct node selected"
    278  );
    279 
    280  // test if selectedItem getter works
    281  is(tree.selectedItem.length, 1, "Correct length of selected item");
    282  is(tree.selectedItem[0], "level1", "Correct selected item");
    283 
    284  // test if clear selection works
    285  tree.clearSelection();
    286  ok(
    287    !doc.querySelector(".theme-selected"),
    288    "Nothing selected after clear selection call"
    289  );
    290 
    291  // test if collapseAll/expandAll work
    292  ok(!!doc.querySelectorAll("[expanded]").length, "Some nodes are expanded");
    293  tree.collapseAll();
    294  is(
    295    doc.querySelectorAll("[expanded]").length,
    296    0,
    297    "Nothing is expanded after collapseAll call"
    298  );
    299  tree.expandAll();
    300  is(
    301    doc.querySelectorAll("[expanded]").length,
    302    13,
    303    "All tree items expanded after expandAll call"
    304  );
    305 
    306  // test if selectNextItem and selectPreviousItem work
    307  tree.selectedItem = ["level1", "level2"];
    308  ok(tree.isSelected(["level1", "level2"]), "Correct item selected");
    309  tree.selectNextItem();
    310  ok(
    311    tree.isSelected(["level1", "level2", "level3"]),
    312    "Correct item selected after selectNextItem call"
    313  );
    314 
    315  tree.selectNextItem();
    316  ok(
    317    tree.isSelected(["level1", "level2-1"]),
    318    "Correct item selected after second selectNextItem call"
    319  );
    320 
    321  tree.selectNextItem();
    322  ok(
    323    tree.isSelected(["level1", "level2-1", "level3-1"]),
    324    "Correct item selected after third selectNextItem call"
    325  );
    326 
    327  tree.selectPreviousItem();
    328  ok(
    329    tree.isSelected(["level1", "level2-1"]),
    330    "Correct item selected after selectPreviousItem call"
    331  );
    332 
    333  tree.selectPreviousItem();
    334  ok(
    335    tree.isSelected(["level1", "level2", "level3"]),
    336    "Correct item selected after second selectPreviousItem call"
    337  );
    338 
    339  // test if remove works
    340  ok(
    341    doc.querySelector(
    342      "[data-id='" + JSON.stringify(["level1", "level2", "level3"]) + "']"
    343    ),
    344    "level1-level2-level3 item exists before removing"
    345  );
    346  tree.remove(["level1", "level2", "level3"]);
    347  ok(
    348    !doc.querySelector(
    349      "[data-id='" + JSON.stringify(["level1", "level2", "level3"]) + "']"
    350    ),
    351    "level1-level2-level3 item does not exist after removing"
    352  );
    353  const level2item = doc.querySelector(
    354    "[data-id='" +
    355      JSON.stringify(["level1", "level2"]) +
    356      "'] > .tree-widget-item"
    357  );
    358  ok(
    359    level2item.hasAttribute("empty"),
    360    "level1-level2 item is marked as empty after removing"
    361  );
    362 
    363  tree.add([
    364    {
    365      id: "level1",
    366      label: "Level 1",
    367    },
    368    {
    369      id: "level2",
    370      label: "Level 2",
    371    },
    372    {
    373      id: "level3",
    374      label: "Level 3",
    375      type: "js",
    376    },
    377  ]);
    378 
    379  // test if clearing the tree works
    380  is(
    381    doc.querySelectorAll("[level='1']").length,
    382    3,
    383    "Correct number of top level items before clearing"
    384  );
    385  tree.clear();
    386  is(
    387    doc.querySelectorAll("[level='1']").length,
    388    0,
    389    "No top level item after clearing the tree"
    390  );
    391 }