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); }); });