tor-browser

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

browser_fontinspector_reveal-in-page.js (5825B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 "use strict";
      4 
      5 // Test that fonts usage can be revealed in the page using the FontsHighlighter.
      6 
      7 const TEST_URI = URL_ROOT + "doc_browser_fontinspector.html";
      8 
      9 add_task(async function () {
     10  // Make sure the toolbox is tall enough to accomodate all fonts, otherwise mouseover
     11  // events simulation will fail.
     12  await pushPref("devtools.toolbox.footer.height", 500);
     13 
     14  const { inspector, view } = await openFontInspectorForURL(TEST_URI);
     15  await testFontHighlighting(view, inspector);
     16 
     17  info("Check that highlighting still works after reloading the page");
     18  await reloadBrowser();
     19 
     20  await testFontHighlighting(view, inspector);
     21 
     22  info("Check that highlighting works for iframe nodes");
     23  await testFontHighlightingInIframe(view, inspector);
     24 });
     25 
     26 async function testFontHighlighting(view, inspector) {
     27  await selectNode("body", inspector);
     28  // The number of window selection change events we expect to get as we hover over each
     29  // font in the list. Waiting for those events is how we know that text-runs were
     30  // highlighted in the page.
     31  const expectedSelectionChangeEvents = [1, 1, 1, 1, 1];
     32 
     33  const viewDoc = view.document;
     34 
     35  // Wait for the view to have all the expected used fonts.
     36  const fontEls = (
     37    await waitFor(() => {
     38      const els = getUsedFontsEls(viewDoc);
     39 
     40      // TODO: We should expect an exact match, but after removing client side
     41      // throttling there is sometimes a 6th font picked up on reload for this
     42      // test page.
     43      if (els.length < expectedSelectionChangeEvents.length) {
     44        return false;
     45      }
     46 
     47      return [...els];
     48    })
     49  ).filter(el => {
     50    // TODO: After removing client-side throttling, the test will request fonts
     51    // too quickly on reload and will sometimes pickup an extra font such as
     52    // "Helvetica" on macos. This font will not match any element on the page,
     53    // ignore it for now.
     54    const expectedFonts = ["ostrich", "arial", "liberation"];
     55    const font = el.textContent.toLowerCase();
     56    return expectedFonts.some(f => font.includes(f));
     57  });
     58 
     59  // See TODO above, we temporarily filter out unwanted fonts picked up on
     60  // reload.
     61  ok(
     62    !!fontEls.length,
     63    "After filtering out unwanted fonts, we still have fonts to test"
     64  );
     65 
     66  info("Expand the details element so all fonts are visible");
     67  const showMoreEl = viewDoc.querySelector("summary:has(.label-open)");
     68  if (showMoreEl) {
     69    EventUtils.synthesizeMouseAtCenter(showMoreEl, {}, viewDoc.defaultView);
     70  }
     71 
     72  for (let i = 0; i < fontEls.length; i++) {
     73    info(
     74      `Mousing over and out of font number ${i} ("${fontEls[i].textContent}") in the list`
     75    );
     76 
     77    const expectedEvents = expectedSelectionChangeEvents[i];
     78 
     79    // Simulating a mouse over event on the font name and expecting a selectionchange.
     80    const nameEl = fontEls[i];
     81    let onEvents = waitForNSelectionEvents(
     82      gBrowser.selectedBrowser,
     83      expectedEvents
     84    );
     85    EventUtils.synthesizeMouse(
     86      nameEl,
     87      2,
     88      2,
     89      { type: "mouseover" },
     90      viewDoc.defaultView
     91    );
     92    await onEvents;
     93 
     94    ok(true, `${expectedEvents} selectionchange events detected on mouseover`);
     95 
     96    // Simulating a mouse out event on the font name and expecting a selectionchange.
     97    const otherEl = viewDoc.querySelector("body");
     98    onEvents = waitForNSelectionEvents(gBrowser.selectedBrowser, 1);
     99    EventUtils.synthesizeMouse(
    100      otherEl,
    101      2,
    102      2,
    103      { type: "mouseover" },
    104      viewDoc.defaultView
    105    );
    106    await onEvents;
    107 
    108    ok(true, "1 selectionchange events detected on mouseout");
    109  }
    110 }
    111 
    112 async function testFontHighlightingInIframe(view, inspector) {
    113  await selectNodeInFrames(["iframe", "div"], inspector);
    114 
    115  const viewDoc = view.document;
    116 
    117  // Wait for the view to have all the expected used fonts.
    118  const fontEls = await waitFor(() => {
    119    const els = getUsedFontsEls(viewDoc);
    120 
    121    if (!els.length) {
    122      return false;
    123    }
    124 
    125    return [...els];
    126  });
    127 
    128  is(fontEls.length, 1, "There's only one font used in the iframe document");
    129  ok(
    130    // On Linux, Times New Roman does not exist. Liberation Serif is used instead.
    131    ["Times New Roman", "Liberation Serif"].includes(fontEls[0].innerText),
    132    "The expected font is displayed"
    133  );
    134 
    135  const iframeBrowsingContext = await SpecialPowers.spawn(
    136    gBrowser.selectedBrowser,
    137    [],
    138    () => content.document.querySelector("iframe").browsingContext
    139  );
    140 
    141  info(`Mousing over and out of the font  in the list`);
    142 
    143  // Simulating a mouse over event on the font name and expecting a selectionchange.
    144  const nameEl = fontEls[0];
    145  let onEvents = waitForNSelectionEvents(iframeBrowsingContext, 1);
    146  EventUtils.synthesizeMouse(
    147    nameEl,
    148    2,
    149    2,
    150    { type: "mouseover" },
    151    viewDoc.defaultView
    152  );
    153  await onEvents;
    154 
    155  ok(true, `A selectionchange events detected on mouseover`);
    156 
    157  // Simulating a mouse out event on the font name and expecting a selectionchange.
    158  const otherEl = viewDoc.querySelector("body");
    159  onEvents = waitForNSelectionEvents(iframeBrowsingContext, 1);
    160  EventUtils.synthesizeMouse(
    161    otherEl,
    162    2,
    163    2,
    164    { type: "mouseover" },
    165    viewDoc.defaultView
    166  );
    167  await onEvents;
    168 
    169  ok(true, "1 selectionchange events detected on mouseout");
    170 }
    171 
    172 async function waitForNSelectionEvents(browser, numberOfTimes) {
    173  await SpecialPowers.spawn(browser, [numberOfTimes], async function (n) {
    174    const win = content.wrappedJSObject;
    175 
    176    await new Promise(resolve => {
    177      let received = 0;
    178      win.document.addEventListener("selectionchange", function listen() {
    179        received++;
    180 
    181        if (received === n) {
    182          win.document.removeEventListener("selectionchange", listen);
    183          resolve();
    184        }
    185      });
    186    });
    187  });
    188 }