tor-browser

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

browser_markup_links_aria_attributes.js (6226B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Tests that the contextual menu shows the right items when clicking on a link
      7 // in aria attributes.
      8 
      9 const TEST_URL = URL_ROOT + "doc_markup_links_aria_attributes.html";
     10 
     11 // The test case array contains objects with the following properties:
     12 // - selector: css selector for the node to select in the inspector
     13 // - attributeName: name of the attribute to test
     14 // - links: an array of id strings that are expected to be in the attribute
     15 const TEST_DATA = [
     16  {
     17    selector: "#aria-activedescendant",
     18    attributeName: "aria-activedescendant",
     19    links: [{ id: "activedescendant01" }],
     20  },
     21  {
     22    selector: "#aria-controls",
     23    attributeName: "aria-controls",
     24    links: [{ id: "controls01" }, { id: "controls02" }],
     25  },
     26  {
     27    selector: "#aria-describedby",
     28    attributeName: "aria-describedby",
     29    links: [{ id: "describedby01" }, { id: "describedby02" }],
     30  },
     31  {
     32    selector: "#aria-details",
     33    attributeName: "aria-details",
     34    links: [{ id: "details01" }, { id: "details02" }],
     35  },
     36  {
     37    selector: "#aria-errormessage",
     38    attributeName: "aria-errormessage",
     39    links: [{ id: "errormessage01" }],
     40  },
     41  {
     42    selector: "#aria-flowto",
     43    attributeName: "aria-flowto",
     44    links: [{ id: "flowto01" }, { id: "flowto02" }],
     45  },
     46  {
     47    selector: "#aria-labelledby",
     48    attributeName: "aria-labelledby",
     49    links: [{ id: "labelledby01" }, { id: "labelledby02" }],
     50  },
     51  {
     52    selector: "#aria-owns",
     53    attributeName: "aria-owns",
     54    links: [{ id: "owns01" }, { id: "owns02" }],
     55  },
     56  {
     57    getContainer: async inspector => {
     58      info("Find and expand the test-component shadow DOM host.");
     59      const hostFront = await getNodeFront("test-component", inspector);
     60      const hostContainer = inspector.markup.getContainer(hostFront);
     61      await expandContainer(inspector, hostContainer);
     62 
     63      info("Expand the shadow root");
     64      const shadowRootContainer = hostContainer.getChildContainers()[0];
     65      await expandContainer(inspector, shadowRootContainer);
     66 
     67      info("Expand the slot");
     68      const slotContainer = shadowRootContainer.getChildContainers()[0];
     69 
     70      is(
     71        slotContainer.elt
     72          .querySelector(`[data-attr="id"]`)
     73          .getAttribute("data-value"),
     74        "aria-describedby-shadow-dom",
     75        `This is the container for button#aria-describedby-shadow-dom`
     76      );
     77 
     78      // The test expect the node to be selected
     79      const updated = inspector.once("inspector-updated");
     80      inspector.selection.setNodeFront(slotContainer.node, { reason: "test" });
     81      await updated;
     82 
     83      return slotContainer;
     84    },
     85    attributeName: "aria-describedby",
     86    links: [{ id: "describedby01", valid: false }, { id: "describedbyshadow" }],
     87  },
     88  {
     89    selector: "#empty-attributes",
     90    attributeName: "aria-activedescendant",
     91    links: [],
     92  },
     93  {
     94    selector: "#empty-attributes",
     95    attributeName: "aria-details",
     96    links: [],
     97  },
     98 ];
     99 
    100 add_task(async function () {
    101  const { inspector } = await openInspectorForURL(TEST_URL);
    102 
    103  for (const test of TEST_DATA) {
    104    let editor;
    105    if (typeof test.getContainer === "function") {
    106      ({ editor } = await test.getContainer(inspector));
    107    } else {
    108      info("Selecting test node " + test.selector);
    109      await selectNode(test.selector, inspector);
    110      info("Finding the popupNode to anchor the context-menu to");
    111      ({ editor } = await getContainerForSelector(test.selector, inspector));
    112    }
    113 
    114    const attributeEl = editor.attrElements.get(test.attributeName);
    115    const linksEl = attributeEl.querySelectorAll(".link");
    116 
    117    is(
    118      linksEl.length,
    119      test.links.length,
    120      "We have the expected number of links in attribute " + test.attributeName
    121    );
    122 
    123    for (let i = 0; i < test.links.length; i++) {
    124      info(`Checking link # ${i} for attribute "${test.attributeName}"`);
    125 
    126      const linkEl = linksEl[i];
    127      ok(linkEl, "Found the link");
    128 
    129      info("Simulating a context click on the link");
    130      const allMenuItems = openContextMenuAndGetAllItems(inspector, {
    131        target: linkEl,
    132      });
    133 
    134      const linkFollow = allMenuItems.find(
    135        ({ id }) => id === "node-menu-link-follow"
    136      );
    137      const linkCopy = allMenuItems.find(
    138        ({ id }) => id === "node-menu-link-copy"
    139      );
    140 
    141      is(linkFollow.visible, true, "The follow-link item is visible");
    142      is(linkCopy.visible, false, "The copy-link item is not visible");
    143      const { id: expectedReferencedNodeId } = test.links[i];
    144      const linkFollowItemLabel = INSPECTOR_L10N.getFormatStr(
    145        "inspector.menu.selectElement.label",
    146        expectedReferencedNodeId
    147      );
    148      is(
    149        linkFollow.label,
    150        linkFollowItemLabel,
    151        "the follow-link label is correct"
    152      );
    153 
    154      info("Check that select node button is displayed");
    155      const buttonEl = linkEl.querySelector("button.select-node");
    156      ok(buttonEl, "Found the select node button");
    157      is(
    158        buttonEl.getAttribute("title"),
    159        linkFollowItemLabel,
    160        "Button has expected title"
    161      );
    162 
    163      if (test.links[i].valid !== false) {
    164        info("Check that clicking on button selects the associated node");
    165        const onSelection = inspector.selection.once("new-node-front");
    166        buttonEl.click();
    167        await onSelection;
    168 
    169        is(
    170          inspector.selection.nodeFront.id,
    171          expectedReferencedNodeId,
    172          "The expected new node was selected"
    173        );
    174      } else {
    175        info(
    176          "Check that clicking on button triggers idref-attribute-link-failed event"
    177        );
    178        const onIdrefAttributeLinkFailed = inspector.markup.once(
    179          "idref-attribute-link-failed"
    180        );
    181        const onSelection = inspector.selection.once("new-node-front");
    182        const onTimeout = wait(500).then(() => "TIMEOUT");
    183        buttonEl.click();
    184        await onIdrefAttributeLinkFailed;
    185        ok(true, "Got expected idref-attribute-link-failed event");
    186        const res = await Promise.race([onSelection, onTimeout]);
    187        is(res, "TIMEOUT", "Clicking the button did not select a new node");
    188      }
    189    }
    190  }
    191 });