Files
community-rule/tests/e2e/performance.spec.ts
T
adilallo a30bf6be4c
CI Pipeline / e2e (chromium) (pull_request) Successful in 6m13s
CI Pipeline / e2e (firefox) (pull_request) Successful in 7m3s
CI Pipeline / e2e (webkit) (pull_request) Successful in 5m52s
CI Pipeline / visual-regression (pull_request) Successful in 7m48s
CI Pipeline / performance (pull_request) Successful in 7m59s
CI Pipeline / lint (pull_request) Successful in 6m16s
CI Pipeline / build (pull_request) Successful in 5m30s
CI Pipeline / test (pull_request) Successful in 6m26s
Update E2E tests and simplify performance tests
2026-01-28 18:22:59 -07:00

126 lines
4.2 KiB
TypeScript

import { test, expect } from "@playwright/test";
// Performance budgets - simplified for E2E tests
// Comprehensive performance testing is handled by Lighthouse CI
const PERFORMANCE_BUDGETS = {
page_load_time: 4000, // 4 seconds
first_contentful_paint: 2500, // 2.5 seconds
largest_contentful_paint: 3000, // 3 seconds
first_input_delay: 150, // 150ms
ttfb: 1500, // 1.5 seconds
dom_content_loaded: 2000, // 2 seconds
full_load: 4000, // 4 seconds
};
test.describe("Performance Monitoring", () => {
test.beforeEach(async () => {
if (process.env.CI) test.slow();
});
test("homepage load performance", async ({ page }) => {
const startTime = Date.now();
// Navigate to homepage
await page.goto("/", { waitUntil: "load", timeout: 60000 });
const loadTime = Date.now() - startTime;
// Get performance metrics from browser
const metrics = await page.evaluate(() => {
const navigation = performance.getEntriesByType("navigation")[0];
const paint = performance.getEntriesByType("paint");
return {
ttfb: navigation?.responseStart - navigation?.requestStart || 0,
domContentLoaded:
navigation?.domContentLoadedEventEnd -
navigation?.domContentLoadedEventStart || 0,
load: navigation?.loadEventEnd - navigation?.loadEventStart || 0,
firstContentfulPaint:
paint.find((p) => p.name === "first-contentful-paint")?.startTime ||
0,
};
});
// Assert page load time is within budget
expect(loadTime).toBeLessThan(PERFORMANCE_BUDGETS.page_load_time);
// Assert individual metrics
expect(metrics.ttfb).toBeLessThan(PERFORMANCE_BUDGETS.ttfb);
expect(metrics.domContentLoaded).toBeLessThan(
PERFORMANCE_BUDGETS.dom_content_loaded,
);
expect(metrics.load).toBeLessThan(PERFORMANCE_BUDGETS.full_load);
expect(metrics.firstContentfulPaint).toBeLessThan(
PERFORMANCE_BUDGETS.first_contentful_paint,
);
});
test("core web vitals", async ({ page }) => {
await page.goto("/", { waitUntil: "load", timeout: 60000 });
await page.waitForLoadState("load");
// Get Core Web Vitals using browser Performance API
const coreWebVitals = (await page.evaluate(() => {
return new Promise<{ lcp: number; fid: number; cls: number }>(
(resolve) => {
const timeout = setTimeout(() => {
observer.disconnect();
resolve({ lcp: 0, fid: 0, cls: 0 }); // Default values if timeout
}, 10000); // 10 second timeout
const observer = new PerformanceObserver((list) => {
const entries = list.getEntries();
const metrics: { lcp?: number; fid?: number; cls?: number } = {};
for (const entry of entries) {
const e = entry as any;
if (
e.name === "LCP" ||
e.entryType === "largest-contentful-paint"
) {
metrics.lcp = e.startTime ?? 0;
} else if (e.name === "FID" || e.entryType === "first-input") {
metrics.fid = (e.processingStart ?? 0) - (e.startTime ?? 0);
} else if (e.name === "CLS" || e.entryType === "layout-shift") {
metrics.cls = e.value ?? 0;
}
}
if (
metrics.lcp !== undefined &&
metrics.fid !== undefined &&
metrics.cls !== undefined
) {
clearTimeout(timeout);
observer.disconnect();
resolve({
lcp: metrics.lcp,
fid: metrics.fid,
cls: metrics.cls,
});
}
});
observer.observe({
entryTypes: [
"largest-contentful-paint",
"first-input",
"layout-shift",
],
});
},
);
})) as { lcp: number; fid: number; cls: number };
// Assert Core Web Vitals are within acceptable ranges
expect(coreWebVitals.lcp).toBeLessThan(
PERFORMANCE_BUDGETS.largest_contentful_paint,
);
expect(coreWebVitals.fid).toBeLessThan(
PERFORMANCE_BUDGETS.first_input_delay,
);
expect(coreWebVitals.cls).toBeLessThan(0.1); // CLS should be less than 0.1
});
});