p19-bug-fixes

This commit is contained in:
2026-02-13 16:57:45 -05:00
parent e2406bf978
commit f6beedd68f
75 changed files with 11989 additions and 48 deletions

151
e2e/tests/fixtures/viewports.ts vendored Normal file
View File

@@ -0,0 +1,151 @@
/**
* Viewport profile helpers for responsive testing
*/
export type ViewportSize = "mobile" | "tablet" | "desktop" | "widescreen";
export interface ViewportDimensions {
width: number;
height: number;
}
export const VIEWPORTS: Record<ViewportSize, ViewportDimensions> = {
mobile: { width: 375, height: 667 }, // iPhone SE / similar
tablet: { width: 768, height: 1024 }, // iPad / similar
desktop: { width: 1280, height: 720 }, // Standard desktop
widescreen: { width: 1920, height: 1080 }, // Large desktop
} as const;
export const VIEWPORT_SIZES: ViewportSize[] = [
"mobile",
"tablet",
"desktop",
"widescreen",
];
/**
* Breakpoint definitions matching CSS media queries
*/
export const BREAKPOINTS = {
sm: 640, // Small devices
md: 768, // Medium devices (tablet)
lg: 1024, // Large devices (desktop)
xl: 1280, // Extra large
"2xl": 1536, // 2X large
} as const;
/**
* Set viewport size
*/
export async function setViewport(
page: any,
size: ViewportSize,
): Promise<void> {
const dimensions = VIEWPORTS[size];
await page.setViewportSize(dimensions);
}
/**
* Get current viewport size
*/
export async function getViewport(page: any): Promise<ViewportDimensions> {
return page.evaluate(() => ({
width: window.innerWidth,
height: window.innerHeight,
}));
}
/**
* Assert viewport is at expected size
*/
export async function assertViewport(
page: any,
size: ViewportSize,
): Promise<void> {
const expected = VIEWPORTS[size];
const actual = await getViewport(page);
if (actual.width !== expected.width || actual.height !== expected.height) {
throw new Error(
`Expected viewport ${size} (${expected.width}x${expected.height}) ` +
`but got ${actual.width}x${actual.height}`,
);
}
}
/**
* Check if element has horizontal overflow
*/
export async function hasHorizontalOverflow(
page: any,
selector: string,
): Promise<boolean> {
return page.evaluate((sel: string) => {
const element = document.querySelector(sel);
if (!element) return false;
return element.scrollWidth > element.clientWidth;
}, selector);
}
/**
* Check if element is clipped (overflow hidden with content exceeding bounds)
*/
export async function isClipped(page: any, selector: string): Promise<boolean> {
return page.evaluate((sel: string) => {
const element = document.querySelector(sel);
if (!element) return false;
const style = window.getComputedStyle(element);
const rect = element.getBoundingClientRect();
// Check if element has overflow hidden and children exceed bounds
const children = element.children;
for (const child of children) {
const childRect = child.getBoundingClientRect();
if (childRect.right > rect.right || childRect.bottom > rect.bottom) {
return (
style.overflow === "hidden" ||
style.overflowX === "hidden" ||
style.overflowY === "hidden"
);
}
}
return false;
}, selector);
}
/**
* Run a test across all viewport sizes
*/
export function testAllViewports(
name: string,
testFn: (size: ViewportSize) => Promise<void> | void,
): void {
for (const size of VIEWPORT_SIZES) {
test(`${name} - ${size}`, async () => {
await testFn(size);
});
}
}
/**
* Check sticky element position
*/
export async function getStickyPosition(
page: any,
selector: string,
): Promise<{ top: number; isSticky: boolean }> {
return page.evaluate((sel: string) => {
const element = document.querySelector(sel);
if (!element) return { top: 0, isSticky: false };
const style = window.getComputedStyle(element);
const rect = element.getBoundingClientRect();
return {
top: rect.top,
isSticky: style.position === "sticky" || style.position === "fixed",
};
}, selector);
}