diff --git a/src/components/tooltip/NetworkMarker.tsx b/src/components/tooltip/NetworkMarker.tsx index c7f231c6c3..91c9a4b329 100644 --- a/src/components/tooltip/NetworkMarker.tsx +++ b/src/components/tooltip/NetworkMarker.tsx @@ -338,6 +338,22 @@ export function getNetworkMarkerDetails( ); } + if (payload.secPurpose) { + details.push( + + {payload.secPurpose} + + ); + } + + if (payload.deliveryType) { + details.push( + + {payload.deliveryType} + + ); + } + if (typeof payload.count === 'number') { details.push( diff --git a/src/profile-logic/marker-schema.ts b/src/profile-logic/marker-schema.ts index 59454a280d..5383bdee19 100644 --- a/src/profile-logic/marker-schema.ts +++ b/src/profile-logic/marker-schema.ts @@ -83,6 +83,18 @@ export const markerSchemaFrontEndOnly: MarkerSchema[] = [ label: 'Response Status', hidden: true, }, + { + format: 'string', + key: 'secPurpose', + label: 'Sec-Purpose', + hidden: true, + }, + { + format: 'string', + key: 'deliveryType', + label: 'Delivery Type', + hidden: true, + }, ], }, ]; diff --git a/src/test/components/NetworkChart.test.tsx b/src/test/components/NetworkChart.test.tsx index df129b0c15..ba71ab9d91 100644 --- a/src/test/components/NetworkChart.test.tsx +++ b/src/test/components/NetworkChart.test.tsx @@ -622,6 +622,62 @@ describe('NetworkChartRowBar MIME-type filter', function () { }); }); +describe('Network chart prefetch search', function () { + // The fields are hidden in the schema, so they never render in the chart; + // they exist so a search for "prefetch" narrows to just these requests. + function setup() { + return setupWithPayload([ + ...getNetworkMarkers({ uri: 'https://mozilla.org/plain', id: 1 }), + ...getNetworkMarkers({ + uri: 'https://mozilla.org/speculative', + id: 2, + payload: { secPurpose: 'prefetch' }, + }), + ...getNetworkMarkers({ + uri: 'https://mozilla.org/activated', + id: 3, + payload: { deliveryType: 'navigational-prefetch' }, + }), + ]); + } + + function visibleUrls(container: HTMLElement) { + return Array.from( + container.querySelectorAll('.networkChartRowItemLabel') + ).map((node) => node.textContent); + } + + it('shows every request when not searching', function () { + const { container } = setup(); + expect(visibleUrls(container)).toHaveLength(3); + }); + + it('narrows to prefetches when searching for "prefetch"', function () { + const { container, dispatch } = setup(); + + act(() => { + dispatch(changeNetworkSearchString('prefetch')); + }); + + const urls = visibleUrls(container); + expect(urls).toHaveLength(2); + expect(urls.join(' ')).toContain('/speculative'); + expect(urls.join(' ')).toContain('/activated'); + }); + + it('narrows to the activated navigation alone', function () { + const { container, dispatch } = setup(); + + act(() => { + dispatch(changeNetworkSearchString('navigational-prefetch')); + }); + + const urls = visibleUrls(container); + expect(urls).toHaveLength(1); + expect(urls[0]).toContain('/activated'); + }); +}); + describe('EmptyReasons', () => { it("shows a reason when a profile's network markers have been filtered out", () => { const { dispatch, container } = setupWithPayload([...NETWORK_MARKERS]); diff --git a/src/test/components/TooltipMarker.test.tsx b/src/test/components/TooltipMarker.test.tsx index 938a5bc361..c80c87ae87 100644 --- a/src/test/components/TooltipMarker.test.tsx +++ b/src/test/components/TooltipMarker.test.tsx @@ -686,6 +686,30 @@ describe('TooltipMarker', function () { expect(container.firstChild).toMatchSnapshot(); }); + it('renders the Sec-Purpose of a prefetched request', () => { + setupWithPayload( + getNetworkMarkers({ + uri: 'https://example.org/next-page.html', + payload: { secPurpose: 'prefetch;anonymous-client-ip' }, + }) + ); + + expect(getValueForProperty('Sec-Purpose')).toBe( + 'prefetch;anonymous-client-ip' + ); + }); + + it('renders the delivery type of a navigation served from a prefetch', () => { + setupWithPayload( + getNetworkMarkers({ + uri: 'https://example.org/next-page.html', + payload: { deliveryType: 'navigational-prefetch' }, + }) + ); + + expect(getValueForProperty('Delivery Type')).toBe('navigational-prefetch'); + }); + it('renders the page information for network markers', () => { setupWithPayload( getNetworkMarkers({ diff --git a/src/types/markers.ts b/src/types/markers.ts index e3eb9217b5..f60d98dfdd 100644 --- a/src/types/markers.ts +++ b/src/types/markers.ts @@ -556,6 +556,15 @@ export type NetworkPayload = { // Used to show the HTTP response status code responseStatus?: number; + // The `Sec-Purpose` request header, only present for prefetches. + // It's always absent in Firefox < 155. + secPurpose?: string; + + // Matches PerformanceNavigationTiming's deliveryType. Only present when the + // navigation was served from a prefetch, as "navigational-prefetch". + // It's always absent in Firefox < 155. + deliveryType?: string; + // NOTE: the following comments are valid for the merged markers. For the raw // markers, startTime and endTime have different meanings. Please look // `src/profile-logic/marker-data.js` for more information.