Bug 1702511 - [devtools] Expose isNavigationRequest on NETWORK_EVENT to highlight request done for top level document navigation. r=jdescottes,nchevobbe,bomsy
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 31 May 2021 20:29:56 +0000
changeset 649882 1a4738901acfca157f47b44faaa55ba9a06e9222
parent 649881 3e18373a945ff09b23c4b71d26c5aa0d60195d1f
child 649883 f7988048b5d7b7827c715ab63eab888f25c882b9
push id15597
push userffxbld-merge
push dateMon, 12 Jul 2021 12:28:04 +0000
treeherdermozilla-beta@9c0e51e068b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes, nchevobbe, bomsy
bugs1702511
milestone91.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 1702511 - [devtools] Expose isNavigationRequest on NETWORK_EVENT to highlight request done for top level document navigation. r=jdescottes,nchevobbe,bomsy Differential Revision: https://phabricator.services.mozilla.com/D112921
devtools/server/actors/network-monitor/network-event-actor.js
devtools/server/actors/network-monitor/utils/network-utils.js
devtools/shared/commands/resource/tests/browser_resources_network_events.js
--- a/devtools/server/actors/network-monitor/network-event-actor.js
+++ b/devtools/server/actors/network-monitor/network-event-actor.js
@@ -85,16 +85,17 @@ const NetworkEventActor = protocol.Actor
     this._channelId = networkEvent.channelId;
     this._browsingContextID = networkEvent.browsingContextID;
     this._serial = networkEvent.serial;
     this._blockedReason = networkEvent.blockedReason;
     this._blockingExtension = networkEvent.blockingExtension;
 
     this._truncated = false;
     this._private = networkEvent.private;
+    this._isNavigationRequest = networkEvent.isNavigationRequest;
   },
 
   /**
    * Returns a grip for this actor.
    */
   asResource() {
     // The browsingContextID is used by the ResourceCommand on the client
     // to find the related Target Front.
@@ -126,16 +127,17 @@ const NetworkEventActor = protocol.Actor
       private: this._private,
       isThirdPartyTrackingResource: this._isThirdPartyTrackingResource,
       referrerPolicy: this._referrerPolicy,
       blockedReason: this._blockedReason,
       blockingExtension: this._blockingExtension,
       // For websocket requests the serial is used instead of the channel id.
       stacktraceResourceId:
         this._cause.type == "websocket" ? this._serial : this._channelId,
+      isNavigationRequest: this._isNavigationRequest,
     };
   },
 
   /**
    * Releases this actor from the pool.
    */
   destroy(conn) {
     if (!this._networkEventWatcher) {
--- a/devtools/server/actors/network-monitor/utils/network-utils.js
+++ b/devtools/server/actors/network-monitor/utils/network-utils.js
@@ -776,16 +776,22 @@ exports.createNetworkEvent = function(
     }
   } else {
     event.blockedReason = blockedReason;
     if (blockingExtension) {
       event.blockingExtension = blockingExtension;
     }
   }
 
+  // isNavigationRequest is true for the one request used to load a new top level document
+  // of a given tab, or top level window. It will typically be false for navigation requests
+  // of iframes, i.e. the request loading another document in an iframe.
+  event.isNavigationRequest =
+    channel.isMainDocumentChannel && channel.loadInfo.isTopLevelLoad;
+
   return event;
 };
 
 /**
  * For a given channel, with its associated http activity object,
  * fetch the request's headers and cookies.
  * This data is passed to the owner, i.e. the NetworkEventActor,
  * so that the frontend can later fetch it via getRequestHeaders/getRequestCookies.
--- a/devtools/shared/commands/resource/tests/browser_resources_network_events.js
+++ b/devtools/shared/commands/resource/tests/browser_resources_network_events.js
@@ -25,20 +25,22 @@ async function testNetworkEventResources
     // 1 available event fired, when live request is created.
     totalExpectedOnAvailableCounts: 2,
     // 1 update events fired, when live request is updated.
     totalExpectedOnUpdatedCounts: 1,
     expectedResourcesOnAvailable: {
       [`${EXAMPLE_DOMAIN}cached_post.html`]: {
         resourceType: ResourceCommand.TYPES.NETWORK_EVENT,
         method: "POST",
+        isNavigationRequest: false,
       },
       [`${EXAMPLE_DOMAIN}live_get.html`]: {
         resourceType: ResourceCommand.TYPES.NETWORK_EVENT,
         method: "GET",
+        isNavigationRequest: false,
       },
     },
     expectedResourcesOnUpdated: {
       [`${EXAMPLE_DOMAIN}live_get.html`]: {
         resourceType: ResourceCommand.TYPES.NETWORK_EVENT,
         method: "GET",
       },
     },
@@ -52,16 +54,17 @@ async function testNetworkEventResources
     // 1 available event fired, when live request is created.
     totalExpectedOnAvailableCounts: 1,
     // 1 update events fired, when live request is updated.
     totalExpectedOnUpdatedCounts: 1,
     expectedResourcesOnAvailable: {
       [`${EXAMPLE_DOMAIN}live_get.html`]: {
         resourceType: ResourceCommand.TYPES.NETWORK_EVENT,
         method: "GET",
+        isNavigationRequest: false,
       },
     },
     expectedResourcesOnUpdated: {
       [`${EXAMPLE_DOMAIN}live_get.html`]: {
         resourceType: ResourceCommand.TYPES.NETWORK_EVENT,
         method: "GET",
       },
     },
@@ -140,37 +143,29 @@ async function testNetworkEventResources
 
   const onAvailable = resources => {
     for (const resource of resources) {
       is(
         resource.resourceType,
         resourceCommand.TYPES.NETWORK_EVENT,
         "Received a network event resource"
       );
-      actualResourcesOnAvailable[resource.url] = {
-        resourceId: resource.resourceId,
-        resourceType: resource.resourceType,
-        method: resource.method,
-      };
+      actualResourcesOnAvailable[resource.url] = resource;
       totalExpectedOnAvailableCounts--;
     }
   };
 
   const onUpdated = updates => {
     for (const { resource } of updates) {
       is(
         resource.resourceType,
         resourceCommand.TYPES.NETWORK_EVENT,
         "Received a network update event resource"
       );
-      actualResourcesOnUpdated[resource.url] = {
-        resourceId: resource.resourceId,
-        resourceType: resource.resourceType,
-        method: resource.method,
-      };
+      actualResourcesOnUpdated[resource.url] = resource;
       totalExpectedOnUpdatedCounts--;
     }
   };
 
   await resourceCommand.watchResources([resourceCommand.TYPES.NETWORK_EVENT], {
     onAvailable,
     onUpdated,
     ignoreExistingResources,
@@ -300,16 +295,31 @@ async function testNetworkEventResources
     "Got three network events fired on available"
   );
   is(
     allResourcesOnUpdate.length,
     3,
     "Got three network events fired on update"
   );
 
+  // Find the page's request
+  const availablePageResource = allResourcesOnAvailable.find(
+    resource => resource.url === CSP_URL
+  );
+  is(
+    availablePageResource.resourceType,
+    resourceCommand.TYPES.NETWORK_EVENT,
+    "This is a network event resource"
+  );
+  is(
+    availablePageResource.isNavigationRequest,
+    true,
+    "The page request is correctly flaged as a navigation request"
+  );
+
   // Find the Blocked CSP JS resource
   const availableJSResource = allResourcesOnAvailable.find(
     resource => resource.url === JS_CSP_URL
   );
   const updateJSResource = allResourcesOnUpdate.find(
     update => update.url === JS_CSP_URL
   );
 
@@ -383,12 +393,19 @@ async function testNetworkEventResources
 
 function assertResources(actual, expected) {
   is(
     actual.resourceType,
     expected.resourceType,
     "The resource type is correct"
   );
   is(actual.method, expected.method, "The method is correct");
+  if ("isNavigationRequest" in expected) {
+    is(
+      actual.isNavigationRequest,
+      expected.isNavigationRequest,
+      "The isNavigationRequest attribute is correct"
+    );
+  }
 }
 
 const cachedRequest = `await fetch("/cached_post.html", { method: "POST" });`;
 const liveRequest = `await fetch("/live_get.html", { method: "GET" });`;