Files
huskies/frontend/tests/e2e/gateway-scroll.spec.ts

76 lines
2.6 KiB
TypeScript

import { expect, test } from "@playwright/test";
/// Regression test: gateway UI must have vertical scrolling when content
/// overflows the viewport. Verifies the `overflow: hidden` fix on
/// `html / body / #root` — without that fix the page is locked at y=0.
test.describe("Gateway UI scrolling", () => {
test("page scrolls when content exceeds viewport height", async ({
page,
}) => {
// Use a small viewport to guarantee overflow even with modest content.
await page.setViewportSize({ width: 1280, height: 400 });
// --- mock API endpoints ---
// Identify this server as a gateway.
await page.route("/gateway/mode", async (route) => {
await route.fulfill({ json: { mode: "gateway" } });
});
// Return enough agents to push the page past 400 px.
const agents = Array.from({ length: 15 }, (_, i) => ({
id: `agent-${i}`,
label: `Build Agent ${i}`,
address: `10.0.0.${i}:5000`,
registered_at: Date.now() / 1000 - 60,
last_seen: Date.now() / 1000 - 10,
}));
await page.route("/gateway/agents", async (route) => {
await route.fulfill({ json: agents });
});
await page.route("/api/gateway", async (route) => {
await route.fulfill({ json: { active: "", projects: [] } });
});
await page.route("/api/gateway/pipeline", async (route) => {
await route.fulfill({ json: { active: "", projects: {} } });
});
// Non-gateway APIs called by App.tsx on startup — respond quickly so the
// loading gate (`isCheckingProject`) clears and the gateway panel renders.
await page.route("/api/project", async (route) => {
await route.fulfill({ json: null });
});
await page.route("/api/projects", async (route) => {
await route.fulfill({ json: [] });
});
await page.route("/oauth/status", async (route) => {
await route.fulfill({ json: { authenticated: false } });
});
await page.route("/api/home", async (route) => {
await route.fulfill({ json: "/home/test" });
});
await page.goto("/");
// Wait until the gateway panel is visible.
await page.waitForSelector('[data-testid="add-agent-button"]');
// The scrolling element should be taller than the visible viewport.
const isOverflowing = await page.evaluate(() => {
const el =
document.scrollingElement ?? document.documentElement;
return el.scrollHeight > el.clientHeight;
});
expect(isOverflowing).toBe(true);
// Scrolling must actually move the viewport.
await page.evaluate(() => window.scrollBy(0, 300));
const scrollY = await page.evaluate(
() => document.scrollingElement?.scrollTop ?? window.scrollY,
);
expect(scrollY).toBeGreaterThan(0);
});
});