import { render, screen, cleanup } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { vi, describe, test, expect, afterEach } from "vitest"; import Page from "../../app/page"; import Header from "../../app/components/Header"; import Footer from "../../app/components/Footer"; afterEach(() => { cleanup(); }); describe("User Journey Integration", () => { test("new user discovers the application through hero section", async () => { const user = userEvent.setup(); render(
); // User sees the main value proposition expect( screen.getByText(/Help your community make important decisions/) ).toBeInTheDocument(); // User clicks the main CTA to learn more const learnButtons = screen.getAllByRole("button", { name: "Learn how CommunityRule works", }); const learnButton = learnButtons[0]; await user.click(learnButton); // User should see the "How it works" section expect(screen.getByText("How CommunityRule works")).toBeInTheDocument(); }); test("user explores different governance types", async () => { const user = userEvent.setup(); render(); // User sees all four governance options expect(screen.getByText("Consensus clusters")).toBeInTheDocument(); expect(screen.getByText("Elected Board")).toBeInTheDocument(); expect(screen.getByText("Consensus")).toBeInTheDocument(); expect(screen.getByText("Petition")).toBeInTheDocument(); // User clicks on a governance type to create a rule const createButtons = screen.getAllByRole("button", { name: "Create CommunityRule", }); expect(createButtons.length).toBeGreaterThan(0); await user.click(createButtons[0]); // Button should remain interactive expect(createButtons[0]).toBeInTheDocument(); }); test("user navigates through the application using header navigation", async () => { const user = userEvent.setup(); render(
); // User clicks on navigation links in header (check that they exist and are clickable) const navigationLinks = screen.getAllByRole("link"); const headerNavLinks = navigationLinks.filter( (link) => link.textContent?.includes("Use Cases") || link.textContent?.includes("Learn") || link.textContent?.includes("About") ); // Test that navigation links are present and clickable for (const link of headerNavLinks) { await user.click(link); expect(link).toBeInTheDocument(); } }); test("user seeks help through ask organizer section", async () => { const user = userEvent.setup(); render(); // User scrolls to the bottom and sees the help section expect(screen.getByText("Still have questions?")).toBeInTheDocument(); expect( screen.getByText("Get answers from an experienced organizer") ).toBeInTheDocument(); // User clicks the ask organizer button (it's actually a link, not a button) const askLink = screen.getByRole("link", { name: /Ask an organizer/i }); await user.click(askLink); expect(askLink).toHaveAttribute("href", "#contact"); }); test("user explores the process through numbered cards", async () => { const user = userEvent.setup(); render(); // User reads through the process steps expect( screen.getByText("Document how your community makes decisions") ).toBeInTheDocument(); expect( screen.getByText("Build an operating manual for a successful community") ).toBeInTheDocument(); expect( screen.getByText( "Get a link to your manual for your group to review and evolve" ) ).toBeInTheDocument(); // User sees the step numbers const stepNumbers = screen.getAllByText(/1|2|3/); expect(stepNumbers.length).toBeGreaterThan(0); }); test("user accesses contact information through footer", async () => { const user = userEvent.setup(); render(
); // User finds contact email in footer const emailLink = screen.getByRole("link", { name: "medlab@colorado.edu" }); expect(emailLink).toHaveAttribute("href", "mailto:medlab@colorado.edu"); // User finds social media links const blueskyLink = screen.getByRole("link", { name: "Follow us on Bluesky", }); const gitlabLink = screen.getByRole("link", { name: "Follow us on GitLab", }); expect(blueskyLink).toBeInTheDocument(); expect(gitlabLink).toBeInTheDocument(); }); test("user explores features and benefits", async () => { const user = userEvent.setup(); render(); // User sees the features section expect( screen.getByText("We've got your back, every step of the way") ).toBeInTheDocument(); expect( screen.getByText( "Use our toolkit to improve, document, and evolve your organization." ) ).toBeInTheDocument(); // User sees the testimonial/quote (check for the actual quote content) expect( screen.getByText(/The rules of decision-making must be open/) ).toBeInTheDocument(); }); test("user interacts with logo wall and social proof", async () => { const user = userEvent.setup(); render(
); // User sees the logo wall with partner logos (check for any logo images) const logoImages = screen.getAllByRole("img"); const partnerLogos = logoImages.filter( (img) => img.alt?.includes("Food Not Bombs") || img.alt?.includes("Start COOP") || img.alt?.includes("Metagov") || img.alt?.includes("Open Civics") || img.alt?.includes("Mutual Aid CO") || img.alt?.includes("CU Boulder") ); expect(partnerLogos.length).toBeGreaterThan(0); // Social links should be present in footer const blueskyLink = screen.getByRole("link", { name: /Bluesky/i }); const gitlabLink = screen.getByRole("link", { name: /GitLab/i }); expect(blueskyLink).toBeInTheDocument(); expect(gitlabLink).toBeInTheDocument(); }); test("user completes the full journey from discovery to action", async () => { const user = userEvent.setup(); render(
); // 1. User discovers the application expect(screen.getByText("Collaborate")).toBeInTheDocument(); expect(screen.getByText("with clarity")).toBeInTheDocument(); // 2. User learns how it works expect(screen.getByText("How CommunityRule works")).toBeInTheDocument(); // 3. User sees governance options expect(screen.getByText("Consensus clusters")).toBeInTheDocument(); // 4. User sees features and benefits expect( screen.getByText("We've got your back, every step of the way") ).toBeInTheDocument(); // 5. User sees social proof expect( screen.getByText(/The rules of decision-making must be open/) ).toBeInTheDocument(); // 6. User can take action const createButtons = screen.getAllByRole("button", { name: "Create CommunityRule", }); expect(createButtons.length).toBeGreaterThan(0); // 7. User can get help if needed expect(screen.getByText("Still have questions?")).toBeInTheDocument(); }); test("user can access all navigation options consistently", async () => { const user = userEvent.setup(); render(
); // Header navigation const headerNav = screen.getByRole("navigation"); expect(headerNav).toBeInTheDocument(); // Footer navigation const footerLinks = screen.getAllByRole("link"); const navigationLinks = footerLinks.filter( (link) => link.textContent?.includes("Use cases") || link.textContent?.includes("Learn") || link.textContent?.includes("About") ); expect(navigationLinks.length).toBeGreaterThan(0); // All navigation links should be accessible navigationLinks.forEach((link) => { expect(link).not.toHaveAttribute("tabindex", "-1"); }); }); test("user can complete actions without errors", async () => { const user = userEvent.setup(); render(
); // Test all interactive elements const buttons = screen.getAllByRole("button"); const links = screen.getAllByRole("link"); // All buttons should be clickable for (const button of buttons) { await user.click(button); expect(button).toBeInTheDocument(); } // All links should be accessible for (const link of links) { expect(link).toBeInTheDocument(); expect(link).not.toHaveAttribute("tabindex", "-1"); } }); });