50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
import { requireAuth, injectAuth } from "./helpers";
|
|
|
|
const VIEWPORTS = [
|
|
{ name: "mobile-sm (375px)", width: 375, height: 812 },
|
|
{ name: "mobile-lg (430px)", width: 430, height: 932 },
|
|
{ name: "tablet (768px)", width: 768, height: 1024 },
|
|
{ name: "desktop (1280px)", width: 1280, height: 800 },
|
|
{ name: "desktop-xl (1440px)", width: 1440, height: 900 },
|
|
];
|
|
|
|
const ROUTES = ["/cap", "/leaderboard", "/community", "/settings", "/notifications"];
|
|
|
|
for (const vp of VIEWPORTS) {
|
|
test(`no horizontal overflow — ${vp.name}`, async ({ page }) => {
|
|
requireAuth();
|
|
await page.setViewportSize({ width: vp.width, height: vp.height });
|
|
await injectAuth(page);
|
|
|
|
for (const route of ROUTES) {
|
|
await page.goto(route);
|
|
await page.waitForLoadState("networkidle", { timeout: 15_000 });
|
|
|
|
const overflow = await page.evaluate(() => {
|
|
return document.documentElement.scrollWidth > document.documentElement.clientWidth;
|
|
});
|
|
expect(overflow, `Horizontal overflow at ${route} / ${vp.name}`).toBe(false);
|
|
}
|
|
});
|
|
|
|
test(`no interactive elements clipped off-screen — ${vp.name}`, async ({ page }) => {
|
|
requireAuth();
|
|
await page.setViewportSize({ width: vp.width, height: vp.height });
|
|
await injectAuth(page);
|
|
|
|
await page.goto("/cap");
|
|
await page.waitForLoadState("networkidle", { timeout: 15_000 });
|
|
|
|
const clipped = await page.evaluate((vpWidth) => {
|
|
return Array.from(document.querySelectorAll("button, a, input"))
|
|
.filter((el) => {
|
|
const r = el.getBoundingClientRect();
|
|
return r.right < 0 || r.left > vpWidth + 50;
|
|
}).length;
|
|
}, vp.width);
|
|
|
|
expect(clipped, `${clipped} elements clipped at ${vp.name}`).toBe(0);
|
|
});
|
|
}
|