Bug 1447679 - Raw headers are displayed in alphabetical order. r=jryans, a=jcristau
authorJan Odvarko <odvarko@gmail.com>
Thu, 22 Mar 2018 14:32:10 +0100
changeset 462849 79c7a5ef721f97f3bd08eca89d26ed81562e51fd
parent 462848 7f9921c6775a809ec655107e44eaa7299c5f19d1
child 462850 49448fdb2c96b17a290395110f3492870ccfebd5
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans, jcristau
bugs1447679
milestone60.0
Bug 1447679 - Raw headers are displayed in alphabetical order. r=jryans, a=jcristau MozReview-Commit-ID: PGbaLmTdI1
devtools/client/netmonitor/src/components/HeadersPanel.js
devtools/client/netmonitor/src/utils/headers-provider.js
devtools/client/netmonitor/test/browser_net_headers_sorted.js
--- a/devtools/client/netmonitor/src/components/HeadersPanel.js
+++ b/devtools/client/netmonitor/src/components/HeadersPanel.js
@@ -215,17 +215,17 @@ class HeadersPanel extends Component {
       } else if (fromServiceWorker) {
         code = "service worker";
       } else {
         code = status;
       }
 
       let statusCodeDocURL = getHTTPStatusCodeURL(status.toString());
       let inputWidth = status.toString().length + statusText.length + 1;
-      let toggleRawHeadersClassList = ["devtools-button"];
+      let toggleRawHeadersClassList = ["devtools-button", "raw-headers-button"];
       if (this.state.rawHeadersOpened) {
         toggleRawHeadersClassList.push("checked");
       }
 
       summaryStatus = (
         div({ className: "tabpanel-summary-container headers-summary" },
           div({
             className: "tabpanel-summary-label headers-summary-label",
@@ -267,23 +267,25 @@ class HeadersPanel extends Component {
     let summaryRawHeaders;
     if (this.state.rawHeadersOpened) {
       summaryRawHeaders = (
         div({ className: "tabpanel-summary-container headers-summary" },
           div({ className: "raw-headers-container" },
             div({ className: "raw-headers" },
               div({ className: "tabpanel-summary-label" }, RAW_HEADERS_REQUEST),
               textarea({
+                className: "raw-request-headers-textarea",
                 value: writeHeaderText(requestHeaders.headers),
                 readOnly: true,
               }),
             ),
             div({ className: "raw-headers" },
               div({ className: "tabpanel-summary-label" }, RAW_HEADERS_RESPONSE),
               textarea({
+                className: "raw-response-headers-textarea",
                 value: statusLine + writeHeaderText(responseHeaders.headers),
                 readOnly: true,
               }),
             ),
           )
         )
       );
     }
--- a/devtools/client/netmonitor/src/utils/headers-provider.js
+++ b/devtools/client/netmonitor/src/utils/headers-provider.js
@@ -63,17 +63,18 @@ var HeadersProvider = {
     return ObjectProvider.getType(object);
   }
 };
 
 /**
  * Helper data structures for list of headers.
  */
 function HeaderList(headers) {
-  this.headers = headers;
+  // Clone, so the sort doesn't affect the original array.
+  this.headers = headers.slice(0);
   this.headers.sort((a, b) => {
     return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
   });
 }
 
 function Header(name, value, key) {
   this.name = name;
   this.value = value;
--- a/devtools/client/netmonitor/test/browser_net_headers_sorted.js
+++ b/devtools/client/netmonitor/test/browser_net_headers_sorted.js
@@ -2,44 +2,58 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 /**
  * Tests if Request-Headers and Response-Headers are sorted in Headers tab.
  * The test also verifies that headers with the same name and headers
  * with an empty value are also displayed.
+ *
+ * The test also checks that raw headers are displayed in the original
+ * order and not sorted.
  */
 add_task(async function () {
   let { tab, monitor } = await initNetMonitor(SIMPLE_SJS);
   info("Starting test... ");
 
-  let { document, store, windowRequire } = monitor.panelWin;
+  let { store, windowRequire } = monitor.panelWin;
   let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
-  let {
-    getSortedRequests,
-  } = windowRequire("devtools/client/netmonitor/src/selectors/index");
-
   store.dispatch(Actions.batchEnable(false));
 
   let wait = waitForNetworkEvents(monitor, 1);
   tab.linkedBrowser.reload();
   await wait;
 
-  wait = waitForDOM(document, ".headers-overview");
+  // Verify request and response headers.
+  await verifyHeaders(monitor);
+  await verifyRawHeaders(monitor);
+
+  // Clean up
+  await teardown(monitor);
+});
+
+async function verifyHeaders(monitor) {
+  let { document, store, windowRequire } = monitor.panelWin;
+  let {
+    getSortedRequests,
+  } = windowRequire("devtools/client/netmonitor/src/selectors/index");
+
+  info("Check if Request-Headers and Response-Headers are sorted");
+
+  let wait = waitForDOM(document, ".headers-overview");
   EventUtils.sendMouseEvent({ type: "mousedown" },
     document.querySelectorAll(".request-list-item")[0]);
   await wait;
 
   await waitUntil(() => {
     let request = getSortedRequests(store.getState()).get(0);
     return request.requestHeaders && request.responseHeaders;
   });
 
-  info("Check if Request-Headers and Response-Headers are sorted");
   let expectedResponseHeaders = ["cache-control", "connection", "content-length",
                                  "content-type", "date", "expires", "foo-bar",
                                  "foo-bar", "foo-bar", "pragma", "server", "set-cookie",
                                  "set-cookie"];
   let expectedRequestHeaders = ["Accept", "Accept-Encoding", "Accept-Language",
                                 "Cache-Control", "Connection", "Cookie", "Host",
                                 "Pragma", "Upgrade-Insecure-Requests", "User-Agent"];
 
@@ -56,11 +70,61 @@ add_task(async function () {
     actualRequestHeaders.push(labelCells[i].innerText);
   }
 
   is(actualResponseHeaders.toString(), expectedResponseHeaders.toString(),
     "Response Headers are sorted");
 
   is(actualRequestHeaders.toString(), expectedRequestHeaders.toString(),
     "Request Headers are sorted");
+}
 
-  await teardown(monitor);
-});
+async function verifyRawHeaders(monitor) {
+  let { document } = monitor.panelWin;
+
+  info("Check if raw Request-Headers and raw Response-Headers are not sorted");
+
+  let actualResponseHeaders = [];
+  let actualRequestHeaders = [];
+
+  let expectedResponseHeaders = ["cache-control", "pragma", "expires",
+                                 "set-cookie", "set-cookie", "content-type", "foo-bar",
+                                 "foo-bar", "foo-bar", "connection", "server",
+                                 "date", "content-length"];
+
+  let expectedRequestHeaders = ["Host", "User-Agent", "Accept", "Accept-Language",
+                                "Accept-Encoding", "Cookie", "Connection",
+                                "Upgrade-Insecure-Requests", "Pragma",
+                                "Cache-Control"];
+
+  // Click the 'Raw headers' button to show original headers source.
+  let rawHeadersBtn = document.querySelector(".raw-headers-button");
+  rawHeadersBtn.click();
+
+  // Wait till raw headers are available.
+  await waitUntil(() => {
+    return document.querySelector(".raw-request-headers-textarea") &&
+      document.querySelector(".raw-response-headers-textarea");
+  });
+
+  let requestHeadersText =
+    document.querySelector(".raw-request-headers-textarea").textContent;
+  let responseHeadersText =
+    document.querySelector(".raw-response-headers-textarea").textContent;
+
+  let rawRequestHeadersArray = requestHeadersText.split("\n");
+  for (let i = 0; i < rawRequestHeadersArray.length; i++) {
+    let header = rawRequestHeadersArray[i];
+    actualRequestHeaders.push(header.split(":")[0]);
+  }
+
+  let rawResponseHeadersArray = responseHeadersText.split("\n");
+  for (let i = 1; i < rawResponseHeadersArray.length; i++) {
+    let header = rawResponseHeadersArray[i];
+    actualResponseHeaders.push(header.split(":")[0]);
+  }
+
+  is(actualResponseHeaders.toString(), expectedResponseHeaders.toString(),
+    "Raw Response Headers are not sorted");
+
+  is(actualRequestHeaders.toString(), expectedRequestHeaders.toString(),
+    "Raw Request Headers are not sorted");
+}