tor-browser

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

browser_net_ws-sse-persist-columns.js (7017B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * Test columns' state for WS and SSE connection.
      8 */
      9 
     10 function shallowArrayEqual(arr1, arr2) {
     11  if (arr1.length !== arr2.length) {
     12    return false;
     13  }
     14  for (let i = 0; i < arr1.length; i++) {
     15    if (
     16      (arr2[i] instanceof RegExp && !arr2[i].test(arr1[i])) ||
     17      (typeof arr2[i] === "string" && arr2[i] !== arr1[i])
     18    ) {
     19      return false;
     20    }
     21  }
     22  return true;
     23 }
     24 
     25 function shallowObjectEqual(obj1, obj2) {
     26  const k1 = Object.keys(obj1);
     27  const k2 = Object.keys(obj2);
     28 
     29  if (k1.length !== k2.length) {
     30    return false;
     31  }
     32 
     33  for (const key of k1) {
     34    if (obj1[key] !== obj2[key]) {
     35      return false;
     36    }
     37  }
     38 
     39  return true;
     40 }
     41 
     42 function shallowEqual(obj1, obj2) {
     43  if (Array.isArray(obj1) && Array.isArray(obj2)) {
     44    return shallowArrayEqual(obj1, obj2);
     45  }
     46  return shallowObjectEqual(obj1, obj2);
     47 }
     48 
     49 add_task(async function () {
     50  const { tab, monitor } = await initNetMonitor(
     51    "http://mochi.test:8888/browser/devtools/client/netmonitor/test/websockets/html_ws-sse-test-page.html",
     52    {
     53      requestCount: 1,
     54    }
     55  );
     56  info("Starting test... ");
     57 
     58  const { document, store, windowRequire } = monitor.panelWin;
     59  const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
     60 
     61  store.dispatch(Actions.batchEnable(false));
     62 
     63  const onNetworkEvents = waitForNetworkEvents(monitor, 2);
     64  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
     65    await content.wrappedJSObject.openWsConnection(1);
     66    // Running openSseConnection() here causes intermittent behavior.
     67  });
     68  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
     69    await content.wrappedJSObject.openSseConnection();
     70  });
     71  await onNetworkEvents;
     72 
     73  const requests = document.querySelectorAll(".request-list-item");
     74  is(requests.length, 2, "There should be two requests");
     75 
     76  // Select the WS request.
     77  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[0]);
     78 
     79  store.dispatch(Actions.toggleMessageColumn("size"));
     80  store.dispatch(Actions.toggleMessageColumn("opCode"));
     81  store.dispatch(Actions.toggleMessageColumn("maskBit"));
     82  store.dispatch(Actions.toggleMessageColumn("finBit"));
     83  clickOnSidebarTab(document, "response");
     84 
     85  // Get all messages present in the "Response" panel
     86  let frames = await waitFor(() => {
     87    const nodeList = document.querySelectorAll(
     88      "#messages-view .message-list-table .message-list-item"
     89    );
     90    return nodeList.length === 2 ? nodeList : null;
     91  });
     92 
     93  // Check expected results
     94 
     95  is(frames.length, 2, "There should be two frames");
     96 
     97  let columnHeaders = Array.prototype.map.call(
     98    document.querySelectorAll(
     99      "#messages-view .message-list-headers .button-text"
    100    ),
    101    node => node.textContent
    102  );
    103 
    104  is(
    105    shallowEqual(columnHeaders, [
    106      "Data",
    107      "Size",
    108      "OpCode",
    109      "MaskBit",
    110      "FinBit",
    111      "Time",
    112    ]),
    113    true,
    114    "WS Column headers are in correct order"
    115  );
    116 
    117  // Get column values of first row for WS.
    118  let columnValues = Array.prototype.map.call(frames, frame =>
    119    Array.prototype.map.call(
    120      frame.querySelectorAll(".message-list-column"),
    121      column => column.textContent.trim()
    122    )
    123  )[0];
    124 
    125  is(
    126    shallowEqual(columnValues, [
    127      "Payload 0",
    128      "9 B",
    129      "1",
    130      "true",
    131      "true",
    132      // Time format is "hh:mm:ss.mmm".
    133      /\d+:\d+:\d+\.\d+/,
    134    ]),
    135    true,
    136    "WS Column values are in correct order"
    137  );
    138 
    139  // Select the SSE request.
    140  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[1]);
    141 
    142  store.dispatch(Actions.toggleMessageColumn("lastEventId"));
    143  store.dispatch(Actions.toggleMessageColumn("eventName"));
    144  store.dispatch(Actions.toggleMessageColumn("retry"));
    145 
    146  await waitFor(
    147    () =>
    148      document.querySelectorAll(
    149        "#messages-view .message-list-headers .button-text"
    150      ).length === 5
    151  );
    152  frames = document.querySelectorAll(
    153    "#messages-view .message-list-table .message-list-item"
    154  );
    155 
    156  columnHeaders = Array.prototype.map.call(
    157    document.querySelectorAll(
    158      "#messages-view .message-list-headers .button-text"
    159    ),
    160    node => node.textContent
    161  );
    162 
    163  is(
    164    shallowEqual(columnHeaders, [
    165      "Data",
    166      "Time",
    167      "Event Name",
    168      "Last Event ID",
    169      "Retry",
    170    ]),
    171    true,
    172    "SSE Column headers are in correct order"
    173  );
    174 
    175  // Get column values of first row for SSE.
    176  columnValues = Array.prototype.map.call(frames, frame =>
    177    Array.prototype.map.call(
    178      frame.querySelectorAll(".message-list-column"),
    179      column => column.textContent.trim()
    180    )
    181  )[0];
    182 
    183  is(
    184    shallowEqual(columnValues, [
    185      "Why so serious?",
    186      /\d+:\d+:\d+\.\d+/,
    187      "message",
    188      "",
    189      "5000",
    190    ]),
    191    true,
    192    "SSE Column values are in correct order"
    193  );
    194 
    195  // Select the WS request again.
    196  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[0]);
    197  is(
    198    shallowEqual(store.getState().messages.columns, {
    199      data: true,
    200      time: true,
    201      size: true,
    202      opCode: true,
    203      maskBit: true,
    204      finBit: true,
    205    }),
    206    true,
    207    "WS columns should persist after request switch"
    208  );
    209 
    210  // Select the SSE request again.
    211  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[1]);
    212  is(
    213    shallowEqual(store.getState().messages.columns, {
    214      data: true,
    215      time: true,
    216      size: false,
    217      lastEventId: true,
    218      eventName: true,
    219      retry: true,
    220    }),
    221    true,
    222    "SSE columns should persist after request switch"
    223  );
    224 
    225  // Reset SSE columns.
    226  store.dispatch(Actions.resetMessageColumns());
    227 
    228  // Switch to WS request again.
    229  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[0]);
    230  is(
    231    shallowEqual(store.getState().messages.columns, {
    232      data: true,
    233      time: true,
    234      size: true,
    235      opCode: true,
    236      maskBit: true,
    237      finBit: true,
    238    }),
    239    true,
    240    "WS columns should not reset after resetting SSE columns"
    241  );
    242 
    243  // Reset WS columns.
    244  store.dispatch(Actions.resetMessageColumns());
    245 
    246  // Switch to SSE request again.
    247  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[1]);
    248  is(
    249    shallowEqual(store.getState().messages.columns, {
    250      data: true,
    251      time: true,
    252      size: false,
    253      lastEventId: false,
    254      eventName: false,
    255      retry: false,
    256    }),
    257    true,
    258    "SSE columns' reset state should persist after request switch"
    259  );
    260 
    261  // Switch to WS request again.
    262  EventUtils.sendMouseEvent({ type: "mousedown" }, requests[0]);
    263  is(
    264    shallowEqual(store.getState().messages.columns, {
    265      data: true,
    266      time: true,
    267      size: false,
    268      opCode: false,
    269      maskBit: false,
    270      finBit: false,
    271    }),
    272    true,
    273    "WS columns' reset state should persist after request switch"
    274  );
    275 
    276  // Close WS connection.
    277  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
    278    await content.wrappedJSObject.closeWsConnection();
    279  });
    280 
    281  return teardown(monitor);
    282 });