test(web): add Playwright E2E and admin API test suite for RCA-19
Prepares the full QA test infrastructure for the admin frontend before all prerequisite feature tasks (RCA-12–18) are complete. - playwright.config.ts: 6 browser/device projects (Chromium, Firefox, WebKit, mobile Chrome, mobile Safari, tablet) - tests/e2e/01-login.spec.ts: login form, route guards, setup wizard - tests/e2e/02-dashboard.spec.ts: stats cards, device list, quick actions - tests/e2e/03-cookies.spec.ts: cookie list, search, detail panel, delete - tests/e2e/04-devices.spec.ts: device cards, revoke flow, status filter - tests/e2e/05-settings.spec.ts: three-tab layout, save/error toasts - tests/e2e/06-responsive.spec.ts: no horizontal scroll on mobile/tablet - tests/api/admin-api.spec.ts: REST API contract tests for all /admin/* endpoints - helpers/auth.ts: loginViaUI + loginViaAPI helpers - helpers/mock-api.ts: route intercept fixtures for all pages Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
63
web/tests/e2e/06-responsive.spec.ts
Normal file
63
web/tests/e2e/06-responsive.spec.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { test, expect, devices } from "@playwright/test";
|
||||
import { loginViaAPI } from "./helpers/auth.js";
|
||||
import { mockDashboard, mockCookies, mockDevices, mockSettings } from "./helpers/mock-api.js";
|
||||
|
||||
/**
|
||||
* Responsive layout tests
|
||||
*
|
||||
* These run on the default desktop viewport; the Playwright projects
|
||||
* in playwright.config.ts also exercise mobile-chrome, mobile-safari,
|
||||
* and tablet viewports automatically.
|
||||
*
|
||||
* This file adds explicit viewport-override tests for key layout expectations.
|
||||
*/
|
||||
|
||||
const PAGES = [
|
||||
{ path: "/dashboard", name: "Dashboard" },
|
||||
{ path: "/cookies", name: "Cookies" },
|
||||
{ path: "/devices", name: "Devices" },
|
||||
{ path: "/settings", name: "Settings" },
|
||||
];
|
||||
|
||||
for (const { path, name } of PAGES) {
|
||||
test.describe(`Responsive — ${name}`, () => {
|
||||
test.beforeEach(async ({ page, request }) => {
|
||||
await loginViaAPI(page, request);
|
||||
await mockDashboard(page);
|
||||
await mockCookies(page);
|
||||
await mockDevices(page);
|
||||
await mockSettings(page);
|
||||
});
|
||||
|
||||
test("renders without horizontal scroll on mobile (375px)", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 812 });
|
||||
await page.goto(path);
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
const scrollWidth = await page.evaluate(() => document.body.scrollWidth);
|
||||
const clientWidth = await page.evaluate(() => document.body.clientWidth);
|
||||
expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 1); // 1px tolerance
|
||||
});
|
||||
|
||||
test("renders without horizontal scroll on tablet (768px)", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 768, height: 1024 });
|
||||
await page.goto(path);
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
const scrollWidth = await page.evaluate(() => document.body.scrollWidth);
|
||||
const clientWidth = await page.evaluate(() => document.body.clientWidth);
|
||||
expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 1);
|
||||
});
|
||||
|
||||
test("navigation is reachable on mobile", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 812 });
|
||||
await page.goto(path);
|
||||
|
||||
// On mobile there's typically a hamburger menu or bottom nav
|
||||
const nav = page
|
||||
.getByRole("navigation")
|
||||
.or(page.getByRole("button", { name: /menu|nav/i }));
|
||||
await expect(nav.first()).toBeVisible();
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user