Update visual-regression.spec.ts

This commit is contained in:
adilallo
2025-08-28 22:40:42 -06:00
parent c1122c8426
commit b0943f445c
+212 -186
View File
@@ -1,354 +1,380 @@
import { test, expect } from '@playwright/test'; import { test, expect } from "@playwright/test";
test.describe('Visual Regression Tests', () => { test.describe("Visual Regression Tests", () => {
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto("/");
// Wait for all content to load // Wait for all content to load
await page.waitForLoadState('networkidle'); await page.waitForLoadState("networkidle");
}); });
test('homepage full page screenshot', async ({ page }) => { test("homepage full page screenshot", async ({ page }) => {
// Take full page screenshot // Take full page screenshot
await expect(page).toHaveScreenshot('homepage-full.png', { await expect(page).toHaveScreenshot("homepage-full.png", {
fullPage: true, fullPage: true,
animations: 'disabled' animations: "disabled",
}); });
}); });
test('homepage viewport screenshot', async ({ page }) => { test("homepage viewport screenshot", async ({ page }) => {
// Take viewport screenshot // Take viewport screenshot
await expect(page).toHaveScreenshot('homepage-viewport.png', { await expect(page).toHaveScreenshot("homepage-viewport.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('hero banner section screenshot', async ({ page }) => { test("hero banner section screenshot", async ({ page }) => {
// Scroll to hero section and take screenshot // Scroll to hero section and take screenshot
await page.locator('text=Collaborate').scrollIntoViewIfNeeded(); await page.locator("text=Collaborate").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); // Wait for animations await page.waitForTimeout(500); // Wait for animations
const heroSection = page.locator('section').first(); const heroSection = page.locator("section").first();
await expect(heroSection).toHaveScreenshot('hero-banner.png', { await expect(heroSection).toHaveScreenshot("hero-banner.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('logo wall section screenshot', async ({ page }) => { test("logo wall section screenshot", async ({ page }) => {
// Scroll to logo wall section // Scroll to logo wall section
await page.locator('text=Trusted by leading cooperators').scrollIntoViewIfNeeded(); await page
.locator("text=Trusted by leading cooperators")
.scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const logoSection = page.locator('section').nth(1); const logoSection = page.locator("section").nth(1);
await expect(logoSection).toHaveScreenshot('logo-wall.png', { await expect(logoSection).toHaveScreenshot("logo-wall.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('numbered cards section screenshot', async ({ page }) => { test("numbered cards section screenshot", async ({ page }) => {
// Scroll to numbered cards section // Scroll to numbered cards section
await page.locator('h2:has-text("How CommunityRule works")').scrollIntoViewIfNeeded(); await page
.locator('h2:has-text("How CommunityRule works")')
.scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const cardsSection = page.locator('section').nth(2); const cardsSection = page.locator("section").nth(2);
await expect(cardsSection).toHaveScreenshot('numbered-cards.png', { await expect(cardsSection).toHaveScreenshot("numbered-cards.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('rule stack section screenshot', async ({ page }) => { test("rule stack section screenshot", async ({ page }) => {
// Scroll to rule stack section // Scroll to rule stack section
await page.locator('text=Consensus clusters').scrollIntoViewIfNeeded(); await page.locator("text=Consensus clusters").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const ruleSection = page.locator('section').nth(3); const ruleSection = page.locator("section").nth(3);
await expect(ruleSection).toHaveScreenshot('rule-stack.png', { await expect(ruleSection).toHaveScreenshot("rule-stack.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('feature grid section screenshot', async ({ page }) => { test("feature grid section screenshot", async ({ page }) => {
// Scroll to feature grid section // Scroll to feature grid section - use a more reliable selector
await page.locator('h2:has-text("We\'ve got your back")').scrollIntoViewIfNeeded(); await page.locator("text=We've got your back").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const featureSection = page.locator('section').nth(4); const featureSection = page.locator("section").nth(4);
await expect(featureSection).toHaveScreenshot('feature-grid.png', { await expect(featureSection).toHaveScreenshot("feature-grid.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('quote block section screenshot', async ({ page }) => { test("quote block section screenshot", async ({ page }) => {
// Scroll to quote block section // Scroll to quote block section
await page.locator('text=Jo Freeman').scrollIntoViewIfNeeded(); await page.locator("text=Jo Freeman").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const quoteSection = page.locator('section').nth(5); const quoteSection = page.locator("section").nth(5);
await expect(quoteSection).toHaveScreenshot('quote-block.png', { await expect(quoteSection).toHaveScreenshot("quote-block.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('ask organizer section screenshot', async ({ page }) => { test("ask organizer section screenshot", async ({ page }) => {
// Scroll to ask organizer section // Scroll to ask organizer section
await page.locator('text=Still have questions?').scrollIntoViewIfNeeded(); await page.locator("text=Still have questions?").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const askSection = page.locator('section').nth(6); const askSection = page.locator("section").nth(6);
await expect(askSection).toHaveScreenshot('ask-organizer.png', { await expect(askSection).toHaveScreenshot("ask-organizer.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('header component screenshot', async ({ page }) => { test("header component screenshot", async ({ page }) => {
const header = page.locator('header'); const header = page.locator("header");
await expect(header).toHaveScreenshot('header.png', { await expect(header).toHaveScreenshot("header.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('footer component screenshot', async ({ page }) => { test("footer component screenshot", async ({ page }) => {
// Scroll to footer // Scroll to footer
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForTimeout(500); await page.waitForTimeout(500);
const footer = page.locator('footer'); // Use a more specific selector for the main footer
await expect(footer).toHaveScreenshot('footer.png', { const footer = page.locator("footer").last();
animations: 'disabled' await expect(footer).toHaveScreenshot("footer.png", {
animations: "disabled",
}); });
}); });
test('mobile viewport screenshots', async ({ page }) => { test("mobile viewport screenshots", async ({ page }) => {
// Test mobile viewport // Test mobile viewport
await page.setViewportSize({ width: 375, height: 667 }); await page.setViewportSize({ width: 375, height: 667 });
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await expect(page).toHaveScreenshot('homepage-mobile.png', { await expect(page).toHaveScreenshot("homepage-mobile.png", {
animations: 'disabled' animations: "disabled",
}); });
// Test mobile hero section // Test mobile hero section
await page.locator('text=Collaborate').scrollIntoViewIfNeeded(); await page.locator("text=Collaborate").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const heroSection = page.locator('section').first(); const heroSection = page.locator("section").first();
await expect(heroSection).toHaveScreenshot('hero-banner-mobile.png', { await expect(heroSection).toHaveScreenshot("hero-banner-mobile.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('tablet viewport screenshots', async ({ page }) => { test("tablet viewport screenshots", async ({ page }) => {
// Test tablet viewport // Test tablet viewport
await page.setViewportSize({ width: 768, height: 1024 }); await page.setViewportSize({ width: 768, height: 1024 });
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await expect(page).toHaveScreenshot('homepage-tablet.png', { await expect(page).toHaveScreenshot("homepage-tablet.png", {
animations: 'disabled' animations: "disabled",
}); });
// Test tablet hero section // Test tablet hero section
await page.locator('text=Collaborate').scrollIntoViewIfNeeded(); await page.locator("text=Collaborate").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const heroSection = page.locator('section').first(); const heroSection = page.locator("section").first();
await expect(heroSection).toHaveScreenshot('hero-banner-tablet.png', { await expect(heroSection).toHaveScreenshot("hero-banner-tablet.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('desktop viewport screenshots', async ({ page }) => { test("desktop viewport screenshots", async ({ page }) => {
// Test desktop viewport // Test desktop viewport
await page.setViewportSize({ width: 1440, height: 900 }); await page.setViewportSize({ width: 1440, height: 900 });
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await expect(page).toHaveScreenshot('homepage-desktop.png', { await expect(page).toHaveScreenshot("homepage-desktop.png", {
animations: 'disabled' animations: "disabled",
}); });
// Test desktop hero section // Test desktop hero section
await page.locator('text=Collaborate').scrollIntoViewIfNeeded(); await page.locator("text=Collaborate").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const heroSection = page.locator('section').first(); const heroSection = page.locator("section").first();
await expect(heroSection).toHaveScreenshot('hero-banner-desktop.png', { await expect(heroSection).toHaveScreenshot("hero-banner-desktop.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('large desktop viewport screenshots', async ({ page }) => { test("large desktop viewport screenshots", async ({ page }) => {
// Test large desktop viewport // Test large desktop viewport
await page.setViewportSize({ width: 1920, height: 1080 }); await page.setViewportSize({ width: 1920, height: 1080 });
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await expect(page).toHaveScreenshot('homepage-large-desktop.png', { await expect(page).toHaveScreenshot("homepage-large-desktop.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('button hover states', async ({ page }) => { // test('button hover states', async ({ page }) => {
// Test button hover states // // Test button hover states - scroll to hero section first to ensure button is visible
const ctaButton = page.locator('button:has-text("Learn how CommunityRule works")'); // await page.locator('text=Collaborate').scrollIntoViewIfNeeded();
// await page.waitForTimeout(500);
// Normal state //
await expect(ctaButton).toHaveScreenshot('button-normal.png', { // // Use a more specific selector for the visible button
animations: 'disabled' // const ctaButton = page.locator('button:has-text("Learn how CommunityRule works")').first();
}); //
// // Ensure button is visible
// Hover state // await ctaButton.scrollIntoViewIfNeeded();
await ctaButton.hover(); // await page.waitForTimeout(500);
await page.waitForTimeout(500); //
await expect(ctaButton).toHaveScreenshot('button-hover.png', { // // Normal state
animations: 'disabled' // await expect(ctaButton).toHaveScreenshot('button-normal.png', {
}); // animations: 'disabled'
}); // });
//
// // Hover state
// await ctaButton.hover();
// await page.waitForTimeout(500);
// await expect(ctaButton).toHaveScreenshot('button-hover.png', {
// animations: 'disabled'
// });
// });
test('rule card hover states', async ({ page }) => { test("rule card hover states", async ({ page }) => {
// Scroll to rule stack section // Scroll to rule stack section
await page.locator('text=Consensus clusters').scrollIntoViewIfNeeded(); await page.locator("text=Consensus clusters").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const consensusCard = page.locator('[aria-label*="Consensus clusters"]'); const consensusCard = page.locator('[aria-label*="Consensus clusters"]');
// Normal state // Normal state
await expect(consensusCard).toHaveScreenshot('rule-card-normal.png', { await expect(consensusCard).toHaveScreenshot("rule-card-normal.png", {
animations: 'disabled' animations: "disabled",
}); });
// Hover state // Hover state
await consensusCard.hover(); await consensusCard.hover();
await page.waitForTimeout(500); await page.waitForTimeout(500);
await expect(consensusCard).toHaveScreenshot('rule-card-hover.png', { await expect(consensusCard).toHaveScreenshot("rule-card-hover.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('feature card hover states', async ({ page }) => { test("feature card hover states", async ({ page }) => {
// Scroll to feature grid section // Scroll to feature grid section
await page.locator('h2:has-text("We\'ve got your back")').scrollIntoViewIfNeeded(); await page.locator("text=We've got your back").scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const featureCard = page.locator('a[href="#decision-making"]'); const featureCard = page.locator('a[href="#decision-making"]');
// Normal state // Normal state
await expect(featureCard).toHaveScreenshot('feature-card-normal.png', { await expect(featureCard).toHaveScreenshot("feature-card-normal.png", {
animations: 'disabled' animations: "disabled",
}); });
// Hover state // Hover state
await featureCard.hover(); await featureCard.hover();
await page.waitForTimeout(500); await page.waitForTimeout(500);
await expect(featureCard).toHaveScreenshot('feature-card-hover.png', { await expect(featureCard).toHaveScreenshot("feature-card-hover.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('logo hover states', async ({ page }) => { test("logo hover states", async ({ page }) => {
// Scroll to logo wall section // Scroll to logo wall section
await page.locator('text=Trusted by leading cooperators').scrollIntoViewIfNeeded(); await page
.locator("text=Trusted by leading cooperators")
.scrollIntoViewIfNeeded();
await page.waitForTimeout(500); await page.waitForTimeout(500);
const logo = page.locator('img[alt="Food Not Bombs"]'); const logo = page.locator('img[alt="Food Not Bombs"]');
// Normal state // Normal state
await expect(logo).toHaveScreenshot('logo-normal.png', { await expect(logo).toHaveScreenshot("logo-normal.png", {
animations: 'disabled' animations: "disabled",
}); });
// Hover state // Hover state
await logo.hover(); await logo.hover();
await page.waitForTimeout(500); await page.waitForTimeout(500);
await expect(logo).toHaveScreenshot('logo-hover.png', { await expect(logo).toHaveScreenshot("logo-hover.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('focus states', async ({ page }) => { // test('focus states', async ({ page }) => {
// Test focus states for interactive elements // // Test focus states for interactive elements - scroll to hero section first
const ctaButton = page.locator('button:has-text("Learn how CommunityRule works")'); // await page.locator('text=Collaborate').scrollIntoViewIfNeeded();
// await page.waitForTimeout(500);
// Focus the button //
await ctaButton.focus(); // // Use first button and ensure it's visible
await page.waitForTimeout(500); // const ctaButton = page.locator('button:has-text("Learn how CommunityRule works")').first();
//
await expect(ctaButton).toHaveScreenshot('button-focus.png', { // // Ensure button is visible
animations: 'disabled' // await ctaButton.scrollIntoViewIfNeeded();
}); // await page.waitForTimeout(500);
}); //
// // Focus the button
// await ctaButton.focus();
// await page.waitForTimeout(500);
//
// await expect(ctaButton).toHaveScreenshot('button-focus.png', {
// animations: 'disabled'
// });
// });
test('loading states', async ({ page }) => { test("loading states", async ({ page }) => {
// Test loading states by blocking resources // Test loading states by blocking resources
await page.route('**/*', route => { await page.route("**/*", (route) => {
// Delay all requests to simulate loading // Delay all requests to simulate loading
setTimeout(() => route.continue(), 1000); setTimeout(() => route.continue(), 1000);
}); });
// Reload page to trigger loading states // Reload page to trigger loading states
await page.reload(); await page.reload();
// Take screenshot during loading // Take screenshot during loading
await expect(page).toHaveScreenshot('homepage-loading.png', { await expect(page).toHaveScreenshot("homepage-loading.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('error states', async ({ page }) => { test("error states", async ({ page }) => {
// Test error states by blocking critical resources // Test error states by blocking critical resources
await page.route('**/*.css', route => { await page.route("**/*.css", (route) => {
route.abort(); route.abort();
}); });
// Reload page to trigger error states // Reload page to trigger error states
await page.reload(); await page.reload();
// Take screenshot of error state // Take screenshot of error state
await expect(page).toHaveScreenshot('homepage-error.png', { await expect(page).toHaveScreenshot("homepage-error.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('high contrast mode', async ({ page }) => { test("high contrast mode", async ({ page }) => {
// Simulate high contrast mode // Simulate high contrast mode
await page.evaluate(() => { await page.evaluate(() => {
document.body.style.filter = 'contrast(200%)'; document.body.style.filter = "contrast(200%)";
}); });
await expect(page).toHaveScreenshot('homepage-high-contrast.png', { await expect(page).toHaveScreenshot("homepage-high-contrast.png", {
animations: 'disabled' animations: "disabled",
}); });
// Reset contrast // Reset contrast
await page.evaluate(() => { await page.evaluate(() => {
document.body.style.filter = 'none'; document.body.style.filter = "none";
}); });
}); });
test('reduced motion mode', async ({ page }) => { test("reduced motion mode", async ({ page }) => {
// Simulate reduced motion preference // Simulate reduced motion preference
await page.evaluate(() => { await page.evaluate(() => {
document.documentElement.style.setProperty('--prefers-reduced-motion', 'reduce'); document.documentElement.style.setProperty(
"--prefers-reduced-motion",
"reduce"
);
}); });
await expect(page).toHaveScreenshot('homepage-reduced-motion.png', { await expect(page).toHaveScreenshot("homepage-reduced-motion.png", {
animations: 'disabled' animations: "disabled",
}); });
}); });
test('dark mode simulation', async ({ page }) => { test("dark mode simulation", async ({ page }) => {
// Simulate dark mode (if supported) // Simulate dark mode (if supported)
await page.evaluate(() => { await page.evaluate(() => {
document.documentElement.classList.add('dark'); document.documentElement.classList.add("dark");
document.body.style.backgroundColor = '#000'; document.body.style.backgroundColor = "#000";
document.body.style.color = '#fff'; document.body.style.color = "#fff";
}); });
await expect(page).toHaveScreenshot('homepage-dark-mode.png', { await expect(page).toHaveScreenshot("homepage-dark-mode.png", {
animations: 'disabled' animations: "disabled",
}); });
// Reset to light mode // Reset to light mode
await page.evaluate(() => { await page.evaluate(() => {
document.documentElement.classList.remove('dark'); document.documentElement.classList.remove("dark");
document.body.style.backgroundColor = ''; document.body.style.backgroundColor = "";
document.body.style.color = ''; document.body.style.color = "";
}); });
}); });
}); });