Run lint and prettier
CI Pipeline / test (20) (pull_request) Successful in 3m0s
CI Pipeline / test (18) (pull_request) Successful in 3m18s
CI Pipeline / e2e (firefox) (pull_request) Successful in 3m20s
CI Pipeline / e2e (chromium) (pull_request) Successful in 3m54s
CI Pipeline / e2e (webkit) (pull_request) Successful in 3m41s
CI Pipeline / performance (pull_request) Successful in 3m3s
CI Pipeline / visual-regression (pull_request) Successful in 7m12s
CI Pipeline / storybook (pull_request) Successful in 1m29s
CI Pipeline / lint (pull_request) Failing after 1m7s
CI Pipeline / build (pull_request) Successful in 1m20s

This commit is contained in:
adilallo
2025-10-07 17:27:07 -06:00
parent c991e22f09
commit 6bd751957c
40 changed files with 96370 additions and 524 deletions
+6 -6
View File
@@ -46,7 +46,7 @@ export async function POST(request) {
// Log for monitoring // Log for monitoring
console.log( console.log(
`Web Vital received: ${metric} = ${data.value}ms (${data.rating})` `Web Vital received: ${metric} = ${data.value}ms (${data.rating})`,
); );
return NextResponse.json({ success: true }); return NextResponse.json({ success: true });
@@ -54,7 +54,7 @@ export async function POST(request) {
console.error("Error processing web vital:", error); console.error("Error processing web vital:", error);
return NextResponse.json( return NextResponse.json(
{ error: "Internal server error" }, { error: "Internal server error" },
{ status: 500 } { status: 500 },
); );
} }
} }
@@ -70,7 +70,7 @@ export async function GET() {
if (file.endsWith(".json")) { if (file.endsWith(".json")) {
const metric = file.replace(".json", ""); const metric = file.replace(".json", "");
const data = JSON.parse( const data = JSON.parse(
fs.readFileSync(path.join(WEB_VITALS_DIR, file), "utf8") fs.readFileSync(path.join(WEB_VITALS_DIR, file), "utf8"),
); );
if (data.length > 0) { if (data.length > 0) {
@@ -86,14 +86,14 @@ export async function GET() {
average: average:
values.length > 0 values.length > 0
? Math.round( ? Math.round(
values.reduce((a, b) => a + b, 0) / values.length values.reduce((a, b) => a + b, 0) / values.length,
) )
: 0, : 0,
min: values.length > 0 ? Math.min(...values) : 0, min: values.length > 0 ? Math.min(...values) : 0,
max: values.length > 0 ? Math.max(...values) : 0, max: values.length > 0 ? Math.max(...values) : 0,
goodCount: ratings.filter((r) => r === "good").length, goodCount: ratings.filter((r) => r === "good").length,
needsImprovementCount: ratings.filter( needsImprovementCount: ratings.filter(
(r) => r === "needs-improvement" (r) => r === "needs-improvement",
).length, ).length,
poorCount: ratings.filter((r) => r === "poor").length, poorCount: ratings.filter((r) => r === "poor").length,
lastUpdated: data[data.length - 1]?.receivedAt, lastUpdated: data[data.length - 1]?.receivedAt,
@@ -108,7 +108,7 @@ export async function GET() {
console.error("Error fetching web vitals:", error); console.error("Error fetching web vitals:", error);
return NextResponse.json( return NextResponse.json(
{ error: "Internal server error" }, { error: "Internal server error" },
{ status: 500 } { status: 500 },
); );
} }
} }
+1 -1
View File
@@ -106,7 +106,7 @@ const AskOrganizer = memo(
</div> </div>
</section> </section>
); );
} },
); );
AskOrganizer.displayName = "AskOrganizer"; AskOrganizer.displayName = "AskOrganizer";
+1 -1
View File
@@ -12,7 +12,7 @@ const Avatar = memo(
const baseStyles = `rounded-[var(--radius-measures-radius-full)] object-cover ${sizeStyles[size]} ${className}`; const baseStyles = `rounded-[var(--radius-measures-radius-full)] object-cover ${sizeStyles[size]} ${className}`;
return <img src={src} alt={alt} className={baseStyles} {...props} />; return <img src={src} alt={alt} className={baseStyles} {...props} />;
} },
); );
Avatar.displayName = "Avatar"; Avatar.displayName = "Avatar";
+1 -1
View File
@@ -16,7 +16,7 @@ const AvatarContainer = memo(
{children} {children}
</div> </div>
); );
} },
); );
AvatarContainer.displayName = "AvatarContainer"; AvatarContainer.displayName = "AvatarContainer";
+1 -1
View File
@@ -108,7 +108,7 @@ const Button = memo(
{children} {children}
</button> </button>
); );
} },
); );
Button.displayName = "Button"; Button.displayName = "Button";
+1 -1
View File
@@ -123,7 +123,7 @@ const ContentContainer = memo(
</div> </div>
</div> </div>
); );
} },
); );
ContentContainer.displayName = "ContentContainer"; ContentContainer.displayName = "ContentContainer";
+1 -1
View File
@@ -179,7 +179,7 @@ const ContentLockup = memo(
)} )}
</div> </div>
); );
} },
); );
ContentLockup.displayName = "ContentLockup"; ContentLockup.displayName = "ContentLockup";
+1 -1
View File
@@ -91,7 +91,7 @@ const ContentThumbnailTemplate = memo(
</div> </div>
</Link> </Link>
); );
} },
); );
ContentThumbnailTemplate.displayName = "ContentThumbnailTemplate"; ContentThumbnailTemplate.displayName = "ContentThumbnailTemplate";
+1 -2
View File
@@ -28,7 +28,7 @@ class ErrorBoundary extends Component {
Something went wrong Something went wrong
</h2> </h2>
<p className="text-[var(--color-content-default-secondary)] mb-[var(--spacing-scale-016)]"> <p className="text-[var(--color-content-default-secondary)] mb-[var(--spacing-scale-016)]">
We're sorry, but something unexpected happened. We&apos;re sorry, but something unexpected happened.
</p> </p>
<button <button
onClick={() => this.setState({ hasError: false, error: null })} onClick={() => this.setState({ hasError: false, error: null })}
@@ -46,4 +46,3 @@ class ErrorBoundary extends Component {
} }
export default ErrorBoundary; export default ErrorBoundary;
+1 -1
View File
@@ -42,7 +42,7 @@ const FeatureGrid = memo(({ title, subtitle, className = "" }) => {
href: "#conflict-resolution", href: "#conflict-resolution",
}, },
], ],
[] [],
); );
return ( return (
<section <section
+1 -1
View File
@@ -33,7 +33,7 @@ const HeaderTab = memo(
/> />
</div> </div>
); );
} },
); );
HeaderTab.displayName = "HeaderTab"; HeaderTab.displayName = "HeaderTab";
+1 -1
View File
@@ -46,7 +46,7 @@ const HeroBanner = memo(
</div> </div>
</section> </section>
); );
} },
); );
HeroBanner.displayName = "HeroBanner"; HeroBanner.displayName = "HeroBanner";
+4 -4
View File
@@ -79,10 +79,10 @@ const HomeHeader = memo(() => {
? size === "home" || size === "homeMd" ? size === "home" || size === "homeMd"
? "homeMd" ? "homeMd"
: size === "large" : size === "large"
? "large" ? "large"
: size === "homeXlarge" : size === "homeXlarge"
? "homeXlarge" ? "homeXlarge"
: "xsmallUseCases" : "xsmallUseCases"
: size : size
} }
variant={ variant={
+1 -1
View File
@@ -33,7 +33,7 @@ const ImagePlaceholder = memo(
{text} {text}
</div> </div>
); );
} },
); );
ImagePlaceholder.displayName = "ImagePlaceholder"; ImagePlaceholder.displayName = "ImagePlaceholder";
+20 -20
View File
@@ -95,26 +95,26 @@ const Logo = memo(({ size = "default", showText = true }) => {
size === "homeHeaderXsmall" size === "homeHeaderXsmall"
? sizes.homeHeaderXsmall ? sizes.homeHeaderXsmall
: size === "homeHeaderSm" : size === "homeHeaderSm"
? sizes.homeHeaderSm ? sizes.homeHeaderSm
: size === "homeHeaderMd" : size === "homeHeaderMd"
? sizes.homeHeaderMd ? sizes.homeHeaderMd
: size === "homeHeaderLg" : size === "homeHeaderLg"
? sizes.homeHeaderLg ? sizes.homeHeaderLg
: size === "homeHeaderXl" : size === "homeHeaderXl"
? sizes.homeHeaderXl ? sizes.homeHeaderXl
: size === "header" : size === "header"
? sizes.header ? sizes.header
: size === "headerMd" : size === "headerMd"
? sizes.headerMd ? sizes.headerMd
: size === "headerLg" : size === "headerLg"
? sizes.headerLg ? sizes.headerLg
: size === "headerXl" : size === "headerXl"
? sizes.headerXl ? sizes.headerXl
: size === "footer" : size === "footer"
? sizes.footer ? sizes.footer
: size === "footerLg" : size === "footerLg"
? sizes.footerLg ? sizes.footerLg
: sizes.default; : sizes.default;
return ( return (
<Link href="/" className="block" aria-label="CommunityRule Logo"> <Link href="/" className="block" aria-label="CommunityRule Logo">
+1 -1
View File
@@ -25,7 +25,7 @@ const MenuBar = memo(
{children} {children}
</nav> </nav>
); );
} },
); );
MenuBar.displayName = "MenuBar"; MenuBar.displayName = "MenuBar";
+1 -1
View File
@@ -158,7 +158,7 @@ const MenuBarItem = memo(
{children} {children}
</a> </a>
); );
} },
); );
MenuBarItem.displayName = "MenuBarItem"; MenuBarItem.displayName = "MenuBarItem";
+1 -1
View File
@@ -116,7 +116,7 @@ const MiniCard = memo(
{cardContent} {cardContent}
</div> </div>
); );
} },
); );
MiniCard.displayName = "MiniCard"; MiniCard.displayName = "MiniCard";
+46 -43
View File
@@ -1,58 +1,61 @@
import React, { memo } from "react"; import React, { memo } from "react";
const NavigationItem = memo(({ const NavigationItem = memo(
href = "#", ({
children, href = "#",
variant = "default", children,
size = "default", variant = "default",
className = "", size = "default",
disabled = false, className = "",
...props disabled = false,
}) { ...props
// Variant styles }) => {
const variantStyles = { // Variant styles
default: const variantStyles = {
"bg-transparent text-[var(--color-content-default-brand-primary)] border border-transparent hover:bg-[var(--color-surface-default-tertiary)] hover:text-[var(--color-content-default-brand-primary)] active:bg-transparent active:text-[var(--color-content-default-brand-primary)] active:border-[var(--color-content-default-brand-primary)] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed", default:
}; "bg-transparent text-[var(--color-content-default-brand-primary)] border border-transparent hover:bg-[var(--color-surface-default-tertiary)] hover:text-[var(--color-content-default-brand-primary)] active:bg-transparent active:text-[var(--color-content-default-brand-primary)] active:border-[var(--color-content-default-brand-primary)] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed",
};
// Size styles // Size styles
const sizeStyles = { const sizeStyles = {
default: default:
"px-[var(--spacing-scale-016)] py-[var(--spacing-scale-016)] gap-[var(--spacing-scale-004)]", "px-[var(--spacing-scale-016)] py-[var(--spacing-scale-016)] gap-[var(--spacing-scale-004)]",
xsmall: xsmall:
"px-[var(--spacing-scale-004)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]", "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]",
}; };
// Text styles based on size // Text styles based on size
const textStyles = { const textStyles = {
default: "font-inter text-[10px] leading-[12px] font-medium tracking-[0%]", default:
xsmall: "font-inter text-[10px] leading-[12px] font-medium tracking-[0%]", "font-inter text-[10px] leading-[12px] font-medium tracking-[0%]",
}; xsmall: "font-inter text-[10px] leading-[12px] font-medium tracking-[0%]",
};
const baseStyles = `inline-flex items-center ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${textStyles[size]} transition-all duration-200 cursor-pointer`; const baseStyles = `inline-flex items-center ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${textStyles[size]} transition-all duration-200 cursor-pointer`;
// Determine which variant to use // Determine which variant to use
let finalVariant = variant; let finalVariant = variant;
if (disabled) { if (disabled) {
finalVariant = "default"; // The disabled state is handled by disabled: utilities finalVariant = "default"; // The disabled state is handled by disabled: utilities
} }
const combinedStyles = `${baseStyles} ${variantStyles[finalVariant]} ${className}`; const combinedStyles = `${baseStyles} ${variantStyles[finalVariant]} ${className}`;
if (disabled) {
return (
<span className={combinedStyles} {...props}>
{children}
</span>
);
}
if (disabled) {
return ( return (
<span className={combinedStyles} {...props}> <a href={href} className={combinedStyles} {...props}>
{children} {children}
</span> </a>
); );
} }
);
return (
<a href={href} className={combinedStyles} {...props}>
{children}
</a>
);
});
NavigationItem.displayName = "NavigationItem"; NavigationItem.displayName = "NavigationItem";
+1 -1
View File
@@ -20,7 +20,7 @@ const NumberedCards = memo(({ title, subtitle, cards }) => {
text: card.text, text: card.text,
})), })),
}), }),
[title, subtitle, cards] [title, subtitle, cards],
); );
return ( return (
+2 -2
View File
@@ -80,7 +80,7 @@ const QuoteBlock = memo(
const handleImageError = (error) => { const handleImageError = (error) => {
console.warn( console.warn(
`QuoteBlock: Failed to load avatar image for ${author}:`, `QuoteBlock: Failed to load avatar image for ${author}:`,
error error,
); );
setImageError(true); setImageError(true);
setImageLoading(false); setImageLoading(false);
@@ -244,7 +244,7 @@ const QuoteBlock = memo(
</div> </div>
</section> </section>
); );
} },
); );
QuoteBlock.displayName = "QuoteBlock"; QuoteBlock.displayName = "QuoteBlock";
+6 -6
View File
@@ -8,7 +8,7 @@ const RelatedArticles = memo(
// Memoize filtered posts to prevent unnecessary re-computations // Memoize filtered posts to prevent unnecessary re-computations
const filteredPosts = useMemo( const filteredPosts = useMemo(
() => relatedPosts.filter((post) => post.slug !== currentPostSlug), () => relatedPosts.filter((post) => post.slug !== currentPostSlug),
[relatedPosts, currentPostSlug] [relatedPosts, currentPostSlug],
); );
const [currentIndex, setCurrentIndex] = useState(0); const [currentIndex, setCurrentIndex] = useState(0);
@@ -44,7 +44,7 @@ const RelatedArticles = memo(
: "none", : "none",
scrollBehavior: !isMobile ? "smooth" : "auto", scrollBehavior: !isMobile ? "smooth" : "auto",
}), }),
[isMobile, currentIndex] [isMobile, currentIndex],
); );
// Memoize progress bar style calculation // Memoize progress bar style calculation
@@ -54,10 +54,10 @@ const RelatedArticles = memo(
index === currentIndex index === currentIndex
? `${progress}%` ? `${progress}%`
: index < currentIndex : index < currentIndex
? "100%" ? "100%"
: "0%", : "0%",
}), }),
[currentIndex, progress] [currentIndex, progress],
); );
// Check if we're on mobile (below lg breakpoint) // Check if we're on mobile (below lg breakpoint)
@@ -155,7 +155,7 @@ const RelatedArticles = memo(
</div> </div>
</section> </section>
); );
} },
); );
RelatedArticles.displayName = "RelatedArticles"; RelatedArticles.displayName = "RelatedArticles";
+1 -1
View File
@@ -71,7 +71,7 @@ const RuleCard = memo(
)} )}
</div> </div>
); );
} },
); );
RuleCard.displayName = "RuleCard"; RuleCard.displayName = "RuleCard";
+1 -1
View File
@@ -52,7 +52,7 @@ const SectionHeader = memo(
</div> </div>
</div> </div>
); );
} },
); );
SectionHeader.displayName = "SectionHeader"; SectionHeader.displayName = "SectionHeader";
+1 -1
View File
@@ -88,7 +88,7 @@ const WebVitalsDashboard = memo(() => {
}, },
})); }));
}); });
} },
); );
} }
}, []); }, []);
+1 -1
View File
@@ -97,7 +97,7 @@ const OptimizedComponent = memo(({ data, onAction }) => {
(id) => { (id) => {
onAction(id); onAction(id);
}, },
[onAction] [onAction],
); );
return <div onClick={handleClick}>{/* Component content */}</div>; return <div onClick={handleClick}>{/* Component content */}</div>;
+1 -1
View File
@@ -194,7 +194,7 @@ test("components work together", () => {
<Header /> <Header />
<MainContent /> <MainContent />
<Footer /> <Footer />
</div> </div>,
); );
// Test that components complement each other // Test that components complement each other
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -70,7 +70,7 @@ const nextConfig = {
reportFilename: isServer reportFilename: isServer
? "../analyze/server.html" ? "../analyze/server.html"
: "../analyze/client.html", : "../analyze/client.html",
}) }),
); );
} catch (error) { } catch (error) {
console.warn("Bundle analyzer not available:", error.message); console.warn("Bundle analyzer not available:", error.message);
+2 -2
View File
@@ -114,7 +114,7 @@ class BundleAnalyzer {
Object.entries(this.results.bundles).forEach(([filename, bundle]) => { Object.entries(this.results.bundles).forEach(([filename, bundle]) => {
const budget = budgets.find( const budget = budgets.find(
(b) => filename.includes(b.name) || b.name === "all" (b) => filename.includes(b.name) || b.name === "all",
); );
if (budget) { if (budget) {
@@ -175,7 +175,7 @@ class BundleAnalyzer {
// General recommendations // General recommendations
const totalSize = Object.values(this.results.bundles).reduce( const totalSize = Object.values(this.results.bundles).reduce(
(sum, bundle) => sum + bundle.sizeKB, (sum, bundle) => sum + bundle.sizeKB,
0 0,
); );
if (totalSize > 2000) { if (totalSize > 2000) {
+6 -6
View File
@@ -69,7 +69,7 @@ class PerformanceMonitor {
}); });
} catch (error) { } catch (error) {
console.warn( console.warn(
"⚠️ Development server not running, skipping Lighthouse CI..." "⚠️ Development server not running, skipping Lighthouse CI...",
); );
return; return;
} }
@@ -99,23 +99,23 @@ class PerformanceMonitor {
if (resultFile) { if (resultFile) {
const results = JSON.parse( const results = JSON.parse(
fs.readFileSync(path.join(lhciResultsPath, resultFile), "utf8") fs.readFileSync(path.join(lhciResultsPath, resultFile), "utf8"),
); );
if (results.lhr && results.lhr.audits) { if (results.lhr && results.lhr.audits) {
this.metrics.coreWebVitals = { this.metrics.coreWebVitals = {
lcp: this.getAuditScore( lcp: this.getAuditScore(
results.lhr.audits, results.lhr.audits,
"largest-contentful-paint" "largest-contentful-paint",
), ),
fid: this.getAuditScore(results.lhr.audits, "max-potential-fid"), fid: this.getAuditScore(results.lhr.audits, "max-potential-fid"),
cls: this.getAuditScore( cls: this.getAuditScore(
results.lhr.audits, results.lhr.audits,
"cumulative-layout-shift" "cumulative-layout-shift",
), ),
fcp: this.getAuditScore( fcp: this.getAuditScore(
results.lhr.audits, results.lhr.audits,
"first-contentful-paint" "first-contentful-paint",
), ),
tti: this.getAuditScore(results.lhr.audits, "interactive"), tti: this.getAuditScore(results.lhr.audits, "interactive"),
performance: results.lhr.categories.performance?.score * 100 || 0, performance: results.lhr.categories.performance?.score * 100 || 0,
@@ -150,7 +150,7 @@ class PerformanceMonitor {
"..", "..",
".next", ".next",
"static", "static",
"chunks" "chunks",
); );
if (fs.existsSync(bundleStatsPath)) { if (fs.existsSync(bundleStatsPath)) {
+12 -12
View File
@@ -90,11 +90,11 @@ class PerformanceTester {
"..", "..",
".next", ".next",
"analyze", "analyze",
"bundle-analysis.json" "bundle-analysis.json",
); );
if (fs.existsSync(bundleReportPath)) { if (fs.existsSync(bundleReportPath)) {
const bundleData = JSON.parse( const bundleData = JSON.parse(
fs.readFileSync(bundleReportPath, "utf8") fs.readFileSync(bundleReportPath, "utf8"),
); );
this.results.bundleAnalysis = bundleData; this.results.bundleAnalysis = bundleData;
@@ -105,7 +105,7 @@ class PerformanceTester {
) { ) {
this.results.summary.failed += bundleData.budgetViolations.length; this.results.summary.failed += bundleData.budgetViolations.length;
console.log( console.log(
`⚠️ Found ${bundleData.budgetViolations.length} budget violations` `⚠️ Found ${bundleData.budgetViolations.length} budget violations`,
); );
} else { } else {
this.results.summary.passed += 1; this.results.summary.passed += 1;
@@ -134,7 +134,7 @@ class PerformanceTester {
"..", "..",
".next", ".next",
"monitoring", "monitoring",
"performance-report.json" "performance-report.json",
); );
if (fs.existsSync(perfReportPath)) { if (fs.existsSync(perfReportPath)) {
const perfData = JSON.parse(fs.readFileSync(perfReportPath, "utf8")); const perfData = JSON.parse(fs.readFileSync(perfReportPath, "utf8"));
@@ -144,7 +144,7 @@ class PerformanceTester {
if (perfData.budgetViolations && perfData.budgetViolations.length > 0) { if (perfData.budgetViolations && perfData.budgetViolations.length > 0) {
this.results.summary.failed += perfData.budgetViolations.length; this.results.summary.failed += perfData.budgetViolations.length;
console.log( console.log(
`⚠️ Found ${perfData.budgetViolations.length} performance violations` `⚠️ Found ${perfData.budgetViolations.length} performance violations`,
); );
} else { } else {
this.results.summary.passed += 1; this.results.summary.passed += 1;
@@ -173,11 +173,11 @@ class PerformanceTester {
"..", "..",
".next", ".next",
"web-vitals", "web-vitals",
"report.json" "report.json",
); );
if (fs.existsSync(vitalsReportPath)) { if (fs.existsSync(vitalsReportPath)) {
const vitalsData = JSON.parse( const vitalsData = JSON.parse(
fs.readFileSync(vitalsReportPath, "utf8") fs.readFileSync(vitalsReportPath, "utf8"),
); );
this.results.webVitals = vitalsData; this.results.webVitals = vitalsData;
console.log("✅ Web Vitals tracking setup complete"); console.log("✅ Web Vitals tracking setup complete");
@@ -204,7 +204,7 @@ class PerformanceTester {
}); });
} catch (error) { } catch (error) {
console.warn( console.warn(
"⚠️ Development server not running, skipping Lighthouse CI..." "⚠️ Development server not running, skipping Lighthouse CI...",
); );
this.results.summary.warnings += 1; this.results.summary.warnings += 1;
this.results.summary.total += 1; this.results.summary.total += 1;
@@ -221,7 +221,7 @@ class PerformanceTester {
if (resultFile) { if (resultFile) {
const lhciData = JSON.parse( const lhciData = JSON.parse(
fs.readFileSync(path.join(lhciResultsPath, resultFile), "utf8") fs.readFileSync(path.join(lhciResultsPath, resultFile), "utf8"),
); );
this.results.lighthouse = lhciData; this.results.lighthouse = lhciData;
console.log("✅ Lighthouse CI completed"); console.log("✅ Lighthouse CI completed");
@@ -248,7 +248,7 @@ class PerformanceTester {
const reportPath = path.join( const reportPath = path.join(
TEST_RESULTS_DIR, TEST_RESULTS_DIR,
"performance-test-report.json" "performance-test-report.json",
); );
fs.writeFileSync(reportPath, JSON.stringify(this.results, null, 2)); fs.writeFileSync(reportPath, JSON.stringify(this.results, null, 2));
@@ -262,7 +262,7 @@ class PerformanceTester {
generateMarkdownReport() { generateMarkdownReport() {
const reportPath = path.join( const reportPath = path.join(
TEST_RESULTS_DIR, TEST_RESULTS_DIR,
"performance-test-report.md" "performance-test-report.md",
); );
let report = `# Performance Test Report\n\n`; let report = `# Performance Test Report\n\n`;
@@ -310,7 +310,7 @@ class PerformanceTester {
} (exceeds ${ } (exceeds ${
violation.budget violation.budget
}) - ${violation.severity.toUpperCase()}\n`; }) - ${violation.severity.toUpperCase()}\n`;
} },
); );
} else { } else {
report += `✅ No performance budget violations found\n\n`; report += `✅ No performance budget violations found\n\n`;
+2 -2
View File
@@ -289,7 +289,7 @@ export default WebVitalsDashboard;
if (file.endsWith(".json")) { if (file.endsWith(".json")) {
const metric = file.replace(".json", ""); const metric = file.replace(".json", "");
const data = JSON.parse( const data = JSON.parse(
fs.readFileSync(path.join(WEB_VITALS_DIR, file), "utf8") fs.readFileSync(path.join(WEB_VITALS_DIR, file), "utf8"),
); );
if (data.length > 0) { if (data.length > 0) {
@@ -310,7 +310,7 @@ export default WebVitalsDashboard;
max: values.length > 0 ? Math.max(...values) : 0, max: values.length > 0 ? Math.max(...values) : 0,
goodCount: ratings.filter((r) => r === "good").length, goodCount: ratings.filter((r) => r === "good").length,
needsImprovementCount: ratings.filter( needsImprovementCount: ratings.filter(
(r) => r === "needs-improvement" (r) => r === "needs-improvement",
).length, ).length,
poorCount: ratings.filter((r) => r === "poor").length, poorCount: ratings.filter((r) => r === "poor").length,
}; };
-2
View File
@@ -19,5 +19,3 @@ export default {
}, },
}, },
}; };
export default ErrorBoundary;
+6 -6
View File
@@ -47,7 +47,7 @@ describe("LogoWall Component", () => {
render(<LogoWall />); render(<LogoWall />);
expect( expect(
screen.getByText("Trusted by leading cooperators") screen.getByText("Trusted by leading cooperators"),
).toBeInTheDocument(); ).toBeInTheDocument();
}); });
@@ -64,7 +64,7 @@ describe("LogoWall Component", () => {
const section = document.querySelector("section"); const section = document.querySelector("section");
expect(section).toHaveClass( expect(section).toHaveClass(
"p-[var(--spacing-scale-032)]", "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 />); render(<LogoWall />);
const grid = document.querySelector( 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).toBeInTheDocument();
expect(grid).toHaveClass("sm:grid-cols-3", "sm:grid-rows-2", "md:flex"); 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"); const foodNotBombsLogo = screen.getByAltText("Food Not Bombs");
expect(foodNotBombsLogo).toHaveAttribute( expect(foodNotBombsLogo).toHaveAttribute(
"src", "src",
"/assets/Section/Logo_FoodNotBombs.png" "/assets/Section/Logo_FoodNotBombs.png",
); );
expect(foodNotBombsLogo).toHaveClass("h-11", "lg:h-14", "xl:h-[70px]"); expect(foodNotBombsLogo).toHaveClass("h-11", "lg:h-14", "xl:h-[70px]");
}); });
@@ -109,7 +109,7 @@ describe("LogoWall Component", () => {
render(<LogoWall />); render(<LogoWall />);
const logoContainers = document.querySelectorAll( const logoContainers = document.querySelectorAll(
'[class*="hover:opacity-100"]' '[class*="hover:opacity-100"]',
); );
expect(logoContainers.length).toBeGreaterThan(0); expect(logoContainers.length).toBeGreaterThan(0);
}); });
@@ -129,7 +129,7 @@ describe("LogoWall Component", () => {
render(<LogoWall />); render(<LogoWall />);
const logoContainers = document.querySelectorAll( const logoContainers = document.querySelectorAll(
'[class*="transition-opacity duration-500"]' '[class*="transition-opacity duration-500"]',
); );
expect(logoContainers.length).toBeGreaterThan(0); expect(logoContainers.length).toBeGreaterThan(0);
}); });