From 8a6ac5e3467fbf659691d03a739689b8e97061d4 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Wed, 3 Sep 2025 13:46:17 -0600 Subject: [PATCH] Add more unit testing --- tests/unit/Button.test.jsx | 202 ++++++++++++++++++----------- tests/unit/Logo.test.jsx | 128 +++++++++++++++++++ tests/unit/NumberedCard.test.jsx | 206 ++++++++++++++++++++++++++++++ tests/unit/RuleCard.test.jsx | 147 +++++++++++++++++++++ tests/unit/SectionHeader.test.jsx | 198 ++++++++++++++++++++++++++++ 5 files changed, 804 insertions(+), 77 deletions(-) create mode 100644 tests/unit/Logo.test.jsx create mode 100644 tests/unit/NumberedCard.test.jsx create mode 100644 tests/unit/RuleCard.test.jsx create mode 100644 tests/unit/SectionHeader.test.jsx diff --git a/tests/unit/Button.test.jsx b/tests/unit/Button.test.jsx index 5dadb81..27b2d08 100644 --- a/tests/unit/Button.test.jsx +++ b/tests/unit/Button.test.jsx @@ -1,112 +1,160 @@ -import { render, screen, cleanup } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { vi, describe, test, expect, afterEach } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; import Button from "../../app/components/Button"; -afterEach(() => { - cleanup(); -}); - describe("Button Component", () => { - test("renders button with children", () => { + it("renders button with default props", () => { render(); - const button = screen.getByRole("button", { name: "Click me" }); + + const button = screen.getByRole("button", { name: /click me/i }); expect(button).toBeInTheDocument(); + expect(button).toHaveClass("bg-[var(--color-surface-inverse-primary)]"); + expect(button).toHaveAttribute("type", "button"); }); - test("handles click events", async () => { - const user = userEvent.setup(); - const onClick = vi.fn(); - render(); + it("renders with custom className", () => { + const customClass = "custom-button-class"; + render(); - const button = screen.getByRole("button", { name: "Click me" }); - await user.click(button); - expect(onClick).toHaveBeenCalledTimes(1); + const button = screen.getByRole("button"); + expect(button).toHaveClass(customClass); }); - test("renders as link when href is provided", () => { - render(); - const link = screen.getByRole("link", { name: "Link Button" }); - expect(link).toBeInTheDocument(); - expect(link).toHaveAttribute("href", "/test"); + it("applies variant classes correctly", () => { + const { rerender } = render(); + let button = screen.getByRole("button"); + expect(button).toHaveClass("bg-transparent"); + + rerender(); + button = screen.getByRole("button"); + expect(button).toHaveClass("bg-[var(--color-surface-default-primary)]"); + + rerender(); + button = screen.getByRole("button"); + expect(button).toHaveClass("bg-transparent", "border-[1.5px]"); }); - test("applies different variants", () => { - const { rerender } = render(); - let button = screen.getByRole("button", { name: "Default" }); - expect(button.className).toContain( - "bg-[var(--color-surface-inverse-primary)]", - ); - - rerender(); - button = screen.getByRole("button", { name: "Secondary" }); - expect(button.className).toContain("bg-transparent"); - }); - - test("applies different sizes", () => { - const { rerender } = render(); - let button = screen.getByRole("button", { name: "Small" }); - expect(button.className).toContain("px-[var(--spacing-scale-006)]"); + it("applies size classes correctly", () => { + const { rerender } = render(); + let button = screen.getByRole("button"); + expect(button).toHaveClass("px-[var(--spacing-measures-spacing-008)]"); rerender(); - button = screen.getByRole("button", { name: "Large" }); - expect(button.className).toContain("px-[var(--spacing-scale-012)]"); + button = screen.getByRole("button"); + expect(button).toHaveClass("px-[var(--spacing-scale-012)]"); + + rerender(); + button = screen.getByRole("button"); + expect(button).toHaveClass("px-[var(--spacing-scale-020)]"); }); - test("handles disabled state", () => { - render(); - const button = screen.getByRole("button", { name: "Disabled" }); + it("renders as link when href is provided", () => { + const href = "/test-page"; + render(); + + const link = screen.getByRole("link", { name: /link button/i }); + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute("href", href); + }); + + it("renders as button when href is not provided", () => { + render(); + + expect(screen.queryByRole("link")).not.toBeInTheDocument(); + expect(screen.getByRole("button")).toBeInTheDocument(); + }); + + it("handles click events", () => { + const handleClick = vi.fn(); + render(); + + const button = screen.getByRole("button"); + fireEvent.click(button); + + expect(handleClick).toHaveBeenCalledTimes(1); + }); + + it("applies disabled state correctly", () => { + render(); + + const button = screen.getByRole("button"); expect(button).toBeDisabled(); + expect(button).toHaveClass( + "disabled:opacity-50", + "disabled:cursor-not-allowed" + ); expect(button).toHaveAttribute("aria-disabled", "true"); - expect(button).toHaveAttribute("tabindex", "-1"); + expect(button).toHaveAttribute("tabIndex", "-1"); }); - test("applies custom className", () => { - render(); - const button = screen.getByRole("button", { name: "Custom" }); - expect(button.className).toContain("custom-class"); - }); + it("applies proper accessibility attributes", () => { + render(); - test("applies aria-label for accessibility", () => { - render(); - const button = screen.getByRole("button", { name: "Custom label" }); + const button = screen.getByRole("button", { name: /custom label/i }); expect(button).toHaveAttribute("aria-label", "Custom label"); }); - test("renders with design tokens", () => { - render(); - const button = screen.getByRole("button", { name: "Token Test" }); + it("applies hover effects correctly", () => { + render(); - // Check that design tokens are applied - expect(button.className).toContain( - "rounded-[var(--radius-measures-radius-full)]", - ); - expect(button.className).toContain( - "bg-[var(--color-surface-inverse-primary)]", - ); + const button = screen.getByRole("button"); + expect(button).toHaveClass("hover:scale-[1.02]", "transition-all"); }); - test("handles keyboard navigation", async () => { - const user = userEvent.setup(); - const onClick = vi.fn(); - render(); + it("applies focus styles correctly", () => { + render(); - const button = screen.getByRole("button", { name: "Keyboard" }); - button.focus(); - expect(button).toHaveFocus(); - - await user.keyboard("{Enter}"); - expect(onClick).toHaveBeenCalledTimes(1); + const button = screen.getByRole("button"); + expect(button).toHaveClass("focus:outline-none", "focus:ring-1"); }); - test("does not render as link when disabled and href provided", () => { + it("applies active styles correctly", () => { + render(); + + const button = screen.getByRole("button"); + expect(button).toHaveClass("active:scale-[0.98]"); + }); + + it("handles target and rel props for links", () => { render( - , + ); - const button = screen.getByRole("button", { name: "Disabled Link" }); + + const link = screen.getByRole("link"); + expect(link).toHaveAttribute("target", "_blank"); + expect(link).toHaveAttribute("rel", "noopener"); + }); + + it("forwards additional props", () => { + render(); + + const button = screen.getByTestId("test-button"); expect(button).toBeInTheDocument(); - expect(button).toBeDisabled(); + }); + + it("applies proper font styles for different sizes", () => { + const { rerender } = render(); + let button = screen.getByRole("button"); + expect(button).toHaveClass("text-[10px]", "leading-[12px]"); + + rerender(); + button = screen.getByRole("button"); + expect(button).toHaveClass("text-[24px]", "leading-[28px]"); + }); + + it("applies proper border radius", () => { + render(); + + const button = screen.getByRole("button"); + expect(button).toHaveClass("rounded-[var(--radius-measures-radius-full)]"); + }); + + it("maintains proper tab index when not disabled", () => { + render(); + + const button = screen.getByRole("button"); + expect(button).toHaveAttribute("tabIndex", "0"); }); }); diff --git a/tests/unit/Logo.test.jsx b/tests/unit/Logo.test.jsx new file mode 100644 index 0000000..4d31d89 --- /dev/null +++ b/tests/unit/Logo.test.jsx @@ -0,0 +1,128 @@ +import { render, screen } from "@testing-library/react"; +import { describe, it, expect } from "vitest"; +import Logo from "../../app/components/Logo"; + +describe("Logo Component", () => { + it("renders the logo with default props", () => { + render(); + + const logo = screen.getByRole("link", { name: /communityrule logo/i }); + expect(logo).toBeInTheDocument(); + expect(screen.getByText("CommunityRule")).toBeInTheDocument(); + expect(screen.getByAltText("CommunityRule Logo Icon")).toBeInTheDocument(); + }); + + it("renders with custom size variant", () => { + const { rerender } = render(); + let logo = screen.getByRole("link"); + expect(logo).toHaveClass("h-[20.85px]"); + + rerender(); + logo = screen.getByRole("link"); + expect(logo).toHaveClass("h-[28px]"); + + rerender(); + logo = screen.getByRole("link"); + expect(logo).toHaveClass("h-[calc(40px*1.37)]"); + }); + + it("renders without text when showText is false", () => { + render(); + + expect(screen.queryByText("CommunityRule")).not.toBeInTheDocument(); + expect(screen.getByAltText("CommunityRule Logo Icon")).toBeInTheDocument(); + }); + + it("applies proper hover effects", () => { + render(); + + const logo = screen.getByRole("link"); + expect(logo).toHaveClass("hover:scale-[1.02]", "transition-all"); + }); + + it("applies proper accessibility attributes", () => { + render(); + + const logo = screen.getByRole("link"); + expect(logo).toHaveAttribute("aria-label", "CommunityRule Logo"); + expect(logo).toHaveAttribute("role", "link"); + }); + + it("applies proper text styling for different sizes", () => { + const { rerender } = render(); + let textElement = screen.getByText("CommunityRule"); + expect(textElement).toHaveClass( + "text-[var(--color-content-inverse-primary)]" + ); + + rerender(); + textElement = screen.getByText("CommunityRule"); + expect(textElement).toHaveClass( + "text-[var(--color-content-default-primary)]" + ); + }); + + it("applies proper icon sizing for different variants", () => { + const { rerender } = render(); + let icon = screen.getByAltText("CommunityRule Logo Icon"); + expect(icon).toHaveClass("w-[14.39px]", "h-[14.39px]"); + + rerender(); + icon = screen.getByAltText("CommunityRule Logo Icon"); + expect(icon).toHaveClass("w-[33.81px]", "h-[33.81px]"); + }); + + it("applies brightness filter for home header variants", () => { + render(); + + const icon = screen.getByAltText("CommunityRule Logo Icon"); + expect(icon).toHaveClass("filter", "brightness-0"); + }); + + it("maintains proper spacing when text is hidden", () => { + render(); + + const logo = screen.getByRole("link"); + // Should not have gap class when text is hidden + expect(logo.className).not.toContain("gap-[8.28px]"); + }); + + it("applies proper font classes to text", () => { + render(); + + const textElement = screen.getByText("CommunityRule"); + expect(textElement).toHaveClass("font-bricolage-grotesque", "font-normal"); + }); + + it("applies proper icon attributes", () => { + render(); + + const icon = screen.getByAltText("CommunityRule Logo Icon"); + expect(icon).toHaveAttribute("src", "assets/Logo.svg"); + expect(icon).toHaveAttribute("aria-hidden", "true"); + }); + + it("handles all size variants correctly", () => { + const sizes = [ + "default", + "homeHeaderXsmall", + "homeHeaderSm", + "homeHeaderMd", + "homeHeaderLg", + "homeHeaderXl", + "header", + "headerMd", + "headerLg", + "headerXl", + "footer", + "footerLg", + ]; + + sizes.forEach((size) => { + const { unmount } = render(); + const logo = screen.getByRole("link"); + expect(logo).toBeInTheDocument(); + unmount(); + }); + }); +}); diff --git a/tests/unit/NumberedCard.test.jsx b/tests/unit/NumberedCard.test.jsx new file mode 100644 index 0000000..9d1dd9b --- /dev/null +++ b/tests/unit/NumberedCard.test.jsx @@ -0,0 +1,206 @@ +import { render, screen } from "@testing-library/react"; +import { describe, it, expect } from "vitest"; +import NumberedCard from "../../app/components/NumberedCard"; + +describe("NumberedCard Component", () => { + const defaultProps = { + number: 1, + text: "Test Card Text", + }; + + it("renders numbered card with all required information", () => { + render(); + + expect(screen.getByText("1")).toBeInTheDocument(); + expect(screen.getByText("Test Card Text")).toBeInTheDocument(); + }); + + it("renders with different numbers", () => { + const { rerender } = render(); + expect(screen.getByText("42")).toBeInTheDocument(); + + rerender(); + expect(screen.getByText("999")).toBeInTheDocument(); + }); + + it("renders with different text content", () => { + const { rerender } = render( + + ); + expect(screen.getByText("Different Text")).toBeInTheDocument(); + + rerender(); + expect(screen.getByText("Another Text")).toBeInTheDocument(); + }); + + it("applies proper responsive layout classes", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("flex", "flex-col", "sm:flex-row", "lg:flex-row"); + }); + + it("applies proper responsive spacing", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("p-5", "sm:p-8", "lg:p-8"); + }); + + it("applies proper responsive gap", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("gap-4", "sm:gap-8", "lg:gap-0"); + }); + + it("applies proper responsive height", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("lg:h-[238px]"); + }); + + it("applies proper background and shadow", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass( + "bg-[var(--color-surface-inverse-primary)]", + "shadow-lg" + ); + }); + + it("applies proper border radius", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("rounded-[12px]"); + }); + + it("renders section number in correct position", () => { + render(); + + const numberElement = screen.getByText("1"); + expect(numberElement).toBeInTheDocument(); + + // Check that it's in a container with proper positioning + const numberContainer = numberElement.closest("div"); + expect(numberContainer).toHaveClass( + "absolute", + "inset-0", + "flex", + "items-center", + "justify-center" + ); + }); + + it("renders text content in correct position", () => { + render(); + + const textElement = screen.getByText("Test Card Text"); + expect(textElement).toBeInTheDocument(); + + // Check that it's in a container with proper positioning + const textContainer = textElement.closest("div"); + expect(textContainer).toHaveClass( + "sm:flex-1", + "lg:absolute", + "lg:bottom-8", + "lg:left-8", + "lg:right-16" + ); + }); + + it("applies proper font classes to text", () => { + render(); + + const textElement = screen.getByText("Test Card Text"); + expect(textElement).toHaveClass("font-bricolage-grotesque"); + }); + + it("applies proper text sizing", () => { + render(); + + const textElement = screen.getByText("Test Card Text"); + expect(textElement).toHaveClass( + "text-[24px]", + "sm:text-[24px]", + "lg:text-[24px]", + "xl:text-[32px]" + ); + }); + + it("applies proper text color", () => { + render(); + + const textElement = screen.getByText("Test Card Text"); + expect(textElement).toHaveClass("text-[#141414]"); + }); + + it("handles long text content gracefully", () => { + const longText = + "This is a very long text that should wrap properly and not break the layout of the numbered card component"; + render(); + + expect(screen.getByText(longText)).toBeInTheDocument(); + }); + + it("maintains proper responsive behavior", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + + // Mobile first approach + expect(card).toHaveClass("flex-col", "gap-4", "p-5"); + + // Small breakpoint + expect(card).toHaveClass( + "sm:flex-row", + "sm:gap-8", + "sm:p-8", + "sm:items-center" + ); + + // Large breakpoint + expect(card).toHaveClass( + "lg:flex-row", + "lg:gap-0", + "lg:p-8", + "lg:items-stretch", + "lg:relative" + ); + }); + + it("renders with proper flex layout", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("flex"); + }); + + it("applies proper items alignment", () => { + render(); + + const card = screen + .getByText("Test Card Text") + .closest("div").parentElement; + expect(card).toHaveClass("sm:items-center", "lg:items-stretch"); + }); +}); diff --git a/tests/unit/RuleCard.test.jsx b/tests/unit/RuleCard.test.jsx new file mode 100644 index 0000000..7a19e4a --- /dev/null +++ b/tests/unit/RuleCard.test.jsx @@ -0,0 +1,147 @@ +import { render, screen, fireEvent } from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; +import RuleCard from "../../app/components/RuleCard"; + +describe("RuleCard Component", () => { + const defaultProps = { + title: "Test Rule", + description: "This is a test rule description", + }; + + it("renders rule card with all required information", () => { + render(); + + expect(screen.getByText("Test Rule")).toBeInTheDocument(); + expect( + screen.getByText("This is a test rule description") + ).toBeInTheDocument(); + }); + + it("renders with custom className", () => { + const customClass = "custom-rule-card"; + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass(customClass); + }); + + it("applies default background color", () => { + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass("bg-[var(--color-community-teal-100)]"); + }); + + it("applies custom background color", () => { + const customBg = "bg-blue-100"; + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass(customBg); + }); + + it("renders with icon when provided", () => { + const Icon = () => 🚀; + render(} />); + + expect(screen.getByTestId("icon")).toBeInTheDocument(); + }); + + it("handles click events", () => { + const handleClick = vi.fn(); + render(); + + const card = screen.getByRole("button"); + fireEvent.click(card); + + expect(handleClick).toHaveBeenCalledTimes(1); + }); + + it("handles keyboard events", () => { + const handleClick = vi.fn(); + render(); + + const card = screen.getByRole("button"); + + // Test Enter key + fireEvent.keyDown(card, { key: "Enter" }); + expect(handleClick).toHaveBeenCalledTimes(1); + + // Test Space key + fireEvent.keyDown(card, { key: " " }); + expect(handleClick).toHaveBeenCalledTimes(2); + }); + + it("applies hover effects correctly", () => { + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass( + "hover:shadow-xl", + "hover:scale-[1.02]", + "transition-all" + ); + }); + + it("renders with proper accessibility attributes", () => { + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveAttribute( + "aria-label", + "Learn more about Test Rule governance pattern" + ); + expect(card).toHaveAttribute("tabIndex", "0"); + }); + + it("handles empty description gracefully", () => { + render(); + + expect(screen.getByText("Test Rule")).toBeInTheDocument(); + expect( + screen.queryByText("This is a test rule description") + ).not.toBeInTheDocument(); + }); + + it("applies proper responsive sizing", () => { + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass("md:h-[210px]", "lg:h-[277px]"); + }); + + it("applies focus styles correctly", () => { + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass("focus:outline-none", "focus:ring-2"); + }); + + it("renders without icon when not provided", () => { + render(); + + expect(screen.queryByTestId("icon")).not.toBeInTheDocument(); + }); + + it("applies proper border and shadow classes", () => { + render(); + + const card = screen.getByRole("button"); + expect(card).toHaveClass("shadow-lg", "backdrop-blur-sm"); + }); + + it("maintains proper heading structure", () => { + render(); + + const heading = screen.getByRole("heading", { level: 3 }); + expect(heading).toHaveTextContent("Test Rule"); + expect(heading.tagName).toBe("H3"); + }); + + it("applies proper font classes", () => { + render(); + + const heading = screen.getByRole("heading", { level: 3 }); + expect(heading).toHaveClass("font-space-grotesk", "font-bold"); + }); +}); diff --git a/tests/unit/SectionHeader.test.jsx b/tests/unit/SectionHeader.test.jsx new file mode 100644 index 0000000..e381d76 --- /dev/null +++ b/tests/unit/SectionHeader.test.jsx @@ -0,0 +1,198 @@ +import { render, screen } from "@testing-library/react"; +import { describe, it, expect } from "vitest"; +import SectionHeader from "../../app/components/SectionHeader"; + +describe("SectionHeader Component", () => { + it("renders section header with title", () => { + render(); + + expect(screen.getByRole("heading", { level: 2 })).toBeInTheDocument(); + // Check for both mobile and desktop versions of the title + expect(screen.getAllByText("Test Section")).toHaveLength(2); + }); + + it("renders with subtitle when provided", () => { + const subtitle = "This is a test subtitle"; + render(); + + expect(screen.getByText(subtitle)).toBeInTheDocument(); + }); + + it("renders with titleLg when provided", () => { + const titleLg = "Large Title for Desktop"; + render(); + + // Check for mobile title and desktop titleLg + expect(screen.getByText("Test Section")).toBeInTheDocument(); + expect(screen.getByText(titleLg)).toBeInTheDocument(); + }); + + it("applies variant classes correctly", () => { + const { rerender } = render( + + ); + let titleContainer = screen + .getByRole("heading", { level: 2 }) + .closest("div"); + expect(titleContainer).toHaveClass( + "lg:w-[369px]", + "lg:h-[var(--spacing-scale-120)]" + ); + + rerender(); + titleContainer = screen.getByRole("heading", { level: 2 }).closest("div"); + expect(titleContainer).toHaveClass( + "lg:w-[50%]", + "lg:h-[var(--spacing-scale-120)]" + ); + }); + + it("renders responsive title spans", () => { + render(); + + const mobileTitle = screen.getByText("Test Section", { + selector: "span.block.lg\\:hidden", + }); + const desktopTitle = screen.getByText("Test Section", { + selector: "span.hidden.lg\\:block", + }); + + expect(mobileTitle).toBeInTheDocument(); + expect(desktopTitle).toBeInTheDocument(); + }); + + it("uses titleLg for desktop when provided", () => { + const titleLg = "Desktop Title"; + render(); + + const mobileTitle = screen.getByText("Mobile Title", { + selector: "span.block.lg\\:hidden", + }); + const desktopTitle = screen.getByText("Desktop Title", { + selector: "span.hidden.lg\\:block", + }); + + expect(mobileTitle).toBeInTheDocument(); + expect(desktopTitle).toBeInTheDocument(); + }); + + it("falls back to title for desktop when titleLg not provided", () => { + render(); + + const mobileTitle = screen.getByText("Test Section", { + selector: "span.block.lg\\:hidden", + }); + const desktopTitle = screen.getByText("Test Section", { + selector: "span.hidden.lg\\:block", + }); + + expect(mobileTitle).toBeInTheDocument(); + expect(desktopTitle).toBeInTheDocument(); + }); + + it("applies proper responsive layout classes", () => { + render(); + + const container = screen + .getByRole("heading", { level: 2 }) + .closest("div").parentElement; + expect(container).toHaveClass( + "flex", + "flex-col", + "lg:flex-row", + "lg:justify-between" + ); + }); + + it("handles empty subtitle gracefully", () => { + render(); + + expect(screen.getByRole("heading", { level: 2 })).toBeInTheDocument(); + // Empty subtitle should not cause issues - check that the paragraph element exists + const subtitleContainer = screen + .getByRole("heading", { level: 2 }) + .closest("div") + .parentElement.querySelector("p"); + expect(subtitleContainer).toBeInTheDocument(); + }); + + it("maintains proper heading structure", () => { + render(); + + const heading = screen.getByRole("heading", { level: 2 }); + expect(heading).toHaveTextContent("Test Section"); + expect(heading.tagName).toBe("H2"); + }); + + it("applies proper font classes", () => { + render(); + + const heading = screen.getByRole("heading", { level: 2 }); + expect(heading).toHaveClass("font-bricolage-grotesque", "font-bold"); + }); + + it("applies proper text sizing", () => { + render(); + + const heading = screen.getByRole("heading", { level: 2 }); + expect(heading).toHaveClass( + "text-[28px]", + "sm:text-[32px]", + "lg:text-[32px]", + "xl:text-[40px]" + ); + }); + + it("applies proper line heights", () => { + render(); + + const heading = screen.getByRole("heading", { level: 2 }); + expect(heading).toHaveClass( + "leading-[36px]", + "sm:leading-[40px]", + "lg:leading-[40px]", + "xl:leading-[52px]" + ); + }); + + it("applies proper text colors", () => { + render(); + + const heading = screen.getByRole("heading", { level: 2 }); + expect(heading).toHaveClass("text-[var(--color-content-default-primary)]"); + }); + + it("applies proper subtitle styling", () => { + const subtitle = "Test Subtitle"; + render(); + + const subtitleElement = screen.getByText(subtitle); + expect(subtitleElement).toHaveClass("font-inter", "font-normal"); + }); + + it("applies proper subtitle text sizing", () => { + const subtitle = "Test Subtitle"; + render(); + + const subtitleElement = screen.getByText(subtitle); + expect(subtitleElement).toHaveClass( + "text-[18px]", + "sm:text-[18px]", + "lg:text-[24px]", + "xl:text-[32px]" + ); + }); + + it("applies proper subtitle colors", () => { + const subtitle = "Test Subtitle"; + render(); + + const subtitleElement = screen.getByText(subtitle); + expect(subtitleElement).toHaveClass( + "text-[#484848]", + "sm:text-[var(--color-content-default-tertiary)]", + "lg:text-[var(--color-content-default-tertiary)]", + "xl:text-[var(--color-content-default-tertiary)]" + ); + }); +});