diff --git a/packages/ui/components/navigation/tabs/HorizontalTabItem.tsx b/packages/ui/components/navigation/tabs/HorizontalTabItem.tsx index a6698503ac..e044d73953 100644 --- a/packages/ui/components/navigation/tabs/HorizontalTabItem.tsx +++ b/packages/ui/components/navigation/tabs/HorizontalTabItem.tsx @@ -43,6 +43,7 @@ const HorizontalTabItem = function ({ props.disabled && "pointer-events-none !opacity-30", props.className )} + data-testid={`horizontal-tab-${name}`} aria-current={isCurrent ? "page" : undefined}> {props.icon && ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ui/components/navigation/tabs/VerticalTabItem.tsx b/packages/ui/components/navigation/tabs/VerticalTabItem.tsx index 883e1c9c5f..b83eca9f36 100644 --- a/packages/ui/components/navigation/tabs/VerticalTabItem.tsx +++ b/packages/ui/components/navigation/tabs/VerticalTabItem.tsx @@ -67,6 +67,7 @@ const VerticalTabItem = ({ "mr-2 h-[16px] w-[16px] stroke-[2px] ltr:mr-2 rtl:ml-2 md:mt-0", props.iconClassName )} + data-testid="icon-component" /> )}
@@ -74,7 +75,7 @@ const VerticalTabItem = ({ {t(name)} - {props.isExternalLink ? : null} + {props.isExternalLink ? : null} {info && ( @@ -88,6 +89,7 @@ const VerticalTabItem = ({ width={20} height={20} className="text-default h-auto w-[20px] stroke-[1.5px]" + data-testid="chevron-right" />
)} diff --git a/packages/ui/components/navigation/tabs/navigation.test.tsx b/packages/ui/components/navigation/tabs/navigation.test.tsx new file mode 100644 index 0000000000..9808513106 --- /dev/null +++ b/packages/ui/components/navigation/tabs/navigation.test.tsx @@ -0,0 +1,135 @@ +/* eslint-disable playwright/missing-playwright-await */ +import { fireEvent, render, screen } from "@testing-library/react"; +import { PlusIcon } from "lucide-react"; +import { vi } from "vitest"; + +import HorizontalTabs from "./HorizontalTabs"; +import VerticalTabs from "./VerticalTabs"; + +vi.mock("@calcom/lib/hooks/useUrlMatchesCurrentUrl", () => ({ + useUrlMatchesCurrentUrl() { + return { + route: "/", + pathname: "", + query: "", + asPath: "", + push: vi.fn(), + events: { + on: vi.fn(), + off: vi.fn(), + }, + beforePopState: vi.fn(() => null), + prefetch: vi.fn(() => null), + }; + }, +})); + +vi.mock("@calcom/lib/hooks/useLocale", () => ({ + useLocale: () => ({ t: (key: string) => key, isLocaleReady: true }), +})); + +describe("Tests for navigation folder", () => { + describe("Test HorizontalTabs Component", () => { + const mockTabs = [ + { name: "Tab 1", href: "/tab1" }, + { name: "Tab 2", href: "/tab2", avatar: "Avatar" }, + { name: "Tab 3", href: "/tab3" }, + ]; + + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("Should render tabs with correct name and href", () => { + render(); + mockTabs.forEach((tab) => { + const tabLabelElement = screen.getByTestId(`horizontal-tab-${tab.name}`); + expect(tabLabelElement).toBeInTheDocument(); + + const name = screen.getByText(tab.name); + expect(name).toBeInTheDocument(); + expect(tabLabelElement).toHaveAttribute("href", tab.href); + }); + }); + + test("Should render actions correctly", () => { + const handleClick = vi.fn(); + const mockActions = ; + render(); + const actionsElement = screen.getByText("Actions"); + expect(actionsElement).toBeInTheDocument(); + fireEvent.click(actionsElement); + + expect(handleClick).toHaveBeenCalled(); + }); + }); + + describe("Test VerticalTabs Component", () => { + const mockTabs = [ + { + name: "Tab 1", + href: "/tab1", + disableChevron: true, + disabled: true, + icon: PlusIcon, + }, + { name: "Tab 2", href: "/tab2", isExternalLink: true }, + { name: "Tab 3", href: "/tab3", info: "info" }, + ]; + + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("Should render tabs with correct name and href", () => { + render(); + mockTabs.forEach((tab) => { + const tabLabelElement = screen.getByTestId(`vertical-tab-${tab.name}`); + expect(tabLabelElement).toBeInTheDocument(); + + const name = screen.getByText(tab.name); + expect(name).toBeInTheDocument(); + expect(tabLabelElement).toHaveAttribute("href", tab.href); + }); + }); + + test("Should render correctly if props are passed", () => { + render(); + + const iconElement = screen.getAllByTestId("icon-component"); + const externalLink = screen.getAllByTestId("external-link"); + const chevronRight = screen.getAllByTestId("chevron-right"); + + mockTabs.forEach((tab) => { + const tabName = screen.getByText(tab.name); + expect(tabName).toBeInTheDocument(); + + const aTag = screen.getByTestId(`vertical-tab-${tab.name}`); + const tabContainer = tabName.closest("a"); + const infoElement = tabContainer?.querySelector("p[title='info']"); + + expect(chevronRight.length).toEqual(mockTabs.length - 1); + if (tab.disabled) { + expect(aTag).tabToBeDisabled(); + } else { + expect(aTag).not.tabToBeDisabled(); + } + + if (tab.info) { + expect(infoElement).toBeInTheDocument(); + } else { + expect(infoElement).toBeNull(); + } + + if (tab.isExternalLink) { + expect(aTag).toHaveAttribute("target", "_blank"); + } else { + expect(aTag).toHaveAttribute("target", "_self"); + } + }); + + expect(externalLink.length).toEqual(1); + expect(iconElement.length).toEqual(1); + }); + }); +}); diff --git a/packages/ui/components/test-setup.ts b/packages/ui/components/test-setup.ts index 2292a27d45..e32ae4d704 100644 --- a/packages/ui/components/test-setup.ts +++ b/packages/ui/components/test-setup.ts @@ -44,6 +44,16 @@ vi.mock("@calcom/lib/OgImages", async () => { return {}; }); +expect.extend({ + tabToBeDisabled(received) { + const isDisabled = received.classList.contains("pointer-events-none"); + return { + pass: isDisabled, + message: () => `Expected tab to be disabled`, + }; + }, +}); + global.ResizeObserver = vi.fn().mockImplementation(() => ({ observe: vi.fn(), unobserve: vi.fn(),