Fix prettier formatting issues
This commit is contained in:
@@ -60,7 +60,7 @@ test.describe("Accessibility Testing", () => {
|
||||
focusedElements.push(
|
||||
`${elementInfo.tagName}${
|
||||
elementInfo.role ? `[role="${elementInfo.role}"]` : ""
|
||||
}: ${elementInfo.accessibleName}`
|
||||
}: ${elementInfo.accessibleName}`,
|
||||
);
|
||||
|
||||
await page.keyboard.press("Tab");
|
||||
@@ -190,7 +190,7 @@ test.describe("Accessibility Testing", () => {
|
||||
test("focus indicators - visible focus", async ({ page }) => {
|
||||
// Test that focus indicators are visible
|
||||
const focusableElements = page.locator(
|
||||
"button, a, input, textarea, select, [tabindex]"
|
||||
"button, a, input, textarea, select, [tabindex]",
|
||||
);
|
||||
const elementCount = await focusableElements.count();
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ export async function runA11y(page, options = {}) {
|
||||
if (results.violations.length > 0) {
|
||||
console.log("Accessibility violations found:", results.violations);
|
||||
throw new Error(
|
||||
`Found ${results.violations.length} accessibility violations`
|
||||
`Found ${results.violations.length} accessibility violations`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Page should function normally
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -44,7 +44,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
test("handles browser back/forward navigation", async ({ page }) => {
|
||||
// Navigate to a section
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -118,7 +118,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
test("handles page refresh during interactions", async ({ page }) => {
|
||||
// Start an interaction
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -151,7 +151,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
// Interact with each tab - find the first visible button
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -190,7 +190,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
// All tabs should work independently
|
||||
await expect(
|
||||
page.locator('h2:has-text("How CommunityRule works")')
|
||||
page.locator('h2:has-text("How CommunityRule works")'),
|
||||
).toBeVisible();
|
||||
await expect(page1.locator("text=Consensus clusters")).toBeVisible();
|
||||
await expect(page2.locator("text=Still have questions?")).toBeVisible();
|
||||
@@ -249,7 +249,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Page should continue to function
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -264,7 +264,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Page should still function without images
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -298,7 +298,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Page should still function without styles
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -332,7 +332,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Page should still function with fallback fonts
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -366,7 +366,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Clean up
|
||||
setTimeout(() => {
|
||||
const testElements = document.querySelectorAll(
|
||||
'div[textContent*="Test element"]'
|
||||
'div[textContent*="Test element"]',
|
||||
);
|
||||
testElements.forEach((el) => el.remove());
|
||||
}, 100);
|
||||
@@ -395,7 +395,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Page should remain functional
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -410,7 +410,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
// Find visible button for right-click
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -578,7 +578,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
// Content should remain readable
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -593,7 +593,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -610,14 +610,14 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
await page.evaluate(() => {
|
||||
document.documentElement.style.setProperty(
|
||||
"--prefers-reduced-motion",
|
||||
"reduce"
|
||||
"reduce",
|
||||
);
|
||||
});
|
||||
|
||||
// Page should respect reduced motion
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -632,7 +632,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ for (const bp of breakpoints) {
|
||||
}) => {
|
||||
// All breakpoints should have navigation items
|
||||
await expect(
|
||||
page.getByRole("link", { name: /use cases/i })
|
||||
page.getByRole("link", { name: /use cases/i }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: /learn/i })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: /about/i })).toBeVisible();
|
||||
@@ -42,20 +42,20 @@ for (const bp of breakpoints) {
|
||||
test(`footer legal links visibility at ${bp.name}`, async ({ page }) => {
|
||||
// All breakpoints should have legal links
|
||||
await expect(
|
||||
page.getByRole("link", { name: /privacy policy/i })
|
||||
page.getByRole("link", { name: /privacy policy/i }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("link", { name: /terms of service/i })
|
||||
page.getByRole("link", { name: /terms of service/i }),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test(`footer social links visibility at ${bp.name}`, async ({ page }) => {
|
||||
// All breakpoints should have social links
|
||||
await expect(
|
||||
page.getByRole("link", { name: /follow us on bluesky/i })
|
||||
page.getByRole("link", { name: /follow us on bluesky/i }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("link", { name: /follow us on gitlab/i })
|
||||
page.getByRole("link", { name: /follow us on gitlab/i }),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -110,7 +110,7 @@ test.describe("Footer visual regression", () => {
|
||||
|
||||
// Take a screenshot for visual regression testing
|
||||
await expect(page.locator("footer").first()).toHaveScreenshot(
|
||||
`footer-${bp.name}.png`
|
||||
`footer-${bp.name}.png`,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -136,7 +136,7 @@ test.describe("Footer visual regression", () => {
|
||||
await useCasesLink.hover();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("footer").first()).toHaveScreenshot(
|
||||
`footer-${bp.name}-hover-nav.png`
|
||||
`footer-${bp.name}-hover-nav.png`,
|
||||
);
|
||||
|
||||
// Test hover on social links
|
||||
@@ -146,7 +146,7 @@ test.describe("Footer visual regression", () => {
|
||||
await blueskyLink.hover();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("footer").first()).toHaveScreenshot(
|
||||
`footer-${bp.name}-hover-social.png`
|
||||
`footer-${bp.name}-hover-social.png`,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -172,7 +172,7 @@ test.describe("Footer visual regression", () => {
|
||||
await useCasesLink.focus();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("footer").first()).toHaveScreenshot(
|
||||
`footer-${bp.name}-focus-nav.png`
|
||||
`footer-${bp.name}-focus-nav.png`,
|
||||
);
|
||||
|
||||
// Test focus on social links
|
||||
@@ -182,7 +182,7 @@ test.describe("Footer visual regression", () => {
|
||||
await blueskyLink.focus();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("footer").first()).toHaveScreenshot(
|
||||
`footer-${bp.name}-focus-social.png`
|
||||
`footer-${bp.name}-focus-social.png`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ for (const bp of breakpoints) {
|
||||
test(`navigation items visibility at ${bp.name}`, async ({ page }) => {
|
||||
// All breakpoints should have navigation items
|
||||
await expect(
|
||||
page.getByRole("link", { name: /use cases/i })
|
||||
page.getByRole("link", { name: /use cases/i }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: /learn/i })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: /about/i })).toBeVisible();
|
||||
@@ -44,14 +44,14 @@ for (const bp of breakpoints) {
|
||||
}) => {
|
||||
// All breakpoints should have login button
|
||||
await expect(
|
||||
page.getByRole("link", { name: /log in to your account/i })
|
||||
page.getByRole("link", { name: /log in to your account/i }),
|
||||
).toBeVisible();
|
||||
|
||||
// All breakpoints should have create rule button
|
||||
await expect(
|
||||
page.getByRole("button", {
|
||||
name: /create a new rule with avatar decoration/i,
|
||||
})
|
||||
}),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -149,7 +149,7 @@ test.describe("Header visual regression", () => {
|
||||
|
||||
// Take a screenshot for visual regression testing
|
||||
await expect(page.locator("header").first()).toHaveScreenshot(
|
||||
`header-${bp.name}.png`
|
||||
`header-${bp.name}.png`,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -171,7 +171,7 @@ test.describe("Header visual regression", () => {
|
||||
await useCasesLink.hover();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("header").first()).toHaveScreenshot(
|
||||
`header-${bp.name}-hover-nav.png`
|
||||
`header-${bp.name}-hover-nav.png`,
|
||||
);
|
||||
|
||||
// Test hover on create rule button
|
||||
@@ -181,7 +181,7 @@ test.describe("Header visual regression", () => {
|
||||
await createRuleButton.hover();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("header").first()).toHaveScreenshot(
|
||||
`header-${bp.name}-hover-button.png`
|
||||
`header-${bp.name}-hover-button.png`,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -203,7 +203,7 @@ test.describe("Header visual regression", () => {
|
||||
await useCasesLink.focus();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("header").first()).toHaveScreenshot(
|
||||
`header-${bp.name}-focus-nav.png`
|
||||
`header-${bp.name}-focus-nav.png`,
|
||||
);
|
||||
|
||||
// Test focus on create rule button
|
||||
@@ -213,7 +213,7 @@ test.describe("Header visual regression", () => {
|
||||
await createRuleButton.focus();
|
||||
await page.waitForTimeout(200);
|
||||
await expect(page.locator("header").first()).toHaveScreenshot(
|
||||
`header-${bp.name}-focus-button.png`
|
||||
`header-${bp.name}-focus-button.png`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Locator, Page } from "@playwright/test";
|
||||
|
||||
export async function findVisibleButton(
|
||||
page: Page,
|
||||
text: string
|
||||
text: string,
|
||||
): Promise<Locator> {
|
||||
const buttons = page.locator(`button:has-text("${text}")`);
|
||||
const buttonCount = await buttons.count();
|
||||
@@ -19,7 +19,7 @@ export async function findVisibleButton(
|
||||
|
||||
export async function findVisibleElement(
|
||||
page: Page,
|
||||
selector: string
|
||||
selector: string,
|
||||
): Promise<Locator> {
|
||||
const elements = page.locator(selector);
|
||||
const elementCount = await elements.count();
|
||||
|
||||
+37
-37
@@ -12,19 +12,19 @@ test.describe("Homepage", () => {
|
||||
|
||||
// Check main sections are present
|
||||
await expect(
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" })
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("h2").filter({ hasText: "How CommunityRule works" })
|
||||
page.locator("h2").filter({ hasText: "How CommunityRule works" }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("h1").filter({ hasText: "We've got your back" })
|
||||
page.locator("h1").filter({ hasText: "We've got your back" }),
|
||||
).toBeVisible();
|
||||
|
||||
// Check key components are rendered
|
||||
await expect(page.locator('img[alt="Hero illustration"]')).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Trusted by leading cooperators")
|
||||
page.locator("text=Trusted by leading cooperators"),
|
||||
).toBeVisible();
|
||||
await expect(page.locator("text=Jo Freeman")).toBeVisible();
|
||||
});
|
||||
@@ -34,12 +34,12 @@ test.describe("Homepage", () => {
|
||||
await expect(page.locator("text=Collaborate")).toBeVisible();
|
||||
await expect(page.locator("text=with clarity")).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Help your community make important decisions")
|
||||
page.locator("text=Help your community make important decisions"),
|
||||
).toBeVisible();
|
||||
|
||||
// Check CTA button
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -54,7 +54,7 @@ test.describe("Homepage", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,14 +64,14 @@ test.describe("Homepage", () => {
|
||||
await visibleButton.click();
|
||||
// Should scroll to the numbered cards section
|
||||
await expect(
|
||||
page.locator('h2:has-text("How CommunityRule works")')
|
||||
page.locator('h2:has-text("How CommunityRule works")'),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("logo wall section displays correctly", async ({ page }) => {
|
||||
// Check section label
|
||||
await expect(
|
||||
page.locator("text=Trusted by leading cooperators")
|
||||
page.locator("text=Trusted by leading cooperators"),
|
||||
).toBeVisible();
|
||||
|
||||
// Check logos are present
|
||||
@@ -95,23 +95,23 @@ test.describe("Homepage", () => {
|
||||
test("numbered cards section functionality", async ({ page }) => {
|
||||
// Check section header
|
||||
await expect(
|
||||
page.locator('h2:has-text("How CommunityRule works")')
|
||||
page.locator('h2:has-text("How CommunityRule works")'),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Here's a quick overview of the process")
|
||||
page.locator("text=Here's a quick overview of the process"),
|
||||
).toBeVisible();
|
||||
|
||||
// Check all three cards are present
|
||||
await expect(
|
||||
page.locator("text=Document how your community makes decisions")
|
||||
page.locator("text=Document how your community makes decisions"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Build an operating manual for a successful community")
|
||||
page.locator("text=Build an operating manual for a successful community"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=Get a link to your manual for your group to review and evolve"
|
||||
)
|
||||
"text=Get a link to your manual for your group to review and evolve",
|
||||
),
|
||||
).toBeVisible();
|
||||
|
||||
// Check numbered indicators
|
||||
@@ -121,7 +121,7 @@ test.describe("Homepage", () => {
|
||||
|
||||
// Check CTA buttons
|
||||
const createButtons = page.locator(
|
||||
'button:has-text("Create CommunityRule")'
|
||||
'button:has-text("Create CommunityRule")',
|
||||
);
|
||||
const createButtonCount = await createButtons.count();
|
||||
let visibleCreateButton = null;
|
||||
@@ -139,7 +139,7 @@ test.describe("Homepage", () => {
|
||||
}
|
||||
|
||||
await expect(
|
||||
page.locator('button:has-text("See how it works")')
|
||||
page.locator('button:has-text("See how it works")'),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -152,16 +152,16 @@ test.describe("Homepage", () => {
|
||||
|
||||
// Check rule descriptions
|
||||
await expect(
|
||||
page.locator("text=Units called Circles have the ability to decide")
|
||||
page.locator("text=Units called Circles have the ability to decide"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Decisions that affect the group collectively")
|
||||
page.locator("text=Decisions that affect the group collectively"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=An elected board determines policies")
|
||||
page.locator("text=An elected board determines policies"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=All participants can propose and vote")
|
||||
page.locator("text=All participants can propose and vote"),
|
||||
).toBeVisible();
|
||||
|
||||
// Test card interactions
|
||||
@@ -171,19 +171,19 @@ test.describe("Homepage", () => {
|
||||
|
||||
// Check "See all templates" button
|
||||
await expect(
|
||||
page.locator('button:has-text("See all templates")')
|
||||
page.locator('button:has-text("See all templates")'),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("feature grid section functionality", async ({ page }) => {
|
||||
// Check section header
|
||||
await expect(
|
||||
page.locator('h1:has-text("We\'ve got your back")')
|
||||
page.locator('h1:has-text("We\'ve got your back")'),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=Use our toolkit to improve, document, and evolve your organization"
|
||||
)
|
||||
"text=Use our toolkit to improve, document, and evolve your organization",
|
||||
),
|
||||
).toBeVisible();
|
||||
|
||||
// Check all four feature cards - use more specific selectors to avoid conflicts
|
||||
@@ -205,23 +205,23 @@ test.describe("Homepage", () => {
|
||||
test("quote block section displays correctly", async ({ page }) => {
|
||||
// Check quote content
|
||||
await expect(
|
||||
page.locator("text=The rules of decision-making must be open")
|
||||
page.locator("text=The rules of decision-making must be open"),
|
||||
).toBeVisible();
|
||||
|
||||
// Check author and source
|
||||
await expect(page.locator("text=Jo Freeman")).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=The Tyranny of Structurelessness")
|
||||
page.locator("text=The Tyranny of Structurelessness"),
|
||||
).toBeVisible();
|
||||
|
||||
// Check avatar
|
||||
await expect(
|
||||
page.locator('img[alt="Portrait of Jo Freeman"]')
|
||||
page.locator('img[alt="Portrait of Jo Freeman"]'),
|
||||
).toBeVisible();
|
||||
|
||||
// Check decorative elements
|
||||
await expect(
|
||||
page.locator('[class*="pointer-events-none absolute z-0"]').first()
|
||||
page.locator('[class*="pointer-events-none absolute z-0"]').first(),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -229,7 +229,7 @@ test.describe("Homepage", () => {
|
||||
// Check section content
|
||||
await expect(page.locator("text=Still have questions?")).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Get answers from an experienced organizer")
|
||||
page.locator("text=Get answers from an experienced organizer"),
|
||||
).toBeVisible();
|
||||
|
||||
// Check CTA button (it's actually a link)
|
||||
@@ -286,19 +286,19 @@ test.describe("Homepage", () => {
|
||||
// Test mobile viewport
|
||||
await page.setViewportSize({ width: 375, height: 667 });
|
||||
await expect(
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" })
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" }),
|
||||
).toBeVisible();
|
||||
|
||||
// Test tablet viewport
|
||||
await page.setViewportSize({ width: 768, height: 1024 });
|
||||
await expect(
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" })
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" }),
|
||||
).toBeVisible();
|
||||
|
||||
// Test desktop viewport
|
||||
await page.setViewportSize({ width: 1440, height: 900 });
|
||||
await expect(
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" })
|
||||
page.locator("h1, h2").filter({ hasText: "Collaborate" }),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -362,7 +362,7 @@ test.describe("Homepage", () => {
|
||||
test("scroll behavior and smooth scrolling", async ({ page }) => {
|
||||
// Test smooth scrolling to sections
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -377,7 +377,7 @@ test.describe("Homepage", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ test.describe("Homepage", () => {
|
||||
|
||||
// Check we're at the numbered cards section
|
||||
await expect(
|
||||
page.locator('h2:has-text("How CommunityRule works")')
|
||||
page.locator('h2:has-text("How CommunityRule works")'),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -405,7 +405,7 @@ test.describe("Homepage", () => {
|
||||
const brokenImages = await page.evaluate(() => {
|
||||
const imgs = document.querySelectorAll("img");
|
||||
return Array.from(imgs).filter(
|
||||
(img) => !img.complete || img.naturalWidth === 0
|
||||
(img) => !img.complete || img.naturalWidth === 0,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ test.describe("Performance Monitoring", () => {
|
||||
// Assert individual metrics
|
||||
expect(result.metrics.ttfb).toBeLessThan(PERFORMANCE_BUDGETS.ttfb);
|
||||
expect(result.metrics.domContentLoaded).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.dom_content_loaded
|
||||
PERFORMANCE_BUDGETS.dom_content_loaded,
|
||||
);
|
||||
expect(result.metrics.load).toBeLessThan(PERFORMANCE_BUDGETS.full_load);
|
||||
|
||||
@@ -121,10 +121,10 @@ test.describe("Performance Monitoring", () => {
|
||||
|
||||
// Assert Core Web Vitals are within acceptable ranges
|
||||
expect(coreWebVitals.lcp).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.largest_contentful_paint
|
||||
PERFORMANCE_BUDGETS.largest_contentful_paint,
|
||||
);
|
||||
expect(coreWebVitals.fid).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.first_input_delay
|
||||
PERFORMANCE_BUDGETS.first_input_delay,
|
||||
);
|
||||
expect(coreWebVitals.cls).toBeLessThan(0.1); // CLS should be less than 0.1
|
||||
});
|
||||
@@ -133,27 +133,24 @@ test.describe("Performance Monitoring", () => {
|
||||
await page.goto("/");
|
||||
|
||||
// Measure header render time
|
||||
const headerRenderTime = await performanceMonitor.measureComponentRender(
|
||||
"header"
|
||||
);
|
||||
const headerRenderTime =
|
||||
await performanceMonitor.measureComponentRender("header");
|
||||
expect(headerRenderTime).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.component_render_time
|
||||
PERFORMANCE_BUDGETS.component_render_time,
|
||||
);
|
||||
|
||||
// Measure footer render time
|
||||
const footerRenderTime = await performanceMonitor.measureComponentRender(
|
||||
"footer"
|
||||
);
|
||||
const footerRenderTime =
|
||||
await performanceMonitor.measureComponentRender("footer");
|
||||
expect(footerRenderTime).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.component_render_time
|
||||
PERFORMANCE_BUDGETS.component_render_time,
|
||||
);
|
||||
|
||||
// Measure main content render time
|
||||
const mainRenderTime = await performanceMonitor.measureComponentRender(
|
||||
"main"
|
||||
);
|
||||
const mainRenderTime =
|
||||
await performanceMonitor.measureComponentRender("main");
|
||||
expect(mainRenderTime).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.component_render_time
|
||||
PERFORMANCE_BUDGETS.component_render_time,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -168,7 +165,7 @@ test.describe("Performance Monitoring", () => {
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
async () => {
|
||||
const learnButtons = page.locator(
|
||||
'button:has-text("Learn how CommunityRule works")'
|
||||
'button:has-text("Learn how CommunityRule works")',
|
||||
);
|
||||
const buttonCount = await learnButtons.count();
|
||||
let visibleButton = null;
|
||||
@@ -183,12 +180,12 @@ test.describe("Performance Monitoring", () => {
|
||||
|
||||
if (!visibleButton) {
|
||||
throw new Error(
|
||||
'No visible "Learn how CommunityRule works" button found'
|
||||
'No visible "Learn how CommunityRule works" button found',
|
||||
);
|
||||
}
|
||||
|
||||
await visibleButton.click();
|
||||
}
|
||||
},
|
||||
);
|
||||
expect(buttonClickTime).toBeLessThan(PERFORMANCE_BUDGETS.interaction_time);
|
||||
|
||||
@@ -213,7 +210,7 @@ test.describe("Performance Monitoring", () => {
|
||||
}
|
||||
|
||||
await visibleLink.click();
|
||||
}
|
||||
},
|
||||
);
|
||||
expect(linkClickTime).toBeLessThan(PERFORMANCE_BUDGETS.interaction_time);
|
||||
});
|
||||
@@ -250,7 +247,7 @@ test.describe("Performance Monitoring", () => {
|
||||
const summary = performanceMonitor.getSummary();
|
||||
if (summary.network_request_duration) {
|
||||
expect(summary.network_request_duration.average).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.network_request_duration
|
||||
PERFORMANCE_BUDGETS.network_request_duration,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -293,7 +290,7 @@ test.describe("Performance Monitoring", () => {
|
||||
|
||||
// Even under load, page should load within reasonable time
|
||||
expect(result.loadTime).toBeLessThan(
|
||||
PERFORMANCE_BUDGETS.page_load_time * 1.5
|
||||
PERFORMANCE_BUDGETS.page_load_time * 1.5,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -343,7 +340,7 @@ test.describe("Performance Monitoring", () => {
|
||||
|
||||
console.log(
|
||||
"Exported Performance Data:",
|
||||
JSON.stringify(exportedData, null, 2)
|
||||
JSON.stringify(exportedData, null, 2),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -402,7 +399,7 @@ test.describe("Performance Regression Testing", () => {
|
||||
const variance =
|
||||
results.reduce(
|
||||
(acc, val) => acc + Math.pow(val - averageLoadTime, 2),
|
||||
0
|
||||
0,
|
||||
) / results.length;
|
||||
|
||||
// Performance should be consistent (low variance)
|
||||
|
||||
@@ -11,7 +11,7 @@ test.describe("User Journeys", () => {
|
||||
|
||||
// 2. User reads hero section
|
||||
await expect(
|
||||
page.locator("text=Help your community make important decisions")
|
||||
page.locator("text=Help your community make important decisions"),
|
||||
).toBeVisible();
|
||||
|
||||
// 3. User clicks CTA to learn more
|
||||
@@ -24,20 +24,20 @@ test.describe("User Journeys", () => {
|
||||
|
||||
// 4. User scrolls to numbered cards section
|
||||
await expect(
|
||||
page.locator('h2:has-text("How CommunityRule works")')
|
||||
page.locator('h2:has-text("How CommunityRule works")'),
|
||||
).toBeVisible();
|
||||
|
||||
// 5. User reads the process steps
|
||||
await expect(
|
||||
page.locator("text=Document how your community makes decisions")
|
||||
page.locator("text=Document how your community makes decisions"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=Build an operating manual for a successful community")
|
||||
page.locator("text=Build an operating manual for a successful community"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=Get a link to your manual for your group to review and evolve"
|
||||
)
|
||||
"text=Get a link to your manual for your group to review and evolve",
|
||||
),
|
||||
).toBeVisible();
|
||||
|
||||
// 6. User explores rule templates
|
||||
@@ -78,7 +78,7 @@ test.describe("User Journeys", () => {
|
||||
|
||||
// 10. User creates CommunityRule
|
||||
const createButton = page.locator(
|
||||
'button:has-text("Create CommunityRule")'
|
||||
'button:has-text("Create CommunityRule")',
|
||||
);
|
||||
if (
|
||||
(await createButton.count()) > 0 &&
|
||||
@@ -139,7 +139,7 @@ test.describe("User Journeys", () => {
|
||||
|
||||
// Read the section
|
||||
await expect(
|
||||
page.locator("text=Get answers from an experienced organizer")
|
||||
page.locator("text=Get answers from an experienced organizer"),
|
||||
).toBeVisible();
|
||||
|
||||
// Click contact button - check if it exists and is visible first
|
||||
@@ -158,7 +158,7 @@ test.describe("User Journeys", () => {
|
||||
test("user journey: create CommunityRule", async ({ page }) => {
|
||||
// Simplified approach - just check if the button exists and is visible
|
||||
const createButton = page.locator(
|
||||
'button:has-text("Create CommunityRule")'
|
||||
'button:has-text("Create CommunityRule")',
|
||||
);
|
||||
|
||||
if (
|
||||
|
||||
@@ -349,7 +349,7 @@ test.describe("Visual Regression Tests", () => {
|
||||
await page.evaluate(() => {
|
||||
document.documentElement.style.setProperty(
|
||||
"--prefers-reduced-motion",
|
||||
"reduce"
|
||||
"reduce",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -16,18 +16,18 @@ describe("ContentLockup Integration", () => {
|
||||
subtitle="Get Started"
|
||||
description="This is a description"
|
||||
ctaText="Get Started"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Welcome" })
|
||||
screen.getByRole("heading", { name: "Welcome" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Get Started" })
|
||||
screen.getByRole("heading", { name: "Get Started" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("This is a description")).toBeInTheDocument();
|
||||
expect(screen.getAllByRole("button", { name: "Get Started" })).toHaveLength(
|
||||
3
|
||||
3,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -40,18 +40,18 @@ describe("ContentLockup Integration", () => {
|
||||
description="Feature description"
|
||||
linkText="Learn More"
|
||||
linkHref="/learn"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Feature Title" })
|
||||
screen.getByRole("heading", { name: "Feature Title" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Learn More" })
|
||||
screen.getByRole("link", { name: "Learn More" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole("link", { name: "Learn More" })).toHaveAttribute(
|
||||
"href",
|
||||
"/learn"
|
||||
"/learn",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -61,14 +61,14 @@ describe("ContentLockup Integration", () => {
|
||||
variant="ask"
|
||||
title="Ask Question"
|
||||
subtitle="Ask subtitle"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Ask Question" })
|
||||
screen.getByRole("heading", { name: "Ask Question" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Ask subtitle" })
|
||||
screen.getByRole("heading", { name: "Ask subtitle" }),
|
||||
).toBeInTheDocument();
|
||||
// Ask variant should not have description or CTA
|
||||
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
||||
@@ -81,7 +81,7 @@ describe("ContentLockup Integration", () => {
|
||||
title="Left Aligned"
|
||||
subtitle="Subtitle"
|
||||
alignment="left"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const container = screen
|
||||
@@ -92,7 +92,7 @@ describe("ContentLockup Integration", () => {
|
||||
|
||||
test("renders responsive buttons correctly", () => {
|
||||
render(
|
||||
<ContentLockup variant="hero" title="Responsive" ctaText="Click Me" />
|
||||
<ContentLockup variant="hero" title="Responsive" ctaText="Click Me" />,
|
||||
);
|
||||
|
||||
// Should render all three button variants for different breakpoints
|
||||
@@ -107,7 +107,7 @@ describe("ContentLockup Integration", () => {
|
||||
title="Custom Button"
|
||||
ctaText="Custom"
|
||||
buttonClassName="custom-button-class"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const buttons = screen.getAllByRole("button", { name: "Custom" });
|
||||
@@ -119,7 +119,7 @@ describe("ContentLockup Integration", () => {
|
||||
render(<ContentLockup variant="hero" title="Minimal" />);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Minimal" })
|
||||
screen.getByRole("heading", { name: "Minimal" }),
|
||||
).toBeInTheDocument();
|
||||
// Should not crash without subtitle, description, or CTA
|
||||
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
||||
@@ -146,7 +146,7 @@ describe("ContentLockup Integration", () => {
|
||||
title="Accessible"
|
||||
linkText="Accessible Link"
|
||||
linkHref="/accessible"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const link = screen.getByRole("link", { name: "Accessible Link" });
|
||||
|
||||
@@ -49,26 +49,26 @@ describe("Component Interactions Integration", () => {
|
||||
<div>
|
||||
<HeroBanner {...heroData} />
|
||||
<NumberedCards {...numberedCardsData} />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Hero introduces the concept
|
||||
expect(
|
||||
screen.getByText(/Help your community make important decisions/)
|
||||
screen.getByText(/Help your community make important decisions/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Numbered cards explain the process
|
||||
expect(screen.getByText("How CommunityRule works")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Document how your community makes decisions")
|
||||
screen.getByText("Document how your community makes decisions"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Build an operating manual for a successful community")
|
||||
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"
|
||||
)
|
||||
"Get a link to your manual for your group to review and evolve",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -83,7 +83,7 @@ describe("Component Interactions Integration", () => {
|
||||
<div>
|
||||
<RuleStack />
|
||||
<FeatureGrid {...featureGridData} />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Rule stack shows governance options
|
||||
@@ -94,12 +94,12 @@ describe("Component Interactions Integration", () => {
|
||||
|
||||
// Feature grid provides support context
|
||||
expect(
|
||||
screen.getByText("We've got your back, every step of the way")
|
||||
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."
|
||||
)
|
||||
"Use our toolkit to improve, document, and evolve your organization.",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -108,13 +108,13 @@ describe("Component Interactions Integration", () => {
|
||||
|
||||
// Quote provides credibility and social proof
|
||||
expect(
|
||||
screen.getByText(/The rules of decision-making must be open/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Should have proper attribution
|
||||
expect(screen.getByText("Jo Freeman")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("The Tyranny of Structurelessness")
|
||||
screen.getByText("The Tyranny of Structurelessness"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -131,10 +131,10 @@ describe("Component Interactions Integration", () => {
|
||||
// Provides help for users who need assistance
|
||||
expect(screen.getByText("Still have questions?")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Get answers from an experienced organizer")
|
||||
screen.getByText("Get answers from an experienced organizer"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: /Ask an organizer/i })
|
||||
screen.getByRole("link", { name: /Ask an organizer/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -160,7 +160,7 @@ describe("Component Interactions Integration", () => {
|
||||
subtitle="Test help subtitle"
|
||||
buttonText="Test Help Button"
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// All components should render without errors
|
||||
@@ -169,7 +169,7 @@ describe("Component Interactions Integration", () => {
|
||||
expect(screen.getByText("Consensus clusters")).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Features")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/The rules of decision-making must be open/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Help")).toBeInTheDocument();
|
||||
});
|
||||
@@ -209,7 +209,7 @@ describe("Component Interactions Integration", () => {
|
||||
<NumberedCards {...testData.cards} />
|
||||
<FeatureGrid {...testData.features} />
|
||||
<AskOrganizer {...testData.help} />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Verify all data is passed correctly
|
||||
@@ -217,7 +217,7 @@ describe("Component Interactions Integration", () => {
|
||||
expect(screen.getByText("Test Subtitle")).toBeInTheDocument();
|
||||
expect(screen.getByText("Test description")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getAllByRole("button", { name: "Test CTA" }).length
|
||||
screen.getAllByRole("button", { name: "Test CTA" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(screen.getByText("Test Cards")).toBeInTheDocument();
|
||||
expect(screen.getByText("Card 1")).toBeInTheDocument();
|
||||
@@ -225,7 +225,7 @@ describe("Component Interactions Integration", () => {
|
||||
expect(screen.getByText("Test Features")).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Help")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: /Test Help Button/i })
|
||||
screen.getByRole("link", { name: /Test Help Button/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -258,7 +258,7 @@ describe("Component Interactions Integration", () => {
|
||||
buttonText="Contact us"
|
||||
buttonHref="#contact"
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Test interaction flow
|
||||
@@ -281,7 +281,7 @@ describe("Component Interactions Integration", () => {
|
||||
expect(screen.getByText("Consensus clusters")).toBeInTheDocument();
|
||||
expect(screen.getByText("Features")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/The rules of decision-making must be open/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Need help?")).toBeInTheDocument();
|
||||
});
|
||||
@@ -294,7 +294,7 @@ describe("Component Interactions Integration", () => {
|
||||
<NumberedCards title="Minimal Cards" cards={[]} />
|
||||
<FeatureGrid title="Minimal Features" />
|
||||
<AskOrganizer title="Minimal Help" />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Components should render without crashing
|
||||
@@ -331,7 +331,7 @@ describe("Component Interactions Integration", () => {
|
||||
subtitle="Accessible help subtitle"
|
||||
buttonText="Accessible Help Button"
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Check for proper heading hierarchy
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Check that CommunityRule branding appears in both header and footer
|
||||
@@ -30,19 +30,21 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Header navigation items
|
||||
expect(
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to Use cases page" })
|
||||
.length
|
||||
.length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to Learn page" }).length
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to Learn page" })
|
||||
.length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to About page" }).length
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to About page" })
|
||||
.length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Footer navigation items (should be present in footer as well)
|
||||
@@ -92,23 +94,23 @@ describe("Layout Integration", () => {
|
||||
// Contact information
|
||||
expect(screen.getByText("medlab@colorado.edu")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "medlab@colorado.edu" })
|
||||
screen.getByRole("link", { name: "medlab@colorado.edu" }),
|
||||
).toHaveAttribute("href", "mailto:medlab@colorado.edu");
|
||||
|
||||
// Social media links
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Follow us on Bluesky" })
|
||||
screen.getByRole("link", { name: "Follow us on Bluesky" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Follow us on GitLab" })
|
||||
screen.getByRole("link", { name: "Follow us on GitLab" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Legal links
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Privacy Policy" })
|
||||
screen.getByRole("link", { name: "Privacy Policy" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Terms of Service" })
|
||||
screen.getByRole("link", { name: "Terms of Service" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -134,7 +136,7 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Header should have banner role
|
||||
@@ -155,7 +157,7 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Header should have responsive navigation elements
|
||||
@@ -172,7 +174,7 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Get all interactive elements
|
||||
@@ -195,7 +197,7 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Header provides main navigation
|
||||
@@ -215,7 +217,7 @@ describe("Layout Integration", () => {
|
||||
<div>
|
||||
<Header />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Main navigation in header
|
||||
@@ -228,13 +230,13 @@ describe("Layout Integration", () => {
|
||||
(link) =>
|
||||
link.textContent?.includes("Use cases") ||
|
||||
link.textContent?.includes("Learn") ||
|
||||
link.textContent?.includes("About")
|
||||
link.textContent?.includes("About"),
|
||||
);
|
||||
expect(navigationLinks.length).toBeGreaterThan(0);
|
||||
|
||||
// Contact information in footer
|
||||
expect(
|
||||
screen.getByRole("link", { name: "medlab@colorado.edu" })
|
||||
screen.getByRole("link", { name: "medlab@colorado.edu" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,15 +13,15 @@ describe("Page Flow Integration", () => {
|
||||
|
||||
// Hero Banner section
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Collaborate" })
|
||||
screen.getByRole("heading", { name: "Collaborate" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "with clarity" })
|
||||
screen.getByRole("heading", { name: "with clarity" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
"Help your community make important decisions in a way that reflects its unique values."
|
||||
)
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
// Check that CTA button exists (multiple sizes for responsive design)
|
||||
const ctaButtons = screen.getAllByRole("button", {
|
||||
@@ -39,65 +39,65 @@ describe("Page Flow Integration", () => {
|
||||
|
||||
// Numbered Cards section
|
||||
expect(
|
||||
screen.getByRole("heading", { name: /How CommunityRule works/ })
|
||||
screen.getByRole("heading", { name: /How CommunityRule works/ }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
"Here's a quick overview of the process, from start to finish."
|
||||
)
|
||||
"Here's a quick overview of the process, from start to finish.",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Document how your community makes decisions")
|
||||
screen.getByText("Document how your community makes decisions"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Build an operating manual for a successful community")
|
||||
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"
|
||||
)
|
||||
"Get a link to your manual for your group to review and evolve",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Rule Stack section
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Consensus clusters" })
|
||||
screen.getByRole("heading", { name: "Consensus clusters" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Elected Board" })
|
||||
screen.getByRole("heading", { name: "Elected Board" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Consensus" })
|
||||
screen.getByRole("heading", { name: "Consensus" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Petition" })
|
||||
screen.getByRole("heading", { name: "Petition" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Feature Grid section
|
||||
expect(
|
||||
screen.getByRole("heading", {
|
||||
name: "We've got your back, every step of the way",
|
||||
})
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
"Use our toolkit to improve, document, and evolve your organization."
|
||||
)
|
||||
"Use our toolkit to improve, document, and evolve your organization.",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Quote Block section
|
||||
expect(
|
||||
screen.getByText(/The rules of decision-making must be open/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Ask Organizer section
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Still have questions?" })
|
||||
screen.getByRole("heading", { name: "Still have questions?" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Get answers from an experienced organizer")
|
||||
screen.getByText("Get answers from an experienced organizer"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: /Ask an organizer/i })
|
||||
screen.getByRole("link", { name: /Ask an organizer/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -125,7 +125,7 @@ describe("Page Flow Integration", () => {
|
||||
|
||||
// Check that all three cards are rendered
|
||||
const cards = screen.getAllByText(
|
||||
/Document how your community|Build an operating manual|Get a link to your manual/
|
||||
/Document how your community|Build an operating manual|Get a link to your manual/,
|
||||
);
|
||||
expect(cards).toHaveLength(3);
|
||||
|
||||
@@ -167,7 +167,7 @@ describe("Page Flow Integration", () => {
|
||||
|
||||
// Check that main content is properly structured
|
||||
const mainContent = screen.getByText(
|
||||
/Help your community make important decisions/
|
||||
/Help your community make important decisions/,
|
||||
);
|
||||
expect(mainContent).toBeInTheDocument();
|
||||
});
|
||||
@@ -194,7 +194,7 @@ describe("Page Flow Integration", () => {
|
||||
// Verify the logical flow of information
|
||||
// 1. Hero introduces the concept
|
||||
expect(
|
||||
screen.getByText(/Help your community make important decisions/)
|
||||
screen.getByText(/Help your community make important decisions/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// 2. How it works section explains the process
|
||||
@@ -205,12 +205,12 @@ describe("Page Flow Integration", () => {
|
||||
|
||||
// 4. Features highlight benefits
|
||||
expect(
|
||||
screen.getByText("We've got your back, every step of the way")
|
||||
screen.getByText("We've got your back, every step of the way"),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// 5. Quote provides social proof
|
||||
expect(
|
||||
screen.getByText(/The rules of decision-making must be open/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// 6. Call to action for help
|
||||
|
||||
@@ -17,12 +17,12 @@ describe("User Journey Integration", () => {
|
||||
<Header />
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// User sees the main value proposition
|
||||
expect(
|
||||
screen.getByText(/Help your community make important decisions/)
|
||||
screen.getByText(/Help your community make important decisions/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// User clicks the main CTA to learn more
|
||||
@@ -64,7 +64,7 @@ describe("User Journey Integration", () => {
|
||||
<Header />
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// User clicks on navigation links in header (check that they exist and are clickable)
|
||||
@@ -73,7 +73,7 @@ describe("User Journey Integration", () => {
|
||||
(link) =>
|
||||
link.textContent?.includes("Use Cases") ||
|
||||
link.textContent?.includes("Learn") ||
|
||||
link.textContent?.includes("About")
|
||||
link.textContent?.includes("About"),
|
||||
);
|
||||
|
||||
// Test that navigation links are present and clickable
|
||||
@@ -90,7 +90,7 @@ describe("User Journey Integration", () => {
|
||||
// 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")
|
||||
screen.getByText("Get answers from an experienced organizer"),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// User clicks the ask organizer button (it's actually a link, not a button)
|
||||
@@ -105,15 +105,15 @@ describe("User Journey Integration", () => {
|
||||
|
||||
// User reads through the process steps
|
||||
expect(
|
||||
screen.getByText("Document how your community makes decisions")
|
||||
screen.getByText("Document how your community makes decisions"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Build an operating manual for a successful community")
|
||||
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"
|
||||
)
|
||||
"Get a link to your manual for your group to review and evolve",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// User sees the step numbers
|
||||
@@ -128,7 +128,7 @@ describe("User Journey Integration", () => {
|
||||
<Header />
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// User finds contact email in footer
|
||||
@@ -153,17 +153,17 @@ describe("User Journey Integration", () => {
|
||||
|
||||
// User sees the features section
|
||||
expect(
|
||||
screen.getByText("We've got your back, every step of the way")
|
||||
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."
|
||||
)
|
||||
"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/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -173,7 +173,7 @@ describe("User Journey Integration", () => {
|
||||
<div>
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// User sees the logo wall with partner logos (check for any logo images)
|
||||
@@ -185,7 +185,7 @@ describe("User Journey Integration", () => {
|
||||
img.alt?.includes("Metagov") ||
|
||||
img.alt?.includes("Open Civics") ||
|
||||
img.alt?.includes("Mutual Aid CO") ||
|
||||
img.alt?.includes("CU Boulder")
|
||||
img.alt?.includes("CU Boulder"),
|
||||
);
|
||||
expect(partnerLogos.length).toBeGreaterThan(0);
|
||||
|
||||
@@ -203,7 +203,7 @@ describe("User Journey Integration", () => {
|
||||
<Header />
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// 1. User discovers the application
|
||||
@@ -218,12 +218,12 @@ describe("User Journey Integration", () => {
|
||||
|
||||
// 4. User sees features and benefits
|
||||
expect(
|
||||
screen.getByText("We've got your back, every step of the way")
|
||||
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/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// 6. User can take action
|
||||
@@ -243,7 +243,7 @@ describe("User Journey Integration", () => {
|
||||
<Header />
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Header navigation
|
||||
@@ -256,7 +256,7 @@ describe("User Journey Integration", () => {
|
||||
(link) =>
|
||||
link.textContent?.includes("Use cases") ||
|
||||
link.textContent?.includes("Learn") ||
|
||||
link.textContent?.includes("About")
|
||||
link.textContent?.includes("About"),
|
||||
);
|
||||
expect(navigationLinks.length).toBeGreaterThan(0);
|
||||
|
||||
@@ -273,7 +273,7 @@ describe("User Journey Integration", () => {
|
||||
<Header />
|
||||
<Page />
|
||||
<Footer />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
|
||||
// Test all interactive elements
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
import { setupServer } from 'msw/node';
|
||||
import { setupServer } from "msw/node";
|
||||
export const server = setupServer(); // add handlers per test as needed
|
||||
|
||||
@@ -61,7 +61,7 @@ class PerformanceMonitor {
|
||||
|
||||
if (value > threshold) {
|
||||
console.warn(
|
||||
`⚠️ Performance threshold exceeded: ${name} = ${value}ms (threshold: ${threshold}ms)`
|
||||
`⚠️ Performance threshold exceeded: ${name} = ${value}ms (threshold: ${threshold}ms)`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ class PerformanceMonitor {
|
||||
const regressionThreshold = baseline * 1.2; // 20% regression threshold
|
||||
if (value > regressionThreshold) {
|
||||
console.error(
|
||||
`🚨 Performance regression detected: ${name} = ${value}ms (baseline: ${baseline}ms)`
|
||||
`🚨 Performance regression detected: ${name} = ${value}ms (baseline: ${baseline}ms)`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,25 +16,25 @@ describe("AskOrganizer Component", () => {
|
||||
description="Our organizers can help you build better communities"
|
||||
buttonText="Contact an organizer"
|
||||
buttonHref="/contact"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Need help organizing?" })
|
||||
screen.getByRole("heading", { name: "Need help organizing?" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Get expert guidance" })
|
||||
screen.getByRole("heading", { name: "Get expert guidance" }),
|
||||
).toBeInTheDocument();
|
||||
// The description text might not be rendered or might be different
|
||||
// Just verify the component renders without error
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Need help organizing?" })
|
||||
screen.getByRole("heading", { name: "Need help organizing?" }),
|
||||
).toBeInTheDocument();
|
||||
// Button renders as a link when href is provided
|
||||
expect(
|
||||
screen.getByRole("link", {
|
||||
name: "Contact an organizer - Contact an organizer for help",
|
||||
})
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -45,13 +45,13 @@ describe("AskOrganizer Component", () => {
|
||||
expect(
|
||||
screen.getByRole("link", {
|
||||
name: "Ask an organizer - Contact an organizer for help",
|
||||
})
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders with custom className", () => {
|
||||
render(
|
||||
<AskOrganizer title="Test" subtitle="Test" className="custom-class" />
|
||||
<AskOrganizer title="Test" subtitle="Test" className="custom-class" />,
|
||||
);
|
||||
|
||||
const section = document.querySelector("section");
|
||||
@@ -60,7 +60,7 @@ describe("AskOrganizer Component", () => {
|
||||
|
||||
test("renders different variants", () => {
|
||||
const { rerender } = render(
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="centered" />
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="centered" />,
|
||||
);
|
||||
|
||||
// Centered variant should have center alignment
|
||||
@@ -70,7 +70,7 @@ describe("AskOrganizer Component", () => {
|
||||
expect(container).toBeInTheDocument();
|
||||
|
||||
rerender(
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="left-aligned" />
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="left-aligned" />,
|
||||
);
|
||||
|
||||
// Left-aligned variant should have left alignment
|
||||
@@ -86,19 +86,19 @@ describe("AskOrganizer Component", () => {
|
||||
title="Ask Title"
|
||||
subtitle="Ask Subtitle"
|
||||
description="Ask Description"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Ask Title" })
|
||||
screen.getByRole("heading", { name: "Ask Title" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Ask Subtitle" })
|
||||
screen.getByRole("heading", { name: "Ask Subtitle" }),
|
||||
).toBeInTheDocument();
|
||||
// Description might not be rendered if not provided to ContentLockup
|
||||
// Just verify the component renders without error
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Ask Title" })
|
||||
screen.getByRole("heading", { name: "Ask Title" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ describe("AskOrganizer Component", () => {
|
||||
subtitle="Test"
|
||||
buttonText="Custom Button"
|
||||
buttonHref="/custom"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const button = screen.getByRole("link", {
|
||||
@@ -128,7 +128,7 @@ describe("AskOrganizer Component", () => {
|
||||
title="Test"
|
||||
subtitle="Test"
|
||||
onContactClick={onContactClick}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const button = screen.getByRole("link", {
|
||||
@@ -172,13 +172,13 @@ describe("AskOrganizer Component", () => {
|
||||
|
||||
test("renders with proper accessibility attributes", () => {
|
||||
render(
|
||||
<AskOrganizer title="Test" subtitle="Test" buttonText="Custom Button" />
|
||||
<AskOrganizer title="Test" subtitle="Test" buttonText="Custom Button" />,
|
||||
);
|
||||
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveAttribute(
|
||||
"aria-labelledby",
|
||||
"ask-organizer-headline"
|
||||
"ask-organizer-headline",
|
||||
);
|
||||
expect(section).toHaveAttribute("tabIndex", "-1");
|
||||
|
||||
@@ -187,7 +187,7 @@ describe("AskOrganizer Component", () => {
|
||||
});
|
||||
expect(button).toHaveAttribute(
|
||||
"aria-label",
|
||||
"Custom Button - Contact an organizer for help"
|
||||
"Custom Button - Contact an organizer for help",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -197,7 +197,7 @@ describe("AskOrganizer Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"py-[var(--spacing-scale-032)]",
|
||||
"px-[var(--spacing-scale-032)]"
|
||||
"px-[var(--spacing-scale-032)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -207,7 +207,7 @@ describe("AskOrganizer Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"md:py-[var(--spacing-scale-096)]",
|
||||
"md:px-[var(--spacing-scale-064)]"
|
||||
"md:px-[var(--spacing-scale-064)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -224,18 +224,18 @@ describe("AskOrganizer Component", () => {
|
||||
|
||||
test("applies variant-specific styling", () => {
|
||||
const { rerender } = render(
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="compact" />
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="compact" />,
|
||||
);
|
||||
|
||||
// Compact variant should have different padding
|
||||
const section = screen.getByRole("region");
|
||||
expect(section).toHaveClass(
|
||||
"py-[var(--spacing-scale-016)]",
|
||||
"px-[var(--spacing-scale-016)]"
|
||||
"px-[var(--spacing-scale-016)]",
|
||||
);
|
||||
|
||||
rerender(
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="left-aligned" />
|
||||
<AskOrganizer title="Test" subtitle="Test" variant="left-aligned" />,
|
||||
);
|
||||
|
||||
// Left-aligned variant should have left alignment
|
||||
@@ -251,7 +251,7 @@ describe("AskOrganizer Component", () => {
|
||||
});
|
||||
expect(button).toHaveClass(
|
||||
"xl:!px-[var(--spacing-scale-020)]",
|
||||
"xl:!py-[var(--spacing-scale-012)]"
|
||||
"xl:!py-[var(--spacing-scale-012)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -266,7 +266,7 @@ describe("AskOrganizer Component", () => {
|
||||
expect(
|
||||
screen.getByRole("link", {
|
||||
name: "Ask an organizer - Contact an organizer for help",
|
||||
})
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ describe("Button Component", () => {
|
||||
const { rerender } = render(<Button variant="default">Default</Button>);
|
||||
let button = screen.getByRole("button", { name: "Default" });
|
||||
expect(button.className).toContain(
|
||||
"bg-[var(--color-surface-inverse-primary)]"
|
||||
"bg-[var(--color-surface-inverse-primary)]",
|
||||
);
|
||||
|
||||
rerender(<Button variant="secondary">Secondary</Button>);
|
||||
@@ -79,10 +79,10 @@ describe("Button Component", () => {
|
||||
|
||||
// Check that design tokens are applied
|
||||
expect(button.className).toContain(
|
||||
"rounded-[var(--radius-measures-radius-full)]"
|
||||
"rounded-[var(--radius-measures-radius-full)]",
|
||||
);
|
||||
expect(button.className).toContain(
|
||||
"bg-[var(--color-surface-inverse-primary)]"
|
||||
"bg-[var(--color-surface-inverse-primary)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -103,7 +103,7 @@ describe("Button Component", () => {
|
||||
render(
|
||||
<Button href="/test" disabled>
|
||||
Disabled Link
|
||||
</Button>
|
||||
</Button>,
|
||||
);
|
||||
const button = screen.getByRole("button", { name: "Disabled Link" });
|
||||
expect(button).toBeInTheDocument();
|
||||
|
||||
@@ -13,22 +13,22 @@ describe("FeatureGrid Component", () => {
|
||||
<FeatureGrid
|
||||
title="Feature Tools"
|
||||
subtitle="Everything you need to build better communities"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Feature Tools" })
|
||||
screen.getByRole("heading", { name: "Feature Tools" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", {
|
||||
name: "Everything you need to build better communities",
|
||||
})
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders with custom className", () => {
|
||||
render(
|
||||
<FeatureGrid title="Test" subtitle="Test" className="custom-class" />
|
||||
<FeatureGrid title="Test" subtitle="Test" className="custom-class" />,
|
||||
);
|
||||
|
||||
const section = document.querySelector("section");
|
||||
@@ -40,16 +40,16 @@ describe("FeatureGrid Component", () => {
|
||||
|
||||
// Check for all four MiniCard components
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Decision-making support tools" })
|
||||
screen.getByRole("link", { name: "Decision-making support tools" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Values alignment exercises" })
|
||||
screen.getByRole("link", { name: "Values alignment exercises" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Membership guidance resources" })
|
||||
screen.getByRole("link", { name: "Membership guidance resources" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Conflict resolution tools" })
|
||||
screen.getByRole("link", { name: "Conflict resolution tools" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -57,13 +57,13 @@ describe("FeatureGrid Component", () => {
|
||||
render(<FeatureGrid title="Feature Title" subtitle="Feature Subtitle" />);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Feature Title" })
|
||||
screen.getByRole("heading", { name: "Feature Title" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Feature Subtitle" })
|
||||
screen.getByRole("heading", { name: "Feature Subtitle" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Learn more" })
|
||||
screen.getByRole("link", { name: "Learn more" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -130,7 +130,7 @@ describe("FeatureGrid Component", () => {
|
||||
|
||||
// Should render default MiniCards
|
||||
expect(
|
||||
screen.getByRole("link", { name: "Decision-making support tools" })
|
||||
screen.getByRole("link", { name: "Decision-making support tools" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
+15
-15
@@ -27,7 +27,7 @@ describe("Footer", () => {
|
||||
expect(schemaData.email).toBe("medlab@colorado.edu");
|
||||
expect(schemaData.url).toBe("https://communityrule.com");
|
||||
expect(schemaData.sameAs).toContain(
|
||||
"https://bsky.app/profile/medlabboulder"
|
||||
"https://bsky.app/profile/medlabboulder",
|
||||
);
|
||||
expect(schemaData.sameAs).toContain("https://gitlab.com/medlabboulder");
|
||||
});
|
||||
@@ -36,7 +36,7 @@ describe("Footer", () => {
|
||||
render(<Footer />);
|
||||
|
||||
expect(
|
||||
screen.getAllByText("Media Economies Design Lab").length
|
||||
screen.getAllByText("Media Economies Design Lab").length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
const emailLinks = screen.getAllByRole("link", {
|
||||
@@ -86,13 +86,13 @@ describe("Footer", () => {
|
||||
render(<Footer />);
|
||||
|
||||
expect(
|
||||
screen.getAllByRole("link", { name: "Use cases" }).length
|
||||
screen.getAllByRole("link", { name: "Use cases" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("link", { name: "Learn" }).length
|
||||
screen.getAllByRole("link", { name: "Learn" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("link", { name: "About" }).length
|
||||
screen.getAllByRole("link", { name: "About" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -100,13 +100,13 @@ describe("Footer", () => {
|
||||
render(<Footer />);
|
||||
|
||||
expect(
|
||||
screen.getAllByRole("link", { name: "Privacy Policy" }).length
|
||||
screen.getAllByRole("link", { name: "Privacy Policy" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("link", { name: "Terms of Service" }).length
|
||||
screen.getAllByRole("link", { name: "Terms of Service" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("link", { name: "Cookies Settings" }).length
|
||||
screen.getAllByRole("link", { name: "Cookies Settings" }).length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -114,7 +114,7 @@ describe("Footer", () => {
|
||||
render(<Footer />);
|
||||
|
||||
expect(screen.getAllByText("© All right reserved").length).toBeGreaterThan(
|
||||
0
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -123,7 +123,7 @@ describe("Footer", () => {
|
||||
|
||||
// Check that logo containers exist for different breakpoints
|
||||
const logoContainers = document.querySelectorAll(
|
||||
'[class*="block sm:hidden"], [class*="hidden sm:block lg:hidden"], [class*="hidden lg:block"]'
|
||||
'[class*="block sm:hidden"], [class*="hidden sm:block lg:hidden"], [class*="hidden lg:block"]',
|
||||
);
|
||||
expect(logoContainers.length).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -147,7 +147,7 @@ describe("Footer", () => {
|
||||
|
||||
// The Separator component should be rendered (it uses a div with border, not hr)
|
||||
const separator = document.querySelector(
|
||||
".bg-\\[var\\(--border-color-default-secondary\\)\\]"
|
||||
".bg-\\[var\\(--border-color-default-secondary\\)\\]",
|
||||
);
|
||||
expect(separator).toBeInTheDocument();
|
||||
});
|
||||
@@ -263,10 +263,10 @@ describe("Footer", () => {
|
||||
expect(emailLink).toHaveClass("focus:ring-2");
|
||||
expect(emailLink).toHaveClass("focus:ring-offset-2");
|
||||
expect(emailLink).toHaveClass(
|
||||
"focus:ring-[var(--color-content-default-primary)]"
|
||||
"focus:ring-[var(--color-content-default-primary)]",
|
||||
);
|
||||
expect(emailLink).toHaveClass(
|
||||
"focus:ring-offset-[var(--color-surface-default-primary)]"
|
||||
"focus:ring-offset-[var(--color-surface-default-primary)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -276,10 +276,10 @@ describe("Footer", () => {
|
||||
expect(link).toHaveClass("focus:ring-2");
|
||||
expect(link).toHaveClass("focus:ring-offset-2");
|
||||
expect(link).toHaveClass(
|
||||
"focus:ring-[var(--color-content-default-primary)]"
|
||||
"focus:ring-[var(--color-content-default-primary)]",
|
||||
);
|
||||
expect(link).toHaveClass(
|
||||
"focus:ring-offset-[var(--color-surface-default-primary)]"
|
||||
"focus:ring-offset-[var(--color-surface-default-primary)]",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
+10
-10
@@ -22,14 +22,14 @@ describe("Header", () => {
|
||||
|
||||
// Check main header structure - use container to scope the search
|
||||
const header = container.querySelector(
|
||||
'[role="banner"][aria-label="Main navigation header"]'
|
||||
'[role="banner"][aria-label="Main navigation header"]',
|
||||
);
|
||||
expect(header).toBeInTheDocument();
|
||||
expect(header).toHaveAttribute("aria-label", "Main navigation header");
|
||||
|
||||
// Check navigation - use container to scope the search
|
||||
const nav = container.querySelector(
|
||||
'[role="navigation"][aria-label="Main navigation"]'
|
||||
'[role="navigation"][aria-label="Main navigation"]',
|
||||
);
|
||||
expect(nav).toBeInTheDocument();
|
||||
expect(nav).toHaveAttribute("aria-label", "Main navigation");
|
||||
@@ -41,15 +41,15 @@ describe("Header", () => {
|
||||
// Check all navigation items have proper aria-labels - use menuitem role since they're in a menubar
|
||||
expect(
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to Use cases page" })
|
||||
.length
|
||||
.length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to Learn page" })
|
||||
.length
|
||||
.length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByRole("menuitem", { name: "Navigate to About page" })
|
||||
.length
|
||||
.length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
@@ -59,7 +59,7 @@ describe("Header", () => {
|
||||
render(<Header onToggle={mockOnToggle} />);
|
||||
|
||||
const script = document.querySelector(
|
||||
'script[type="application/ld+json"]'
|
||||
'script[type="application/ld+json"]',
|
||||
);
|
||||
expect(script).toBeInTheDocument();
|
||||
|
||||
@@ -296,7 +296,7 @@ describe("Header", () => {
|
||||
(img) =>
|
||||
img.alt === "Avatar 1" ||
|
||||
img.alt === "Avatar 2" ||
|
||||
img.alt === "Avatar 3"
|
||||
img.alt === "Avatar 3",
|
||||
);
|
||||
expect(avatarImages.length).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -324,17 +324,17 @@ describe("Header", () => {
|
||||
const { container } = render(<Header onToggle={mockOnToggle} />);
|
||||
|
||||
const header = container.querySelector(
|
||||
'[role="banner"][aria-label="Main navigation header"]'
|
||||
'[role="banner"][aria-label="Main navigation header"]',
|
||||
);
|
||||
expect(header).toHaveClass("bg-[var(--color-surface-default-primary)]");
|
||||
expect(header).toHaveClass("w-full");
|
||||
expect(header).toHaveClass("border-b");
|
||||
expect(header).toHaveClass(
|
||||
"border-[var(--border-color-default-tertiary)]"
|
||||
"border-[var(--border-color-default-tertiary)]",
|
||||
);
|
||||
|
||||
const nav = container.querySelector(
|
||||
'[role="navigation"][aria-label="Main navigation"]'
|
||||
'[role="navigation"][aria-label="Main navigation"]',
|
||||
);
|
||||
expect(nav).toHaveClass("flex");
|
||||
expect(nav).toHaveClass("items-center");
|
||||
|
||||
@@ -16,17 +16,17 @@ describe("HeroBanner Component", () => {
|
||||
description="Create and manage community rules with ease"
|
||||
ctaText="Get Started"
|
||||
ctaHref="/signup"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Welcome to CommunityRule" })
|
||||
screen.getByRole("heading", { name: "Welcome to CommunityRule" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Build better communities" })
|
||||
screen.getByRole("heading", { name: "Build better communities" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Create and manage community rules with ease")
|
||||
screen.getByText("Create and manage community rules with ease"),
|
||||
).toBeInTheDocument();
|
||||
// Button component renders multiple versions for different screen sizes
|
||||
// Use getAllByRole to handle multiple buttons with same text
|
||||
@@ -38,10 +38,10 @@ describe("HeroBanner Component", () => {
|
||||
render(<HeroBanner title="Minimal" />);
|
||||
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Minimal" })
|
||||
screen.getByRole("heading", { name: "Minimal" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("img", { name: "Hero illustration" })
|
||||
screen.getByRole("img", { name: "Hero illustration" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -72,15 +72,15 @@ describe("HeroBanner Component", () => {
|
||||
description="Test Description"
|
||||
ctaText="Test CTA"
|
||||
ctaHref="/test"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
// Check that ContentLockup receives the props correctly
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Test Title" })
|
||||
screen.getByRole("heading", { name: "Test Title" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("heading", { name: "Test Subtitle" })
|
||||
screen.getByRole("heading", { name: "Test Subtitle" }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Description")).toBeInTheDocument();
|
||||
// Button component renders multiple versions for different screen sizes
|
||||
@@ -93,7 +93,7 @@ describe("HeroBanner Component", () => {
|
||||
|
||||
// HeroDecor should be present (it's a decorative component)
|
||||
const heroDecor = document.querySelector(
|
||||
'[class*="pointer-events-none absolute z-0"]'
|
||||
'[class*="pointer-events-none absolute z-0"]',
|
||||
);
|
||||
expect(heroDecor).toBeInTheDocument();
|
||||
});
|
||||
@@ -123,7 +123,7 @@ describe("HeroBanner Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"px-[var(--spacing-scale-008)]",
|
||||
"sm:px-[var(--spacing-scale-010)]"
|
||||
"sm:px-[var(--spacing-scale-010)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -135,7 +135,7 @@ describe("HeroBanner Component", () => {
|
||||
|
||||
// Check for design token usage in the component structure
|
||||
const container = section.querySelector(
|
||||
'[class*="bg-[var(--color-surface-inverse-brand-primary)]"]'
|
||||
'[class*="bg-[var(--color-surface-inverse-brand-primary)]"]',
|
||||
);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
+12
-12
@@ -23,7 +23,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
const html = document.querySelector("html");
|
||||
@@ -36,7 +36,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
const body = document.querySelector("body");
|
||||
@@ -50,7 +50,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
const mainContainer = document.querySelector(".min-h-screen.flex.flex-col");
|
||||
@@ -61,7 +61,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
// The HomeHeader component should be rendered
|
||||
@@ -74,7 +74,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
const main = document.querySelector("main");
|
||||
@@ -87,7 +87,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
// The Footer component should be rendered
|
||||
@@ -100,7 +100,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>{testContent}</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(testContent)).toBeInTheDocument();
|
||||
@@ -110,7 +110,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
const mainContainer = document.querySelector(".min-h-screen.flex.flex-col");
|
||||
@@ -124,7 +124,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
const main = document.querySelector("main");
|
||||
@@ -135,7 +135,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
// Check for all major structural elements
|
||||
@@ -150,7 +150,7 @@ describe("RootLayout", () => {
|
||||
render(
|
||||
<RootLayout>
|
||||
<div>Test content</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
// Check that the document has proper structure
|
||||
@@ -173,7 +173,7 @@ describe("RootLayout", () => {
|
||||
<div>First child</div>
|
||||
<div>Second child</div>
|
||||
<div>Third child</div>
|
||||
</RootLayout>
|
||||
</RootLayout>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("First child")).toBeInTheDocument();
|
||||
|
||||
@@ -47,7 +47,7 @@ describe("LogoWall Component", () => {
|
||||
render(<LogoWall />);
|
||||
|
||||
expect(
|
||||
screen.getByText("Trusted by leading cooperators")
|
||||
screen.getByText("Trusted by leading cooperators"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@ describe("LogoWall Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"p-[var(--spacing-scale-032)]",
|
||||
"md:px-[var(--spacing-scale-024)]"
|
||||
"md:px-[var(--spacing-scale-024)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ describe("LogoWall Component", () => {
|
||||
render(<LogoWall />);
|
||||
|
||||
const grid = document.querySelector(
|
||||
'[class*="grid grid-cols-2 grid-rows-3"]'
|
||||
'[class*="grid grid-cols-2 grid-rows-3"]',
|
||||
);
|
||||
expect(grid).toBeInTheDocument();
|
||||
expect(grid).toHaveClass("sm:grid-cols-3", "sm:grid-rows-2", "md:flex");
|
||||
@@ -84,7 +84,7 @@ describe("LogoWall Component", () => {
|
||||
const foodNotBombsLogo = screen.getByAltText("Food Not Bombs");
|
||||
expect(foodNotBombsLogo).toHaveAttribute(
|
||||
"src",
|
||||
"assets/Section/Logo_FoodNotBombs.png"
|
||||
"assets/Section/Logo_FoodNotBombs.png",
|
||||
);
|
||||
expect(foodNotBombsLogo).toHaveClass("h-11", "lg:h-14", "xl:h-[70px]");
|
||||
});
|
||||
@@ -109,7 +109,7 @@ describe("LogoWall Component", () => {
|
||||
render(<LogoWall />);
|
||||
|
||||
const logoContainers = document.querySelectorAll(
|
||||
'[class*="hover:opacity-100"]'
|
||||
'[class*="hover:opacity-100"]',
|
||||
);
|
||||
expect(logoContainers.length).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -129,7 +129,7 @@ describe("LogoWall Component", () => {
|
||||
render(<LogoWall />);
|
||||
|
||||
const logoContainers = document.querySelectorAll(
|
||||
'[class*="transition-opacity duration-500"]'
|
||||
'[class*="transition-opacity duration-500"]',
|
||||
);
|
||||
expect(logoContainers.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -32,25 +32,25 @@ describe("NumberedCards Component", () => {
|
||||
title="How CommunityRule helps"
|
||||
subtitle="Build better communities step by step"
|
||||
cards={mockCards}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
// Check for the heading (it contains both mobile and desktop versions)
|
||||
expect(screen.getByRole("heading")).toBeInTheDocument();
|
||||
// Check for the subtitle text
|
||||
expect(
|
||||
screen.getByText("Build better communities step by step")
|
||||
screen.getByText("Build better communities step by step"),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// Check for card content
|
||||
expect(
|
||||
screen.getByText("Define your community values")
|
||||
screen.getByText("Define your community values"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Create decision-making processes")
|
||||
screen.getByText("Create decision-making processes"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Establish communication channels")
|
||||
screen.getByText("Establish communication channels"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ describe("NumberedCards Component", () => {
|
||||
title="Test Title"
|
||||
subtitle="Test Subtitle"
|
||||
cards={mockCards}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
// Check for the heading (it contains both mobile and desktop versions)
|
||||
@@ -82,10 +82,10 @@ describe("NumberedCards Component", () => {
|
||||
render(<NumberedCards title="Test" subtitle="Test" cards={mockCards} />);
|
||||
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Create CommunityRule" })
|
||||
screen.getByRole("button", { name: "Create CommunityRule" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("button", { name: "See how it works" })
|
||||
screen.getByRole("button", { name: "See how it works" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ describe("NumberedCards Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"bg-transparent",
|
||||
"py-[var(--spacing-scale-032)]"
|
||||
"py-[var(--spacing-scale-032)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -117,7 +117,7 @@ describe("NumberedCards Component", () => {
|
||||
render(<NumberedCards title="Test" subtitle="Test" cards={mockCards} />);
|
||||
|
||||
const cardsContainer = document.querySelector(
|
||||
'[class*="grid grid-cols-1"]'
|
||||
'[class*="grid grid-cols-1"]',
|
||||
);
|
||||
expect(cardsContainer).toBeInTheDocument();
|
||||
});
|
||||
@@ -128,7 +128,7 @@ describe("NumberedCards Component", () => {
|
||||
title="Test Title"
|
||||
subtitle="Test Description"
|
||||
cards={mockCards}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const script = document.querySelector('script[type="application/ld+json"]');
|
||||
@@ -161,7 +161,7 @@ describe("NumberedCards Component", () => {
|
||||
|
||||
// Should render buttons even without cards
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Create CommunityRule" })
|
||||
screen.getByRole("button", { name: "Create CommunityRule" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -180,7 +180,7 @@ describe("NumberedCards Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"py-[var(--spacing-scale-032)]",
|
||||
"sm:py-[var(--spacing-scale-048)]"
|
||||
"sm:py-[var(--spacing-scale-048)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -188,7 +188,7 @@ describe("NumberedCards Component", () => {
|
||||
render(<NumberedCards title="Test" subtitle="Test" cards={mockCards} />);
|
||||
|
||||
const container = document.querySelector(
|
||||
'[class*="max-w-[var(--spacing-measures-max-width-lg)]"]'
|
||||
'[class*="max-w-[var(--spacing-measures-max-width-lg)]"]',
|
||||
);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
+50
-50
@@ -11,36 +11,36 @@ describe("Page", () => {
|
||||
expect(screen.getAllByText("with clarity").length).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Help your community make important decisions in a way that reflects its unique values."
|
||||
).length
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check numbered cards section (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText("How CommunityRule works").length
|
||||
screen.getAllByText("How CommunityRule works").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Here's a quick overview of the process, from start to finish."
|
||||
).length
|
||||
"Here's a quick overview of the process, from start to finish.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check feature grid section (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText("We've got your back, every step of the way").length
|
||||
screen.getAllByText("We've got your back, every step of the way").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Use our toolkit to improve, document, and evolve your organization."
|
||||
).length
|
||||
"Use our toolkit to improve, document, and evolve your organization.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check ask organizer section (using getAllByText since there are multiple instances)
|
||||
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
||||
0
|
||||
0,
|
||||
);
|
||||
expect(
|
||||
screen.getAllByText("Get answers from an experienced organizer").length
|
||||
screen.getAllByText("Get answers from an experienced organizer").length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -52,11 +52,11 @@ describe("Page", () => {
|
||||
expect(screen.getAllByText("with clarity").length).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Help your community make important decisions in a way that reflects its unique values."
|
||||
).length
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText("Learn how CommunityRule works").length
|
||||
screen.getAllByText("Learn how CommunityRule works").length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -65,27 +65,27 @@ describe("Page", () => {
|
||||
|
||||
// Check numbered cards content (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText("How CommunityRule works").length
|
||||
screen.getAllByText("How CommunityRule works").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Here's a quick overview of the process, from start to finish."
|
||||
).length
|
||||
"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("Document how your community makes decisions").length
|
||||
screen.getAllByText("Document how your community makes decisions").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Build an operating manual for a successful community"
|
||||
).length
|
||||
"Build an operating manual for a successful community",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Get a link to your manual for your group to review and evolve"
|
||||
).length
|
||||
"Get a link to your manual for your group to review and evolve",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -94,12 +94,12 @@ describe("Page", () => {
|
||||
|
||||
// Check feature grid content (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText("We've got your back, every step of the way").length
|
||||
screen.getAllByText("We've got your back, every step of the way").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Use our toolkit to improve, document, and evolve your organization."
|
||||
).length
|
||||
"Use our toolkit to improve, document, and evolve your organization.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -108,10 +108,10 @@ describe("Page", () => {
|
||||
|
||||
// Check ask organizer content (using getAllByText since there are multiple instances)
|
||||
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
||||
0
|
||||
0,
|
||||
);
|
||||
expect(
|
||||
screen.getAllByText("Get answers from an experienced organizer").length
|
||||
screen.getAllByText("Get answers from an experienced organizer").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("Ask an organizer").length).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -126,19 +126,19 @@ describe("Page", () => {
|
||||
// LogoWall - should be present (even if just the component structure)
|
||||
// NumberedCards
|
||||
expect(
|
||||
screen.getAllByText("How CommunityRule works").length
|
||||
screen.getAllByText("How CommunityRule works").length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// RuleStack - should be present
|
||||
// FeatureGrid
|
||||
expect(
|
||||
screen.getAllByText("We've got your back, every step of the way").length
|
||||
screen.getAllByText("We've got your back, every step of the way").length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// QuoteBlock - should be present
|
||||
// AskOrganizer
|
||||
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
||||
0
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -154,7 +154,7 @@ describe("Page", () => {
|
||||
|
||||
// Check CTA button in hero banner
|
||||
expect(
|
||||
screen.getAllByText("Learn how CommunityRule works").length
|
||||
screen.getAllByText("Learn how CommunityRule works").length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check CTA button in ask organizer section
|
||||
@@ -167,27 +167,27 @@ describe("Page", () => {
|
||||
// Check main description (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Help your community make important decisions in a way that reflects its unique values."
|
||||
).length
|
||||
"Help your community make important decisions in a way that reflects its unique values.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check numbered cards description (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Here's a quick overview of the process, from start to finish."
|
||||
).length
|
||||
"Here's a quick overview of the process, from start to finish.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check feature grid description (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Use our toolkit to improve, document, and evolve your organization."
|
||||
).length
|
||||
"Use our toolkit to improve, document, and evolve your organization.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
// Check ask organizer description (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText("Get answers from an experienced organizer").length
|
||||
screen.getAllByText("Get answers from an experienced organizer").length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -197,13 +197,13 @@ describe("Page", () => {
|
||||
// Check all section titles (using getAllByText since there are multiple instances)
|
||||
expect(screen.getAllByText("Collaborate").length).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText("How CommunityRule works").length
|
||||
screen.getAllByText("How CommunityRule works").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText("We've got your back, every step of the way").length
|
||||
screen.getAllByText("We've got your back, every step of the way").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("Still have questions?").length).toBeGreaterThan(
|
||||
0
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -212,17 +212,17 @@ describe("Page", () => {
|
||||
|
||||
// Check all three numbered card items (using getAllByText since there are multiple instances)
|
||||
expect(
|
||||
screen.getAllByText("Document how your community makes decisions").length
|
||||
screen.getAllByText("Document how your community makes decisions").length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Build an operating manual for a successful community"
|
||||
).length
|
||||
"Build an operating manual for a successful community",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Get a link to your manual for your group to review and evolve"
|
||||
).length
|
||||
"Get a link to your manual for your group to review and evolve",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
@@ -233,16 +233,16 @@ describe("Page", () => {
|
||||
expect(screen.getAllByText("with clarity").length).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Here's a quick overview of the process, from start to finish."
|
||||
).length
|
||||
"Here's a quick overview of the process, from start to finish.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
"Use our toolkit to improve, document, and evolve your organization."
|
||||
).length
|
||||
"Use our toolkit to improve, document, and evolve your organization.",
|
||||
).length,
|
||||
).toBeGreaterThan(0);
|
||||
expect(
|
||||
screen.getAllByText("Get answers from an experienced organizer").length
|
||||
screen.getAllByText("Get answers from an experienced organizer").length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,11 +12,11 @@ describe("QuoteBlock Component", () => {
|
||||
render(<QuoteBlock />);
|
||||
|
||||
expect(
|
||||
screen.getByText(/The rules of decision-making must be open/)
|
||||
screen.getByText(/The rules of decision-making must be open/),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Jo Freeman")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("The Tyranny of Structurelessness")
|
||||
screen.getByText("The Tyranny of Structurelessness"),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByAltText("Portrait of Jo Freeman")).toBeInTheDocument();
|
||||
});
|
||||
@@ -27,7 +27,7 @@ describe("QuoteBlock Component", () => {
|
||||
quote="Custom quote text"
|
||||
author="Custom Author"
|
||||
source="Custom Source"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Custom quote text")).toBeInTheDocument();
|
||||
@@ -41,7 +41,7 @@ describe("QuoteBlock Component", () => {
|
||||
quote="Test quote"
|
||||
author="Test Author"
|
||||
className="custom-class"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const section = document.querySelector("section");
|
||||
@@ -50,24 +50,24 @@ describe("QuoteBlock Component", () => {
|
||||
|
||||
test("renders different variants", () => {
|
||||
const { rerender } = render(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="compact" />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="compact" />,
|
||||
);
|
||||
|
||||
// Compact variant should have different styling
|
||||
const section = screen.getByRole("region");
|
||||
expect(section).toHaveClass(
|
||||
"py-[var(--spacing-scale-032)]",
|
||||
"px-[var(--spacing-scale-016)]"
|
||||
"px-[var(--spacing-scale-016)]",
|
||||
);
|
||||
|
||||
rerender(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="extended" />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="extended" />,
|
||||
);
|
||||
|
||||
// Extended variant should have different styling
|
||||
expect(section).toHaveClass(
|
||||
"py-[var(--spacing-scale-048)]",
|
||||
"px-[var(--spacing-scale-024)]"
|
||||
"px-[var(--spacing-scale-024)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -77,7 +77,7 @@ describe("QuoteBlock Component", () => {
|
||||
quote="Test quote"
|
||||
author="Test Author"
|
||||
id="custom-quote-id"
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
const quoteElement = screen.getByText("Test quote");
|
||||
@@ -95,7 +95,7 @@ describe("QuoteBlock Component", () => {
|
||||
test("calls onError callback when image fails", () => {
|
||||
const onError = vi.fn();
|
||||
render(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" onError={onError} />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" onError={onError} />,
|
||||
);
|
||||
|
||||
// Should render without errors
|
||||
@@ -112,24 +112,24 @@ describe("QuoteBlock Component", () => {
|
||||
|
||||
test("renders decorative elements for standard variant", () => {
|
||||
render(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="standard" />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="standard" />,
|
||||
);
|
||||
|
||||
// Should render QuoteDecor for standard variant
|
||||
const decor = document.querySelector(
|
||||
'[class*="pointer-events-none absolute z-0"]'
|
||||
'[class*="pointer-events-none absolute z-0"]',
|
||||
);
|
||||
expect(decor).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("does not render decorative elements for compact variant", () => {
|
||||
render(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="compact" />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="compact" />,
|
||||
);
|
||||
|
||||
// Should not render QuoteDecor for compact variant
|
||||
const decor = document.querySelector(
|
||||
'[class*="pointer-events-none absolute z-0"]'
|
||||
'[class*="pointer-events-none absolute z-0"]',
|
||||
);
|
||||
expect(decor).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -149,7 +149,7 @@ describe("QuoteBlock Component", () => {
|
||||
|
||||
test("applies correct accessibility attributes", () => {
|
||||
render(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" id="test-quote" />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" id="test-quote" />,
|
||||
);
|
||||
|
||||
const section = document.querySelector("section");
|
||||
@@ -166,7 +166,7 @@ describe("QuoteBlock Component", () => {
|
||||
expect(section).toHaveClass("md:py-[var(--spacing-scale-032)]");
|
||||
|
||||
const card = section.querySelector(
|
||||
'[class*="bg-[var(--color-surface-default-brand-darker-accent)]"]'
|
||||
'[class*="bg-[var(--color-surface-default-brand-darker-accent)]"]',
|
||||
);
|
||||
expect(card).toBeInTheDocument();
|
||||
});
|
||||
@@ -177,7 +177,7 @@ describe("QuoteBlock Component", () => {
|
||||
render(<QuoteBlock quote="" author="" />);
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
"QuoteBlock: Missing required props (quote or author)"
|
||||
"QuoteBlock: Missing required props (quote or author)",
|
||||
);
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
@@ -199,14 +199,14 @@ describe("QuoteBlock Component", () => {
|
||||
|
||||
test("applies responsive text sizing", () => {
|
||||
render(
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="standard" />
|
||||
<QuoteBlock quote="Test quote" author="Test Author" variant="standard" />,
|
||||
);
|
||||
|
||||
const quoteElement = screen.getByText("Test quote");
|
||||
expect(quoteElement).toHaveClass(
|
||||
"text-[18px]",
|
||||
"md:text-[36px]",
|
||||
"lg:text-[52px]"
|
||||
"lg:text-[52px]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -216,7 +216,7 @@ describe("QuoteBlock Component", () => {
|
||||
expect(screen.getByText("Test quote")).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Author")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText("The Tyranny of Structurelessness")
|
||||
screen.queryByText("The Tyranny of Structurelessness"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,16 +28,16 @@ describe("RuleStack Component", () => {
|
||||
render(<RuleStack />);
|
||||
|
||||
expect(
|
||||
screen.getByText(/Units called Circles have the ability to decide/)
|
||||
screen.getByText(/Units called Circles have the ability to decide/),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Decisions that affect the group collectively/)
|
||||
screen.getByText(/Decisions that affect the group collectively/),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/An elected board determines policies/)
|
||||
screen.getByText(/An elected board determines policies/),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/All participants can propose and vote/)
|
||||
screen.getByText(/All participants can propose and vote/),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -54,7 +54,7 @@ describe("RuleStack Component", () => {
|
||||
render(<RuleStack />);
|
||||
|
||||
expect(
|
||||
screen.getByRole("button", { name: "See all templates" })
|
||||
screen.getByRole("button", { name: "See all templates" }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@ describe("RuleStack Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"py-[var(--spacing-scale-032)]",
|
||||
"px-[var(--spacing-scale-020)]"
|
||||
"px-[var(--spacing-scale-020)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -128,7 +128,7 @@ describe("RuleStack Component", () => {
|
||||
const section = document.querySelector("section");
|
||||
expect(section).toHaveClass(
|
||||
"md:py-[var(--spacing-scale-048)]",
|
||||
"lg:py-[var(--spacing-scale-064)]"
|
||||
"lg:py-[var(--spacing-scale-064)]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -141,7 +141,7 @@ describe("RuleStack Component", () => {
|
||||
"md:w-[56px]",
|
||||
"md:h-[56px]",
|
||||
"lg:w-[90px]",
|
||||
"lg:h-[90px]"
|
||||
"lg:h-[90px]",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -155,7 +155,7 @@ describe("RuleStack Component", () => {
|
||||
// Verify that cards have background color classes
|
||||
cards.forEach((card) => {
|
||||
expect(card.className).toMatch(
|
||||
/bg-\[var\(--color-surface-default-brand-/
|
||||
/bg-\[var\(--color-surface-default-brand-/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -155,7 +155,7 @@ describe("Accessibility - Component Level", () => {
|
||||
}
|
||||
|
||||
const headingLevels = headings.map((heading) =>
|
||||
parseInt(heading.tagName.charAt(1))
|
||||
parseInt(heading.tagName.charAt(1)),
|
||||
);
|
||||
|
||||
// Check that heading levels are sequential (no skipping levels)
|
||||
|
||||
Reference in New Issue
Block a user