- Installed Playwright and Storybook packages - Created playwright.config.ts with viewport matrix and browser configurations - Installed Playwright chromium browser - Created e2e/viewport-matrix.spec.ts for viewport matrix testing - Created e2e/horizontal-overflow.spec.ts for horizontal overflow testing - Added test scripts to package.json (test:e2e, test:e2e:ui, test:e2e:viewport, test:e2e:overflow) - Updated LAUNCH_READY_UI_UX_ROADMAP.md checklist with testing infrastructure status
89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
/**
|
|
* Horizontal Overflow Tests
|
|
*
|
|
* Tests that no production route has accidental horizontal overflow
|
|
* across all viewport sizes.
|
|
*/
|
|
|
|
const routes = [
|
|
'/',
|
|
'/portfolio',
|
|
'/research',
|
|
'/plans',
|
|
'/markets',
|
|
'/screener',
|
|
'/watchlist',
|
|
'/alerts',
|
|
'/settings',
|
|
];
|
|
|
|
test.describe('Horizontal Overflow', () => {
|
|
routes.forEach((route) => {
|
|
test(`Route ${route} has no horizontal overflow`, async ({ page }) => {
|
|
await page.goto(route);
|
|
|
|
// Wait for page to load
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check body width vs viewport width
|
|
const metrics = await page.evaluate(() => {
|
|
const body = document.body;
|
|
const viewportWidth = window.innerWidth;
|
|
const bodyWidth = body.scrollWidth;
|
|
|
|
return {
|
|
bodyWidth,
|
|
viewportWidth,
|
|
overflow: bodyWidth > viewportWidth,
|
|
overflowAmount: bodyWidth - viewportWidth,
|
|
};
|
|
});
|
|
|
|
// Allow 1px tolerance for rounding errors
|
|
expect(metrics.overflowAmount).toBeLessThanOrEqual(1);
|
|
|
|
// Check for any elements causing overflow
|
|
const overflowElements = await page.evaluate(() => {
|
|
const elements: Array<{ tag: string; className: string; width: number; scrollWidth: number }> = [];
|
|
const allElements = document.querySelectorAll('*');
|
|
|
|
allElements.forEach((el) => {
|
|
const rect = el.getBoundingClientRect();
|
|
const scrollWidth = el.scrollWidth;
|
|
const clientWidth = el.clientWidth;
|
|
|
|
if (scrollWidth > clientWidth && scrollWidth > window.innerWidth) {
|
|
elements.push({
|
|
tag: el.tagName,
|
|
className: el.className,
|
|
width: clientWidth,
|
|
scrollWidth,
|
|
});
|
|
}
|
|
});
|
|
|
|
return elements;
|
|
});
|
|
|
|
expect(overflowElements.length).toBe(0);
|
|
});
|
|
});
|
|
|
|
test('Critical routes at common breakpoints', async ({ page }) => {
|
|
const breakpoints = [375, 768, 1024, 1200, 1440];
|
|
|
|
for (const width of breakpoints) {
|
|
await page.setViewportSize({ width, height: 800 });
|
|
await page.goto('/');
|
|
|
|
const overflowAmount = await page.evaluate(() => {
|
|
return document.body.scrollWidth - window.innerWidth;
|
|
});
|
|
|
|
expect(overflowAmount).toBeLessThanOrEqual(1);
|
|
}
|
|
});
|
|
});
|