diff --git a/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap b/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap
new file mode 100644
index 0000000000..05dea48730
--- /dev/null
+++ b/src/features/top-bar/extension-api/__snapshots__/extendability-using-extension-api.test.tsx.snap
@@ -0,0 +1,815 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`extendability-using-extension-api given an extension with a weakly typed and invalid top-bar item is enabled renders without blowing up 1`] = `
+
+
+
+
+
+
+
+ home
+
+
+
+
+ arrow_back
+
+
+
+
+ arrow_forward
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to OpenLens!
+
+
+ To get you started we have auto-detected your clusters in your
+
+ kubeconfig file and added them to the catalog, your centralized
+
+ view for managing all your cloud-native resources.
+
+
+ If you have any questions or feedback, please join our
+
+ Lens Community slack channel
+
+ .
+
+
+
+
+
+
+
+
+
+
+
+
+ arrow_left
+
+
+
+
+
+ arrow_right
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`extendability-using-extension-api given an extension with top-bar items is enabled renders 1`] = `
+
+
+
+
+
+
+
+ home
+
+
+
+
+ arrow_back
+
+
+
+
+ arrow_forward
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to OpenLens!
+
+
+ To get you started we have auto-detected your clusters in your
+
+ kubeconfig file and added them to the catalog, your centralized
+
+ view for managing all your cloud-native resources.
+
+
+ If you have any questions or feedback, please join our
+
+ Lens Community slack channel
+
+ .
+
+
+
+
+
+
+
+
+
+
+
+
+ arrow_left
+
+
+
+
+
+ arrow_right
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`extendability-using-extension-api given an extension with top-bar items is enabled when the extension is disabled renders 1`] = `
+
+
+
+
+
+
+
+ home
+
+
+
+
+ arrow_back
+
+
+
+
+ arrow_forward
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to OpenLens!
+
+
+ To get you started we have auto-detected your clusters in your
+
+ kubeconfig file and added them to the catalog, your centralized
+
+ view for managing all your cloud-native resources.
+
+
+ If you have any questions or feedback, please join our
+
+ Lens Community slack channel
+
+ .
+
+
+
+
+
+
+
+
+
+
+
+
+ arrow_left
+
+
+
+
+
+ arrow_right
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`extendability-using-extension-api renders 1`] = `
+
+
+
+
+
+
+
+ home
+
+
+
+
+ arrow_back
+
+
+
+
+ arrow_forward
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to OpenLens!
+
+
+ To get you started we have auto-detected your clusters in your
+
+ kubeconfig file and added them to the catalog, your centralized
+
+ view for managing all your cloud-native resources.
+
+
+ If you have any questions or feedback, please join our
+
+ Lens Community slack channel
+
+ .
+
+
+
+
+
+
+
+
+
+
+
+
+ arrow_left
+
+
+
+
+
+ arrow_right
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/features/top-bar/extension-api/extendability-using-extension-api.test.tsx b/src/features/top-bar/extension-api/extendability-using-extension-api.test.tsx
new file mode 100644
index 0000000000..70a06574a7
--- /dev/null
+++ b/src/features/top-bar/extension-api/extendability-using-extension-api.test.tsx
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import React from "react";
+import type { RenderResult } from "@testing-library/react";
+
+import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
+import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
+import type { FakeExtensionOptions } from "../../../renderer/components/test-utils/get-extension-fake";
+
+describe("extendability-using-extension-api", () => {
+ let rendered: RenderResult;
+ let applicationBuilder: ApplicationBuilder;
+
+ beforeEach(async () => {
+ applicationBuilder = getApplicationBuilder();
+
+ rendered = await applicationBuilder.render();
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("given an extension with top-bar items has not been enabled yet, does not render the top-bar item", () => {
+ expect(rendered.queryByTestId("some-top-bar-item")).not.toBeInTheDocument();
+ });
+
+ describe("given an extension with top-bar items is enabled", () => {
+ let testExtension: FakeExtensionOptions;
+
+ beforeEach(() => {
+ testExtension = {
+ id: "test-extension",
+ name: "Test Extension",
+
+ rendererOptions: {
+ topBarItems: [
+ {
+ components: {
+ Item: () => (
+ Some-content
+ ),
+ },
+ },
+ ],
+ },
+ };
+
+ applicationBuilder.extensions.enable(testExtension);
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("renders the top-bar item", () => {
+ expect(rendered.getByTestId("some-top-bar-item")).toBeInTheDocument();
+ });
+
+ describe("when the extension is disabled", () => {
+ beforeEach(() => {
+ applicationBuilder.extensions.disable(testExtension);
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("no longer renders the top-bar item", () => {
+ expect(rendered.queryByTestId("some-top-bar-item")).not.toBeInTheDocument();
+ });
+ });
+ });
+
+ describe("given an extension with a weakly typed and invalid top-bar item is enabled", () => {
+ beforeEach(() => {
+ const testExtension: FakeExtensionOptions = {
+ id: "test-extension",
+ name: "Test Extension",
+
+ rendererOptions: {
+ topBarItems: [
+ {
+ components: {
+ // Note: this makes the item invalid.
+ Item: undefined,
+ },
+ } as any,
+
+ // Note: empty object makes the item invalid.
+ {} as any,
+
+ // Note: non-object makes the item invalid.
+ undefined as any,
+ ],
+ },
+ };
+
+ applicationBuilder.extensions.enable(testExtension);
+ });
+
+ it("renders without blowing up", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+ });
+});