Puts Workshops in the header, pairs the hero with a static rule card and breakpoint CTAs, and shows the three pilot marks with no wall label. Co-authored-by: Cursor <cursoragent@cursor.com>
299 lines
9.7 KiB
React
299 lines
9.7 KiB
React
import { describe, test, expect } from "vitest";
|
|
import {
|
|
renderWithProviders as render,
|
|
screen,
|
|
waitFor,
|
|
} from "../utils/test-utils";
|
|
import Page from "../../app/(marketing)/page";
|
|
|
|
describe("Page", () => {
|
|
test("renders all main sections", async () => {
|
|
render(<Page />);
|
|
|
|
// Check that all main sections are rendered (using getAllByText since there are multiple instances)
|
|
expect(screen.getAllByText("Build structure").length).toBeGreaterThan(0);
|
|
expect(screen.getAllByText("before you need it").length).toBeGreaterThan(0);
|
|
expect(
|
|
screen.getAllByText(
|
|
"Strong communities agree on four things early. They settle how they talk, who belongs, how they decide and what happens when they disagree. Write yours down together.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
|
|
// Wait for dynamically imported components to load
|
|
// Check CardSteps section (using getAllByText since there are multiple instances)
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("How CommunityRule helps").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(
|
|
screen.getAllByText(
|
|
"Here's a quick overview of the process, from start to finish.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
|
|
// FeatureGrid is next/dynamic — wait like other code-split sections
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("Tools for the parts that get hard")
|
|
.length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(
|
|
screen.getAllByText(
|
|
"Every community runs into the same knots. CommunityRule gives you a way through, and a written record of what you decided.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
|
|
// Check ask organizer section (using getAllByText since there are multiple instances)
|
|
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
|
0,
|
|
);
|
|
expect(
|
|
screen.getAllByText("Get answers from an experienced organizer").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders hero banner with correct data", () => {
|
|
render(<Page />);
|
|
|
|
// Check hero banner content (using getAllByText since there are multiple instances)
|
|
expect(screen.getAllByText("Build structure").length).toBeGreaterThan(0);
|
|
expect(screen.getAllByText("before you need it").length).toBeGreaterThan(0);
|
|
expect(
|
|
screen.getAllByText(
|
|
"Strong communities agree on four things early. They settle how they talk, who belongs, how they decide and what happens when they disagree. Write yours down together.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
expect(
|
|
screen.getAllByText("Talk to a facilitator").length,
|
|
).toBeGreaterThan(0);
|
|
const learnLinks = screen.getAllByRole("link", {
|
|
name: "Talk to a facilitator",
|
|
});
|
|
expect(learnLinks[0]).toHaveAttribute("href", "/workshops");
|
|
});
|
|
|
|
test("renders CardSteps section with correct data", async () => {
|
|
render(<Page />);
|
|
|
|
// Wait for dynamically imported CardSteps component to load
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("How CommunityRule helps").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(
|
|
screen.getAllByText(
|
|
"Here's a quick overview of the process, from start to finish.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
|
|
// Check individual card content (using getAllByText since there are multiple instances)
|
|
expect(
|
|
screen.getAllByText("See what has worked for other communities").length,
|
|
).toBeGreaterThan(0);
|
|
expect(
|
|
screen.getAllByText(
|
|
"Decide how you will decide, while things are calm",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
expect(
|
|
screen.getAllByText(
|
|
"Invite your members and change it together as you grow",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders feature grid with correct data", async () => {
|
|
render(<Page />);
|
|
|
|
// Wait for dynamically imported FeatureGrid component to load
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("Tools for the parts that get hard")
|
|
.length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(
|
|
screen.getAllByText(
|
|
"Every community runs into the same knots. CommunityRule gives you a way through, and a written record of what you decided.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
const learnMore = screen.getAllByRole("link", {
|
|
name: "Explore the patterns",
|
|
});
|
|
expect(learnMore[0]).toHaveAttribute("href", "/learn");
|
|
});
|
|
|
|
test("renders ask organizer section with correct data", () => {
|
|
render(<Page />);
|
|
|
|
// Check ask organizer content (using getAllByText since there are multiple instances)
|
|
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
|
0,
|
|
);
|
|
expect(
|
|
screen.getAllByText("Get answers from an experienced organizer").length,
|
|
).toBeGreaterThan(0);
|
|
expect(screen.getAllByText("Ask an organizer").length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders all component sections", async () => {
|
|
render(<Page />);
|
|
|
|
// Check that all major components are present by looking for their content
|
|
// HeroBanner
|
|
expect(screen.getAllByText("Build structure").length).toBeGreaterThan(0);
|
|
|
|
// Wait for dynamically imported components to load
|
|
// LogoWall - should be present (even if just the component structure)
|
|
// CardSteps
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("How CommunityRule helps").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
// RuleStack - should be present
|
|
// FeatureGrid
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("Tools for the parts that get hard")
|
|
.length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
// QuoteBlock - should be present
|
|
// AskOrganizer
|
|
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
|
0,
|
|
);
|
|
});
|
|
|
|
test("has correct page structure", () => {
|
|
render(<Page />);
|
|
|
|
const mainContainer = screen.getAllByText("Build structure")[0].closest("div");
|
|
expect(mainContainer).toBeInTheDocument();
|
|
});
|
|
|
|
test("renders call-to-action elements", () => {
|
|
render(<Page />);
|
|
|
|
// Check CTA button in hero banner
|
|
expect(
|
|
screen.getAllByText("Talk to a facilitator").length,
|
|
).toBeGreaterThan(0);
|
|
|
|
// Check CTA button in ask organizer section
|
|
expect(screen.getAllByText("Ask an organizer").length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders descriptive text content", async () => {
|
|
render(<Page />);
|
|
|
|
// Check main description (using getAllByText since there are multiple instances)
|
|
expect(
|
|
screen.getAllByText(
|
|
"Strong communities agree on four things early. They settle how they talk, who belongs, how they decide and what happens when they disagree. Write yours down together.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
|
|
// Wait for dynamically imported CardSteps component
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText(
|
|
"Here's a quick overview of the process, from start to finish.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
// Wait for dynamically imported FeatureGrid component
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText(
|
|
"Every community runs into the same knots. CommunityRule gives you a way through, and a written record of what you decided.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
// Check ask organizer description (using getAllByText since there are multiple instances)
|
|
expect(
|
|
screen.getAllByText("Get answers from an experienced organizer").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders section titles correctly", async () => {
|
|
render(<Page />);
|
|
|
|
// Check all section titles (using getAllByText since there are multiple instances)
|
|
expect(screen.getAllByText("Build structure").length).toBeGreaterThan(0);
|
|
|
|
// Wait for dynamically imported components
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("How CommunityRule helps").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText("Tools for the parts that get hard")
|
|
.length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
|
0,
|
|
);
|
|
});
|
|
|
|
test("renders CardSteps step tiles with correct content", async () => {
|
|
render(<Page />);
|
|
|
|
// Wait for dynamically imported CardSteps component
|
|
await waitFor(() => {
|
|
// Three Step tiles inside CardSteps
|
|
expect(
|
|
screen.getAllByText("See what has worked for other communities")
|
|
.length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(
|
|
screen.getAllByText(
|
|
"Decide how you will decide, while things are calm",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
expect(
|
|
screen.getAllByText(
|
|
"Invite your members and change it together as you grow",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("renders subtitle content correctly", async () => {
|
|
render(<Page />);
|
|
|
|
// Check subtitles (using getAllByText since there are multiple instances)
|
|
expect(screen.getAllByText("before you need it").length).toBeGreaterThan(0);
|
|
|
|
// Wait for dynamically imported components
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText(
|
|
"Here's a quick overview of the process, from start to finish.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
await waitFor(() => {
|
|
expect(
|
|
screen.getAllByText(
|
|
"Every community runs into the same knots. CommunityRule gives you a way through, and a written record of what you decided.",
|
|
).length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
expect(
|
|
screen.getAllByText("Get answers from an experienced organizer").length,
|
|
).toBeGreaterThan(0);
|
|
});
|
|
});
|