tor-browser

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

browser_net_simple-request-data.js (13383B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * Tests if requests render correct information in the menu UI.
      8 */
      9 
     10 function test() {
     11  // Disable tcp fast open, because it is setting a response header indicator
     12  // (bug 1352274). TCP Fast Open is not present on all platforms therefore the
     13  // number of response headers will vary depending on the platform.
     14  Services.prefs.setBoolPref("network.tcp.tcp_fastopen_enable", false);
     15 
     16  const {
     17    L10N,
     18  } = require("resource://devtools/client/netmonitor/src/utils/l10n.js");
     19 
     20  initNetMonitor(SIMPLE_SJS, { requestCount: 1 }).then(async ({ monitor }) => {
     21    info("Starting test... ");
     22 
     23    const { document, store, windowRequire, connector } = monitor.panelWin;
     24    const { EVENTS, TEST_EVENTS } = windowRequire(
     25      "devtools/client/netmonitor/src/constants"
     26    );
     27    const { getDisplayedRequests, getSelectedRequest, getSortedRequests } =
     28      windowRequire("devtools/client/netmonitor/src/selectors/index");
     29 
     30    const promiseList = [];
     31    promiseList.push(waitForNetworkEvents(monitor, 1));
     32 
     33    function expectEvent(evt, cb) {
     34      promiseList.push(
     35        new Promise((resolve, reject) => {
     36          monitor.panelWin.api.once(evt, _ => {
     37            cb().then(resolve, reject);
     38          });
     39        })
     40      );
     41    }
     42 
     43    expectEvent(TEST_EVENTS.NETWORK_EVENT, async () => {
     44      is(
     45        getSelectedRequest(store.getState()),
     46        undefined,
     47        "There shouldn't be any selected item in the requests menu."
     48      );
     49      is(
     50        store.getState().requests.requests.length,
     51        1,
     52        "The requests menu should not be empty after the first request."
     53      );
     54      is(
     55        !!document.querySelector(".network-details-bar"),
     56        false,
     57        "The network details panel should still be hidden after first request."
     58      );
     59 
     60      const requestItem = getSortedRequests(store.getState())[0];
     61 
     62      is(
     63        typeof requestItem.id,
     64        "string",
     65        "The attached request id is incorrect."
     66      );
     67      isnot(requestItem.id, "", "The attached request id should not be empty.");
     68 
     69      is(
     70        typeof requestItem.startedMs,
     71        "number",
     72        "The attached startedMs is incorrect."
     73      );
     74      isnot(
     75        requestItem.startedMs,
     76        0,
     77        "The attached startedMs should not be zero."
     78      );
     79 
     80      /*
     81         * Bug 1666495: this is not possible to assert not yet set attributes
     82         * because of throttling, which only updates the frontend after a few attributes
     83         * are already retrieved via onResourceUpdates events.
     84         * This test should be tweaked with slow responding requests in order to assert
     85         * such behavior without disabling throttling.
     86 
     87        is(
     88          requestItem.requestHeaders,
     89          undefined,
     90          "The requestHeaders should not yet be set."
     91        );
     92        is(
     93          requestItem.requestCookies,
     94          undefined,
     95          "The requestCookies should not yet be set."
     96        );
     97        is(
     98          requestItem.requestPostData,
     99          undefined,
    100          "The requestPostData should not yet be set."
    101        );
    102 
    103        is(
    104          requestItem.responseHeaders,
    105          undefined,
    106          "The responseHeaders should not yet be set."
    107        );
    108        is(
    109          requestItem.responseCookies,
    110          undefined,
    111          "The responseCookies should not yet be set."
    112        );
    113 
    114        is(
    115          requestItem.httpVersion,
    116          undefined,
    117          "The httpVersion should not yet be set."
    118        );
    119        is(requestItem.status, undefined, "The status should not yet be set.");
    120        is(
    121          requestItem.statusText,
    122          undefined,
    123          "The statusText should not yet be set."
    124        );
    125 
    126        is(
    127          requestItem.headersSize,
    128          undefined,
    129          "The headersSize should not yet be set."
    130        );
    131        is(
    132          requestItem.transferredSize,
    133          undefined,
    134          "The transferredSize should not yet be set."
    135        );
    136        is(
    137          requestItem.contentSize,
    138          undefined,
    139          "The contentSize should not yet be set."
    140        );
    141 
    142        is(
    143          requestItem.responseContent,
    144          undefined,
    145          "The responseContent should not yet be set."
    146        );
    147 
    148        is(
    149          requestItem.totalTime,
    150          undefined,
    151          "The totalTime should not yet be set."
    152        );
    153        is(
    154          requestItem.eventTimings,
    155          undefined,
    156          "The eventTimings should not yet be set."
    157        );
    158        */
    159 
    160      await verifyRequestItemTarget(
    161        document,
    162        getDisplayedRequests(store.getState()),
    163        requestItem,
    164        "GET",
    165        SIMPLE_SJS
    166      );
    167    });
    168 
    169    expectEvent(TEST_EVENTS.RECEIVED_REQUEST_HEADERS, async () => {
    170      await waitForRequestData(store, ["requestHeaders"]);
    171 
    172      const requestItem = getSortedRequests(store.getState())[0];
    173 
    174      ok(
    175        requestItem.requestHeaders,
    176        "There should be a requestHeaders data available."
    177      );
    178      is(
    179        requestItem.requestHeaders.headers.length,
    180        10,
    181        "The requestHeaders data has an incorrect |headers| property."
    182      );
    183      isnot(
    184        requestItem.requestHeaders.headersSize,
    185        0,
    186        "The requestHeaders data has an incorrect |headersSize| property."
    187      );
    188      // Can't test for the exact request headers size because the value may
    189      // vary across platforms ("User-Agent" header differs).
    190 
    191      await verifyRequestItemTarget(
    192        document,
    193        getDisplayedRequests(store.getState()),
    194        requestItem,
    195        "GET",
    196        SIMPLE_SJS
    197      );
    198    });
    199 
    200    expectEvent(TEST_EVENTS.RECEIVED_REQUEST_COOKIES, async () => {
    201      await waitForRequestData(store, ["requestCookies"]);
    202 
    203      const requestItem = getSortedRequests(store.getState())[0];
    204 
    205      ok(
    206        requestItem.requestCookies,
    207        "There should be a requestCookies data available."
    208      );
    209      is(
    210        requestItem.requestCookies.length,
    211        2,
    212        "The requestCookies data has an incorrect |cookies| property."
    213      );
    214 
    215      await verifyRequestItemTarget(
    216        document,
    217        getDisplayedRequests(store.getState()),
    218        requestItem,
    219        "GET",
    220        SIMPLE_SJS
    221      );
    222    });
    223 
    224    monitor.panelWin.api.once(TEST_EVENTS.RECEIVED_REQUEST_POST_DATA, () => {
    225      ok(false, "Trap listener: this request doesn't have any post data.");
    226    });
    227 
    228    expectEvent(TEST_EVENTS.RECEIVED_RESPONSE_HEADERS, async () => {
    229      await waitForRequestData(store, ["responseHeaders"]);
    230 
    231      const requestItem = getSortedRequests(store.getState())[0];
    232 
    233      ok(
    234        requestItem.responseHeaders,
    235        "There should be a responseHeaders data available."
    236      );
    237      is(
    238        requestItem.responseHeaders.headers.length,
    239        13,
    240        "The responseHeaders data has an incorrect |headers| property."
    241      );
    242      is(
    243        requestItem.responseHeaders.headersSize,
    244        335,
    245        "The responseHeaders data has an incorrect |headersSize| property."
    246      );
    247 
    248      await verifyRequestItemTarget(
    249        document,
    250        getDisplayedRequests(store.getState()),
    251        requestItem,
    252        "GET",
    253        SIMPLE_SJS
    254      );
    255    });
    256 
    257    expectEvent(TEST_EVENTS.RECEIVED_RESPONSE_COOKIES, async () => {
    258      await waitForRequestData(store, ["responseCookies"]);
    259 
    260      const requestItem = getSortedRequests(store.getState())[0];
    261 
    262      ok(
    263        requestItem.responseCookies,
    264        "There should be a responseCookies data available."
    265      );
    266      is(
    267        requestItem.responseCookies.length,
    268        2,
    269        "The responseCookies data has an incorrect |cookies| property."
    270      );
    271 
    272      await verifyRequestItemTarget(
    273        document,
    274        getDisplayedRequests(store.getState()),
    275        requestItem,
    276        "GET",
    277        SIMPLE_SJS
    278      );
    279    });
    280 
    281    expectEvent(TEST_EVENTS.STARTED_RECEIVING_RESPONSE, async () => {
    282      await waitForRequestData(store, [
    283        "httpVersion",
    284        "status",
    285        "statusText",
    286        "headersSize",
    287      ]);
    288 
    289      const requestItem = getSortedRequests(store.getState())[0];
    290 
    291      is(
    292        requestItem.httpVersion,
    293        "HTTP/1.1",
    294        "The httpVersion data has an incorrect value."
    295      );
    296      is(requestItem.status, "200", "The status data has an incorrect value.");
    297      is(
    298        requestItem.statusText,
    299        "Och Aye",
    300        "The statusText data has an incorrect value."
    301      );
    302      is(
    303        requestItem.headersSize,
    304        335,
    305        "The headersSize data has an incorrect value."
    306      );
    307 
    308      const requestListItem = document.querySelector(".request-list-item");
    309      requestListItem.scrollIntoView();
    310      const requestsListStatus = requestListItem.querySelector(".status-code");
    311      EventUtils.sendMouseEvent({ type: "mouseover" }, requestsListStatus);
    312      await waitUntil(() => requestsListStatus.title);
    313      await waitForDOMIfNeeded(requestListItem, ".requests-list-timings-total");
    314 
    315      await verifyRequestItemTarget(
    316        document,
    317        getDisplayedRequests(store.getState()),
    318        requestItem,
    319        "GET",
    320        SIMPLE_SJS,
    321        {
    322          status: "200",
    323          statusText: "Och Aye",
    324        }
    325      );
    326    });
    327 
    328    expectEvent(EVENTS.PAYLOAD_READY, async () => {
    329      await waitForRequestData(store, [
    330        "transferredSize",
    331        "contentSize",
    332        "mimeType",
    333      ]);
    334 
    335      const requestItem = getSortedRequests(store.getState())[0];
    336 
    337      is(
    338        requestItem.transferredSize,
    339        347,
    340        "The transferredSize data has an incorrect value."
    341      );
    342      is(
    343        requestItem.contentSize,
    344        12,
    345        "The contentSize data has an incorrect value."
    346      );
    347      is(
    348        requestItem.mimeType,
    349        "text/plain; charset=utf-8",
    350        "The mimeType data has an incorrect value."
    351      );
    352 
    353      await verifyRequestItemTarget(
    354        document,
    355        getDisplayedRequests(store.getState()),
    356        requestItem,
    357        "GET",
    358        SIMPLE_SJS,
    359        {
    360          type: "plain",
    361          fullMimeType: "text/plain; charset=utf-8",
    362          transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 347),
    363          size: L10N.getFormatStrWithNumbers("networkMenu.sizeB", 12),
    364        }
    365      );
    366    });
    367 
    368    expectEvent(EVENTS.UPDATING_EVENT_TIMINGS, async () => {
    369      await waitForRequestData(store, ["eventTimings"]);
    370 
    371      const requestItem = getSortedRequests(store.getState())[0];
    372 
    373      is(
    374        typeof requestItem.totalTime,
    375        "number",
    376        "The attached totalTime is incorrect."
    377      );
    378      Assert.greaterOrEqual(
    379        requestItem.totalTime,
    380        0,
    381        "The attached totalTime should be positive."
    382      );
    383 
    384      await verifyRequestItemTarget(
    385        document,
    386        getDisplayedRequests(store.getState()),
    387        requestItem,
    388        "GET",
    389        SIMPLE_SJS,
    390        {
    391          time: true,
    392        }
    393      );
    394    });
    395 
    396    expectEvent(EVENTS.RECEIVED_EVENT_TIMINGS, async () => {
    397      await waitForRequestData(store, ["eventTimings"]);
    398 
    399      const requestItem = getSortedRequests(store.getState())[0];
    400 
    401      ok(
    402        requestItem.eventTimings,
    403        "There should be a eventTimings data available."
    404      );
    405      is(
    406        typeof requestItem.eventTimings.timings.blocked,
    407        "number",
    408        "The eventTimings data has an incorrect |timings.blocked| property."
    409      );
    410      is(
    411        typeof requestItem.eventTimings.timings.dns,
    412        "number",
    413        "The eventTimings data has an incorrect |timings.dns| property."
    414      );
    415      is(
    416        typeof requestItem.eventTimings.timings.ssl,
    417        "number",
    418        "The eventTimings data has an incorrect |timings.ssl| property."
    419      );
    420      is(
    421        typeof requestItem.eventTimings.timings.connect,
    422        "number",
    423        "The eventTimings data has an incorrect |timings.connect| property."
    424      );
    425      is(
    426        typeof requestItem.eventTimings.timings.send,
    427        "number",
    428        "The eventTimings data has an incorrect |timings.send| property."
    429      );
    430      is(
    431        typeof requestItem.eventTimings.timings.wait,
    432        "number",
    433        "The eventTimings data has an incorrect |timings.wait| property."
    434      );
    435      is(
    436        typeof requestItem.eventTimings.timings.receive,
    437        "number",
    438        "The eventTimings data has an incorrect |timings.receive| property."
    439      );
    440      is(
    441        typeof requestItem.eventTimings.totalTime,
    442        "number",
    443        "The eventTimings data has an incorrect |totalTime| property."
    444      );
    445 
    446      await verifyRequestItemTarget(
    447        document,
    448        getDisplayedRequests(store.getState()),
    449        requestItem,
    450        "GET",
    451        SIMPLE_SJS,
    452        {
    453          time: true,
    454        }
    455      );
    456    });
    457 
    458    const wait = waitForNetworkEvents(monitor, 1);
    459    await reloadBrowser();
    460    await wait;
    461 
    462    const requestItem = getSortedRequests(store.getState())[0];
    463 
    464    if (!requestItem.requestHeaders) {
    465      connector.requestData(requestItem.id, "requestHeaders");
    466    }
    467    if (!requestItem.responseHeaders) {
    468      connector.requestData(requestItem.id, "responseHeaders");
    469    }
    470 
    471    await Promise.all(promiseList);
    472    await teardown(monitor);
    473    finish();
    474  });
    475 }