From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../client/shared/test/browser_treeWidget_basic.js | 391 +++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 devtools/client/shared/test/browser_treeWidget_basic.js (limited to 'devtools/client/shared/test/browser_treeWidget_basic.js') diff --git a/devtools/client/shared/test/browser_treeWidget_basic.js b/devtools/client/shared/test/browser_treeWidget_basic.js new file mode 100644 index 0000000000..48702b9b8d --- /dev/null +++ b/devtools/client/shared/test/browser_treeWidget_basic.js @@ -0,0 +1,391 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that the tree widget api works fine +"use strict"; + +const TEST_URI = + "data:text/html;charset=utf-8," + + "
"; +const { + TreeWidget, +} = require("resource://devtools/client/shared/widgets/TreeWidget.js"); + +add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["security.allow_unsafe_parent_loads", true]], + }); + await addTab("about:blank"); + const { host, doc } = await createHost("bottom", TEST_URI); + + const tree = new TreeWidget(doc.querySelector("div"), { + defaultType: "store", + }); + + populateTree(tree, doc); + testTreeItemInsertedCorrectly(tree, doc); + testAPI(tree, doc); + populateUnsortedTree(tree, doc); + testUnsortedTreeItemInsertedCorrectly(tree, doc); + + tree.destroy(); + host.destroy(); + gBrowser.removeCurrentTab(); +}); + +function populateTree(tree, doc) { + tree.add([ + { + id: "level1", + label: "Level 1", + }, + { + id: "level2-1", + label: "Level 2", + }, + { + id: "level3-1", + label: "Level 3 - Child 1", + type: "dir", + }, + ]); + tree.add([ + "level1", + "level2-1", + { + id: "level3-2", + label: "Level 3 - Child 2", + }, + ]); + tree.add([ + "level1", + "level2-1", + { + id: "level3-3", + label: "Level 3 - Child 3", + }, + ]); + tree.add([ + "level1", + { + id: "level2-2", + label: "Level 2.1", + }, + { + id: "level3-1", + label: "Level 3.1", + }, + ]); + tree.add([ + { + id: "level1", + label: "Level 1", + }, + { + id: "level2", + label: "Level 2", + }, + { + id: "level3", + label: "Level 3", + type: "js", + }, + ]); + tree.add(["level1.1", "level2", { id: "level3", type: "url" }]); +} + +/** + * Test if the nodes are inserted correctly in the tree. + */ +function testTreeItemInsertedCorrectly(tree, doc) { + is( + tree.root.children.children.length, + 2, + "Number of top level elements match" + ); + is( + tree.root.children.firstChild.lastChild.children.length, + 3, + "Number of first second level elements match" + ); + is( + tree.root.children.lastChild.lastChild.children.length, + 1, + "Number of second second level elements match" + ); + + ok(tree.root.items.has("level1"), "Level1 top level element exists"); + is( + tree.root.children.firstChild.dataset.id, + JSON.stringify(["level1"]), + "Data id of first top level element matches" + ); + is( + tree.root.children.firstChild.firstChild.textContent, + "Level 1", + "Text content of first top level element matches" + ); + + ok(tree.root.items.has("level1.1"), "Level1.1 top level element exists"); + is( + tree.root.children.firstChild.nextSibling.dataset.id, + JSON.stringify(["level1.1"]), + "Data id of second top level element matches" + ); + is( + tree.root.children.firstChild.nextSibling.firstChild.textContent, + "level1.1", + "Text content of second top level element matches" + ); + + // Adding a new non text item in the tree. + const node = doc.createElement("div"); + node.textContent = "Foo Bar"; + node.className = "foo bar"; + tree.add([ + { + id: "level1.2", + node, + attachment: { + foo: "bar", + }, + }, + ]); + + is( + tree.root.children.children.length, + 3, + "Number of top level elements match after update" + ); + ok(tree.root.items.has("level1.2"), "New level node got added"); + ok( + tree.attachments.has(JSON.stringify(["level1.2"])), + "Attachment is present for newly added node" + ); + // The item should be added before level1 and level 1.1 as lexical sorting + is( + tree.root.children.firstChild.dataset.id, + JSON.stringify(["level1.2"]), + "Data id of last top level element matches" + ); + is( + tree.root.children.firstChild.firstChild.firstChild, + node, + "Newly added node is inserted at the right location" + ); +} + +/** + * Populate the unsorted tree. + */ +function populateUnsortedTree(tree, doc) { + tree.sorted = false; + + tree.add([{ id: "g-1", label: "g-1" }]); + tree.add(["g-1", { id: "d-2", label: "d-2.1" }]); + tree.add(["g-1", { id: "b-2", label: "b-2.2" }]); + tree.add(["g-1", { id: "a-2", label: "a-2.3" }]); +} + +/** + * Test if the nodes are inserted correctly in the unsorted tree. + */ +function testUnsortedTreeItemInsertedCorrectly(tree, doc) { + ok(tree.root.items.has("g-1"), "g-1 top level element exists"); + + is( + tree.root.children.firstChild.lastChild.children.length, + 3, + "Number of children for g-1 matches" + ); + is( + tree.root.children.firstChild.dataset.id, + JSON.stringify(["g-1"]), + "Data id of g-1 matches" + ); + is( + tree.root.children.firstChild.firstChild.textContent, + "g-1", + "Text content of g-1 matches" + ); + is( + tree.root.children.firstChild.lastChild.firstChild.dataset.id, + JSON.stringify(["g-1", "d-2"]), + "Data id of d-2 matches" + ); + is( + tree.root.children.firstChild.lastChild.firstChild.textContent, + "d-2.1", + "Text content of d-2 matches" + ); + is( + tree.root.children.firstChild.lastChild.firstChild.nextSibling.textContent, + "b-2.2", + "Text content of b-2 matches" + ); + is( + tree.root.children.firstChild.lastChild.lastChild.textContent, + "a-2.3", + "Text content of a-2 matches" + ); +} + +/** + * Tests if the API exposed by TreeWidget works properly + */ +function testAPI(tree, doc) { + info("Testing TreeWidget API"); + // Check if selectItem and selectedItem setter works as expected + // Nothing should be selected beforehand + ok(!doc.querySelector(".theme-selected"), "Nothing is selected"); + tree.selectItem(["level1"]); + const node = doc.querySelector(".theme-selected"); + ok(!!node, "Something got selected"); + is( + node.parentNode.dataset.id, + JSON.stringify(["level1"]), + "Correct node selected" + ); + + tree.selectItem(["level1", "level2"]); + const node2 = doc.querySelector(".theme-selected"); + ok(!!node2, "Something is still selected"); + isnot(node, node2, "Newly selected node is different from previous"); + is( + node2.parentNode.dataset.id, + JSON.stringify(["level1", "level2"]), + "Correct node selected" + ); + + // test if selectedItem getter works + is(tree.selectedItem.length, 2, "Correct length of selected item"); + is(tree.selectedItem[0], "level1", "Correct selected item"); + is(tree.selectedItem[1], "level2", "Correct selected item"); + + // test if isSelected works + ok(tree.isSelected(["level1", "level2"]), "isSelected works"); + + tree.selectedItem = ["level1"]; + const node3 = doc.querySelector(".theme-selected"); + ok(!!node3, "Something is still selected"); + isnot(node2, node3, "Newly selected node is different from previous"); + is(node3, node, "First and third selected nodes should be same"); + is( + node3.parentNode.dataset.id, + JSON.stringify(["level1"]), + "Correct node selected" + ); + + // test if selectedItem getter works + is(tree.selectedItem.length, 1, "Correct length of selected item"); + is(tree.selectedItem[0], "level1", "Correct selected item"); + + // test if clear selection works + tree.clearSelection(); + ok( + !doc.querySelector(".theme-selected"), + "Nothing selected after clear selection call" + ); + + // test if collapseAll/expandAll work + ok(!!doc.querySelectorAll("[expanded]").length, "Some nodes are expanded"); + tree.collapseAll(); + is( + doc.querySelectorAll("[expanded]").length, + 0, + "Nothing is expanded after collapseAll call" + ); + tree.expandAll(); + is( + doc.querySelectorAll("[expanded]").length, + 13, + "All tree items expanded after expandAll call" + ); + + // test if selectNextItem and selectPreviousItem work + tree.selectedItem = ["level1", "level2"]; + ok(tree.isSelected(["level1", "level2"]), "Correct item selected"); + tree.selectNextItem(); + ok( + tree.isSelected(["level1", "level2", "level3"]), + "Correct item selected after selectNextItem call" + ); + + tree.selectNextItem(); + ok( + tree.isSelected(["level1", "level2-1"]), + "Correct item selected after second selectNextItem call" + ); + + tree.selectNextItem(); + ok( + tree.isSelected(["level1", "level2-1", "level3-1"]), + "Correct item selected after third selectNextItem call" + ); + + tree.selectPreviousItem(); + ok( + tree.isSelected(["level1", "level2-1"]), + "Correct item selected after selectPreviousItem call" + ); + + tree.selectPreviousItem(); + ok( + tree.isSelected(["level1", "level2", "level3"]), + "Correct item selected after second selectPreviousItem call" + ); + + // test if remove works + ok( + doc.querySelector( + "[data-id='" + JSON.stringify(["level1", "level2", "level3"]) + "']" + ), + "level1-level2-level3 item exists before removing" + ); + tree.remove(["level1", "level2", "level3"]); + ok( + !doc.querySelector( + "[data-id='" + JSON.stringify(["level1", "level2", "level3"]) + "']" + ), + "level1-level2-level3 item does not exist after removing" + ); + const level2item = doc.querySelector( + "[data-id='" + + JSON.stringify(["level1", "level2"]) + + "'] > .tree-widget-item" + ); + ok( + level2item.hasAttribute("empty"), + "level1-level2 item is marked as empty after removing" + ); + + tree.add([ + { + id: "level1", + label: "Level 1", + }, + { + id: "level2", + label: "Level 2", + }, + { + id: "level3", + label: "Level 3", + type: "js", + }, + ]); + + // test if clearing the tree works + is( + doc.querySelectorAll("[level='1']").length, + 3, + "Correct number of top level items before clearing" + ); + tree.clear(); + is( + doc.querySelectorAll("[level='1']").length, + 0, + "No top level item after clearing the tree" + ); +} -- cgit v1.2.3