Split RequestHeadersView into multiple components. [2/3]
This stack of CLs extracts multiple separate components from the
`RequestHeadersView`. The existing logic and UI stay almost unchanged.
Part 2/3:
RequestHeaderSection: contains the logic for request headers, renders
multiple HeaderSectionRows
Bug: 1297533
Change-Id: If28c6c309220cc9513e5e7e040744b36bf899e41
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3870838
Commit-Queue: Wolfgang Beyer <[email protected]>
Reviewed-by: Simon Zünd <[email protected]>
diff --git a/config/gni/devtools_grd_files.gni b/config/gni/devtools_grd_files.gni
index 91de418..98bf8ac 100644
--- a/config/gni/devtools_grd_files.gni
+++ b/config/gni/devtools_grd_files.gni
@@ -1140,6 +1140,8 @@
"front_end/panels/network/blockedURLsPane.css.js",
"front_end/panels/network/components/HeaderSectionRow.css.js",
"front_end/panels/network/components/HeaderSectionRow.js",
+ "front_end/panels/network/components/RequestHeaderSection.css.js",
+ "front_end/panels/network/components/RequestHeaderSection.js",
"front_end/panels/network/components/RequestHeadersView.css.js",
"front_end/panels/network/components/RequestHeadersView.js",
"front_end/panels/network/components/RequestTrustTokensView.css.js",
diff --git a/front_end/core/i18n/locales/en-US.json b/front_end/core/i18n/locales/en-US.json
index 1023a50..7e2699e 100644
--- a/front_end/core/i18n/locales/en-US.json
+++ b/front_end/core/i18n/locales/en-US.json
@@ -6869,6 +6869,18 @@
"panels/network/components/HeaderSectionRow.ts | learnMoreInTheIssuesTab": {
"message": "Learn more in the issues tab"
},
+ "panels/network/components/RequestHeaderSection.ts | learnMore": {
+ "message": "Learn more"
+ },
+ "panels/network/components/RequestHeaderSection.ts | onlyProvisionalHeadersAre": {
+ "message": "Only provisional headers are available because this request was not sent over the network and instead was served from a local cache, which doesn’t store the original request headers. Disable cache to see full request headers."
+ },
+ "panels/network/components/RequestHeaderSection.ts | provisionalHeadersAreShown": {
+ "message": "Provisional headers are shown."
+ },
+ "panels/network/components/RequestHeaderSection.ts | provisionalHeadersAreShownDisableCache": {
+ "message": "Provisional headers are shown. Disable cache to see full headers."
+ },
"panels/network/components/RequestHeadersView.ts | chooseThisOptionIfTheResourceAnd": {
"message": "Choose this option if the resource and the document are served from the same site."
},
@@ -6896,21 +6908,9 @@
"panels/network/components/RequestHeadersView.ts | headerOverrides": {
"message": "Header overrides"
},
- "panels/network/components/RequestHeadersView.ts | learnMore": {
- "message": "Learn more"
- },
"panels/network/components/RequestHeadersView.ts | onlyChooseThisOptionIfAn": {
"message": "Only choose this option if an arbitrary website including this resource does not impose a security risk."
},
- "panels/network/components/RequestHeadersView.ts | onlyProvisionalHeadersAre": {
- "message": "Only provisional headers are available because this request was not sent over the network and instead was served from a local cache, which doesn’t store the original request headers. Disable cache to see full request headers."
- },
- "panels/network/components/RequestHeadersView.ts | provisionalHeadersAreShown": {
- "message": "Provisional headers are shown."
- },
- "panels/network/components/RequestHeadersView.ts | provisionalHeadersAreShownDisableCache": {
- "message": "Provisional headers are shown. Disable cache to see full headers."
- },
"panels/network/components/RequestHeadersView.ts | raw": {
"message": "Raw"
},
diff --git a/front_end/core/i18n/locales/en-XL.json b/front_end/core/i18n/locales/en-XL.json
index 7044e25..1e74947 100644
--- a/front_end/core/i18n/locales/en-XL.json
+++ b/front_end/core/i18n/locales/en-XL.json
@@ -6869,6 +6869,18 @@
"panels/network/components/HeaderSectionRow.ts | learnMoreInTheIssuesTab": {
"message": "L̂éâŕn̂ ḿôŕê ín̂ t́ĥé îśŝúêś t̂áb̂"
},
+ "panels/network/components/RequestHeaderSection.ts | learnMore": {
+ "message": "L̂éâŕn̂ ḿôŕê"
+ },
+ "panels/network/components/RequestHeaderSection.ts | onlyProvisionalHeadersAre": {
+ "message": "Ôńl̂ý p̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê áv̂áîĺâb́l̂é b̂éĉáûśê t́ĥíŝ ŕêq́ûéŝt́ ŵáŝ ńôt́ ŝén̂t́ ôv́êŕ t̂h́ê ńêt́ŵór̂ḱ âńd̂ ín̂śt̂éâd́ ŵáŝ śêŕv̂éd̂ f́r̂óm̂ á l̂óĉál̂ ćâćĥé, ŵh́îćĥ d́ôéŝń’t̂ śt̂ór̂é t̂h́ê ór̂íĝín̂ál̂ ŕêq́ûéŝt́ ĥéâd́êŕŝ. D́îśâb́l̂é ĉáĉh́ê t́ô śêé f̂úl̂ĺ r̂éq̂úêśt̂ h́êád̂ér̂ś."
+ },
+ "panels/network/components/RequestHeaderSection.ts | provisionalHeadersAreShown": {
+ "message": "P̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê śĥóŵń."
+ },
+ "panels/network/components/RequestHeaderSection.ts | provisionalHeadersAreShownDisableCache": {
+ "message": "P̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê śĥóŵń. D̂íŝáb̂ĺê ćâćĥé t̂ó ŝéê f́ûĺl̂ h́êád̂ér̂ś."
+ },
"panels/network/components/RequestHeadersView.ts | chooseThisOptionIfTheResourceAnd": {
"message": "Ĉh́ôóŝé t̂h́îś ôṕt̂íôń îf́ t̂h́ê ŕêśôúr̂ćê án̂d́ t̂h́ê d́ôćûḿêńt̂ ár̂é ŝér̂v́êd́ f̂ŕôḿ t̂h́ê śâḿê śît́ê."
},
@@ -6896,21 +6908,9 @@
"panels/network/components/RequestHeadersView.ts | headerOverrides": {
"message": "Ĥéâd́êŕ ôv́êŕr̂íd̂éŝ"
},
- "panels/network/components/RequestHeadersView.ts | learnMore": {
- "message": "L̂éâŕn̂ ḿôŕê"
- },
"panels/network/components/RequestHeadersView.ts | onlyChooseThisOptionIfAn": {
"message": "Ôńl̂ý ĉh́ôóŝé t̂h́îś ôṕt̂íôń îf́ âń âŕb̂ít̂ŕâŕŷ ẃêb́ŝít̂é îńĉĺûd́îńĝ t́ĥíŝ ŕêśôúr̂ćê d́ôéŝ ńôt́ îḿp̂óŝé â śêćûŕît́ŷ ŕîśk̂."
},
- "panels/network/components/RequestHeadersView.ts | onlyProvisionalHeadersAre": {
- "message": "Ôńl̂ý p̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê áv̂áîĺâb́l̂é b̂éĉáûśê t́ĥíŝ ŕêq́ûéŝt́ ŵáŝ ńôt́ ŝén̂t́ ôv́êŕ t̂h́ê ńêt́ŵór̂ḱ âńd̂ ín̂śt̂éâd́ ŵáŝ śêŕv̂éd̂ f́r̂óm̂ á l̂óĉál̂ ćâćĥé, ŵh́îćĥ d́ôéŝń’t̂ śt̂ór̂é t̂h́ê ór̂íĝín̂ál̂ ŕêq́ûéŝt́ ĥéâd́êŕŝ. D́îśâb́l̂é ĉáĉh́ê t́ô śêé f̂úl̂ĺ r̂éq̂úêśt̂ h́êád̂ér̂ś."
- },
- "panels/network/components/RequestHeadersView.ts | provisionalHeadersAreShown": {
- "message": "P̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê śĥóŵń."
- },
- "panels/network/components/RequestHeadersView.ts | provisionalHeadersAreShownDisableCache": {
- "message": "P̂ŕôv́îśîón̂ál̂ h́êád̂ér̂ś âŕê śĥóŵń. D̂íŝáb̂ĺê ćâćĥé t̂ó ŝéê f́ûĺl̂ h́êád̂ér̂ś."
- },
"panels/network/components/RequestHeadersView.ts | raw": {
"message": "R̂áŵ"
},
diff --git a/front_end/panels/network/components/BUILD.gn b/front_end/panels/network/components/BUILD.gn
index 93ad7be..92298a0 100644
--- a/front_end/panels/network/components/BUILD.gn
+++ b/front_end/panels/network/components/BUILD.gn
@@ -10,6 +10,7 @@
generate_css("css_files") {
sources = [
"HeaderSectionRow.css",
+ "RequestHeaderSection.css",
"RequestHeadersView.css",
"RequestTrustTokensView.css",
"WebBundleInfoView.css",
@@ -19,6 +20,7 @@
devtools_module("components") {
sources = [
"HeaderSectionRow.ts",
+ "RequestHeaderSection.ts",
"RequestHeadersView.ts",
"RequestTrustTokensView.ts",
"WebBundleInfoView.ts",
diff --git a/front_end/panels/network/components/RequestHeaderSection.css b/front_end/panels/network/components/RequestHeaderSection.css
new file mode 100644
index 0000000..6d4e98e
--- /dev/null
+++ b/front_end/panels/network/components/RequestHeaderSection.css
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2022 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+:host {
+ display: block;
+}
+
+devtools-header-section-row:last-of-type {
+ margin-bottom: 10px;
+}
+
+devtools-header-section-row:first-of-type {
+ margin-top: 2px;
+}
+
+.call-to-action {
+ background-color: var(--color-background-elevation-1);
+ padding: 8px;
+ border-radius: 2px;
+}
+
+.call-to-action-body {
+ padding: 6px 0;
+ margin-left: 9.5px;
+ border-left: 2px solid var(--issue-color-yellow);
+ padding-left: 18px;
+ line-height: 20px;
+}
+
+.call-to-action .explanation {
+ font-weight: bold;
+}
+
+.call-to-action code {
+ font-size: 90%;
+}
+
+.call-to-action .example .comment::before {
+ content: " — ";
+}
+
+.link,
+.devtools-link {
+ color: var(--color-link);
+ text-decoration: underline;
+ cursor: pointer;
+ padding: 2px 0; /* adjust focus ring size */
+}
+
+.explanation .link {
+ font-weight: normal;
+}
+
+.inline-icon {
+ vertical-align: middle;
+}
diff --git a/front_end/panels/network/components/RequestHeaderSection.ts b/front_end/panels/network/components/RequestHeaderSection.ts
new file mode 100644
index 0000000..058939f
--- /dev/null
+++ b/front_end/panels/network/components/RequestHeaderSection.ts
@@ -0,0 +1,133 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
+import * as LitHtml from '../../../ui/lit-html/lit-html.js';
+
+import type * as SDK from '../../../core/sdk/sdk.js';
+import * as i18n from '../../../core/i18n/i18n.js';
+import * as NetworkForward from '../forward/forward.js';
+import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
+import * as Platform from '../../../core/platform/platform.js';
+import {type HeaderDescriptor, HeaderSectionRow, type HeaderSectionRowData} from './HeaderSectionRow.js';
+
+import requestHeaderSectionStyles from './RequestHeaderSection.css.js';
+
+const {render, html} = LitHtml;
+
+const UIStrings = {
+ /**
+ *@description Text that is usually a hyperlink to more documentation
+ */
+ learnMore: 'Learn more',
+ /**
+ *@description Message to explain lack of raw headers for a particular network request
+ */
+ provisionalHeadersAreShownDisableCache: 'Provisional headers are shown. Disable cache to see full headers.',
+ /**
+ *@description Tooltip to explain lack of raw headers for a particular network request
+ */
+ onlyProvisionalHeadersAre:
+ 'Only provisional headers are available because this request was not sent over the network and instead was served from a local cache, which doesn’t store the original request headers. Disable cache to see full request headers.',
+ /**
+ *@description Message to explain lack of raw headers for a particular network request
+ */
+ provisionalHeadersAreShown: 'Provisional headers are shown.',
+};
+
+const str_ = i18n.i18n.registerUIStrings('panels/network/components/RequestHeaderSection.ts', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
+
+export interface RequestHeaderSectionData {
+ request: SDK.NetworkRequest.NetworkRequest;
+ toReveal?: {section: NetworkForward.UIRequestLocation.UIHeaderSection, header?: string};
+}
+
+export class RequestHeaderSection extends HTMLElement {
+ static readonly litTagName = LitHtml.literal`devtools-request-header-section`;
+ readonly #shadow = this.attachShadow({mode: 'open'});
+ #request?: Readonly<SDK.NetworkRequest.NetworkRequest>;
+ #headers: HeaderDescriptor[] = [];
+
+ connectedCallback(): void {
+ this.#shadow.adoptedStyleSheets = [requestHeaderSectionStyles];
+ }
+
+ set data(data: RequestHeaderSectionData) {
+ this.#request = data.request;
+
+ this.#headers = this.#request.requestHeaders().map(header => ({...header, headerNotSet: false}));
+ this.#headers.sort(function(a, b) {
+ return Platform.StringUtilities.compare(a.name.toLowerCase(), b.name.toLowerCase());
+ });
+
+ if (data.toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.Request) {
+ this.#headers.filter(header => header.name.toUpperCase() === data.toReveal?.header?.toUpperCase())
+ .forEach(header => {
+ header.highlight = true;
+ });
+ }
+
+ this.#render();
+ }
+
+ #render(): void {
+ if (!this.#request) {
+ return;
+ }
+
+ // Disabled until https://crbug.com/1079231 is fixed.
+ // clang-format off
+ render(html`
+ ${this.#maybeRenderProvisionalHeadersWarning()}
+ ${this.#headers.map(header => html`
+ <${HeaderSectionRow.litTagName} .data=${{
+ header: header,
+ } as HeaderSectionRowData}></${HeaderSectionRow.litTagName}>
+ `)}
+ `, this.#shadow, {host: this});
+ // clang-format on
+ }
+
+ #maybeRenderProvisionalHeadersWarning(): LitHtml.LitTemplate {
+ if (!this.#request || this.#request.requestHeadersText() !== undefined) {
+ return LitHtml.nothing;
+ }
+
+ let cautionText;
+ let cautionTitle = '';
+ if (this.#request.cachedInMemory() || this.#request.cached()) {
+ cautionText = i18nString(UIStrings.provisionalHeadersAreShownDisableCache);
+ cautionTitle = i18nString(UIStrings.onlyProvisionalHeadersAre);
+ } else {
+ cautionText = i18nString(UIStrings.provisionalHeadersAreShown);
+ }
+ // Disabled until https://crbug.com/1079231 is fixed.
+ // clang-format off
+ return html`
+ <div class="call-to-action">
+ <div class="call-to-action-body">
+ <div class="explanation" title=${cautionTitle}>
+ <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
+ iconName: 'clear-warning_icon',
+ width: '12px',
+ height: '12px',
+ } as IconButton.Icon.IconData}>
+ </${IconButton.Icon.Icon.litTagName}>
+ ${cautionText} <x-link href="https://developer.chrome.com/docs/devtools/network/reference/#provisional-headers" class="link">${i18nString(UIStrings.learnMore)}</x-link>
+ </div>
+ </div>
+ </div>
+ `;
+ // clang-format on
+ }
+}
+
+ComponentHelpers.CustomElements.defineComponent('devtools-request-header-section', RequestHeaderSection);
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'devtools-request-header-section': RequestHeaderSection;
+ }
+}
diff --git a/front_end/panels/network/components/RequestHeadersView.ts b/front_end/panels/network/components/RequestHeadersView.ts
index ba9dab4..ee24da8 100644
--- a/front_end/panels/network/components/RequestHeadersView.ts
+++ b/front_end/panels/network/components/RequestHeadersView.ts
@@ -21,6 +21,7 @@
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
import * as Sources from '../../sources/sources.js';
import {type HeaderSectionRowData, HeaderSectionRow, type HeaderDescriptor} from './HeaderSectionRow.js';
+import {type RequestHeaderSectionData, RequestHeaderSection} from './RequestHeaderSection.js';
import requestHeadersViewStyles from './RequestHeadersView.css.js';
@@ -67,10 +68,6 @@
*/
headerOverrides: 'Header overrides',
/**
- *@description Text that is usually a hyperlink to more documentation
- */
- learnMore: 'Learn more',
- /**
*@description Label for a checkbox to switch between raw and parsed headers
*/
raw: 'Raw',
@@ -80,19 +77,6 @@
onlyChooseThisOptionIfAn:
'Only choose this option if an arbitrary website including this resource does not impose a security risk.',
/**
- *@description Message to explain lack of raw headers for a particular network request
- */
- provisionalHeadersAreShownDisableCache: 'Provisional headers are shown. Disable cache to see full headers.',
- /**
- *@description Tooltip to explain lack of raw headers for a particular network request
- */
- onlyProvisionalHeadersAre:
- 'Only provisional headers are available because this request was not sent over the network and instead was served from a local cache, which doesn’t store the original request headers. Disable cache to see full request headers.',
- /**
- *@description Message to explain lack of raw headers for a particular network request
- */
- provisionalHeadersAreShown: 'Provisional headers are shown.',
- /**
*@description Text in Request Headers View of the Network panel
*/
referrerPolicy: 'Referrer Policy',
@@ -413,23 +397,7 @@
if (!this.#request) {
return LitHtml.nothing;
}
-
- const headers: HeaderDescriptor[] =
- this.#request.requestHeaders().map(header => ({...header, headerNotSet: false}));
- headers.sort(function(a, b) {
- return Platform.StringUtilities.compare(a.name.toLowerCase(), b.name.toLowerCase());
- });
-
- if (this.#toReveal?.section === NetworkForward.UIRequestLocation.UIHeaderSection.Request) {
- headers.filter(header => header.name.toUpperCase() === this.#toReveal?.header?.toUpperCase()).forEach(header => {
- header.highlight = true;
- });
- }
-
const requestHeadersText = this.#request.requestHeadersText();
- if (!headers.length && requestHeadersText !== undefined) {
- return LitHtml.nothing;
- }
const toggleShowRaw = (): void => {
this.#showRequestHeadersText = !this.#showRequestHeadersText;
@@ -452,51 +420,16 @@
>
${(this.#showRequestHeadersText && requestHeadersText) ?
this.#renderRawHeaders(requestHeadersText, false) : html`
- ${this.#maybeRenderProvisionalHeadersWarning()}
- ${headers.map(header => html`
- <${HeaderSectionRow.litTagName} .data=${{
- header: header,
- } as HeaderSectionRowData}></${HeaderSectionRow.litTagName}>
- `)}
+ <${RequestHeaderSection.litTagName} .data=${{
+ request: this.#request,
+ toReveal: this.#toReveal,
+ } as RequestHeaderSectionData}></${RequestHeaderSection.litTagName}>
`}
</${Category.litTagName}>
`;
// clang-format on
}
- #maybeRenderProvisionalHeadersWarning(): LitHtml.LitTemplate {
- if (!this.#request || this.#request.requestHeadersText() !== undefined) {
- return LitHtml.nothing;
- }
-
- let cautionText;
- let cautionTitle = '';
- if (this.#request.cachedInMemory() || this.#request.cached()) {
- cautionText = i18nString(UIStrings.provisionalHeadersAreShownDisableCache);
- cautionTitle = i18nString(UIStrings.onlyProvisionalHeadersAre);
- } else {
- cautionText = i18nString(UIStrings.provisionalHeadersAreShown);
- }
- // Disabled until https://crbug.com/1079231 is fixed.
- // clang-format off
- return html`
- <div class="call-to-action">
- <div class="call-to-action-body">
- <div class="explanation" title=${cautionTitle}>
- <${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
- iconName: 'clear-warning_icon',
- width: '12px',
- height: '12px',
- } as IconButton.Icon.IconData}>
- </${IconButton.Icon.Icon.litTagName}>
- ${cautionText} <x-link href="https://developer.chrome.com/docs/devtools/network/reference/#provisional-headers" class="link">${i18nString(UIStrings.learnMore)}</x-link>
- </div>
- </div>
- </div>
- `;
- // clang-format on
- }
-
#renderRawHeaders(rawHeadersText: string, forResponseHeaders: boolean): LitHtml.TemplateResult {
const trimmed = rawHeadersText.trim();
const showFull = forResponseHeaders ? this.#showResponseHeadersTextFull : this.#showRequestHeadersTextFull;
diff --git a/front_end/panels/network/components/components.ts b/front_end/panels/network/components/components.ts
index a772dc7..aab9464 100644
--- a/front_end/panels/network/components/components.ts
+++ b/front_end/panels/network/components/components.ts
@@ -3,11 +3,13 @@
// found in the LICENSE file.
import * as HeaderSectionRow from './HeaderSectionRow.js';
+import * as RequestHeaderSection from './RequestHeaderSection.js';
import * as RequestHeadersView from './RequestHeadersView.js';
import * as RequestTrustTokensView from './RequestTrustTokensView.js';
export {
HeaderSectionRow,
+ RequestHeaderSection,
RequestHeadersView,
RequestTrustTokensView,
};
diff --git a/test/unittests/front_end/panels/network/components/BUILD.gn b/test/unittests/front_end/panels/network/components/BUILD.gn
index 878ad8c..b062bf3 100644
--- a/test/unittests/front_end/panels/network/components/BUILD.gn
+++ b/test/unittests/front_end/panels/network/components/BUILD.gn
@@ -8,6 +8,7 @@
testonly = true
sources = [
"HeaderSectionRow_test.ts",
+ "RequestHeaderSection_test.ts",
"RequestHeadersView_test.ts",
"RequestTrustTokensView_test.ts",
]
diff --git a/test/unittests/front_end/panels/network/components/RequestHeaderSection_test.ts b/test/unittests/front_end/panels/network/components/RequestHeaderSection_test.ts
new file mode 100644
index 0000000..2299f02
--- /dev/null
+++ b/test/unittests/front_end/panels/network/components/RequestHeaderSection_test.ts
@@ -0,0 +1,85 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as NetworkComponents from '../../../../../../front_end/panels/network/components/components.js';
+import * as Coordinator from '../../../../../../front_end/ui/components/render_coordinator/render_coordinator.js';
+import type * as SDK from '../../../../../../front_end/core/sdk/sdk.js';
+
+import {
+ assertElement,
+ assertShadowRoot,
+ getCleanTextContentFromElements,
+ renderElementIntoDOM,
+} from '../../../helpers/DOMHelpers.js';
+import {describeWithEnvironment} from '../../../helpers/EnvironmentHelpers.js';
+
+const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
+
+const {assert} = chai;
+
+async function renderRequestHeaderSection(request: SDK.NetworkRequest.NetworkRequest):
+ Promise<NetworkComponents.RequestHeaderSection.RequestHeaderSection> {
+ const component = new NetworkComponents.RequestHeaderSection.RequestHeaderSection();
+ renderElementIntoDOM(component);
+ component.data = {request};
+ await coordinator.done();
+ assertElement(component, HTMLElement);
+ assertShadowRoot(component.shadowRoot);
+ return component;
+}
+
+describeWithEnvironment('RequestHeaderSection', () => {
+ it('renders provisional headers warning', async () => {
+ const request = {
+ cachedInMemory: () => true,
+ requestHeaders: () =>
+ [{name: ':method', value: 'GET'},
+ {name: 'accept-encoding', value: 'gzip, deflate, br'},
+ {name: 'cache-control', value: 'no-cache'},
+ ],
+ requestHeadersText: () => undefined,
+ } as unknown as SDK.NetworkRequest.NetworkRequest;
+
+ const component = await renderRequestHeaderSection(request);
+ assertShadowRoot(component.shadowRoot);
+
+ assert.strictEqual(
+ getCleanTextContentFromElements(component.shadowRoot, '.call-to-action')[0],
+ 'Provisional headers are shown. Disable cache to see full headers. Learn more',
+ );
+ });
+
+ it('sorts headers alphabetically', async () => {
+ const request = {
+ cachedInMemory: () => true,
+ requestHeaders: () =>
+ [{name: 'Ab', value: 'second'},
+ {name: 'test', value: 'fifth'},
+ {name: 'name', value: 'fourth'},
+ {name: 'abc', value: 'third'},
+ {name: 'aa', value: 'first'},
+ ],
+ requestHeadersText: () => 'placeholderText',
+ } as unknown as SDK.NetworkRequest.NetworkRequest;
+
+ const component = await renderRequestHeaderSection(request);
+ assertShadowRoot(component.shadowRoot);
+
+ const rows = component.shadowRoot.querySelectorAll('devtools-header-section-row');
+ const sorted = Array.from(rows).map(row => {
+ assertShadowRoot(row.shadowRoot);
+ return [
+ row.shadowRoot.querySelector('.header-name')?.textContent?.trim() || '',
+ row.shadowRoot.querySelector('.header-value')?.textContent?.trim() || '',
+ ];
+ });
+ assert.deepStrictEqual(sorted, [
+ ['aa:', 'first'],
+ ['Ab:', 'second'],
+ ['abc:', 'third'],
+ ['name:', 'fourth'],
+ ['test:', 'fifth'],
+ ]);
+ });
+});
diff --git a/test/unittests/front_end/panels/network/components/RequestHeadersView_test.ts b/test/unittests/front_end/panels/network/components/RequestHeadersView_test.ts
index 597855c..ff3fe32 100644
--- a/test/unittests/front_end/panels/network/components/RequestHeadersView_test.ts
+++ b/test/unittests/front_end/panels/network/components/RequestHeadersView_test.ts
@@ -173,22 +173,6 @@
});
// Test will be refactored in follow-up CL
- it.skip('[crbug.com/1297533]: renders provisional headers warning', async () => {
- const component = await renderHeadersComponent({
- ...defaultRequest,
- requestHeadersText: () => undefined,
- } as unknown as SDK.NetworkRequest.NetworkRequest);
- assertShadowRoot(component.shadowRoot);
-
- const requestHeadersCategory = component.shadowRoot.querySelector('[aria-label="Request Headers"]');
- assertElement(requestHeadersCategory, HTMLElement);
- assert.strictEqual(
- getCleanTextContentFromElements(requestHeadersCategory, '.call-to-action')[0],
- 'Provisional headers are shown. Disable cache to see full headers. Learn more',
- );
- });
-
- // Test will be refactored in follow-up CL
it.skip('[crbug.com/1297533]: can switch between source and parsed view', async () => {
const component = await renderHeadersComponent(defaultRequest);
assertShadowRoot(component.shadowRoot);
@@ -368,36 +352,6 @@
const linkElement = responseHeadersCategory.shadowRoot.querySelector('x-link');
assert.isNull(linkElement);
});
-
- it('skips rendering category if there are no headers', async () => {
- const component = await renderHeadersComponent({
- ...defaultRequest,
- sortedResponseHeaders: [],
- requestHeaders: () => [],
- } as unknown as SDK.NetworkRequest.NetworkRequest);
- assertShadowRoot(component.shadowRoot);
-
- assert.isNull(component.shadowRoot.querySelector('[aria-label="Response Headers"]'));
- assert.isNull(component.shadowRoot.querySelector('[aria-label="Request Headers"]'));
- });
-
- it('renders provisional headers warning for request headers even if there are no headers', async () => {
- const component = await renderHeadersComponent({
- ...defaultRequest,
- sortedResponseHeaders: [],
- requestHeaders: () => [],
- requestHeadersText: () => undefined,
- } as unknown as SDK.NetworkRequest.NetworkRequest);
- assertShadowRoot(component.shadowRoot);
-
- assert.isNull(component.shadowRoot.querySelector('[aria-label="Response Headers"]'));
- const requestHeadersCategory = component.shadowRoot.querySelector('[aria-label="Request Headers"]');
- assertElement(requestHeadersCategory, HTMLElement);
- assert.strictEqual(
- getCleanTextContentFromElements(requestHeadersCategory, '.call-to-action')[0],
- 'Provisional headers are shown. Disable cache to see full headers. Learn more',
- );
- });
});
describeWithEnvironment('RequestHeadersView\'s Category', () => {