Files
community-rule/tests/components/FeatureGrid.test.tsx
T
adilallo ca928e306b Match the 3 Nov color ramps and size-based strokes, and replace leftover palette hex with tokens.
Drop Cookies Settings from the footer, link the Home features that already have pages, and give leftover routes their own descriptions.
2026-11-05 15:37:55 -07:00

149 lines
5.1 KiB
TypeScript

import React from "react";
import { renderWithProviders as render, screen } from "../utils/test-utils";
import { describe, it, expect } from "vitest";
import FeatureGrid from "../../app/components/sections/FeatureGrid";
import {
componentTestSuite,
ComponentTestSuiteConfig,
} from "../utils/componentTestSuite";
type FeatureGridProps = React.ComponentProps<typeof FeatureGrid>;
const baseProps: FeatureGridProps = {
title: "Feature Tools",
subtitle: "Everything you need",
};
const config: ComponentTestSuiteConfig<FeatureGridProps> = {
component: FeatureGrid,
name: "FeatureGrid",
props: baseProps,
optionalProps: {
className: "custom-class",
title: undefined,
subtitle: undefined,
},
primaryRole: "region",
testCases: {
renders: true,
accessibility: true,
keyboardNavigation: false,
disabledState: false,
errorState: false,
},
};
componentTestSuite<FeatureGridProps>(config);
describe("FeatureGrid (behavioral tests)", () => {
it("renders title and subtitle", () => {
render(<FeatureGrid title="Test Title" subtitle="Test Subtitle" />);
const title = screen.getByRole("heading", { name: "Test Title" });
expect(title).toBeInTheDocument();
expect(title.tagName).toBe("H2");
expect(screen.getByText("Test Subtitle")).toBeInTheDocument();
expect(
screen.queryByRole("heading", { name: "Test Subtitle" }),
).not.toBeInTheDocument();
});
it("links the two features that have pages and leaves the others as tiles", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
expect(screen.getByText("Choose how you decide")).toBeInTheDocument();
expect(screen.getByText("Plan for conflict")).toBeInTheDocument();
expect(
screen.queryByRole("link", { name: /Choose how you decide/ }),
).not.toBeInTheDocument();
expect(
screen.queryByRole("link", { name: /Plan for conflict/ }),
).not.toBeInTheDocument();
expect(
screen.getByRole("link", { name: /Name your values/ }),
).toHaveAttribute("href", "/how-it-works");
expect(
screen.getByRole("link", { name: /Define membership/ }),
).toHaveAttribute(
"href",
"/blog/integrating-new-members-without-dilution",
);
});
it("sends Explore the patterns to the templates page", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
expect(
screen.getByRole("link", { name: "Explore the patterns" }),
).toHaveAttribute("href", "/templates");
});
it("does not apply a focus ring to the entire grid shell", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
const shell = document.querySelector('[data-figma-node="18632-10668"]');
expect(shell?.className).not.toContain("focus-within:ring-2");
});
it("has proper accessibility attributes", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
const section = document.querySelector("section");
expect(section).toHaveAttribute("aria-labelledby", "feature-grid-headline");
});
it("handles missing props gracefully", () => {
render(<FeatureGrid />);
const section = document.querySelector("section");
expect(section).toBeInTheDocument();
});
it("uses Figma invert surface colors on feature cards", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
expect(
document.querySelector(
'[class*="bg-[var(--color-surface-invert-brand-lavender)]"]',
),
).toBeInTheDocument();
expect(
document.querySelector(
'[class*="bg-[var(--color-surface-invert-brand-lime)]"]',
),
).toBeInTheDocument();
expect(
document.querySelector(
'[class*="bg-[var(--color-surface-invert-brand-rust)]"]',
),
).toBeInTheDocument();
expect(
document.querySelector(
'[class*="bg-[var(--color-surface-invert-brand-teal)]"]',
),
).toBeInTheDocument();
});
it("marks the content block with the Figma node id", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
expect(
document.querySelector('[data-figma-node="18632-10668"]'),
).toBeInTheDocument();
});
it("uses Figma responsive typography on the feature lockup", () => {
render(<FeatureGrid title="Test Title" subtitle="Test Subtitle" />);
const title = screen.getByRole("heading", { name: "Test Title" });
expect(title.className).toMatch(/text-\[18px\]/);
expect(title.className).toMatch(/md:text-\[length:var\(--sizing-600\)\]/);
const subtitle = screen.getByText("Test Subtitle");
expect(subtitle.tagName).toBe("P");
expect(subtitle).toHaveClass("text-small-paragraph", "md:text-medium-paragraph");
});
it("renders 40px decorative icons from Figma", () => {
render(<FeatureGrid title="Test" subtitle="Test" />);
const icons = document.querySelectorAll("section img");
expect(icons.length).toBe(4);
icons.forEach((icon) => {
expect(icon).toHaveAttribute("width", "40");
expect(icon).toHaveAttribute("height", "40");
expect(icon).toHaveAttribute("alt", "");
expect(icon.getAttribute("src")).toMatch(/^\/assets\/icons\/icon-/);
});
});
});