Files
HiveGrid-Wireframes/hivegrid-cloud/tests/e2e/mobile-public.spec.ts
T

114 lines
5.1 KiB
TypeScript

import { expect, test } from "./utils/test";
import { expectNoCriticalA11yViolations } from "./utils/axe";
import { compactMobileViewport, expectNoHorizontalOverflow, narrowMobileViewport } from "./utils/mobile";
test.describe("mobile public pages", () => {
test.use({ viewport: narrowMobileViewport, isMobile: true, hasTouch: true });
test("landing page fits a narrow mobile viewport", async ({ page }) => {
await page.goto("/", { waitUntil: "domcontentloaded" });
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
test("not-found page fits a narrow mobile viewport", async ({ page }) => {
await page.goto("/__nonexistent_route__", { waitUntil: "domcontentloaded" });
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
test("feature-disabled page has no mobile overflow or critical a11y violations", async ({ page }) => {
await page.goto("/feature-disabled?feature=Advanced%20reports&tenant=acme", { waitUntil: "domcontentloaded" });
await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
await expect(page.getByRole("link", { name: /dashboard/i })).toHaveAttribute("href", /\/acme\/dashboard$/);
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
for (const errorPath of ["/401", "/403", "/500"]) {
test(`${errorPath} has no mobile overflow or critical a11y violations`, async ({ page }) => {
await page.goto(errorPath, { waitUntil: "domcontentloaded" });
await expect(page.locator('[data-testid="error-page"]')).toBeVisible();
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
}
for (const publicPage of [
{ path: "/privacy-policy", heading: /privacy policy|datenschutzerklarung|datenschutzerklärung/i },
{ path: "/terms-and-conditions", heading: /terms and conditions|allgemeine geschaftsbedingungen|allgemeine geschäftsbedingungen/i },
]) {
test(`${publicPage.path} has no mobile overflow or critical a11y violations`, async ({ page }) => {
await page.goto(publicPage.path, { waitUntil: "domcontentloaded" });
await expect(page.getByRole("heading", { level: 1, name: publicPage.heading })).toBeVisible();
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
}
test("public footer selectors open without mobile overflow", async ({ page }) => {
await page.goto("/privacy-policy", { waitUntil: "domcontentloaded" });
await page
.getByRole("button", { name: /language|sprache/i })
.last()
.click();
await expect(page.getByRole("menu", { name: /language|sprache/i })).toBeVisible();
await expectNoHorizontalOverflow(page);
await page.keyboard.press("Escape");
// Radix keeps the closing menu mounted during its exit animation; wait for it
// to detach so the theme menu is the only matching role="menu".
await expect(page.getByRole("menu", { name: /language|sprache/i })).toBeHidden();
await page.getByRole("button", { name: /theme/i }).last().click();
await expect(page.getByRole("menu", { name: /theme/i })).toBeVisible();
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
});
test.describe("compact mobile public pages", () => {
test.use({ viewport: compactMobileViewport, isMobile: true, hasTouch: true });
for (const route of ["/", "/401", "/403", "/500", "/privacy-policy", "/terms-and-conditions"]) {
test(`${route} fits a 320px mobile viewport`, async ({ page }) => {
await page.goto(route, { waitUntil: "domcontentloaded" });
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
}
test("feature-disabled page handles long labels on compact mobile", async ({ page }) => {
const feature = "VeryLongUnbrokenFeatureNameThatShouldStillWrapSafelyOnSmallMobileScreens";
await page.goto(`/feature-disabled?feature=${feature}&tenant=acme`, { waitUntil: "domcontentloaded" });
await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
test("public footer selectors stay inside a 320px viewport", async ({ page }) => {
await page.goto("/privacy-policy", { waitUntil: "domcontentloaded" });
await page
.getByRole("button", { name: /language|sprache/i })
.last()
.click();
await expect(page.getByRole("menu", { name: /language|sprache/i })).toBeVisible();
await expectNoHorizontalOverflow(page);
await page.keyboard.press("Escape");
// Radix keeps the closing menu mounted during its exit animation; wait for it
// to detach so the theme menu is the only matching role="menu".
await expect(page.getByRole("menu", { name: /language|sprache/i })).toBeHidden();
await page.getByRole("button", { name: /theme/i }).last().click();
await expect(page.getByRole("menu", { name: /theme/i })).toBeVisible();
await expectNoHorizontalOverflow(page);
await expectNoCriticalA11yViolations(page);
});
});