tor-browser

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

browser_webconsole_custom_formatters.js (5950B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Check display of custom formatters.
      7 const TEST_URI =
      8  "https://example.com/browser/devtools/client/webconsole/" +
      9  "test/browser/test-console-custom-formatters.html";
     10 
     11 add_task(async function () {
     12  await pushPref("devtools.custom-formatters.enabled", true);
     13 
     14  const hud = await openNewTabAndConsole(TEST_URI);
     15 
     16  // Reload the browser to ensure the custom formatters are picked up
     17  await reloadBrowser();
     18 
     19  await testString(hud);
     20  await testNumber(hud);
     21  await testObjectWithoutFormatting(hud);
     22  await testObjectWithFormattedHeader(hud);
     23  await testObjectWithFormattedHeaderAndBody(hud);
     24  await testCustomFormatterWithObjectTag(hud);
     25  await testProxyObject(hud);
     26 });
     27 
     28 async function testString(hud) {
     29  info("Test for string not being custom formatted");
     30  await testCustomFormatting(hud, {
     31    hasCustomFormatter: false,
     32    messageText: "string",
     33  });
     34 }
     35 
     36 async function testNumber(hud) {
     37  info("Test for number not being custom formatted");
     38  await testCustomFormatting(hud, {
     39    hasCustomFormatter: false,
     40    messageText: 1337,
     41  });
     42 }
     43 
     44 async function testObjectWithoutFormatting(hud) {
     45  info("Test for object not being custom formatted");
     46  await testCustomFormatting(hud, {
     47    hasCustomFormatter: false,
     48    messageText: "Object { noFormat: true }",
     49  });
     50 }
     51 
     52 async function testObjectWithFormattedHeader(hud) {
     53  info("Simple test for custom formatted header");
     54  await testCustomFormatting(hud, {
     55    hasCustomFormatter: true,
     56    messageText: "custom formatted header",
     57    headerStyles: "font-size: 3rem;",
     58  });
     59 }
     60 
     61 async function testObjectWithFormattedHeaderAndBody(hud) {
     62  info("Simple test for custom formatted header with body");
     63  await testCustomFormatting(hud, {
     64    hasCustomFormatter: true,
     65    messageText: "custom formatted body",
     66    headerStyles: "font-style: italic;",
     67    bodyText: "body",
     68    bodyStyles: "font-size: 2rem; font-family: serif;",
     69  });
     70 }
     71 
     72 async function testCustomFormatterWithObjectTag(hud) {
     73  info(`Test for custom formatted object with "object" tag in the jsonMl`);
     74  const node = await waitFor(() => {
     75    return findConsoleAPIMessage(hud, "object tag");
     76  });
     77 
     78  const headerJsonMlNode = node.querySelector(".objectBox-jsonml");
     79  is(
     80    headerJsonMlNode.getAttribute("style"),
     81    "color: purple;",
     82    "The custom formatting of the header is correct"
     83  );
     84  const [buttonEl, child1, child2, child3, child4] =
     85    headerJsonMlNode.childNodes;
     86  is(child1.textContent, "object tag", "Got expected first item");
     87  is(
     88    child2.textContent,
     89    `~[1,"a"]~`,
     90    "Got expected second item, the replaced object, custom formatted"
     91  );
     92  ok(
     93    child3.classList.contains("objectBox-null"),
     94    "Got expected third item, an actual NullRep"
     95  );
     96  is(child3.textContent, `null`, "third item has expected content");
     97 
     98  is(
     99    child4.textContent,
    100    ` | serialized: 42n undefined null Infinity [object Object]`,
    101    "Got expected fourth item, serialized values"
    102  );
    103 
    104  buttonEl.click();
    105  const bodyLevel1 = await waitFor(() =>
    106    node.querySelector(".objectBox-jsonml-body-wrapper .objectBox-jsonml")
    107  );
    108  const [bodyChild1, bodyChild2] = bodyLevel1.childNodes;
    109  is(bodyChild1.textContent, "body");
    110 
    111  const bodyCustomFormattedChild = await waitFor(() =>
    112    bodyChild2.querySelector(".objectBox-jsonml")
    113  );
    114  const [subButtonEl, subChild1, subChild2, subChild3] =
    115    bodyCustomFormattedChild.childNodes;
    116  ok(!!subButtonEl, "The body child can also be expanded");
    117  is(subChild1.textContent, "object tag", "Got expected first item");
    118  is(
    119    subChild2.textContent,
    120    `~[2,"b"]~`,
    121    "Got expected body second item, the replaced object, custom formatted"
    122  );
    123  ok(
    124    subChild3.classList.contains("object-inspector"),
    125    "Got expected body third item, an actual ObjectInspector"
    126  );
    127  is(
    128    subChild3.textContent,
    129    `Array [ 2, "b" ]`,
    130    "body third item has expected content"
    131  );
    132 }
    133 
    134 async function testProxyObject(hud) {
    135  info("Test that Proxy objects can be handled by custom formatter");
    136  await testCustomFormatting(hud, {
    137    hasCustomFormatter: true,
    138    messageText: "Formatted Proxy",
    139    headerStyles: "font-weight: bold;",
    140  });
    141 }
    142 
    143 async function testCustomFormatting(
    144  hud,
    145  { hasCustomFormatter, messageText, headerStyles, bodyText, bodyStyles }
    146 ) {
    147  const node = await waitFor(() => {
    148    return findMessageVirtualizedByType({
    149      hud,
    150      text: messageText,
    151      typeSelector: ".console-api",
    152    });
    153  });
    154 
    155  const headerJsonMlNode = node.querySelector(".objectBox-jsonml");
    156  if (hasCustomFormatter) {
    157    ok(headerJsonMlNode, "The message is custom formatted");
    158 
    159    if (!headerJsonMlNode) {
    160      return;
    161    }
    162 
    163    is(
    164      headerJsonMlNode.getAttribute("style"),
    165      headerStyles,
    166      "The custom formatting of the header is correct"
    167    );
    168 
    169    if (bodyText) {
    170      const arrow = node.querySelector(".collapse-button");
    171 
    172      ok(arrow, "There must be a toggle arrow for the header");
    173 
    174      info("Expanding the Object");
    175      const onBodyRendered = waitFor(
    176        () =>
    177          !!node.querySelector(
    178            ".objectBox-jsonml-body-wrapper .objectBox-jsonml"
    179          )
    180      );
    181 
    182      arrow.click();
    183      await onBodyRendered;
    184 
    185      ok(
    186        node.querySelector(".collapse-button").classList.contains("expanded"),
    187        "The arrow of the node has the expected class after clicking on it"
    188      );
    189 
    190      const bodyJsonMlNode = node.querySelector(
    191        ".objectBox-jsonml-body-wrapper > .objectBox-jsonml"
    192      );
    193      ok(bodyJsonMlNode, "The body is custom formatted");
    194 
    195      is(bodyJsonMlNode?.textContent, bodyText, "The body text is correct");
    196      is(
    197        bodyJsonMlNode.getAttribute("style"),
    198        bodyStyles,
    199        "The custom formatting of the body is correct"
    200      );
    201    }
    202  } else {
    203    ok(!headerJsonMlNode, "The message is not custom formatted");
    204  }
    205 }