tor-browser

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

test_NodeCache.js (8834B)


      1 const { NodeCache } = ChromeUtils.importESModule(
      2  "chrome://remote/content/shared/webdriver/NodeCache.sys.mjs"
      3 );
      4 
      5 function setupTest() {
      6  const browser = Services.appShell.createWindowlessBrowser(false);
      7 
      8  browser.document.body.innerHTML = `
      9    <div id="foo" style="margin: 50px">
     10      <iframe></iframe>
     11      <video></video>
     12      <svg xmlns="http://www.w3.org/2000/svg"></svg>
     13      <textarea></textarea>
     14    </div>
     15    <div id="with-comment"><!-- Comment --></div>
     16  `;
     17 
     18  const divEl = browser.document.querySelector("div");
     19  const svgEl = browser.document.querySelector("svg");
     20  const textareaEl = browser.document.querySelector("textarea");
     21  const videoEl = browser.document.querySelector("video");
     22 
     23  const iframeEl = browser.document.querySelector("iframe");
     24  const childEl = iframeEl.contentDocument.createElement("div");
     25  iframeEl.contentDocument.body.appendChild(childEl);
     26 
     27  const shadowRoot = videoEl.openOrClosedShadowRoot;
     28 
     29  return {
     30    browser,
     31    nodeCache: new NodeCache(),
     32    childEl,
     33    divEl,
     34    iframeEl,
     35    shadowRoot,
     36    seenNodeIds: new Map(),
     37    svgEl,
     38    textareaEl,
     39    videoEl,
     40  };
     41 }
     42 
     43 add_task(function getOrCreateNodeReference_invalid() {
     44  const { nodeCache, seenNodeIds } = setupTest();
     45 
     46  const invalidValues = [null, undefined, "foo", 42, true, [], {}];
     47 
     48  for (const value of invalidValues) {
     49    info(`Testing value: ${value}`);
     50    Assert.throws(
     51      () => nodeCache.getOrCreateNodeReference(value, seenNodeIds),
     52      /TypeError/
     53    );
     54  }
     55 });
     56 
     57 add_task(function getOrCreateNodeReference_supportedNodeTypes() {
     58  const { browser, divEl, nodeCache, seenNodeIds } = setupTest();
     59 
     60  // Bug 1820734: No ownerGlobal is available in XPCShell tests
     61  // const xmlDocument = new DOMParser().parseFromString(
     62  //   "<xml></xml>",
     63  //   "application/xml"
     64  // );
     65 
     66  const values = [
     67    { node: divEl, type: Node.ELEMENT_NODE },
     68    { node: divEl.attributes[0], type: Node.ATTRIBUTE_NODE },
     69    { node: browser.document.createTextNode("foo"), type: Node.TEXT_NODE },
     70    // Bug 1820734: No ownerGlobal is available in XPCShell tests
     71    // {
     72    //   node: xmlDocument.createCDATASection("foo"),
     73    //   type: Node.CDATA_SECTION_NODE,
     74    // },
     75    {
     76      node: browser.document.createProcessingInstruction(
     77        "xml-stylesheet",
     78        "href='foo.css'"
     79      ),
     80      type: Node.PROCESSING_INSTRUCTION_NODE_NODE,
     81    },
     82    { node: browser.document.createComment("foo"), type: Node.COMMENT_NODE },
     83    { node: browser.document, type: Node.Document_NODE },
     84    {
     85      node: browser.document.implementation.createDocumentType(
     86        "foo",
     87        "bar",
     88        "dtd"
     89      ),
     90      type: Node.DOCUMENT_TYPE_NODE_NODE,
     91    },
     92    {
     93      node: browser.document.createDocumentFragment(),
     94      type: Node.DOCUMENT_FRAGMENT_NODE,
     95    },
     96  ];
     97 
     98  values.forEach((value, index) => {
     99    info(`Testing value: ${value.type}`);
    100    const nodeRef = nodeCache.getOrCreateNodeReference(value.node, seenNodeIds);
    101    equal(nodeCache.size, index + 1);
    102    equal(typeof nodeRef, "string");
    103    ok(seenNodeIds.get(browser.browsingContext).includes(nodeRef));
    104  });
    105 });
    106 
    107 add_task(function getOrCreateNodeReference_referenceAlreadyCreated() {
    108  const { browser, divEl, nodeCache, seenNodeIds } = setupTest();
    109 
    110  const divElRef = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    111  const divElRefOther = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    112 
    113  equal(divElRefOther, divElRef);
    114  equal(nodeCache.size, 1);
    115  equal(seenNodeIds.size, 1);
    116  ok(seenNodeIds.get(browser.browsingContext).includes(divElRef));
    117 });
    118 
    119 add_task(function getOrCreateNodeReference_differentReference() {
    120  const { browser, divEl, nodeCache, seenNodeIds, shadowRoot } = setupTest();
    121 
    122  const divElRef = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    123  equal(nodeCache.size, 1);
    124  equal(seenNodeIds.size, 1);
    125  ok(seenNodeIds.get(browser.browsingContext).includes(divElRef));
    126 
    127  const shadowRootRef = nodeCache.getOrCreateNodeReference(
    128    shadowRoot,
    129    seenNodeIds
    130  );
    131  equal(nodeCache.size, 2);
    132  equal(seenNodeIds.size, 1);
    133  ok(seenNodeIds.get(browser.browsingContext).includes(divElRef));
    134  ok(seenNodeIds.get(browser.browsingContext).includes(shadowRootRef));
    135 
    136  notEqual(divElRef, shadowRootRef);
    137 });
    138 
    139 add_task(function getOrCreateNodeReference_differentReferencePerNodeCache() {
    140  const { browser, divEl, nodeCache, seenNodeIds } = setupTest();
    141  const nodeCache2 = new NodeCache();
    142 
    143  const divElRef1 = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    144  const divElRef2 = nodeCache2.getOrCreateNodeReference(divEl, seenNodeIds);
    145 
    146  notEqual(divElRef1, divElRef2);
    147  equal(
    148    nodeCache.getNode(browser.browsingContext, divElRef1),
    149    nodeCache2.getNode(browser.browsingContext, divElRef2)
    150  );
    151 
    152  equal(seenNodeIds.size, 1);
    153  ok(seenNodeIds.get(browser.browsingContext).includes(divElRef1));
    154  ok(seenNodeIds.get(browser.browsingContext).includes(divElRef2));
    155 
    156  equal(nodeCache.getNode(browser.browsingContext, divElRef2), null);
    157 });
    158 
    159 add_task(function clear() {
    160  const { browser, divEl, nodeCache, seenNodeIds, svgEl } = setupTest();
    161 
    162  nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    163  nodeCache.getOrCreateNodeReference(svgEl, seenNodeIds);
    164  equal(nodeCache.size, 2);
    165  equal(seenNodeIds.size, 1);
    166 
    167  // Clear requires explicit arguments.
    168  Assert.throws(() => nodeCache.clear(), /Error/);
    169 
    170  // Clear references for a different browsing context
    171  const browser2 = Services.appShell.createWindowlessBrowser(false);
    172  const imgEl = browser2.document.createElement("img");
    173  const imgElRef = nodeCache.getOrCreateNodeReference(imgEl, seenNodeIds);
    174  equal(nodeCache.size, 3);
    175  equal(seenNodeIds.size, 2);
    176 
    177  nodeCache.clear({ browsingContext: browser.browsingContext });
    178  equal(nodeCache.size, 1);
    179  equal(nodeCache.getNode(browser2.browsingContext, imgElRef), imgEl);
    180 
    181  // Clear all references
    182  nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    183  equal(nodeCache.size, 2);
    184  equal(seenNodeIds.size, 2);
    185 
    186  nodeCache.clear({ all: true });
    187  equal(nodeCache.size, 0);
    188 });
    189 
    190 add_task(function getNode_multiple_nodes() {
    191  const { browser, divEl, nodeCache, seenNodeIds, svgEl } = setupTest();
    192 
    193  const divElRef = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    194  const svgElRef = nodeCache.getOrCreateNodeReference(svgEl, seenNodeIds);
    195 
    196  equal(nodeCache.getNode(browser.browsingContext, svgElRef), svgEl);
    197  equal(nodeCache.getNode(browser.browsingContext, divElRef), divEl);
    198 });
    199 
    200 add_task(function getNode_differentBrowsingContextInSameGroup() {
    201  const { iframeEl, divEl, nodeCache, seenNodeIds } = setupTest();
    202 
    203  const divElRef = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    204  equal(nodeCache.size, 1);
    205 
    206  equal(
    207    nodeCache.getNode(iframeEl.contentWindow.browsingContext, divElRef),
    208    divEl
    209  );
    210 });
    211 
    212 add_task(function getNode_differentBrowsingContextInOtherGroup() {
    213  const { divEl, nodeCache, seenNodeIds } = setupTest();
    214 
    215  const divElRef = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    216  equal(nodeCache.size, 1);
    217 
    218  const browser2 = Services.appShell.createWindowlessBrowser(false);
    219  equal(nodeCache.getNode(browser2.browsingContext, divElRef), null);
    220 });
    221 
    222 add_task(async function getNode_nodeDeleted() {
    223  const { browser, nodeCache, seenNodeIds } = setupTest();
    224  let el = browser.document.createElement("div");
    225 
    226  const elRef = nodeCache.getOrCreateNodeReference(el, seenNodeIds);
    227 
    228  // Delete element and force a garbage collection
    229  el = null;
    230 
    231  await doGC();
    232 
    233  equal(nodeCache.getNode(browser.browsingContext, elRef), null);
    234 });
    235 
    236 add_task(function getNodeDetails_forTopBrowsingContext() {
    237  const { browser, divEl, nodeCache, seenNodeIds } = setupTest();
    238 
    239  const divElRef = nodeCache.getOrCreateNodeReference(divEl, seenNodeIds);
    240 
    241  const nodeDetails = nodeCache.getReferenceDetails(divElRef);
    242  equal(nodeDetails.browserId, browser.browsingContext.browserId);
    243  equal(nodeDetails.browsingContextGroupId, browser.browsingContext.group.id);
    244  equal(nodeDetails.browsingContextId, browser.browsingContext.id);
    245  ok(nodeDetails.isTopBrowsingContext);
    246  ok(nodeDetails.nodeWeakRef);
    247  equal(nodeDetails.nodeWeakRef.get(), divEl);
    248 });
    249 
    250 add_task(async function getNodeDetails_forChildBrowsingContext() {
    251  const { browser, iframeEl, childEl, nodeCache, seenNodeIds } = setupTest();
    252 
    253  const childElRef = nodeCache.getOrCreateNodeReference(childEl, seenNodeIds);
    254 
    255  const nodeDetails = nodeCache.getReferenceDetails(childElRef);
    256  equal(nodeDetails.browserId, browser.browsingContext.browserId);
    257  equal(nodeDetails.browsingContextGroupId, browser.browsingContext.group.id);
    258  equal(
    259    nodeDetails.browsingContextId,
    260    iframeEl.contentWindow.browsingContext.id
    261  );
    262  ok(!nodeDetails.isTopBrowsingContext);
    263  ok(nodeDetails.nodeWeakRef);
    264  equal(nodeDetails.nodeWeakRef.get(), childEl);
    265 });