Repository: microsoft/vscode-edge-devtools
Pull request #128 (2020-04-16 17:33:25)

Merging Network Extension
This PR adds the network tool to the devtools extension!  The majority of this change was moving over the various patches and tests unique to the Network tool.

Here are some other notable changes from in this PR:
- Created "applyAppendTabPatch" as the one tabbing patch.  This targets the 'appendTab' function which later funnels into the showTab/selectTab functions that were previously being patched.
- Simplified tests by making variable names consistent and separating tests that were grouped together (some tests has result1, result2, result3...)
- Changed `.tabbed-pane-right-toolbar` patch to be `visibility: hidden` over `display: none` since it was hiding the network search close button and could not reveal when its parent had `display: none`
- Removed `applyInspectorCommonCssHeaderContentsPatch` since it was hiding the header toolbar.  Depending on how we want to expose the Network pane, we can re-add this code


![image](https://user-images.githubusercontent.com/14304598/79489233-d6632100-7fcf-11ea-8a1b-815f7dcbe127.png)
![image](https://user-images.githubusercontent.com/14304598/79489253-db27d500-7fcf-11ea-90cf-9a3c57f55138.png)
The original network extension can be found here: https://github.com/microsoft/vscode-edge-devtools-network


Patch:
diff --git a/postBuildStep.ts b/postBuildStep.ts
index 037fd08..b253452 100644
--- a/postBuildStep.ts
+++ b/postBuildStep.ts
@@ -7,14 +7,19 @@ import applyPaddingInlineCssPatch from "./src/host/polyfills/cssPaddingInline";
 import { applyCreateElementPatch, applyUIUtilsPatch } from "./src/host/polyfills/customElements";
 import { applyContentSecurityPolicyPatch } from "./src/host/polyfills/inspectorContentPolicy";
 import {
+    applyAppendTabPatch,
     applyCommonRevealerPatch,
-    applyInspectorCommonCssHeaderContentsPatch,
+    applyDrawerTabLocationPatch,
+    applyInspectorCommonContextMenuPatch,
+    applyInspectorCommonCssPatch,
     applyInspectorCommonCssRightToolbarPatch,
     applyInspectorCommonCssTabSliderPatch,
-    applyInspectorViewHandleActionPatch,
-    applyInspectorViewShowDrawerPatch,
+    applyInspectorCommonNetworkPatch,
     applyMainViewPatch,
-    applySelectTabPatch,
+    applyPersistRequestBlockingTab,
+    applySetTabIconPatch,
+    applyShowElementsTab,
+    applyShowRequestBlockingTab,
 } from "./src/host/polyfills/simpleView";
 import applySetupTextSelectionPatch from "./src/host/polyfills/textSelection";
 
@@ -78,7 +83,6 @@ async function copyStaticFiles(debugMode: boolean) {
 }
 
 async function patchFilesForWebView(toolsOutDir: string, debugMode: boolean) {
-
     // Release file versions
     if (!debugMode) {
         // tslint:disable-next-line:no-console
@@ -86,8 +90,10 @@ async function patchFilesForWebView(toolsOutDir: string, debugMode: boolean) {
         await patchFileForWebView("shell.js", toolsOutDir, true, [
             applyUIUtilsPatch,
             applyCreateElementPatch,
-            applyInspectorCommonCssHeaderContentsPatch,
+            applyInspectorCommonContextMenuPatch,
             applyInspectorCommonCssRightToolbarPatch,
+            applyInspectorCommonCssPatch,
+            applyInspectorCommonNetworkPatch,
             applyInspectorCommonCssTabSliderPatch,
         ]);
 
@@ -98,11 +104,16 @@ async function patchFilesForWebView(toolsOutDir: string, debugMode: boolean) {
             applyPaddingInlineCssPatch,
         ]);
         await patchFileForWebView("inspector.html", toolsOutDir, true, [applyContentSecurityPolicyPatch]);
-        await patchFileForWebView("ui/InspectorView.js", toolsOutDir, true, [
-            applyInspectorViewHandleActionPatch,
-            applyInspectorViewShowDrawerPatch]);
-        await patchFileForWebView("ui/TabbedPane.js", toolsOutDir, true, [applySelectTabPatch]);
-
+        await patchFileForWebView("ui/InspectorView.js", toolsOutDir, true, [applyDrawerTabLocationPatch]);
+        await patchFileForWebView("ui/TabbedPane.js", toolsOutDir, true, [
+            applyAppendTabPatch,
+            applyPersistRequestBlockingTab,
+            applySetTabIconPatch,
+        ]);
+        await patchFileForWebView("ui/ViewManager.js", toolsOutDir, true, [
+            applyShowElementsTab,
+            applyShowRequestBlockingTab,
+        ]);
     } else {
         // tslint:disable-next-line:no-console
         console.log("Patching files for debug version");
@@ -113,16 +124,23 @@ async function patchFilesForWebView(toolsOutDir: string, debugMode: boolean) {
             applyPaddingInlineCssPatch,
         ]);
         await patchFileForWebView("inspector.html", toolsOutDir, false, [applyContentSecurityPolicyPatch]);
-        await patchFileForWebView("ui/InspectorView.js", toolsOutDir, false, [
-            applyInspectorViewHandleActionPatch,
-            applyInspectorViewShowDrawerPatch]);
-        await patchFileForWebView("ui/TabbedPane.js", toolsOutDir, false, [applySelectTabPatch]);
+        await patchFileForWebView("ui/InspectorView.js", toolsOutDir, false, [applyDrawerTabLocationPatch]);
+        await patchFileForWebView("ui/TabbedPane.js", toolsOutDir, false, [
+            applyAppendTabPatch,
+            applyPersistRequestBlockingTab,
+            applySetTabIconPatch,
+        ]);
+        await patchFileForWebView("ui/ViewManager.js", toolsOutDir, true, [
+            applyShowElementsTab,
+            applyShowRequestBlockingTab,
+        ]);
         // Debug file versions
         await patchFileForWebView("ui/UIUtils.js", toolsOutDir, false, [applyUIUtilsPatch]);
         await patchFileForWebView("dom_extension/DOMExtension.js", toolsOutDir, false, [applyCreateElementPatch]);
         await patchFileForWebView("elements/ElementsPanel.js", toolsOutDir, false, [applySetupTextSelectionPatch]);
-        await patchFileForWebView("themes/base.css", toolsOutDir, false, [applyInspectorCommonCssHeaderContentsPatch,
-           applyInspectorCommonCssRightToolbarPatch, applyInspectorCommonCssTabSliderPatch]);
+        await patchFileForWebView("themes/base.css", toolsOutDir, false, [
+            applyInspectorCommonContextMenuPatch, applyInspectorCommonCssPatch, applyInspectorCommonNetworkPatch,
+            applyInspectorCommonCssRightToolbarPatch, applyInspectorCommonCssTabSliderPatch]);
         await patchFileForWebView("elements/elementsTreeOutline.css", toolsOutDir, false, [applyPaddingInlineCssPatch]);
         await patchFileForWebView("elements/stylesSectionTree.css", toolsOutDir, false, [applyPaddingInlineCssPatch]);
     }
diff --git a/src/host/polyfills/simpleView.ts b/src/host/polyfills/simpleView.ts
index 9eb61f2..0a82aab 100644
--- a/src/host/polyfills/simpleView.ts
+++ b/src/host/polyfills/simpleView.ts
@@ -36,7 +36,11 @@ export function applyCommonRevealerPatch(content: string) {
     }
 }
 
+// This function is needed for Elements-only version, but we need the drawer
+// for the Request Blocking tool when enabling the Network Panel.
 export function applyInspectorViewHandleActionPatch(content: string) {
+    // This patch removes the ability to open/close the drawer using 'ESC'
+    // and using CTRL + [ or CTRL + ] to navigate between tabs.
     const pattern = /handleAction\(context,\s*actionId\)\s*{/g;
 
     if (content.match(pattern)) {
@@ -47,7 +51,10 @@ export function applyInspectorViewHandleActionPatch(content: string) {
     }
 }
 
+// This function is needed for Elements-only version, but we need the drawer
+// for the Request Blocking tool when enabling the Network Panel.
 export function applyInspectorViewShowDrawerPatch(content: string) {
+    // This patch hides the drawer.
     const pattern = /_showDrawer\(focus\)\s*{/g;
 
     if (content.match(pattern)) {
@@ -67,7 +74,55 @@ export function applyMainViewPatch(content: string) {
     }
 }
 
-export function applySelectTabPatch(content: string) {
+export function applyShowElementsTab(content: string) {
+    // This tab sets the Elements tool as the default tab,
+    // so the extension will always show the Elements tool first.
+    const pattern = /this\._defaultTab\s*=\s*defaultTab;/;
+
+    if (content.match(pattern)) {
+        return content.replace(pattern, "this._defaultTab = 'elements';");
+    } else {
+    return null;
+    }
+}
+
+export function applyShowRequestBlockingTab(content: string) {
+    // Appends the Request Blocking tab in the drawer even if it is not open.
+    const pattern = /if\s*\(!view\.isCloseable\(\)\)/;
+
+    if (content.match(pattern)) {
+        return content.replace(pattern, "if(!view.isCloseable()||id==='network.blocked-urls')");
+    } else {
+        return null;
+    }
+}
+
+export function applyPersistRequestBlockingTab(content: string) {
+    // Removes the close button from the Request blocking tab by making the tab non-closeable.
+    const pattern = /this\._closeable\s*=\s*closeable;/;
+
+    if (content.match(pattern)) {
+        return content.replace(pattern, "this._closeable=id==='network.blocked-urls'?false:closeable;");
+    } else {
+        return null;
+    }
+}
+
+export function applySetTabIconPatch(content: string) {
+    // Adding undefined check in SetTabIcon so it doesn't throw an error trying to access disabled tabs.
+    // This is needed due to applyAppendTabPatch which removes unused tabs from the tablist.
+    const pattern = /setTabIcon\(id,\s*icon\)\s*{\s*const tab\s*=\s*this\._tabsById\.get\(id\);/;
+
+    if (content.match(pattern)) {
+        return content.replace(pattern, "setTabIcon(id,icon){const tab=this._tabsById.get(id); if(!tab){return;}");
+    } else {
+        return null;
+    }
+}
+
+export function applyAppendTabPatch(content: string) {
+    // The appendTab function chooses which tabs to put in the tabbed pane header section
+    // showTabElement and selectTab are only called by tabs that have already been appended via appendTab.
     const allowedTabs = [
         "elements",
         "Styles",
@@ -76,6 +131,17 @@ export function applySelectTabPatch(content: string) {
         "elements.domProperties",
         "elements.domBreakpoints",
         "elements.eventListeners",
+        "network",
+        "network.blocked-urls",
+        "network.search-network-tab",
+        "headers",
+        "preview",
+        "response",
+        "timing",
+        "initiator",
+        "cookies",
+        "eventSource",
+        "webSocketFrames",
         "preferences",
         "workspace",
         "experiments",
@@ -86,34 +152,115 @@ export function applySelectTabPatch(content: string) {
         "Shortcuts",
     ];
 
-    const condition = allowedTabs.map((v) => {
-        return `id !== '${v}'`;
+    const condition = allowedTabs.map((tab) => {
+        return `id !== '${tab}'`;
     }).join(" && ");
 
-    const pattern = /selectTab\(id,\s*userGesture,\s*forceFocus\)\s*{/g;
+    const pattern = /appendTab\(id,\s*tabTitle\s*,\s*view,\s*tabTooltip,\s*userGesture,\s*isCloseable,\s*index\)\s*{/;
 
     if (content.match(pattern)) {
         return content.replace(
             pattern,
-            `selectTab(id, userGesture, forceFocus) { if (${condition}) return false;`);
+            `appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index) { if (${condition}) return;`);
     } else {
         return null;
     }
 }
 
-export function applyInspectorCommonCssHeaderContentsPatch(content: string, isRelease?: boolean) {
+export function applyDrawerTabLocationPatch(content: string) {
+    // This shows the drawer with the network.blocked-urls tab open.
+    const pattern = /this._showDrawer.bind\s*\(this,\s*false\),\s*'drawer-view',\s*true,\s*true/g;
+    if (content.match(pattern)) {
+        return content.replace(pattern,
+            `this._showDrawer.bind\(this, false\), 'drawer-view', true, true, 'network.blocked-urls'`);
+    } else {
+        return null;
+    }
+}
+
+export function applyInspectorCommonCssPatch(content: string, isRelease?: boolean) {
+    // Hides the inspect button, the more tools button in the drawer and reveals the screen cast button.
     const separator = (isRelease ? "\\n" : "\n");
-    const cssHeaderContents =
-        `.main-tabbed-pane .tabbed-pane-header-contents {
+
+    const hideInspectBtn =
+        `.toolbar-button[aria-label='Select an element in the page to inspect it'] {
             display: none !important;
         }`.replace(/\n/g, separator);
 
-    const mainPattern = /(\.main-tabbed-pane\s*\.tabbed-pane-header-contents\s*\{([^\}]*)?\})/g;
+    const hideMoreToolsBtn =
+        `.toolbar-button[aria-label='More Tools'] {
+            display: none !important;
+        }`.replace(/\n/g, separator);
 
-    if (content.match(mainPattern)) {
-        return content.replace(
-            mainPattern,
-            cssHeaderContents);
+    const unHideScreenCastBtn =
+        `.toolbar-button[aria-label='Toggle screencast'] {
+            visibility: visible !important;
+        }`.replace(/\n/g, separator);
+
+    const topHeaderCSS =
+        hideInspectBtn +
+        hideMoreToolsBtn +
+        unHideScreenCastBtn;
+
+    const pattern = /(:host-context\(\.platform-mac\)\s*\.monospace,)/g;
+    if (content.match(pattern)) {
+        return content.replace(pattern, `${topHeaderCSS}${separator} $1`);
+    } else {
+        return null;
+    }
+}
+
+export function applyInspectorCommonNetworkPatch(content: string, isRelease?: boolean) {
+    // Hides export HAR button and pretty print button and reveals the Network search close button in the Network Panel.
+    const separator = (isRelease ? "\\n" : "\n");
+
+    const hideExportHarBtn =
+        `.toolbar-button[aria-label='Export HAR...'] {
+            display: none !important;
+        }`.replace(/\n/g, separator);
+
+    const hidePrettyPrintBtn =
+        `.toolbar-button[aria-label='Pretty print'] {
+            display: none !important;
+        }`.replace(/\n/g, separator);
+
+    // Search close button initially hidden by applyInspectorCommonCssRightToolbarPatch
+    const unHideSearchCloseButton =
+        `.toolbar-button[aria-label='Close'] {
+            visibility: visible !important;
+        }`.replace(/\n/g, separator);
+
+    const networkCSS =
+        hideExportHarBtn +
+        hidePrettyPrintBtn +
+        unHideSearchCloseButton;
+
+    const pattern = /(:host-context\(\.platform-mac\)\s*\.monospace,)/g;
+    if (content.match(pattern)) {
+        return content.replace(pattern, `${networkCSS}${separator} $1`);
+    } else {
+        return null;
+    }
+}
+
+export function applyInspectorCommonContextMenuPatch(content: string, isRelease?: boolean) {
+    // Hides certain context menu items from elements in the Network Panel.
+    const separator = (isRelease ? "\\n" : "\n");
+
+    const hideContextMenuItems =
+        `.soft-context-menu-separator,
+        .soft-context-menu-item[aria-label='Open in new tab'],
+        .soft-context-menu-item[aria-label='Open in Sources panel'],
+        .soft-context-menu-item[aria-label='Clear browser cache'],
+        .soft-context-menu-item[aria-label='Clear browser cookies'],
+        .soft-context-menu-item[aria-label='Save all as HAR with content'],
+        .soft-context-menu-item[aria-label='Save as...'] {
+            display: none !important;
+        }`.replace(/\n/g, separator);
+
+    const pattern = /(:host-context\(\.platform-mac\)\s*\.monospace,)/g;
+    if (content.match(pattern)) {
+        return content.replace(pattern, `${hideContextMenuItems}${separator} $1`);
     } else {
         return null;
     }
@@ -123,7 +270,7 @@ export function applyInspectorCommonCssRightToolbarPatch(content: string, isRele
     const separator = (isRelease ? "\\n" : "\n");
     const cssRightToolbar =
         `.tabbed-pane-right-toolbar {
-            display: none !important;
+            visibility: hidden !important;
         }`.replace(/\n/g, separator);
 
     const tabbedPanePattern = /(\.tabbed-pane-right-toolbar\s*\{([^\}]*)?\})/g;


Test patch:
diff --git a/src/host/polyfills/simpleView.test.ts b/src/host/polyfills/simpleView.test.ts
index be5bddf..0878cf6 100644
--- a/src/host/polyfills/simpleView.test.ts
+++ b/src/host/polyfills/simpleView.test.ts
@@ -75,102 +75,211 @@ describe("simpleView", () => {
             expect.stringContaining("const moreTools = { defaultSection: () => ({ appendItem: () => {} }) };"));
     });
 
-    it("applySelectTabPatch correctly changes text", async () => {
-        const comparableText = "selectTab(id, userGesture, forceFocus) {";
+    it("applyDrawerTabLocationPatch correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = "this._showDrawer.bind(this, false), 'drawer-view', true, true";
+        let fileContents = getTextFromFile("ui/InspectorView.js");
+        // The file was not found, so test that at least the text is being replaced.
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyDrawerTabLocationPatch(fileContents);
+        expect(result).not.toEqual(null);
+        expect(result).toEqual(expect.stringContaining(
+            "this._showDrawer.bind(this, false), 'drawer-view', true, true, 'network.blocked-urls'"));
+    });
+
+    it("applySetTabIconPatch correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText =
+            " setTabIcon(id, icon) {const tab = this._tabsById.get(id); tab._setIcon(icon);this._updateTabElements();}";
         let fileContents = getTextFromFile("ui/TabbedPane.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applySetTabIconPatch(fileContents);
+        expect(result).not.toEqual(null);
+        expect(result).toEqual(expect.stringContaining("if(!tab){return;}"));
+    });
 
-        // The file was not found, so test that at least the text is being replaced.
+    it("applyAppendTabPatch correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = "appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index) {";
+        let fileContents = getTextFromFile("ui/TabbedPane.js");
         fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyAppendTabPatch(fileContents);
+        expect(result).not.toEqual(null);
+        expect(result).toEqual(expect.stringContaining(
+            "appendTab(id, tabTitle, view, tabTooltip, userGesture, isCloseable, index) { if (id"));
+    });
+
+    it("applyShowElementsTab correctly changes text", async () => {
         const apply = await import("./simpleView");
-        const result = apply.applySelectTabPatch(fileContents);
+        const comparableText = "this._defaultTab = defaultTab;";
+        let fileContents = getTextFromFile("ui/ViewManager.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyShowElementsTab(fileContents);
         expect(result).not.toEqual(null);
-        expect(result).toEqual(expect.stringContaining("selectTab(id, userGesture, forceFocus) { if ("));
+        if (result) {
+            expect(result).toEqual(expect.stringContaining("this._defaultTab = 'elements';"));
+        }
     });
 
-    it("applyInspectorCommonCssPatch correctly changes tabbed-pane-header-contents", async () => {
-        const expectedCss = `.main-tabbed-pane .tabbed-pane-header-contents {
-            flex: auto;
-            pointer-events: none;
-            margin-left: 0;
-            position: relative;
-        }`;
-        const expectedResult = `.main-tabbed-pane .tabbed-pane-header-contents {
-            display: none !important;
-        }`;
+    it("applyShowRequestBlockingTab correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = "if(!view.isCloseable())";
+        let fileContents = getTextFromFile("ui/ViewManager.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyShowRequestBlockingTab(fileContents);
+        expect(result).not.toEqual(null);
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(
+                "if(!view.isCloseable()||id==='network.blocked-urls')"));
+        }
+    });
+
+    it("applyPersistRequestBlockingTab correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = "this._closeable = closeable;";
+        let fileContents = getTextFromFile("ui/TabbedPane.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyPersistRequestBlockingTab(fileContents);
+        expect(result).not.toEqual(null);
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(
+                "this._closeable=id==='network.blocked-urls'?false:closeable;"));
+        }
+    });
+
+    it("applyInspectorCommonCssPatch correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = ":host-context(.platform-mac) .monospace,";
         let fileContents = getTextFromFile("shell.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyInspectorCommonCssPatch(fileContents);
 
-        // The file was not found, so test that at least the text is being replaced.
-        fileContents = fileContents ? fileContents : expectedCss;
+        // If this part of the css was correctly applied to the file, the rest of the css will be there as well.
+        const expectedString =
+            ".toolbar-button[aria-label='Toggle screencast'] {\n            visibility: visible !important;";
+        expect(result).not.toEqual(null);
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(expectedString));
+        }
+    });
+
+    it("applyInspectorCommonCssPatch correctly changes text (release)", async () => {
         const apply = await import("./simpleView");
-        const result = apply.applyInspectorCommonCssHeaderContentsPatch(fileContents);
+        const comparableText = ":host-context(.platform-mac) .monospace,";
+        let fileContents = getTextFromFile("shell.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyInspectorCommonCssPatch(fileContents, true);
+        // If this part of the css was correctly applied to the file, the rest of the css will be there as well.
+        const expectedString =
+            ".toolbar-button[aria-label='Toggle screencast'] {\\n            visibility: visible !important;";
+
         expect(result).not.toEqual(null);
-        expect(result).toEqual(expect.stringContaining(expectedResult));
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(expectedString));
+        }
     });
 
-    it("applyInspectorCommonCssPatch correctly changes tabbed-pane-tab-slider", async () => {
-        const expectedCss = `.tabbed-pane-tab-slider {
-            height: 2px;
-            position: absolute;
-            bottom: -1px;
-            background-color: var(--accent-color);
-            left: 0;
-            z-index: 50;
-            transform-origin: 0 100%;
-            transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);
-            visibility: hidden;
-        }`;
-        const expectedResult = `.tabbed-pane-tab-slider {
-            display: none !important;
-        }`;
+    it("applyInspectorCommonNetworkPatch correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = ":host-context(.platform-mac) .monospace,";
         let fileContents = getTextFromFile("shell.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyInspectorCommonNetworkPatch(fileContents);
 
-        // The file was not found, so test that at least the text is being replaced.
-        fileContents = fileContents ? fileContents : expectedCss;
+        // If this part of the css was correctly applied to the file, the rest of the css will be there as well.
+        const expectedString =
+            ".toolbar-button[aria-label='Export HAR...'] {\n            display: none !important;";
+        expect(result).not.toEqual(null);
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(expectedString));
+        }
+    });
+
+    it("applyInspectorCommonNetworkPatch correctly changes text (release)", async () => {
         const apply = await import("./simpleView");
-        const result = apply.applyInspectorCommonCssTabSliderPatch(fileContents);
+        const comparableText = ":host-context(.platform-mac) .monospace,";
+        let fileContents = getTextFromFile("shell.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyInspectorCommonNetworkPatch(fileContents, true);
+        // If this part of the css was correctly applied to the file, the rest of the css will be there as well.
+        const expectedString =
+            ".toolbar-button[aria-label='Export HAR...'] {\\n            display: none !important;";
+
         expect(result).not.toEqual(null);
-        expect(result).toEqual(expect.stringContaining(expectedResult));
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(expectedString));
+        }
+    });
+
+    it("applyInspectorCommonContextMenuPatch correctly changes text", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = ":host-context(.platform-mac) .monospace,";
+        let fileContents = getTextFromFile("shell.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyInspectorCommonContextMenuPatch(fileContents);
+
+        // If this part of the css was correctly applied to the file, the rest of the css will be there as well.
+        const expectedString =
+            ".soft-context-menu-item[aria-label='Save as...'] {\n            display: none !important;";
+        expect(result).not.toEqual(null);
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(expectedString));
+        }
+    });
+
+    it("applyInspectorCommonContextMenuPatch correctly changes text (release)", async () => {
+        const apply = await import("./simpleView");
+        const comparableText = ":host-context(.platform-mac) .monospace,";
+        let fileContents = getTextFromFile("shell.js");
+        fileContents = fileContents ? fileContents : comparableText;
+        const result = apply.applyInspectorCommonContextMenuPatch(fileContents, true);
+        // If this part of the css was correctly applied to the file, the rest of the css will be there as well.
+        const expectedString =
+            ".soft-context-menu-item[aria-label='Save as...'] {\\n            display: none !important;";
+
+        expect(result).not.toEqual(null);
+        if (result) {
+            expect(result).toEqual(expect.stringContaining(expectedString));
+        }
     });
 
-    it("applyInspectorCommonCssPatch correctly changes tabbed-pane-right-toolbar", async () => {
-        const expectedCss = `.tabbed-pane-right-toolbar {
+    it("applyInspectorCommonCssRightToolbarPatch correctly changes tabbed-pane-right-toolbar (release)", async () => {
+        const comparableText = `.tabbed-pane-right-toolbar {
             margin-left: -4px;
             flex: none;
         }`;
         const expectedResult = `.tabbed-pane-right-toolbar {
-            display: none !important;
+            visibility: hidden !important;
         }`;
         let fileContents = getTextFromFile("shell.js");
 
         // The file was not found, so test that at least the text is being replaced.
-        fileContents = fileContents ? fileContents : expectedCss;
+        fileContents = fileContents ? fileContents : comparableText;
         const apply = await import("./simpleView");
         const result = apply.applyInspectorCommonCssRightToolbarPatch(fileContents);
         expect(result).not.toEqual(null);
         expect(result).toEqual(expect.stringContaining(expectedResult));
     });
 
-    it("applyInspectorCommonCssPatch correctly changes tabbed-pane-header-contents in release mode", async () => {
-        const expectedCss = `.main-tabbed-pane .tabbed-pane-header-contents {
-            flex: auto;
-            pointer-events: none;
-            margin-left: 0;
-            position: relative;
+    it("applyInspectorCommonCssRightToolbarPatch correctly changes tabbed-pane-right-toolbar", async () => {
+        const comparableText = `.tabbed-pane-right-toolbar {
+            margin-left: -4px;
+            flex: none;
         }`;
         const expectedResult =
-            ".main-tabbed-pane .tabbed-pane-header-contents {\\n            display: none !important;\\n        }";
+            ".tabbed-pane-right-toolbar {\\n            visibility: hidden !important;\\n        }";
         let fileContents = getTextFromFile("shell.js");
 
         // The file was not found, so test that at least the text is being replaced.
-        fileContents = fileContents ? fileContents : expectedCss;
+        fileContents = fileContents ? fileContents : comparableText;
         const apply = await import("./simpleView");
-        const result = apply.applyInspectorCommonCssHeaderContentsPatch(fileContents, true);
+        const result = apply.applyInspectorCommonCssRightToolbarPatch(fileContents, true);
         expect(result).not.toEqual(null);
         expect(result).toEqual(expect.stringContaining(expectedResult));
     });
 
-    it("applyInspectorCommonCssPatch correctly changes tabbed-pane-tab-slider in release mode", async () => {
-        const expectedCss = `.tabbed-pane-tab-slider {
+    it("applyInspectorCommonCssTabSliderPatch correctly changes tabbed-pane-tab-slider (release)", async () => {
+        const comparableText = `.tabbed-pane-tab-slider {
             height: 2px;
             position: absolute;
             bottom: -1px;
@@ -186,26 +295,34 @@ describe("simpleView", () => {
         let fileContents = getTextFromFile("shell.js");
 
         // The file was not found, so test that at least the text is being replaced.
-        fileContents = fileContents ? fileContents : expectedCss;
+        fileContents = fileContents ? fileContents : comparableText;
         const apply = await import("./simpleView");
         const result = apply.applyInspectorCommonCssTabSliderPatch(fileContents, true);
         expect(result).not.toEqual(null);
         expect(result).toEqual(expect.stringContaining(expectedResult));
     });
 
-    it("applyInspectorCommonCssPatch correctly changes tabbed-pane-right-toolbar in release mode", async () => {
-        const expectedCss = `.tabbed-pane-right-toolbar {
-            margin-left: -4px;
-            flex: none;
+    it("applyInspectorCommonCssTabSliderPatch correctly changes tabbed-pane-tab-slider", async () => {
+        const comparableText = `.tabbed-pane-tab-slider {
+            height: 2px;
+            position: absolute;
+            bottom: -1px;
+            background-color: var(--accent-color);
+            left: 0;
+            z-index: 50;
+            transform-origin: 0 100%;
+            transition: transform 150ms cubic-bezier(0, 0, 0.2, 1);
+            visibility: hidden;
+        }`;
+        const expectedResult = `.tabbed-pane-tab-slider {
+            display: none !important;
         }`;
-        const expectedResult =
-            ".tabbed-pane-right-toolbar {\\n            display: none !important;\\n        }";
         let fileContents = getTextFromFile("shell.js");
 
         // The file was not found, so test that at least the text is being replaced.
-        fileContents = fileContents ? fileContents : expectedCss;
+        fileContents = fileContents ? fileContents : comparableText;
         const apply = await import("./simpleView");
-        const result = apply.applyInspectorCommonCssRightToolbarPatch(fileContents, true);
+        const result = apply.applyInspectorCommonCssTabSliderPatch(fileContents);
         expect(result).not.toEqual(null);
         expect(result).toEqual(expect.stringContaining(expectedResult));
     });