Bug 1470815 - Make sure the Security panel is visible for HTTP requests in the Console panel; r=nchevobbe
authorJan Odvarko <odvarko@gmail.com>
Wed, 22 Aug 2018 11:14:45 +0000
changeset 487884 b39ce58378e1b7b08f8b45538d8146a2863d575f
parent 487883 ed26ed848a8e61972094c37d9eabb781f0f3d03f
child 487885 02647608ed585de04dd8d78fcfc1263675c7d958
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe
bugs1470815
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1470815 - Make sure the Security panel is visible for HTTP requests in the Console panel; r=nchevobbe Differential Revision: https://phabricator.services.mozilla.com/D3904
devtools/client/netmonitor/src/connector/firefox-data-provider.js
devtools/client/netmonitor/src/reducers/requests.js
devtools/client/netmonitor/src/utils/request-utils.js
devtools/client/webconsole/reducers/messages.js
devtools/client/webconsole/test/fixtures/stubs/networkEvent.js
devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_expand.js
devtools/client/webconsole/utils/messages.js
devtools/shared/webconsole/client.js
--- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js
+++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js
@@ -346,17 +346,17 @@ class FirefoxDataProvider {
    */
   onNetworkEventUpdate(data) {
     const { packet, networkInfo } = data;
     const { actor } = networkInfo;
     const { updateType } = packet;
 
     switch (updateType) {
       case "securityInfo":
-        this.pushRequestToQueue(actor, { securityState: networkInfo.securityInfo });
+        this.pushRequestToQueue(actor, { securityState: networkInfo.securityState });
         break;
       case "responseStart":
         this.pushRequestToQueue(actor, {
           httpVersion: networkInfo.response.httpVersion,
           remoteAddress: networkInfo.response.remoteAddress,
           remotePort: networkInfo.response.remotePort,
           status: networkInfo.response.status,
           statusText: networkInfo.response.statusText,
--- a/devtools/client/netmonitor/src/reducers/requests.js
+++ b/devtools/client/netmonitor/src/reducers/requests.js
@@ -82,17 +82,17 @@ function requestsReducer(state = Request
 
       let request = requests.get(action.id);
       if (!request) {
         return state;
       }
 
       request = {
         ...request,
-        ...processNetworkUpdates(action.data),
+        ...processNetworkUpdates(action.data, request),
       };
       const requestEndTime = request.startedMillis +
         (request.eventTimings ? request.eventTimings.totalTime : 0);
 
       return {
         ...state,
         requests: mapSet(state.requests, action.id, request),
         lastEndedMillis: requestEndTime > lastEndedMillis ?
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -486,28 +486,31 @@ async function updateFormDataSections(pr
   }
 }
 
 /**
  * This helper function is used for additional processing of
  * incoming network update packets. It's used by Network and
  * Console panel reducers.
  */
-function processNetworkUpdates(request = {}) {
+function processNetworkUpdates(update, request) {
   const result = {};
-  for (const [key, value] of Object.entries(request)) {
+  for (const [key, value] of Object.entries(update)) {
     if (UPDATE_PROPS.includes(key)) {
       result[key] = value;
 
       switch (key) {
         case "securityInfo":
           result.securityState = value.state;
           break;
+        case "securityState":
+          result.securityState = update.securityState || request.securityState;
+          break;
         case "totalTime":
-          result.totalTime = request.totalTime;
+          result.totalTime = update.totalTime;
           break;
         case "requestPostData":
           result.requestHeadersFromUploadStream = value.uploadHeaders;
           break;
       }
     }
   }
   return result;
--- a/devtools/client/webconsole/reducers/messages.js
+++ b/devtools/client/webconsole/reducers/messages.js
@@ -309,17 +309,17 @@ function messages(state = MessageState()
       }
 
       return {
         ...state,
         networkMessagesUpdateById: {
           ...networkMessagesUpdateById,
           [action.id]: {
             ...request,
-            ...processNetworkUpdates(action.data),
+            ...processNetworkUpdates(action.data, request),
           }
         }
       };
     }
 
     case constants.REMOVED_ACTORS_CLEAR:
       return {
         ...state,
--- a/devtools/client/webconsole/test/fixtures/stubs/networkEvent.js
+++ b/devtools/client/webconsole/test/fixtures/stubs/networkEvent.js
@@ -25,17 +25,16 @@ stubPreparedMessages.set("GET request", 
   "response": {},
   "source": "network",
   "type": "log",
   "groupId": null,
   "timeStamp": 1487022056850,
   "indent": 0,
   "updates": [],
   "openedOnce": false,
-  "securityState": null,
   "securityInfo": null,
   "requestHeadersFromUploadStream": null,
   "private": false,
   "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
   "urlDetails": {
     "baseNameWithQuery": "inexistent.html",
     "host": "example.com",
     "scheme": "http",
@@ -73,17 +72,16 @@ stubPreparedMessages.set("GET request up
     "transferredSize": 904
   },
   "source": "network",
   "type": "log",
   "groupId": null,
   "totalTime": 16,
   "indent": 0,
   "openedOnce": false,
-  "securityState": null,
   "securityInfo": null,
   "requestHeadersFromUploadStream": null,
   "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
   "urlDetails": {
     "baseNameWithQuery": "inexistent.html",
     "host": "example.com",
     "scheme": "http",
     "unicodeUrl": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
@@ -104,17 +102,16 @@ stubPreparedMessages.set("XHR GET reques
   "response": {},
   "source": "network",
   "type": "log",
   "groupId": null,
   "timeStamp": 1487022057746,
   "indent": 0,
   "updates": [],
   "openedOnce": false,
-  "securityState": null,
   "securityInfo": null,
   "requestHeadersFromUploadStream": null,
   "private": false,
   "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
   "urlDetails": {
     "baseNameWithQuery": "inexistent.html",
     "host": "example.com",
     "scheme": "http",
@@ -152,17 +149,16 @@ stubPreparedMessages.set("XHR GET reques
     "transferredSize": 904
   },
   "source": "network",
   "type": "log",
   "groupId": null,
   "totalTime": 16,
   "indent": 0,
   "openedOnce": false,
-  "securityState": null,
   "securityInfo": null,
   "requestHeadersFromUploadStream": null,
   "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
   "urlDetails": {
     "baseNameWithQuery": "inexistent.html",
     "host": "example.com",
     "scheme": "http",
     "unicodeUrl": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
@@ -183,17 +179,16 @@ stubPreparedMessages.set("XHR POST reque
   "response": {},
   "source": "network",
   "type": "log",
   "groupId": null,
   "timeStamp": 1487022058414,
   "indent": 0,
   "updates": [],
   "openedOnce": false,
-  "securityState": null,
   "securityInfo": null,
   "requestHeadersFromUploadStream": null,
   "private": false,
   "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
   "urlDetails": {
     "baseNameWithQuery": "inexistent.html",
     "host": "example.com",
     "scheme": "http",
@@ -231,17 +226,16 @@ stubPreparedMessages.set("XHR POST reque
     "transferredSize": 904
   },
   "source": "network",
   "type": "log",
   "groupId": null,
   "totalTime": 10,
   "indent": 0,
   "openedOnce": false,
-  "securityState": null,
   "securityInfo": null,
   "requestHeadersFromUploadStream": null,
   "url": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
   "urlDetails": {
     "baseNameWithQuery": "inexistent.html",
     "host": "example.com",
     "scheme": "http",
     "unicodeUrl": "http://example.com/browser/devtools/client/webconsole/test/fixtures/stub-generators/inexistent.html",
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_expand.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_expand.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const TEST_FILE = "test-network-request.html";
-const TEST_PATH = "http://example.com/browser/devtools/client/webconsole/" +
+const TEST_PATH = "https://example.com/browser/devtools/client/webconsole/" +
                   "test/mochitest/";
 const TEST_URI = TEST_PATH + TEST_FILE;
 
 const NET_PREF = "devtools.webconsole.filter.net";
 const XHR_PREF = "devtools.webconsole.filter.netxhr";
 
 requestLongerTimeout(2);
 
@@ -39,16 +39,20 @@ const tabs = [{
 }, {
   id: "timings",
   testEmpty: testEmptyTimings,
   testContent: testTimings,
 }, {
   id: "stack-trace",
   testEmpty: testEmptyStackTrace,
   testContent: testStackTrace,
+}, {
+  id: "security",
+  testEmpty: testEmptySecurity,
+  testContent: testSecurity,
 }];
 
 /**
  * Main test for checking HTTP logs in the Console panel.
  */
 add_task(async function task() {
   const hud = await openNewTabAndConsole(TEST_URI);
   const currentTab = gBrowser.selectedTab;
@@ -124,23 +128,28 @@ async function openRequestBeforeUpdates(
   // Set the default panel.
   const state = hud.ui.consoleOutput.getStore().getState();
   state.ui.networkMessageActiveTabId = tab.id;
 
   // Expand network log
   const urlNode = messageNode.querySelector(".url");
   urlNode.click();
 
-  // Make sure the current tab is the expected one.
-  const currentTab = messageNode.querySelector(`#${tab.id}-tab`);
-  is(currentTab.getAttribute("aria-selected"), "true",
-    "The correct tab is selected");
+  // Except the security tab. It isn't available till the
+  // "securityInfo" packet type is received, so doesn't
+  // fit this part of the test.
+  if (tab.id != "security") {
+    // Make sure the current tab is the expected one.
+    const currentTab = messageNode.querySelector(`#${tab.id}-tab`);
+    is(currentTab.getAttribute("aria-selected"), "true",
+      "The correct tab is selected");
 
-  // The tab should be empty now.
-  tab.testEmpty(messageNode);
+    // The tab should be empty now.
+    tab.testEmpty(messageNode);
+  }
 
   // Wait till all updates and payload are received.
   await updates;
   await payload;
 
   // Test content of the default tab.
   await tab.testContent(messageNode);
 
@@ -153,16 +162,17 @@ async function openRequestBeforeUpdates(
 async function testNetworkMessage(toolbox, messageNode) {
   await testStatusInfo(messageNode);
   await testHeaders(messageNode);
   await testCookies(messageNode);
   await testParams(messageNode);
   await testResponse(messageNode);
   await testTimings(messageNode);
   await testStackTrace(messageNode);
+  await testSecurity(messageNode);
   await waitForLazyRequests(toolbox);
 }
 
 // Status Info
 
 function testStatusInfo(messageNode) {
   const statusInfo = messageNode.querySelector(".status-info");
   ok(statusInfo, "Status info is not empty");
@@ -284,16 +294,34 @@ async function testStackTrace(messageNod
 
   // Select Timings tab and check the content.
   stackTraceTab.click();
   await waitUntil(() => {
     return !!messageNode.querySelector("#stack-trace-panel .frame-link");
   });
 }
 
+// Security
+
+function testEmptySecurity(messageNode) {
+  const panel = messageNode.querySelector("#security-panel .tab-panel");
+  is(panel.textContent, "", "Security tab is empty");
+}
+
+async function testSecurity(messageNode) {
+  const securityTab = messageNode.querySelector("#security-tab");
+  ok(securityTab, "Security tab is available");
+
+  // Select Timings tab and check the content.
+  securityTab.click();
+  await waitUntil(() => {
+    return !!messageNode.querySelector("#security-panel .treeTable .treeRow");
+  });
+}
+
 // Waiting helpers
 
 async function waitForPayloadReady(toolbox) {
   const {ui} = toolbox.getCurrentPanel().hud;
   return new Promise(resolve => {
     ui.jsterm.hud.on("network-request-payload-ready", () => {
       info("network-request-payload-ready received");
       resolve();
@@ -313,17 +341,17 @@ async function waitForRequestUpdates(too
     ui.jsterm.hud.on("network-message-updated", () => {
       info("network-message-updated received");
       resolve();
     });
   });
 }
 
 /**
- * Wait until all lazily fetch requests in netmonitor get finsished.
+ * Wait until all lazily fetch requests in netmonitor get finished.
  * Otherwise test will be shutdown too early and cause failure.
  */
 async function waitForLazyRequests(toolbox) {
   const {ui} = toolbox.getCurrentPanel().hud;
   const proxy = ui.jsterm.hud.proxy;
   return waitUntil(() => {
     return !proxy.networkDataProvider.lazyRequestData.size;
   });
--- a/devtools/client/webconsole/utils/messages.js
+++ b/devtools/client/webconsole/utils/messages.js
@@ -265,16 +265,17 @@ function transformNetworkEventPacket(pac
     timeStamp: networkEvent.timeStamp,
     totalTime: networkEvent.totalTime,
     url: networkEvent.request.url,
     urlDetails: getUrlDetails(networkEvent.request.url),
     method: networkEvent.request.method,
     updates: networkEvent.updates,
     cause: networkEvent.cause,
     private: networkEvent.private,
+    securityState: networkEvent.securityState,
   });
 }
 
 function transformEvaluationResultPacket(packet) {
   let {
     exceptionMessage,
     exceptionDocURL,
     exception,
--- a/devtools/shared/webconsole/client.js
+++ b/devtools/shared/webconsole/client.js
@@ -160,17 +160,17 @@ WebConsoleClient.prototype = {
         networkInfo.response.bodySize = packet.contentSize;
         networkInfo.response.transferredSize = packet.transferredSize;
         networkInfo.discardResponseBody = packet.discardResponseBody;
         break;
       case "eventTimings":
         networkInfo.totalTime = packet.totalTime;
         break;
       case "securityInfo":
-        networkInfo.securityInfo = packet.state;
+        networkInfo.securityState = packet.state;
         break;
       case "responseCache":
         networkInfo.response.responseCache = packet.responseCache;
         break;
     }
 
     this.emit("networkEventUpdate", {
       packet: packet,