diff --git a/app/react/sidebar/AzureSidebar/AzureSidebar.tsx b/app/react/sidebar/AzureSidebar/AzureSidebar.tsx
index 64db4f224..0adcec5b0 100644
--- a/app/react/sidebar/AzureSidebar/AzureSidebar.tsx
+++ b/app/react/sidebar/AzureSidebar/AzureSidebar.tsx
@@ -12,12 +12,17 @@ interface Props {
export function AzureSidebar({ environmentId }: Props) {
return (
<>
-
+
>
);
diff --git a/app/react/sidebar/DockerSidebar.tsx b/app/react/sidebar/DockerSidebar.tsx
index 1eba959ea..bf4ad0333 100644
--- a/app/react/sidebar/DockerSidebar.tsx
+++ b/app/react/sidebar/DockerSidebar.tsx
@@ -58,27 +58,35 @@ export function DockerSidebar({ environmentId, environment }: Props) {
label: 'Swarm',
icon: Trello,
to: 'docker.swarm',
+ dataCy: 'portainerSidebar-swarm',
}
: {
label: 'Host',
icon: Trello,
to: 'docker.host',
+ dataCy: 'portainerSidebar-host',
};
return (
<>
-
+
@@ -88,6 +96,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
params={{ endpointId: environmentId }}
icon={Layers}
label="Stacks"
+ data-cy="dockerSidebar-stacks"
/>
)}
@@ -97,6 +106,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
params={{ endpointId: environmentId }}
icon={Shuffle}
label="Services"
+ data-cy="dockerSidebar-services"
/>
)}
@@ -105,6 +115,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
params={{ endpointId: environmentId }}
icon={Box}
label="Containers"
+ data-cy="dockerSidebar-containers"
/>
-
+
{apiVersion >= 1.3 && isSwarmManager && (
)}
@@ -138,6 +156,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
params={{ endpointId: environmentId }}
icon={Lock}
label="Secrets"
+ data-cy="dockerSidebar-secrets"
/>
)}
@@ -147,6 +166,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
params={{ endpointId: environmentId }}
icon={Clock}
label="Events"
+ data-cy="dockerSidebar-events"
/>
)}
@@ -155,6 +175,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
icon={setupSubMenuProps.icon}
to={setupSubMenuProps.to}
params={{ endpointId: environmentId }}
+ data-cy={setupSubMenuProps.dataCy}
>
-
-
-
-
+
+
+
+
);
}
diff --git a/app/react/sidebar/KubernetesSidebar/KubernetesSidebar.tsx b/app/react/sidebar/KubernetesSidebar/KubernetesSidebar.tsx
index 1b58ecfb9..92838e4c2 100644
--- a/app/react/sidebar/KubernetesSidebar/KubernetesSidebar.tsx
+++ b/app/react/sidebar/KubernetesSidebar/KubernetesSidebar.tsx
@@ -21,13 +21,18 @@ export function KubernetesSidebar({ environmentId }: Props) {
<>
{isOpen && }
-
+
@@ -43,6 +49,7 @@ export function KubernetesSidebar({ environmentId }: Props) {
params={{ endpointId: environmentId }}
icon={Loader}
label="Helm"
+ data-cy="k8sSidebar-helm"
/>
@@ -51,6 +58,7 @@ export function KubernetesSidebar({ environmentId }: Props) {
params={{ endpointId: environmentId }}
icon={Box}
label="Applications"
+ data-cy="k8sSidebar-applications"
/>
-
+
@@ -81,6 +96,7 @@ export function KubernetesSidebar({ environmentId }: Props) {
to="portainer.k8sendpoint.securityConstraint"
params={{ id: environmentId }}
label="Security constraints"
+ data-cy="k8sSidebar-securityConstraints"
/>
@@ -88,6 +104,7 @@ export function KubernetesSidebar({ environmentId }: Props) {
to="kubernetes.registries"
params={{ endpointId: environmentId }}
label="Registries"
+ data-cy="k8sSidebar-registries"
/>
>
diff --git a/app/react/sidebar/SettingsSidebar.tsx b/app/react/sidebar/SettingsSidebar.tsx
index 6e80b83f3..5caa599f9 100644
--- a/app/react/sidebar/SettingsSidebar.tsx
+++ b/app/react/sidebar/SettingsSidebar.tsx
@@ -27,10 +27,25 @@ export function SettingsSidebar({ isAdmin }: Props) {
return (
{showUsersSection && (
-
-
+
+
- {isAdmin && }
+ {isAdmin && (
+
+ )}
)}
{isAdmin && (
@@ -40,15 +55,25 @@ export function SettingsSidebar({ isAdmin }: Props) {
to="portainer.endpoints"
icon={HardDrive}
openOnPaths={['portainer.wizard.endpoints']}
+ data-cy="portainerSidebar-environments"
>
-
-
+
+
{process.env.PORTAINER_EDITION !== 'CE' && (
@@ -56,6 +81,7 @@ export function SettingsSidebar({ isAdmin }: Props) {
to="portainer.licenses"
label="Licenses"
icon={Award}
+ data-cy="portainerSidebar-licenses"
/>
)}
@@ -63,22 +89,38 @@ export function SettingsSidebar({ isAdmin }: Props) {
label="Authentication logs"
to="portainer.authLogs"
icon={FileText}
+ data-cy="portainerSidebar-authLogs"
>
-
+
-
+
{!window.ddExtension && (
)}
-
+
@@ -90,7 +132,7 @@ export function SettingsSidebar({ isAdmin }: Props) {
}
target="_blank"
rel="noreferrer"
- className="px-3 rounded flex h-full items-center"
+ className="px-3 rounded flex h-8 items-center"
>
Help / About
diff --git a/app/react/sidebar/Sidebar.tsx b/app/react/sidebar/Sidebar.tsx
index 07bb634ae..3902c83d6 100644
--- a/app/react/sidebar/Sidebar.tsx
+++ b/app/react/sidebar/Sidebar.tsx
@@ -41,7 +41,12 @@ export function Sidebar() {
{/* negative margin + padding -> scrollbar won't hide the content */}
-
+
diff --git a/app/react/sidebar/SidebarItem/Head.tsx b/app/react/sidebar/SidebarItem/Head.tsx
index 98b58beaa..bf2a2ee08 100644
--- a/app/react/sidebar/SidebarItem/Head.tsx
+++ b/app/react/sidebar/SidebarItem/Head.tsx
@@ -6,12 +6,17 @@ import {
import clsx from 'clsx';
import { ComponentProps } from 'react';
+import { AutomationTestingProps } from '@/types';
+
import { Link } from '@@/Link';
import { IconProps, Icon } from '@@/Icon';
import { useSidebarState } from '../useSidebarState';
-interface Props extends IconProps, ComponentProps {
+interface Props
+ extends IconProps,
+ ComponentProps,
+ AutomationTestingProps {
label: string;
ignorePaths?: string[];
}
@@ -23,6 +28,7 @@ export function Head({
label,
icon,
ignorePaths = [],
+ 'data-cy': dataCy,
}: Props) {
const { isOpen } = useSidebarState();
const anchorProps = useSrefActive(
@@ -43,6 +49,7 @@ export function Head({
'text-inherit no-underline hover:no-underline hover:text-inherit focus:no-underline focus:text-inherit w-full flex-1 rounded-md',
{ 'px-3': isOpen }
)}
+ data-cy={dataCy}
>
);
diff --git a/app/react/sidebar/items/DashboardLink.tsx b/app/react/sidebar/items/DashboardLink.tsx
index 9ed05be9e..9e295941f 100644
--- a/app/react/sidebar/items/DashboardLink.tsx
+++ b/app/react/sidebar/items/DashboardLink.tsx
@@ -1,21 +1,27 @@
import { Layout } from 'react-feather';
import { EnvironmentId } from '@/portainer/environments/types';
+import { AutomationTestingProps } from '@/types';
import { SidebarItem } from '../SidebarItem';
-interface Props {
+interface Props extends AutomationTestingProps {
environmentId: EnvironmentId;
platformPath: string;
}
-export function DashboardLink({ environmentId, platformPath }: Props) {
+export function DashboardLink({
+ environmentId,
+ platformPath,
+ 'data-cy': dataCy,
+}: Props) {
return (
);
}
diff --git a/app/react/sidebar/items/VolumesLink.tsx b/app/react/sidebar/items/VolumesLink.tsx
index 7d59d9499..131ada783 100644
--- a/app/react/sidebar/items/VolumesLink.tsx
+++ b/app/react/sidebar/items/VolumesLink.tsx
@@ -1,21 +1,27 @@
import { Database } from 'react-feather';
import { EnvironmentId } from '@/portainer/environments/types';
+import { AutomationTestingProps } from '@/types';
import { SidebarItem } from '../SidebarItem';
-interface Props {
+interface Props extends AutomationTestingProps {
environmentId: EnvironmentId;
platformPath: string;
}
-export function VolumesLink({ environmentId, platformPath }: Props) {
+export function VolumesLink({
+ environmentId,
+ platformPath,
+ 'data-cy': dataCy,
+}: Props) {
return (
);
}